Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7341)

Unified Diff: chrome/browser/resources/file_manager/js/metadata/exif_parser.js

Issue 39123003: [Files.app] Split the JavaScript files into subdirectories: common, background, and foreground (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixed test failure. Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resources/file_manager/js/metadata/exif_parser.js
diff --git a/chrome/browser/resources/file_manager/js/metadata/exif_parser.js b/chrome/browser/resources/file_manager/js/metadata/exif_parser.js
deleted file mode 100644
index f81e5cc0b9f3068202988bf7a6cec331453ee19b..0000000000000000000000000000000000000000
--- a/chrome/browser/resources/file_manager/js/metadata/exif_parser.js
+++ /dev/null
@@ -1,439 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-var EXIF_MARK_SOI = 0xffd8; // Start of image data.
-var EXIF_MARK_SOS = 0xffda; // Start of "stream" (the actual image data).
-var EXIF_MARK_SOF = 0xffc0; // Start of "frame"
-var EXIF_MARK_EXIF = 0xffe1; // Start of exif block.
-
-var EXIF_ALIGN_LITTLE = 0x4949; // Indicates little endian exif data.
-var EXIF_ALIGN_BIG = 0x4d4d; // Indicates big endian exif data.
-
-var EXIF_TAG_TIFF = 0x002a; // First directory containing TIFF data.
-var EXIF_TAG_GPSDATA = 0x8825; // Pointer from TIFF to the GPS directory.
-var EXIF_TAG_EXIFDATA = 0x8769; // Pointer from TIFF to the EXIF IFD.
-var EXIF_TAG_SUBIFD = 0x014a; // Pointer from TIFF to "Extra" IFDs.
-
-var EXIF_TAG_JPG_THUMB_OFFSET = 0x0201; // Pointer from TIFF to thumbnail.
-var EXIF_TAG_JPG_THUMB_LENGTH = 0x0202; // Length of thumbnail data.
-
-var EXIF_TAG_ORIENTATION = 0x0112;
-var EXIF_TAG_X_DIMENSION = 0xA002;
-var EXIF_TAG_Y_DIMENSION = 0xA003;
-
-function ExifParser(parent) {
- ImageParser.call(this, parent, 'jpeg', /\.jpe?g$/i);
-}
-
-ExifParser.prototype = {__proto__: ImageParser.prototype};
-
-/**
- * @param {File} file // TODO(JSDOC).
- * @param {Object} metadata // TODO(JSDOC).
- * @param {function} callback // TODO(JSDOC).
- * @param {function} errorCallback // TODO(JSDOC).
- */
-ExifParser.prototype.parse = function(file, metadata, callback, errorCallback) {
- this.requestSlice(file, callback, errorCallback, metadata, 0);
-};
-
-/**
- * @param {File} file // TODO(JSDOC).
- * @param {function} callback // TODO(JSDOC).
- * @param {function} errorCallback // TODO(JSDOC).
- * @param {Object} metadata // TODO(JSDOC).
- * @param {number} filePos // TODO(JSDOC).
- * @param {number=} opt_length // TODO(JSDOC).
- */
-ExifParser.prototype.requestSlice = function(
- file, callback, errorCallback, metadata, filePos, opt_length) {
- // Read at least 1Kb so that we do not issue too many read requests.
- opt_length = Math.max(1024, opt_length || 0);
-
- var self = this;
- var reader = new FileReader();
- reader.onerror = errorCallback;
- reader.onload = function() { self.parseSlice(
- file, callback, errorCallback, metadata, filePos, reader.result);
- };
- reader.readAsArrayBuffer(file.slice(filePos, filePos + opt_length));
-};
-
-/**
- * @param {File} file // TODO(JSDOC).
- * @param {function} callback // TODO(JSDOC).
- * @param {function} errorCallback // TODO(JSDOC).
- * @param {Object} metadata // TODO(JSDOC).
- * @param {number} filePos // TODO(JSDOC).
- * @param {ArrayBuffer} buf // TODO(JSDOC).
- */
-ExifParser.prototype.parseSlice = function(
- file, callback, errorCallback, metadata, filePos, buf) {
- try {
- var br = new ByteReader(buf);
-
- if (!br.canRead(4)) {
- // We never ask for less than 4 bytes. This can only mean we reached EOF.
- throw new Error('Unexpected EOF @' + (filePos + buf.byteLength));
- }
-
- if (filePos == 0) {
- // First slice, check for the SOI mark.
- var firstMark = this.readMark(br);
- if (firstMark != EXIF_MARK_SOI)
- throw new Error('Invalid file header: ' + firstMark.toString(16));
- }
-
- var self = this;
- var reread = function(opt_offset, opt_bytes) {
- self.requestSlice(file, callback, errorCallback, metadata,
- filePos + br.tell() + (opt_offset || 0), opt_bytes);
- };
-
- while (true) {
- if (!br.canRead(4)) {
- // Cannot read the mark and the length, request a minimum-size slice.
- reread();
- return;
- }
-
- var mark = this.readMark(br);
- if (mark == EXIF_MARK_SOS)
- throw new Error('SOS marker found before SOF');
-
- var markLength = this.readMarkLength(br);
-
- var nextSectionStart = br.tell() + markLength;
- if (!br.canRead(markLength)) {
- // Get the entire section.
- if (filePos + br.tell() + markLength > file.size) {
- throw new Error(
- 'Invalid section length @' + (filePos + br.tell() - 2));
- }
- reread(-4, markLength + 4);
- return;
- }
-
- if (mark == EXIF_MARK_EXIF) {
- this.parseExifSection(metadata, buf, br);
- } else if (ExifParser.isSOF_(mark)) {
- // The most reliable size information is encoded in the SOF section.
- br.seek(1, ByteReader.SEEK_CUR); // Skip the precision byte.
- var height = br.readScalar(2);
- var width = br.readScalar(2);
- ExifParser.setImageSize(metadata, width, height);
- callback(metadata); // We are done!
- return;
- }
-
- br.seek(nextSectionStart, ByteReader.SEEK_BEG);
- }
- } catch (e) {
- errorCallback(e.toString());
- }
-};
-
-/**
- * @private
- * @param {number} mark // TODO(JSDOC).
- * @return {boolean} // TODO(JSDOC).
- */
-ExifParser.isSOF_ = function(mark) {
- // There are 13 variants of SOF fragment format distinguished by the last
- // hex digit of the mark, but the part we want is always the same.
- if ((mark & ~0xF) != EXIF_MARK_SOF) return false;
-
- // If the last digit is 4, 8 or 12 it is not really a SOF.
- var type = mark & 0xF;
- return (type != 4 && type != 8 && type != 12);
-};
-
-/**
- * @param {Object} metadata // TODO(JSDOC).
- * @param {ArrayBuffer} buf // TODO(JSDOC).
- * @param {ByteReader} br // TODO(JSDOC).
- */
-ExifParser.prototype.parseExifSection = function(metadata, buf, br) {
- var magic = br.readString(6);
- if (magic != 'Exif\0\0') {
- // Some JPEG files may have sections marked with EXIF_MARK_EXIF
- // but containing something else (e.g. XML text). Ignore such sections.
- this.vlog('Invalid EXIF magic: ' + magic + br.readString(100));
- return;
- }
-
- // Offsets inside the EXIF block are based after the magic string.
- // Create a new ByteReader based on the current position to make offset
- // calculations simpler.
- br = new ByteReader(buf, br.tell());
-
- var order = br.readScalar(2);
- if (order == EXIF_ALIGN_LITTLE) {
- br.setByteOrder(ByteReader.LITTLE_ENDIAN);
- } else if (order != EXIF_ALIGN_BIG) {
- this.log('Invalid alignment value: ' + order.toString(16));
- return;
- }
-
- var tag = br.readScalar(2);
- if (tag != EXIF_TAG_TIFF) {
- this.log('Invalid TIFF tag: ' + tag.toString(16));
- return;
- }
-
- metadata.littleEndian = (order == EXIF_ALIGN_LITTLE);
- metadata.ifd = {
- image: {},
- thumbnail: {}
- };
- var directoryOffset = br.readScalar(4);
-
- // Image directory.
- this.vlog('Read image directory.');
- br.seek(directoryOffset);
- directoryOffset = this.readDirectory(br, metadata.ifd.image);
- metadata.imageTransform = this.parseOrientation(metadata.ifd.image);
-
- // Thumbnail Directory chained from the end of the image directory.
- if (directoryOffset) {
- this.vlog('Read thumbnail directory.');
- br.seek(directoryOffset);
- this.readDirectory(br, metadata.ifd.thumbnail);
- // If no thumbnail orientation is encoded, assume same orientation as
- // the primary image.
- metadata.thumbnailTransform =
- this.parseOrientation(metadata.ifd.thumbnail) ||
- metadata.imageTransform;
- }
-
- // EXIF Directory may be specified as a tag in the image directory.
- if (EXIF_TAG_EXIFDATA in metadata.ifd.image) {
- this.vlog('Read EXIF directory.');
- directoryOffset = metadata.ifd.image[EXIF_TAG_EXIFDATA].value;
- br.seek(directoryOffset);
- metadata.ifd.exif = {};
- this.readDirectory(br, metadata.ifd.exif);
- }
-
- // GPS Directory may also be linked from the image directory.
- if (EXIF_TAG_GPSDATA in metadata.ifd.image) {
- this.vlog('Read GPS directory.');
- directoryOffset = metadata.ifd.image[EXIF_TAG_GPSDATA].value;
- br.seek(directoryOffset);
- metadata.ifd.gps = {};
- this.readDirectory(br, metadata.ifd.gps);
- }
-
- // Thumbnail may be linked from the image directory.
- if (EXIF_TAG_JPG_THUMB_OFFSET in metadata.ifd.thumbnail &&
- EXIF_TAG_JPG_THUMB_LENGTH in metadata.ifd.thumbnail) {
- this.vlog('Read thumbnail image.');
- br.seek(metadata.ifd.thumbnail[EXIF_TAG_JPG_THUMB_OFFSET].value);
- metadata.thumbnailURL = br.readImage(
- metadata.ifd.thumbnail[EXIF_TAG_JPG_THUMB_LENGTH].value);
- } else {
- this.vlog('Image has EXIF data, but no JPG thumbnail.');
- }
-};
-
-/**
- * @param {Object} metadata // TODO(JSDOC).
- * @param {number} width // TODO(JSDOC).
- * @param {number} height // TODO(JSDOC).
- */
-ExifParser.setImageSize = function(metadata, width, height) {
- if (metadata.imageTransform && metadata.imageTransform.rotate90) {
- metadata.width = height;
- metadata.height = width;
- } else {
- metadata.width = width;
- metadata.height = height;
- }
-};
-
-/**
- * @param {ByteReader} br // TODO(JSDOC).
- * @return {number} // TODO(JSDOC).
- */
-ExifParser.prototype.readMark = function(br) {
- return br.readScalar(2);
-};
-
-/**
- * @param {ByteReader} br // TODO(JSDOC).
- * @return {number} // TODO(JSDOC).
- */
-ExifParser.prototype.readMarkLength = function(br) {
- // Length includes the 2 bytes used to store the length.
- return br.readScalar(2) - 2;
-};
-
-/**
- * @param {ByteReader} br // TODO(JSDOC).
- * @param {Array.<Object>} tags // TODO(JSDOC).
- * @return {number} // TODO(JSDOC).
- */
-ExifParser.prototype.readDirectory = function(br, tags) {
- var entryCount = br.readScalar(2);
- for (var i = 0; i < entryCount; i++) {
- var tagId = br.readScalar(2);
- var tag = tags[tagId] = {id: tagId};
- tag.format = br.readScalar(2);
- tag.componentCount = br.readScalar(4);
- this.readTagValue(br, tag);
- }
-
- return br.readScalar(4);
-};
-
-/**
- * @param {ByteReader} br // TODO(JSDOC).
- * @param {Object} tag // TODO(JSDOC).
- */
-ExifParser.prototype.readTagValue = function(br, tag) {
- var self = this;
-
- function safeRead(size, readFunction, signed) {
- try {
- unsafeRead(size, readFunction, signed);
- } catch (ex) {
- self.log('error reading tag 0x' + tag.id.toString(16) + '/' +
- tag.format + ', size ' + tag.componentCount + '*' + size + ' ' +
- (ex.stack || '<no stack>') + ': ' + ex);
- tag.value = null;
- }
- }
-
- function unsafeRead(size, readFunction, signed) {
- if (!readFunction)
- readFunction = function(size) { return br.readScalar(size, signed) };
-
- var totalSize = tag.componentCount * size;
- if (totalSize < 1) {
- // This is probably invalid exif data, skip it.
- tag.componentCount = 1;
- tag.value = br.readScalar(4);
- return;
- }
-
- if (totalSize > 4) {
- // If the total size is > 4, the next 4 bytes will be a pointer to the
- // actual data.
- br.pushSeek(br.readScalar(4));
- }
-
- if (tag.componentCount == 1) {
- tag.value = readFunction(size);
- } else {
- // Read multiple components into an array.
- tag.value = [];
- for (var i = 0; i < tag.componentCount; i++)
- tag.value[i] = readFunction(size);
- }
-
- if (totalSize > 4) {
- // Go back to the previous position if we had to jump to the data.
- br.popSeek();
- } else if (totalSize < 4) {
- // Otherwise, if the value wasn't exactly 4 bytes, skip over the
- // unread data.
- br.seek(4 - totalSize, ByteReader.SEEK_CUR);
- }
- }
-
- switch (tag.format) {
- case 1: // Byte
- case 7: // Undefined
- safeRead(1);
- break;
-
- case 2: // String
- safeRead(1);
- if (tag.componentCount == 0) {
- tag.value = '';
- } else if (tag.componentCount == 1) {
- tag.value = String.fromCharCode(tag.value);
- } else {
- tag.value = String.fromCharCode.apply(null, tag.value);
- }
- break;
-
- case 3: // Short
- safeRead(2);
- break;
-
- case 4: // Long
- safeRead(4);
- break;
-
- case 9: // Signed Long
- safeRead(4, null, true);
- break;
-
- case 5: // Rational
- safeRead(8, function() {
- return [br.readScalar(4), br.readScalar(4)];
- });
- break;
-
- case 10: // Signed Rational
- safeRead(8, function() {
- return [br.readScalar(4, true), br.readScalar(4, true)];
- });
- break;
-
- default: // ???
- this.vlog('Unknown tag format 0x' + Number(tag.id).toString(16) +
- ': ' + tag.format);
- safeRead(4);
- break;
- }
-
- this.vlog('Read tag: 0x' + tag.id.toString(16) + '/' + tag.format + ': ' +
- tag.value);
-};
-
-/**
- * TODO(JSDOC)
- * @const
- * @type {Array.<number>}
- */
-ExifParser.SCALEX = [1, -1, -1, 1, 1, 1, -1, -1];
-
-/**
- * TODO(JSDOC)
- * @const
- * @type {Array.<number>}
- */
-ExifParser.SCALEY = [1, 1, -1, -1, -1, 1, 1, -1];
-
-/**
- * TODO(JSDOC)
- * @const
- * @type {Array.<number>}
- */
-ExifParser.ROTATE90 = [0, 0, 0, 0, 1, 1, 1, 1];
-
-/**
- * Transform exif-encoded orientation into a set of parameters compatible with
- * CSS and canvas transforms (scaleX, scaleY, rotation).
- *
- * @param {Object} ifd exif property dictionary (image or thumbnail).
- * @return {Object} // TODO(JSDOC).
- */
-ExifParser.prototype.parseOrientation = function(ifd) {
- if (ifd[EXIF_TAG_ORIENTATION]) {
- var index = (ifd[EXIF_TAG_ORIENTATION].value || 1) - 1;
- return {
- scaleX: ExifParser.SCALEX[index],
- scaleY: ExifParser.SCALEY[index],
- rotate90: ExifParser.ROTATE90[index]
- };
- }
- return null;
-};
-
-MetadataDispatcher.registerParserClass(ExifParser);

Powered by Google App Engine
This is Rietveld 408576698