1 | 'use strict';
|
2 |
|
3 |
|
4 |
|
5 | var str2arr = require('../common').str2arr;
|
6 | var sliceEq = require('../common').sliceEq;
|
7 | var readUInt16LE = require('../common').readUInt16LE;
|
8 | var readUInt16BE = require('../common').readUInt16BE;
|
9 | var readUInt32LE = require('../common').readUInt32LE;
|
10 | var readUInt32BE = require('../common').readUInt32BE;
|
11 |
|
12 |
|
13 | var SIG_1 = str2arr('II\x2A\0');
|
14 | var SIG_2 = str2arr('MM\0\x2A');
|
15 |
|
16 |
|
17 | function readUInt16(buffer, offset, is_big_endian) {
|
18 | return is_big_endian ? readUInt16BE(buffer, offset) : readUInt16LE(buffer, offset);
|
19 | }
|
20 |
|
21 | function readUInt32(buffer, offset, is_big_endian) {
|
22 | return is_big_endian ? readUInt32BE(buffer, offset) : readUInt32LE(buffer, offset);
|
23 | }
|
24 |
|
25 | function 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 |
|
38 | module.exports = function (data) {
|
39 | if (data.length < 8) return;
|
40 |
|
41 |
|
42 | if (!sliceEq(data, 0, SIG_1) && !sliceEq(data, 0, SIG_2)) return;
|
43 |
|
44 | var is_big_endian = (data[0] === 77 );
|
45 | var count = readUInt32(data, 4, is_big_endian) - 8;
|
46 |
|
47 | if (count < 0) return;
|
48 |
|
49 |
|
50 | var offset = count + 8;
|
51 |
|
52 | if (data.length - offset < 2) return;
|
53 |
|
54 |
|
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 |
|
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 | };
|