1 | 'use strict';
|
2 |
|
3 |
|
4 | var ParserStream = require('../common').ParserStream;
|
5 | var str2arr = require('../common').str2arr;
|
6 | var sliceEq = require('../common').sliceEq;
|
7 |
|
8 |
|
9 | var SIG_1 = str2arr('II\x2A\0');
|
10 | var SIG_2 = str2arr('MM\0\x2A');
|
11 |
|
12 |
|
13 | function readUInt16(buffer, offset, is_big_endian) {
|
14 | return is_big_endian ? buffer.readUInt16BE(offset) : buffer.readUInt16LE(offset);
|
15 | }
|
16 |
|
17 | function readUInt32(buffer, offset, is_big_endian) {
|
18 | return is_big_endian ? buffer.readUInt32BE(offset) : buffer.readUInt32LE(offset);
|
19 | }
|
20 |
|
21 | function 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 |
|
36 | module.exports = function () {
|
37 | var parser = new ParserStream();
|
38 |
|
39 |
|
40 | parser._bytes(8, function (data) {
|
41 |
|
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 );
|
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) {
|
59 | callback();
|
60 | return;
|
61 | }
|
62 |
|
63 | parser._skipBytes(count, callback);
|
64 | }
|
65 |
|
66 |
|
67 | safeSkip(parser, count, function () {
|
68 |
|
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 |
|
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 | };
|