UNPKG

2.83 kBJavaScriptView Raw
1'use strict';
2
3
4var ParserStream = require('../common').ParserStream;
5var str2arr = require('../common').str2arr;
6var sliceEq = require('../common').sliceEq;
7
8
9var SIG_1 = str2arr('II\x2A\0');
10var SIG_2 = str2arr('MM\0\x2A');
11
12
13function readUInt16(buffer, offset, is_big_endian) {
14 return is_big_endian ? buffer.readUInt16BE(offset) : buffer.readUInt16LE(offset);
15}
16
17function readUInt32(buffer, offset, is_big_endian) {
18 return is_big_endian ? buffer.readUInt32BE(offset) : buffer.readUInt32LE(offset);
19}
20
21function readIFDValue(data, data_offset, is_big_endian) {
22 var type = readUInt16(data, data_offset + 2, is_big_endian);
23 var values = readUInt32(data, data_offset + 4, is_big_endian);
24
25 if (values !== 1 || (type !== 3 && type !== 4)) {
26 return null;
27 }
28
29 if (type === 3) {
30 return readUInt16(data, data_offset + 8, is_big_endian);
31 }
32
33 return readUInt32(data, data_offset + 8, is_big_endian);
34}
35
36module.exports = function () {
37 var parser = new ParserStream();
38
39 // read header
40 parser._bytes(8, function (data) {
41 // check TIFF signature
42 if (!sliceEq(data, 0, SIG_1) && !sliceEq(data, 0, SIG_2)) {
43 parser._skipBytes(Infinity);
44 parser.push(null);
45 return;
46 }
47
48 var is_big_endian = (data[0] === 77 /* 'MM' */);
49 var count = readUInt32(data, 4, is_big_endian) - 8;
50
51 if (count < 0) {
52 parser._skipBytes(Infinity);
53 parser.push(null);
54 return;
55 }
56
57 function safeSkip(parser, count, callback) {
58 if (count === 0) { // parser._skipBytes throws error if count === 0
59 callback();
60 return;
61 }
62
63 parser._skipBytes(count, callback);
64 }
65
66 // skip until IFD
67 safeSkip(parser, count, function () {
68 // read number of IFD entries
69 parser._bytes(2, function (data) {
70 var ifd_size = readUInt16(data, 0, is_big_endian) * 12;
71
72 if (ifd_size <= 0) {
73 parser._skipBytes(Infinity);
74 parser.push(null);
75 return;
76 }
77
78 // read all IFD entries
79 parser._bytes(ifd_size, function (data) {
80 parser._skipBytes(Infinity);
81
82 var i, width, height, tag;
83
84 for (i = 0; i < ifd_size; i += 12) {
85 tag = readUInt16(data, i, is_big_endian);
86
87 if (tag === 256) {
88 width = readIFDValue(data, i, is_big_endian);
89 } else if (tag === 257) {
90 height = readIFDValue(data, i, is_big_endian);
91 }
92 }
93
94 if (width && height) {
95 parser.push({
96 width: width,
97 height: height,
98 type: 'tiff',
99 mime: 'image/tiff',
100 wUnits: 'px',
101 hUnits: 'px'
102 });
103 }
104
105 parser.push(null);
106 });
107 });
108 });
109 });
110
111 return parser;
112};