1 | 'use strict';
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | var str2arr = require('../common').str2arr;
|
7 | var sliceEq = require('../common').sliceEq;
|
8 | var readUInt16LE = require('../common').readUInt16LE;
|
9 | var readUInt32LE = require('../common').readUInt32LE;
|
10 |
|
11 |
|
12 | var SIG_RIFF = str2arr('RIFF');
|
13 | var SIG_WEBPVP8 = str2arr('WEBPVP8');
|
14 |
|
15 |
|
16 | function parseVP8(data) {
|
17 | if (data.length < 16 + 14) return;
|
18 |
|
19 | if (data[16 + 7] !== 0x9D || data[16 + 8] !== 0x01 || data[16 + 9] !== 0x2A) {
|
20 |
|
21 | return;
|
22 | }
|
23 |
|
24 | return {
|
25 | width: readUInt16LE(data, 16 + 10) & 0x3FFF,
|
26 | height: readUInt16LE(data, 16 + 12) & 0x3FFF,
|
27 | type: 'webp',
|
28 | mime: 'image/webp',
|
29 | wUnits: 'px',
|
30 | hUnits: 'px'
|
31 | };
|
32 | }
|
33 |
|
34 |
|
35 | function parseVP8L(data) {
|
36 | if (data.length < 16 + 9) return;
|
37 |
|
38 | if (data[16 + 4] !== 0x2F) return;
|
39 |
|
40 | var bits = readUInt32LE(data, 16 + 5);
|
41 |
|
42 | return {
|
43 | width: (bits & 0x3FFF) + 1,
|
44 | height: ((bits >> 14) & 0x3FFF) + 1,
|
45 | type: 'webp',
|
46 | mime: 'image/webp',
|
47 | wUnits: 'px',
|
48 | hUnits: 'px'
|
49 | };
|
50 | }
|
51 |
|
52 |
|
53 | function parseVP8X(data) {
|
54 | if (data.length < 16 + 14) return;
|
55 |
|
56 | return {
|
57 |
|
58 |
|
59 | width: ((data[16 + 10] << 16) | (data[16 + 9] << 8) | data[16 + 8]) + 1,
|
60 | height: ((data[16 + 13] << 16) | (data[16 + 12] << 8) | data[16 + 11]) + 1,
|
61 | type: 'webp',
|
62 | mime: 'image/webp',
|
63 | wUnits: 'px',
|
64 | hUnits: 'px'
|
65 | };
|
66 | }
|
67 |
|
68 |
|
69 | module.exports = function (data) {
|
70 | if (data.length < 16) return;
|
71 |
|
72 |
|
73 | if (sliceEq(data, 0, SIG_RIFF) && sliceEq(data, 8, SIG_WEBPVP8)) {
|
74 | switch (data[15]) {
|
75 | case 32: return parseVP8(data);
|
76 | case 76: return parseVP8L(data);
|
77 | case 88: return parseVP8X(data);
|
78 | }
|
79 | }
|
80 | };
|