'use strict'; /* eslint-disable consistent-return */ var str2arr = require('../common').str2arr; var sliceEq = require('../common').sliceEq; var readUInt16LE = require('../common').readUInt16LE; var readUInt16BE = require('../common').readUInt16BE; var readUInt32LE = require('../common').readUInt32LE; var readUInt32BE = require('../common').readUInt32BE; var SIG_1 = str2arr('II\x2A\0'); var SIG_2 = str2arr('MM\0\x2A'); function readUInt16(buffer, offset, is_big_endian) { return is_big_endian ? readUInt16BE(buffer, offset) : readUInt16LE(buffer, offset); } function readUInt32(buffer, offset, is_big_endian) { return is_big_endian ? readUInt32BE(buffer, offset) : readUInt32LE(buffer, offset); } function readIFDValue(data, data_offset, is_big_endian) { var type = readUInt16(data, data_offset + 2, is_big_endian); var values = readUInt32(data, data_offset + 4, is_big_endian); if (values !== 1 || (type !== 3 && type !== 4)) return null; if (type === 3) { return readUInt16(data, data_offset + 8, is_big_endian); } return readUInt32(data, data_offset + 8, is_big_endian); } module.exports = function (data) { if (data.length < 8) return; // check TIFF signature if (!sliceEq(data, 0, SIG_1) && !sliceEq(data, 0, SIG_2)) return; var is_big_endian = (data[0] === 77 /* 'MM' */); var count = readUInt32(data, 4, is_big_endian) - 8; if (count < 0) return; // skip until IFD var offset = count + 8; if (data.length - offset < 2) return; // read number of IFD entries var ifd_size = readUInt16(data, offset + 0, is_big_endian) * 12; if (ifd_size <= 0) return; offset += 2; // read all IFD entries if (data.length - offset < ifd_size) return; var i, width, height, tag; for (i = 0; i < ifd_size; i += 12) { tag = readUInt16(data, offset + i, is_big_endian); if (tag === 256) { width = readIFDValue(data, offset + i, is_big_endian); } else if (tag === 257) { height = readIFDValue(data, offset + i, is_big_endian); } } if (width && height) { return { width: width, height: height, type: 'tiff', mime: 'image/tiff', wUnits: 'px', hUnits: 'px' }; } };