'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; };