| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 'use strict'; | |
| 6 | |
| 7 /* Base class for image metadata parsers that only need to look at a short | |
| 8 fragment at the start of the file */ | |
| 9 function SimpleImageParser(parent, type, urlFilter, headerSize) { | |
| 10 ImageParser.call(this, parent, type, urlFilter); | |
| 11 this.headerSize = headerSize; | |
| 12 } | |
| 13 | |
| 14 SimpleImageParser.prototype = {__proto__: ImageParser.prototype}; | |
| 15 | |
| 16 /** | |
| 17 * @param {File} file // TODO(JSDOC). | |
| 18 * @param {Object} metadata // TODO(JSDOC). | |
| 19 * @param {function(Object)} callback // TODO(JSDOC). | |
| 20 * @param {function(string)} errorCallback // TODO(JSDOC). | |
| 21 */ | |
| 22 SimpleImageParser.prototype.parse = function( | |
| 23 file, metadata, callback, errorCallback) { | |
| 24 var self = this; | |
| 25 util.readFileBytes(file, 0, this.headerSize, | |
| 26 function(file, br) { | |
| 27 try { | |
| 28 self.parseHeader(metadata, br); | |
| 29 callback(metadata); | |
| 30 } catch (e) { | |
| 31 errorCallback(e.toString()); | |
| 32 } | |
| 33 }, | |
| 34 errorCallback); | |
| 35 }; | |
| 36 | |
| 37 | |
| 38 function PngParser(parent) { | |
| 39 SimpleImageParser.call(this, parent, 'png', /\.png$/i, 24); | |
| 40 } | |
| 41 | |
| 42 PngParser.prototype = {__proto__: SimpleImageParser.prototype}; | |
| 43 | |
| 44 /** | |
| 45 * @param {Object} metadata // TODO(JSDOC). | |
| 46 * @param {ByteReader} br // TODO(JSDOC). | |
| 47 */ | |
| 48 PngParser.prototype.parseHeader = function(metadata, br) { | |
| 49 br.setByteOrder(ByteReader.BIG_ENDIAN); | |
| 50 | |
| 51 var signature = br.readString(8); | |
| 52 if (signature != '\x89PNG\x0D\x0A\x1A\x0A') | |
| 53 throw new Error('Invalid PNG signature: ' + signature); | |
| 54 | |
| 55 br.seek(12); | |
| 56 var ihdr = br.readString(4); | |
| 57 if (ihdr != 'IHDR') | |
| 58 throw new Error('Missing IHDR chunk'); | |
| 59 | |
| 60 metadata.width = br.readScalar(4); | |
| 61 metadata.height = br.readScalar(4); | |
| 62 }; | |
| 63 | |
| 64 MetadataDispatcher.registerParserClass(PngParser); | |
| 65 | |
| 66 | |
| 67 function BmpParser(parent) { | |
| 68 SimpleImageParser.call(this, parent, 'bmp', /\.bmp$/i, 28); | |
| 69 } | |
| 70 | |
| 71 BmpParser.prototype = {__proto__: SimpleImageParser.prototype}; | |
| 72 | |
| 73 /** | |
| 74 * @param {Object} metadata // TODO(JSDOC). | |
| 75 * @param {ByteReader} br // TODO(JSDOC). | |
| 76 */ | |
| 77 BmpParser.prototype.parseHeader = function(metadata, br) { | |
| 78 br.setByteOrder(ByteReader.LITTLE_ENDIAN); | |
| 79 | |
| 80 var signature = br.readString(2); | |
| 81 if (signature != 'BM') | |
| 82 throw new Error('Invalid BMP signature: ' + signature); | |
| 83 | |
| 84 br.seek(18); | |
| 85 metadata.width = br.readScalar(4); | |
| 86 metadata.height = br.readScalar(4); | |
| 87 }; | |
| 88 | |
| 89 MetadataDispatcher.registerParserClass(BmpParser); | |
| 90 | |
| 91 | |
| 92 function GifParser(parent) { | |
| 93 SimpleImageParser.call(this, parent, 'gif', /\.Gif$/i, 10); | |
| 94 } | |
| 95 | |
| 96 GifParser.prototype = {__proto__: SimpleImageParser.prototype}; | |
| 97 | |
| 98 /** | |
| 99 * @param {Object} metadata // TODO(JSDOC). | |
| 100 * @param {ByteReader} br // TODO(JSDOC). | |
| 101 */ | |
| 102 GifParser.prototype.parseHeader = function(metadata, br) { | |
| 103 br.setByteOrder(ByteReader.LITTLE_ENDIAN); | |
| 104 | |
| 105 var signature = br.readString(6); | |
| 106 if (!signature.match(/GIF8(7|9)a/)) | |
| 107 throw new Error('Invalid GIF signature: ' + signature); | |
| 108 | |
| 109 metadata.width = br.readScalar(2); | |
| 110 metadata.height = br.readScalar(2); | |
| 111 }; | |
| 112 | |
| 113 MetadataDispatcher.registerParserClass(GifParser); | |
| 114 | |
| 115 | |
| 116 function WebpParser(parent) { | |
| 117 SimpleImageParser.call(this, parent, 'webp', /\.webp$/i, 30); | |
| 118 } | |
| 119 | |
| 120 WebpParser.prototype = {__proto__: SimpleImageParser.prototype}; | |
| 121 | |
| 122 /** | |
| 123 * @param {Object} metadata // TODO(JSDOC). | |
| 124 * @param {ByteReader} br // TODO(JSDOC). | |
| 125 */ | |
| 126 WebpParser.prototype.parseHeader = function(metadata, br) { | |
| 127 br.setByteOrder(ByteReader.LITTLE_ENDIAN); | |
| 128 | |
| 129 var riffSignature = br.readString(4); | |
| 130 if (riffSignature != 'RIFF') | |
| 131 throw new Error('Invalid RIFF signature: ' + riffSignature); | |
| 132 | |
| 133 br.seek(8); | |
| 134 var webpSignature = br.readString(4); | |
| 135 if (webpSignature != 'WEBP') | |
| 136 throw new Error('Invalid WEBP signature: ' + webpSignature); | |
| 137 | |
| 138 var chunkFormat = br.readString(4); | |
| 139 if (chunkFormat != 'VP8 ' && chunkFormat != 'VP8L') | |
| 140 throw new Error('Invalid chunk format: ' + chunkFormat); | |
| 141 | |
| 142 if (chunkFormat == 'VP8 ') { | |
| 143 // VP8 lossy bitstream format. | |
| 144 br.seek(23); | |
| 145 var lossySignature = br.readScalar(2) | (br.readScalar(1) << 16); | |
| 146 if (lossySignature != 0x2a019d) | |
| 147 throw new Error('Invalid VP8 lossy bitstream signature: ' + | |
| 148 lossySignature); | |
| 149 | |
| 150 var dimensionBits = br.readScalar(4); | |
| 151 metadata.width = dimensionBits & 0x3fff; | |
| 152 metadata.height = (dimensionBits >> 16) & 0x3fff; | |
| 153 } else { | |
| 154 // VP8 lossless bitstream format. | |
| 155 br.seek(20); | |
| 156 var losslessSignature = br.readScalar(1); | |
| 157 if (losslessSignature != 0x2f) | |
| 158 throw new Error('Invalid VP8 lossless bitstream signature: ' + | |
| 159 losslessSignature); | |
| 160 | |
| 161 var dimensionBits = br.readScalar(4); | |
| 162 metadata.width = (dimensionBits & 0x3fff) + 1; | |
| 163 metadata.height = ((dimensionBits >> 14) & 0x3fff) + 1; | |
| 164 } | |
| 165 }; | |
| 166 | |
| 167 MetadataDispatcher.registerParserClass(WebpParser); | |
| OLD | NEW |