105 lines
2.2 KiB
JavaScript
105 lines
2.2 KiB
JavaScript
'use strict';
|
|
|
|
/* eslint-disable no-bitwise */
|
|
|
|
var ParserStream = require('../common').ParserStream;
|
|
var str2arr = require('../common').str2arr;
|
|
var sliceEq = require('../common').sliceEq;
|
|
|
|
|
|
var SIG_RIFF = str2arr('RIFF');
|
|
var SIG_WEBPVP8 = str2arr('WEBPVP8');
|
|
|
|
|
|
function parseVP8(parser) {
|
|
parser._bytes(14, function (data) {
|
|
parser._skipBytes(Infinity);
|
|
|
|
if (data[7] !== 0x9D || data[8] !== 0x01 || data[9] !== 0x2A) {
|
|
// bad code block signature
|
|
parser.push(null);
|
|
return;
|
|
}
|
|
|
|
parser.push({
|
|
width: data.readUInt16LE(10) & 0x3FFF,
|
|
height: data.readUInt16LE(12) & 0x3FFF,
|
|
type: 'webp',
|
|
mime: 'image/webp',
|
|
wUnits: 'px',
|
|
hUnits: 'px'
|
|
});
|
|
|
|
parser.push(null);
|
|
});
|
|
}
|
|
|
|
|
|
function parseVP8L(parser) {
|
|
parser._bytes(9, function (data) {
|
|
parser._skipBytes(Infinity);
|
|
|
|
if (data[4] !== 0x2F) {
|
|
// bad code block signature
|
|
parser.push(null);
|
|
return;
|
|
}
|
|
|
|
var bits = data.readUInt32LE(5);
|
|
|
|
parser.push({
|
|
width: (bits & 0x3FFF) + 1,
|
|
height: ((bits >> 14) & 0x3FFF) + 1,
|
|
type: 'webp',
|
|
mime: 'image/webp',
|
|
wUnits: 'px',
|
|
hUnits: 'px'
|
|
});
|
|
|
|
parser.push(null);
|
|
});
|
|
}
|
|
|
|
|
|
function parseVP8X(parser) {
|
|
parser._bytes(14, function (data) {
|
|
parser._skipBytes(Infinity);
|
|
|
|
parser.push({
|
|
// TODO: replace with `data.readUIntLE(8, 3) + 1`
|
|
// when 0.10 support is dropped
|
|
width: ((data[10] << 16) | (data[9] << 8) | data[8]) + 1,
|
|
height: ((data[13] << 16) | (data[12] << 8) | data[11]) + 1,
|
|
type: 'webp',
|
|
mime: 'image/webp',
|
|
wUnits: 'px',
|
|
hUnits: 'px'
|
|
});
|
|
|
|
parser.push(null);
|
|
});
|
|
}
|
|
|
|
|
|
module.exports = function () {
|
|
var parser = new ParserStream();
|
|
|
|
parser._bytes(16, function (data) {
|
|
|
|
// check /^RIFF....WEBPVP8([ LX])$/ signature
|
|
|
|
if (sliceEq(data, 0, SIG_RIFF) && sliceEq(data, 8, SIG_WEBPVP8)) {
|
|
switch (data[15]) {
|
|
case 32/*' '*/: parseVP8(parser); return;
|
|
case 76/* L */: parseVP8L(parser); return;
|
|
case 88/* X */: parseVP8X(parser); return;
|
|
}
|
|
} else {
|
|
parser._skipBytes(Infinity);
|
|
parser.push(null);
|
|
}
|
|
});
|
|
|
|
return parser;
|
|
};
|