UNPKG

2.22 kBJavaScriptView Raw
1'use strict';
2
3/* eslint-disable consistent-return */
4
5var str2arr = require('../common').str2arr;
6var sliceEq = require('../common').sliceEq;
7var readUInt16LE = require('../common').readUInt16LE;
8var readUInt16BE = require('../common').readUInt16BE;
9var readUInt32LE = require('../common').readUInt32LE;
10var readUInt32BE = require('../common').readUInt32BE;
11
12
13var SIG_1 = str2arr('II\x2A\0');
14var SIG_2 = str2arr('MM\0\x2A');
15
16
17function readUInt16(buffer, offset, is_big_endian) {
18 return is_big_endian ? readUInt16BE(buffer, offset) : readUInt16LE(buffer, offset);
19}
20
21function readUInt32(buffer, offset, is_big_endian) {
22 return is_big_endian ? readUInt32BE(buffer, offset) : readUInt32LE(buffer, offset);
23}
24
25function readIFDValue(data, data_offset, is_big_endian) {
26 var type = readUInt16(data, data_offset + 2, is_big_endian);
27 var values = readUInt32(data, data_offset + 4, is_big_endian);
28
29 if (values !== 1 || (type !== 3 && type !== 4)) return null;
30
31 if (type === 3) {
32 return readUInt16(data, data_offset + 8, is_big_endian);
33 }
34
35 return readUInt32(data, data_offset + 8, is_big_endian);
36}
37
38module.exports = function (data) {
39 if (data.length < 8) return;
40
41 // check TIFF signature
42 if (!sliceEq(data, 0, SIG_1) && !sliceEq(data, 0, SIG_2)) return;
43
44 var is_big_endian = (data[0] === 77 /* 'MM' */);
45 var count = readUInt32(data, 4, is_big_endian) - 8;
46
47 if (count < 0) return;
48
49 // skip until IFD
50 var offset = count + 8;
51
52 if (data.length - offset < 2) return;
53
54 // read number of IFD entries
55 var ifd_size = readUInt16(data, offset + 0, is_big_endian) * 12;
56
57 if (ifd_size <= 0) return;
58
59 offset += 2;
60
61 // read all IFD entries
62 if (data.length - offset < ifd_size) return;
63
64 var i, width, height, tag;
65
66 for (i = 0; i < ifd_size; i += 12) {
67 tag = readUInt16(data, offset + i, is_big_endian);
68
69 if (tag === 256) {
70 width = readIFDValue(data, offset + i, is_big_endian);
71 } else if (tag === 257) {
72 height = readIFDValue(data, offset + i, is_big_endian);
73 }
74 }
75
76 if (width && height) {
77 return {
78 width: width,
79 height: height,
80 type: 'tiff',
81 mime: 'image/tiff',
82 wUnits: 'px',
83 hUnits: 'px'
84 };
85 }
86};