Commit fedca72d authored by François Degros's avatar François Degros Committed by Commit Bot

[Files app] ES6 class for image_parsers.js

Bug: 778674
Change-Id: I4f545b2c914adc2dff16489610f4134b062609e8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1647494
Commit-Queue: François Degros <fdegros@chromium.org>
Commit-Queue: Luciano Pacheco <lucmult@chromium.org>
Auto-Submit: François Degros <fdegros@chromium.org>
Reviewed-by: default avatarLuciano Pacheco <lucmult@chromium.org>
Cr-Commit-Position: refs/heads/master@{#666563}
parent 0f7f51bb
...@@ -5,253 +5,245 @@ ...@@ -5,253 +5,245 @@
/** /**
* Base class for image metadata parsers that only need to look at a short * Base class for image metadata parsers that only need to look at a short
* fragment at the start of the file. * fragment at the start of the file.
* @param {MetadataParserLogger} parent Parent object. * @abstract
* @param {string} type Image type.
* @param {RegExp} urlFilter RegExp to match URLs.
* @param {number} headerSize Size of header.
* @constructor
* @struct
* @extends {ImageParser}
*/ */
function SimpleImageParser(parent, type, urlFilter, headerSize) { class SimpleImageParser extends ImageParser {
ImageParser.call(this, parent, type, urlFilter); /**
this.headerSize = headerSize; * @param {!MetadataParserLogger} parent Parent object.
} * @param {string} type Image type.
* @param {!RegExp} urlFilter RegExp to match URLs.
SimpleImageParser.prototype.__proto__ = ImageParser.prototype; * @param {number} headerSize Size of header.
*/
constructor(parent, type, urlFilter, headerSize) {
super(parent, type, urlFilter);
/** @public @const {number} */
this.headerSize = headerSize;
}
/** /**
* @param {File} file File to be parses. * @param {File} file File to be parses.
* @param {Object} metadata Metadata object of the file. * @param {Object} metadata Metadata object of the file.
* @param {function(Object)} callback Success callback. * @param {function(Object)} callback Success callback.
* @param {function(string)} errorCallback Error callback. * @param {function(string)} errorCallback Error callback.
*/ */
SimpleImageParser.prototype.parse = function( parse(file, metadata, callback, errorCallback) {
file, metadata, callback, errorCallback) { const self = this;
const self = this; MetadataParser.readFileBytes(file, 0, this.headerSize, (file, br) => {
MetadataParser.readFileBytes(file, 0, this.headerSize, (file, br) => { try {
try { self.parseHeader(metadata, br);
self.parseHeader(metadata, br); callback(metadata);
callback(metadata); } catch (e) {
} catch (e) { errorCallback(e.toString());
errorCallback(e.toString()); }
} }, errorCallback);
}, errorCallback); }
};
/** /**
* Parse header of an image. Inherited class must implement this. * Parse header of an image. Inherited class must implement this.
* @param {Object} metadata Dictionary to store the parsed metadata. * @abstract
* @param {ByteReader} byteReader Reader for header binary data. * @param {Object} metadata Dictionary to store the parsed metadata.
*/ * @param {ByteReader} byteReader Reader for header binary data.
SimpleImageParser.prototype.parseHeader = (metadata, byteReader) => {}; */
parseHeader(metadata, byteReader) {}
}
/** /**
* Parser for the header of png files. * Parser for the header of png files.
* @param {MetadataParserLogger} parent Parent object. * @final
* @extends {SimpleImageParser}
* @constructor
* @struct
*/ */
function PngParser(parent) { class PngParser extends SimpleImageParser {
SimpleImageParser.call(this, parent, 'png', /\.png$/i, 24); /**
} * @param {!MetadataParserLogger} parent Parent object.
*/
constructor(parent) {
super(parent, 'png', /\.png$/i, 24);
}
PngParser.prototype = { /**
__proto__: SimpleImageParser.prototype * @override
}; */
parseHeader(metadata, br) {
br.setByteOrder(ByteReader.BIG_ENDIAN);
/** const signature = br.readString(8);
* @override if (signature != '\x89PNG\x0D\x0A\x1A\x0A') {
*/ throw new Error('Invalid PNG signature: ' + signature);
PngParser.prototype.parseHeader = (metadata, br) => { }
br.setByteOrder(ByteReader.BIG_ENDIAN);
const signature = br.readString(8); br.seek(12);
if (signature != '\x89PNG\x0D\x0A\x1A\x0A') { const ihdr = br.readString(4);
throw new Error('Invalid PNG signature: ' + signature); if (ihdr != 'IHDR') {
} throw new Error('Missing IHDR chunk');
}
br.seek(12); metadata.width = br.readScalar(4);
const ihdr = br.readString(4); metadata.height = br.readScalar(4);
if (ihdr != 'IHDR') {
throw new Error('Missing IHDR chunk');
} }
}
metadata.width = br.readScalar(4);
metadata.height = br.readScalar(4);
};
registerParserClass(PngParser); registerParserClass(PngParser);
/** /**
* Parser for the header of bmp files. * Parser for the header of bmp files.
* @param {MetadataParserLogger} parent Parent object. * @final
* @constructor
* @extends {SimpleImageParser}
* @struct
*/ */
function BmpParser(parent) { class BmpParser extends SimpleImageParser {
SimpleImageParser.call(this, parent, 'bmp', /\.bmp$/i, 28); /**
} * @param {!MetadataParserLogger} parent Parent object.
*/
constructor(parent) {
super(parent, 'bmp', /\.bmp$/i, 28);
}
BmpParser.prototype = { /**
__proto__: SimpleImageParser.prototype * @override
}; */
parseHeader(metadata, br) {
br.setByteOrder(ByteReader.LITTLE_ENDIAN);
/** const signature = br.readString(2);
* @override if (signature != 'BM') {
*/ throw new Error('Invalid BMP signature: ' + signature);
BmpParser.prototype.parseHeader = (metadata, br) => { }
br.setByteOrder(ByteReader.LITTLE_ENDIAN);
const signature = br.readString(2); br.seek(18);
if (signature != 'BM') { metadata.width = br.readScalar(4);
throw new Error('Invalid BMP signature: ' + signature); metadata.height = br.readScalar(4);
} }
}
br.seek(18);
metadata.width = br.readScalar(4);
metadata.height = br.readScalar(4);
};
registerParserClass(BmpParser); registerParserClass(BmpParser);
/** /**
* Parser for the header of gif files. * Parser for the header of gif files.
* @param {MetadataParserLogger} parent Parent object. * @final
* @constructor
* @extends {SimpleImageParser}
* @struct
*/ */
function GifParser(parent) { class GifParser extends SimpleImageParser {
SimpleImageParser.call(this, parent, 'gif', /\.Gif$/i, 10); /**
} * @param {!MetadataParserLogger} parent Parent object.
*/
constructor(parent) {
super(parent, 'gif', /\.Gif$/i, 10);
}
GifParser.prototype = { /**
__proto__: SimpleImageParser.prototype * @override
}; */
parseHeader(metadata, br) {
br.setByteOrder(ByteReader.LITTLE_ENDIAN);
/** const signature = br.readString(6);
* @override if (!signature.match(/GIF8(7|9)a/)) {
*/ throw new Error('Invalid GIF signature: ' + signature);
GifParser.prototype.parseHeader = (metadata, br) => { }
br.setByteOrder(ByteReader.LITTLE_ENDIAN);
const signature = br.readString(6); metadata.width = br.readScalar(2);
if (!signature.match(/GIF8(7|9)a/)) { metadata.height = br.readScalar(2);
throw new Error('Invalid GIF signature: ' + signature);
} }
}
metadata.width = br.readScalar(2);
metadata.height = br.readScalar(2);
};
registerParserClass(GifParser); registerParserClass(GifParser);
/** /**
* Parser for the header of webp files. * Parser for the header of webp files.
* @param {MetadataParserLogger} parent Parent object. * @final
* @constructor
* @extends {SimpleImageParser}
* @struct
*/ */
function WebpParser(parent) { class WebpParser extends SimpleImageParser {
SimpleImageParser.call(this, parent, 'webp', /\.webp$/i, 30); /**
} * @param {!MetadataParserLogger} parent Parent object.
*/
constructor(parent) {
super(parent, 'webp', /\.webp$/i, 30);
}
WebpParser.prototype = { /**
__proto__: SimpleImageParser.prototype * @override
}; */
parseHeader(metadata, br) {
br.setByteOrder(ByteReader.LITTLE_ENDIAN);
/** const riffSignature = br.readString(4);
* @override if (riffSignature != 'RIFF') {
*/ throw new Error('Invalid RIFF signature: ' + riffSignature);
WebpParser.prototype.parseHeader = (metadata, br) => { }
br.setByteOrder(ByteReader.LITTLE_ENDIAN);
const riffSignature = br.readString(4);
if (riffSignature != 'RIFF') {
throw new Error('Invalid RIFF signature: ' + riffSignature);
}
br.seek(8); br.seek(8);
const webpSignature = br.readString(4); const webpSignature = br.readString(4);
if (webpSignature != 'WEBP') { if (webpSignature != 'WEBP') {
throw new Error('Invalid WEBP signature: ' + webpSignature); throw new Error('Invalid WEBP signature: ' + webpSignature);
} }
const chunkFormat = br.readString(4); const chunkFormat = br.readString(4);
switch (chunkFormat) { switch (chunkFormat) {
// VP8 lossy bitstream format. // VP8 lossy bitstream format.
case 'VP8 ': case 'VP8 ':
br.seek(23); br.seek(23);
const lossySignature = br.readScalar(2) | (br.readScalar(1) << 16); const lossySignature = br.readScalar(2) | (br.readScalar(1) << 16);
if (lossySignature != 0x2a019d) { if (lossySignature != 0x2a019d) {
throw new Error( throw new Error(
'Invalid VP8 lossy bitstream signature: ' + lossySignature); 'Invalid VP8 lossy bitstream signature: ' + lossySignature);
} }
var dimensionBits = br.readScalar(4); var dimensionBits = br.readScalar(4);
metadata.width = dimensionBits & 0x3fff; metadata.width = dimensionBits & 0x3fff;
metadata.height = (dimensionBits >> 16) & 0x3fff; metadata.height = (dimensionBits >> 16) & 0x3fff;
break; break;
// VP8 lossless bitstream format. // VP8 lossless bitstream format.
case 'VP8L': case 'VP8L':
br.seek(20); br.seek(20);
const losslessSignature = br.readScalar(1); const losslessSignature = br.readScalar(1);
if (losslessSignature != 0x2f) { if (losslessSignature != 0x2f) {
throw new Error( throw new Error(
'Invalid VP8 lossless bitstream signature: ' + losslessSignature); 'Invalid VP8 lossless bitstream signature: ' + losslessSignature);
} }
var dimensionBits = br.readScalar(4); var dimensionBits = br.readScalar(4);
metadata.width = (dimensionBits & 0x3fff) + 1; metadata.width = (dimensionBits & 0x3fff) + 1;
metadata.height = ((dimensionBits >> 14) & 0x3fff) + 1; metadata.height = ((dimensionBits >> 14) & 0x3fff) + 1;
break; break;
// VP8 extended file format. // VP8 extended file format.
case 'VP8X': case 'VP8X':
br.seek(20); br.seek(20);
// Read 24-bit value. ECMAScript assures left-to-right evaluation order. // Read 24-bit value. ECMAScript assures left-to-right evaluation order.
metadata.width = (br.readScalar(2) | (br.readScalar(1) << 16)) + 1; metadata.width = (br.readScalar(2) | (br.readScalar(1) << 16)) + 1;
metadata.height = (br.readScalar(2) | (br.readScalar(1) << 16)) + 1; metadata.height = (br.readScalar(2) | (br.readScalar(1) << 16)) + 1;
break; break;
default: default:
throw new Error('Invalid chunk format: ' + chunkFormat); throw new Error('Invalid chunk format: ' + chunkFormat);
}
} }
}; }
registerParserClass(WebpParser); registerParserClass(WebpParser);
/** /**
* Parser for the header of .ico icon files. * Parser for the header of .ico icon files.
* @param {MetadataParserLogger} parent Parent metadata dispatcher object. * @final
* @constructor
* @extends {SimpleImageParser}
*/ */
function IcoParser(parent) { class IcoParser extends SimpleImageParser {
SimpleImageParser.call(this, parent, 'ico', /\.ico$/i, 8); /**
} * @param {!MetadataParserLogger} parent Parent metadata dispatcher object.
*/
constructor(parent) {
super(parent, 'ico', /\.ico$/i, 8);
}
IcoParser.prototype = { /**
__proto__: SimpleImageParser.prototype * @override
}; */
parseHeader(metadata, byteReader) {
byteReader.setByteOrder(ByteReader.LITTLE_ENDIAN);
/** const signature = byteReader.readString(4);
* @override if (signature !== '\x00\x00\x00\x01') {
*/ throw new Error('Invalid ICO signature: ' + signature);
IcoParser.prototype.parseHeader = (metadata, byteReader) => { }
byteReader.setByteOrder(ByteReader.LITTLE_ENDIAN);
const signature = byteReader.readString(4); byteReader.seek(2);
if (signature !== '\x00\x00\x00\x01') { metadata.width = byteReader.readScalar(1);
throw new Error('Invalid ICO signature: ' + signature); metadata.height = byteReader.readScalar(1);
} }
}
byteReader.seek(2);
metadata.width = byteReader.readScalar(1);
metadata.height = byteReader.readScalar(1);
};
registerParserClass(IcoParser); registerParserClass(IcoParser);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment