first commit
This commit is contained in:
2
build/node_modules/exif-parser/.npmignore
generated
vendored
Normal file
2
build/node_modules/exif-parser/.npmignore
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
node_modules
|
||||
dist
|
||||
16
build/node_modules/exif-parser/CHANGELOG.md
generated
vendored
Normal file
16
build/node_modules/exif-parser/CHANGELOG.md
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
# Changelog
|
||||
|
||||
## 0.1.11 - July 9th 2017
|
||||
|
||||
- On nodejs, decode strings using UTF-8 instead of ASCII. Ideally we'd do this in the browser (UTF-16 currently) as well but that is a bit more work.
|
||||
|
||||
## 0.1.10 - July 9th 2017
|
||||
|
||||
- Ignore unknown tag formats instead of failing. There seem to be images with format 0 that otherwise contain valid data.
|
||||
- Fix bug in date parsing to not rely on the current date. This broke when the current date was the 31st of the month.
|
||||
- In case a tag appears more than once, take the first, not the last. For example some pictures taken on an iPhone suffer from duplicate Orientation tags, where the first one is the wrong one.
|
||||
- treat ModifyDate tag as a date value
|
||||
|
||||
## 0.1.9 - April 9th 2015
|
||||
|
||||
- parse ISO 8601 dates with timezone offset
|
||||
23
build/node_modules/exif-parser/LICENSE.md
generated
vendored
Normal file
23
build/node_modules/exif-parser/LICENSE.md
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
The MIT License
|
||||
===============
|
||||
|
||||
Copyright (c) 2010 Bruno Windels <bruno.windels@gmail.com>, Daniel Leinich <leinich@gmx.net>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
16
build/node_modules/exif-parser/Makefile
generated
vendored
Normal file
16
build/node_modules/exif-parser/Makefile
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
VERSION=$(shell node --eval "console.log(require('./package.json').version)")
|
||||
BUNDLE=dist/exif-parser-$(VERSION).js
|
||||
MIN_BUNDLE=dist/exif-parser-$(VERSION)-min.js
|
||||
BROWSERIFY=node_modules/.bin/browserify
|
||||
UGLIFY=node_modules/.bin/uglifyjs
|
||||
|
||||
build-browser-bundle: setup
|
||||
@echo "building $(BUNDLE) ..."
|
||||
@mkdir -p dist/
|
||||
@$(BROWSERIFY) --bare browser-global.js -o $(BUNDLE)
|
||||
@echo "building $(MIN_BUNDLE) ..."
|
||||
@$(UGLIFY) $(BUNDLE) -o $(MIN_BUNDLE) --compress
|
||||
setup:
|
||||
@npm install --no-optional --loglevel error --development
|
||||
clean:
|
||||
@rm -rf dist/
|
||||
83
build/node_modules/exif-parser/README.md
generated
vendored
Normal file
83
build/node_modules/exif-parser/README.md
generated
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
exif-parser
|
||||
========
|
||||
exif-parser is a parser for image metadata in the exif format, the most popular metadata format for jpeg and tiff images. It is written in pure javascript and has no external dependencies. It can also get the size of jpeg images and the size of the jpeg thumbnail embedded in the exif data. It can also extract the embedded thumbnail image.
|
||||
|
||||
### Installing
|
||||
|
||||
npm install exif-parser
|
||||
|
||||
You can also build a browser bundle to include it with a `<script>` tag in a HTML document, like this:
|
||||
|
||||
git clone git@github.com:bwindels/exif-parser.git
|
||||
cd exif-parser/
|
||||
make build-browser-bundle
|
||||
|
||||
Built versions of the bundles are also available in the [exif-parser-browser-bundles repo](https://github.com/bwindels/exif-parser-browser-bundles).
|
||||
|
||||
This will generate a `dist/exif-parser-(version).js` and `dist/exif-parser-(version)-min.js` file. These bundles expose the parser on the `ExifParser` global variable, which you would use like this:
|
||||
|
||||
var parser = window.ExifParser.create(arrayBuffer);
|
||||
|
||||
### Creating a parser
|
||||
To start parsing exif data, create a new parser like below. Note that the buffer you pass does not have to be the buffer for the full jpeg file. The exif section of a jpeg file has a maximum size of 65535 bytes and the section seems to always occur within the first 100 bytes of the file. So it is safe to only fetch the first 65635 bytes of a jpeg file and pass those to the parser.
|
||||
|
||||
The buffer you pass to create can be a node buffer or a DOM ArrayBuffer.
|
||||
|
||||
```
|
||||
var parser = require('exif-parser').create(buffer);
|
||||
var result = parser.parse();
|
||||
```
|
||||
|
||||
### Setting the flags
|
||||
|
||||
Before calling parse, you can set a number of flags on the parser, telling it how to behave while parsing.
|
||||
|
||||
Add fields in the binary format to result. Since these fields are mostly used for internal fields like Padding, you generally are not interested in these. If enabled, values for these fields will be a Buffer object in node or an ArrayBuffer in DOM environments (browsers).
|
||||
|
||||
parser.enableBinaryFields([boolean]), default false;
|
||||
|
||||
EXIF tags are organized into different sections, and to tell you the offset to other sections, EXIF uses certain tags. These tags don't tell you anything about the image, but are more for parsers to find out about all tags. Hence, these "pointer" fields are not included in the result tags field by default. Change this flag to include them nonetheless.
|
||||
|
||||
parser.enablePointers([boolean]), default false;
|
||||
|
||||
Resolve tags to their textual name, making result.tags a dictonary object instead of an array with the tag objects with no textual tag name.
|
||||
|
||||
parser.enableTagNames([boolean]), default true;
|
||||
|
||||
Read the image size while parsing.
|
||||
|
||||
parser.enableImageSize([boolean]), default true;
|
||||
|
||||
Read the EXIF tags. Could be useful to disable if you only want to read the image size.
|
||||
|
||||
parser.enableReturnTags([boolean]), default true;
|
||||
|
||||
EXIF values can be represented in a number of formats (fractions, degrees, arrays, ...) with different precision.
|
||||
Enabling this tries to cast values as much as possible to the appropriate javascript types like number, Date.
|
||||
|
||||
parser.enableSimpleValues([boolean]), default true;
|
||||
|
||||
### working with the result
|
||||
|
||||
#### Getting the tags
|
||||
the tags that were found while parsing are stored in ```result.tags``` unless you set ```parser.enableReturnTags(false)```. If ```parser.enableTagNames``` is set to true, ```result.tags``` will be an object with the key being the tag name and the value being the tag value. If ```parser.enableTagNames``` is set to false, ```result.tags``` will be an array of objects containing section, type and value properties.
|
||||
|
||||
#### Getting the image size
|
||||
If ```parser.enableImageSize``` is set to true, ```result.getImageSize()``` will give you the image size as an object with width and height properties.
|
||||
|
||||
#### Getting the thumbnail
|
||||
|
||||
You can check if there is a thumbnail present in the exif data with ```result.hasThumbnail()```. Exif supports thumbnails is jpeg and tiff format, though most are in jpeg format. You can check if there is a thumbnail present in a give format by passing the mime type: ```result.hasThumbnail("image/jpeg")```.
|
||||
|
||||
You can also get the image size of the thumbnail as an object with width and height properties: ```result.getThumbnailSize()```.
|
||||
|
||||
To get the node buffer or arraybuffer containing just the thumbnail, call ```result.getThumbnailBuffer()```
|
||||
|
||||
# Running the unit tests
|
||||
|
||||
Install `nodeunit` globally from npm if you haven't done so already.
|
||||
You can run the tests with `nodeunit test/test-*.js`.
|
||||
|
||||
# Contributions
|
||||
|
||||
I welcome external contributions through pull requests. If you do so, please don't use regular expressions. I don't like them, and don't want to maintain a project where they are used. Also, when fixing a bug please provide a regression unit test if it makes sense.
|
||||
3
build/node_modules/exif-parser/browser-global.js
generated
vendored
Normal file
3
build/node_modules/exif-parser/browser-global.js
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
var api = require('./index');
|
||||
var global = (1,eval)('this');
|
||||
global.ExifParser = api;
|
||||
16
build/node_modules/exif-parser/cmd/extract-thumbnail.js
generated
vendored
Normal file
16
build/node_modules/exif-parser/cmd/extract-thumbnail.js
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
var exifParser = require('../index');
|
||||
|
||||
var buf = require('fs').readFileSync(process.argv[2]);
|
||||
var parser = exifParser.create(buf).enableReturnTags(false);
|
||||
var result = parser.parse();
|
||||
|
||||
if(!result.hasThumbnail('image/jpeg')) {
|
||||
console.log('no jpeg thumbnail in this image');
|
||||
process.exit(1);
|
||||
} else {
|
||||
var size = result.getThumbnailSize();
|
||||
var buffer = result.getThumbnailBuffer();
|
||||
require('fs').writeFileSync(process.argv[3], buffer);
|
||||
console.log('wrote thumbnail of size ' + size.width + 'x' + size.height + ' to ' + process.argv[3] + ' (' + buffer.length + ' bytes)');
|
||||
process.exit(0);
|
||||
}
|
||||
9
build/node_modules/exif-parser/cmd/list.js
generated
vendored
Normal file
9
build/node_modules/exif-parser/cmd/list.js
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
var exifParser = require('../index');
|
||||
|
||||
var buf = require('fs').readFileSync(process.argv[2]);
|
||||
var parser = exifParser.create(buf);
|
||||
var result = parser.parse();
|
||||
|
||||
Object.keys(result.tags).forEach(function(name) {
|
||||
console.log(name+': ' + result.tags[name]);
|
||||
});
|
||||
18
build/node_modules/exif-parser/index.js
generated
vendored
Normal file
18
build/node_modules/exif-parser/index.js
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
var Parser = require('./lib/parser');
|
||||
|
||||
function getGlobal() {
|
||||
return (1,eval)('this');
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
create: function(buffer, global) {
|
||||
global = global || getGlobal();
|
||||
if(buffer instanceof global.ArrayBuffer) {
|
||||
var DOMBufferStream = require('./lib/dom-bufferstream');
|
||||
return new Parser(new DOMBufferStream(buffer, 0, buffer.byteLength, true, global));
|
||||
} else {
|
||||
var NodeBufferStream = require('./lib/bufferstream');
|
||||
return new Parser(new NodeBufferStream(buffer, 0, buffer.length, true));
|
||||
}
|
||||
}
|
||||
};
|
||||
88
build/node_modules/exif-parser/lib/bufferstream.js
generated
vendored
Normal file
88
build/node_modules/exif-parser/lib/bufferstream.js
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
function BufferStream(buffer, offset, length, bigEndian) {
|
||||
this.buffer = buffer;
|
||||
this.offset = offset || 0;
|
||||
length = typeof length === 'number' ? length : buffer.length;
|
||||
this.endPosition = this.offset + length;
|
||||
this.setBigEndian(bigEndian);
|
||||
}
|
||||
|
||||
BufferStream.prototype = {
|
||||
setBigEndian: function(bigEndian) {
|
||||
this.bigEndian = !!bigEndian;
|
||||
},
|
||||
nextUInt8: function() {
|
||||
var value = this.buffer.readUInt8(this.offset);
|
||||
this.offset += 1;
|
||||
return value;
|
||||
},
|
||||
nextInt8: function() {
|
||||
var value = this.buffer.readInt8(this.offset);
|
||||
this.offset += 1;
|
||||
return value;
|
||||
},
|
||||
nextUInt16: function() {
|
||||
var value = this.bigEndian ? this.buffer.readUInt16BE(this.offset) : this.buffer.readUInt16LE(this.offset);
|
||||
this.offset += 2;
|
||||
return value;
|
||||
},
|
||||
nextUInt32: function() {
|
||||
var value = this.bigEndian ? this.buffer.readUInt32BE(this.offset) : this.buffer.readUInt32LE(this.offset);
|
||||
this.offset += 4;
|
||||
return value;
|
||||
},
|
||||
nextInt16: function() {
|
||||
var value = this.bigEndian ? this.buffer.readInt16BE(this.offset) : this.buffer.readInt16LE(this.offset);
|
||||
this.offset += 2;
|
||||
return value;
|
||||
},
|
||||
nextInt32: function() {
|
||||
var value = this.bigEndian ? this.buffer.readInt32BE(this.offset) : this.buffer.readInt32LE(this.offset);
|
||||
this.offset += 4;
|
||||
return value;
|
||||
},
|
||||
nextFloat: function() {
|
||||
var value = this.bigEndian ? this.buffer.readFloatBE(this.offset) : this.buffer.readFloatLE(this.offset);
|
||||
this.offset += 4;
|
||||
return value;
|
||||
},
|
||||
nextDouble: function() {
|
||||
var value = this.bigEndian ? this.buffer.readDoubleBE(this.offset) : this.buffer.readDoubleLE(this.offset);
|
||||
this.offset += 8;
|
||||
return value;
|
||||
},
|
||||
nextBuffer: function(length) {
|
||||
var value = this.buffer.slice(this.offset, this.offset + length);
|
||||
this.offset += length;
|
||||
return value;
|
||||
},
|
||||
remainingLength: function() {
|
||||
return this.endPosition - this.offset;
|
||||
},
|
||||
nextString: function(length) {
|
||||
var value = this.buffer.toString('utf8', this.offset, this.offset + length);
|
||||
this.offset += length;
|
||||
return value;
|
||||
},
|
||||
mark: function() {
|
||||
var self = this;
|
||||
return {
|
||||
openWithOffset: function(offset) {
|
||||
offset = (offset || 0) + this.offset;
|
||||
return new BufferStream(self.buffer, offset, self.endPosition - offset, self.bigEndian);
|
||||
},
|
||||
offset: this.offset
|
||||
};
|
||||
},
|
||||
offsetFrom: function(marker) {
|
||||
return this.offset - marker.offset;
|
||||
},
|
||||
skip: function(amount) {
|
||||
this.offset += amount;
|
||||
},
|
||||
branch: function(offset, length) {
|
||||
length = typeof length === 'number' ? length : this.endPosition - (this.offset + offset);
|
||||
return new BufferStream(this.buffer, this.offset + offset, length, this.bigEndian);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = BufferStream;
|
||||
84
build/node_modules/exif-parser/lib/date.js
generated
vendored
Normal file
84
build/node_modules/exif-parser/lib/date.js
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
function parseNumber(s) {
|
||||
return parseInt(s, 10);
|
||||
}
|
||||
|
||||
//in seconds
|
||||
var hours = 3600;
|
||||
var minutes = 60;
|
||||
|
||||
//take date (year, month, day) and time (hour, minutes, seconds) digits in UTC
|
||||
//and return a timestamp in seconds
|
||||
function parseDateTimeParts(dateParts, timeParts) {
|
||||
dateParts = dateParts.map(parseNumber);
|
||||
timeParts = timeParts.map(parseNumber);
|
||||
var year = dateParts[0];
|
||||
var month = dateParts[1] - 1;
|
||||
var day = dateParts[2];
|
||||
var hours = timeParts[0];
|
||||
var minutes = timeParts[1];
|
||||
var seconds = timeParts[2];
|
||||
var date = Date.UTC(year, month, day, hours, minutes, seconds, 0);
|
||||
var timestamp = date / 1000;
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
//parse date with "2004-09-04T23:39:06-08:00" format,
|
||||
//one of the formats supported by ISO 8601, and
|
||||
//convert to utc timestamp in seconds
|
||||
function parseDateWithTimezoneFormat(dateTimeStr) {
|
||||
|
||||
var dateParts = dateTimeStr.substr(0, 10).split('-');
|
||||
var timeParts = dateTimeStr.substr(11, 8).split(':');
|
||||
var timezoneStr = dateTimeStr.substr(19, 6);
|
||||
var timezoneParts = timezoneStr.split(':').map(parseNumber);
|
||||
var timezoneOffset = (timezoneParts[0] * hours) +
|
||||
(timezoneParts[1] * minutes);
|
||||
|
||||
var timestamp = parseDateTimeParts(dateParts, timeParts);
|
||||
//minus because the timezoneOffset describes
|
||||
//how much the described time is ahead of UTC
|
||||
timestamp -= timezoneOffset;
|
||||
|
||||
if(typeof timestamp === 'number' && !isNaN(timestamp)) {
|
||||
return timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
//parse date with "YYYY:MM:DD hh:mm:ss" format, convert to utc timestamp in seconds
|
||||
function parseDateWithSpecFormat(dateTimeStr) {
|
||||
var parts = dateTimeStr.split(' '),
|
||||
dateParts = parts[0].split(':'),
|
||||
timeParts = parts[1].split(':');
|
||||
|
||||
var timestamp = parseDateTimeParts(dateParts, timeParts);
|
||||
|
||||
if(typeof timestamp === 'number' && !isNaN(timestamp)) {
|
||||
return timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
function parseExifDate(dateTimeStr) {
|
||||
//some easy checks to determine two common date formats
|
||||
|
||||
//is the date in the standard "YYYY:MM:DD hh:mm:ss" format?
|
||||
var isSpecFormat = dateTimeStr.length === 19 &&
|
||||
dateTimeStr.charAt(4) === ':';
|
||||
//is the date in the non-standard format,
|
||||
//"2004-09-04T23:39:06-08:00" to include a timezone?
|
||||
var isTimezoneFormat = dateTimeStr.length === 25 &&
|
||||
dateTimeStr.charAt(10) === 'T';
|
||||
var timestamp;
|
||||
|
||||
if(isTimezoneFormat) {
|
||||
return parseDateWithTimezoneFormat(dateTimeStr);
|
||||
}
|
||||
else if(isSpecFormat) {
|
||||
return parseDateWithSpecFormat(dateTimeStr);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
parseDateWithSpecFormat: parseDateWithSpecFormat,
|
||||
parseDateWithTimezoneFormat: parseDateWithTimezoneFormat,
|
||||
parseExifDate: parseExifDate
|
||||
};
|
||||
98
build/node_modules/exif-parser/lib/dom-bufferstream.js
generated
vendored
Normal file
98
build/node_modules/exif-parser/lib/dom-bufferstream.js
generated
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
/*jslint browser: true, devel: true, bitwise: false, debug: true, eqeq: false, es5: true, evil: false, forin: false, newcap: false, nomen: true, plusplus: true, regexp: false, unparam: false, sloppy: true, stupid: false, sub: false, todo: true, vars: true, white: true */
|
||||
|
||||
function DOMBufferStream(arrayBuffer, offset, length, bigEndian, global, parentOffset) {
|
||||
this.global = global;
|
||||
offset = offset || 0;
|
||||
length = length || (arrayBuffer.byteLength - offset);
|
||||
this.arrayBuffer = arrayBuffer.slice(offset, offset + length);
|
||||
this.view = new global.DataView(this.arrayBuffer, 0, this.arrayBuffer.byteLength);
|
||||
this.setBigEndian(bigEndian);
|
||||
this.offset = 0;
|
||||
this.parentOffset = (parentOffset || 0) + offset;
|
||||
}
|
||||
|
||||
DOMBufferStream.prototype = {
|
||||
setBigEndian: function(bigEndian) {
|
||||
this.littleEndian = !bigEndian;
|
||||
},
|
||||
nextUInt8: function() {
|
||||
var value = this.view.getUint8(this.offset);
|
||||
this.offset += 1;
|
||||
return value;
|
||||
},
|
||||
nextInt8: function() {
|
||||
var value = this.view.getInt8(this.offset);
|
||||
this.offset += 1;
|
||||
return value;
|
||||
},
|
||||
nextUInt16: function() {
|
||||
var value = this.view.getUint16(this.offset, this.littleEndian);
|
||||
this.offset += 2;
|
||||
return value;
|
||||
},
|
||||
nextUInt32: function() {
|
||||
var value = this.view.getUint32(this.offset, this.littleEndian);
|
||||
this.offset += 4;
|
||||
return value;
|
||||
},
|
||||
nextInt16: function() {
|
||||
var value = this.view.getInt16(this.offset, this.littleEndian);
|
||||
this.offset += 2;
|
||||
return value;
|
||||
},
|
||||
nextInt32: function() {
|
||||
var value = this.view.getInt32(this.offset, this.littleEndian);
|
||||
this.offset += 4;
|
||||
return value;
|
||||
},
|
||||
nextFloat: function() {
|
||||
var value = this.view.getFloat32(this.offset, this.littleEndian);
|
||||
this.offset += 4;
|
||||
return value;
|
||||
},
|
||||
nextDouble: function() {
|
||||
var value = this.view.getFloat64(this.offset, this.littleEndian);
|
||||
this.offset += 8;
|
||||
return value;
|
||||
},
|
||||
nextBuffer: function(length) {
|
||||
//this won't work in IE10
|
||||
var value = this.arrayBuffer.slice(this.offset, this.offset + length);
|
||||
this.offset += length;
|
||||
return value;
|
||||
},
|
||||
remainingLength: function() {
|
||||
return this.arrayBuffer.byteLength - this.offset;
|
||||
},
|
||||
nextString: function(length) {
|
||||
var value = this.arrayBuffer.slice(this.offset, this.offset + length);
|
||||
value = String.fromCharCode.apply(null, new this.global.Uint8Array(value));
|
||||
this.offset += length;
|
||||
return value;
|
||||
},
|
||||
mark: function() {
|
||||
var self = this;
|
||||
return {
|
||||
openWithOffset: function(offset) {
|
||||
offset = (offset || 0) + this.offset;
|
||||
return new DOMBufferStream(self.arrayBuffer, offset, self.arrayBuffer.byteLength - offset, !self.littleEndian, self.global, self.parentOffset);
|
||||
},
|
||||
offset: this.offset,
|
||||
getParentOffset: function() {
|
||||
return self.parentOffset;
|
||||
}
|
||||
};
|
||||
},
|
||||
offsetFrom: function(marker) {
|
||||
return this.parentOffset + this.offset - (marker.offset + marker.getParentOffset());
|
||||
},
|
||||
skip: function(amount) {
|
||||
this.offset += amount;
|
||||
},
|
||||
branch: function(offset, length) {
|
||||
length = typeof length === 'number' ? length : this.arrayBuffer.byteLength - (this.offset + offset);
|
||||
return new DOMBufferStream(this.arrayBuffer, this.offset + offset, length, !this.littleEndian, this.global, this.parentOffset);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = DOMBufferStream;
|
||||
468
build/node_modules/exif-parser/lib/exif-tags.js
generated
vendored
Normal file
468
build/node_modules/exif-parser/lib/exif-tags.js
generated
vendored
Normal file
@@ -0,0 +1,468 @@
|
||||
module.exports = {
|
||||
exif : {
|
||||
0x0001 : "InteropIndex",
|
||||
0x0002 : "InteropVersion",
|
||||
0x000B : "ProcessingSoftware",
|
||||
0x00FE : "SubfileType",
|
||||
0x00FF : "OldSubfileType",
|
||||
0x0100 : "ImageWidth",
|
||||
0x0101 : "ImageHeight",
|
||||
0x0102 : "BitsPerSample",
|
||||
0x0103 : "Compression",
|
||||
0x0106 : "PhotometricInterpretation",
|
||||
0x0107 : "Thresholding",
|
||||
0x0108 : "CellWidth",
|
||||
0x0109 : "CellLength",
|
||||
0x010A : "FillOrder",
|
||||
0x010D : "DocumentName",
|
||||
0x010E : "ImageDescription",
|
||||
0x010F : "Make",
|
||||
0x0110 : "Model",
|
||||
0x0111 : "StripOffsets",
|
||||
0x0112 : "Orientation",
|
||||
0x0115 : "SamplesPerPixel",
|
||||
0x0116 : "RowsPerStrip",
|
||||
0x0117 : "StripByteCounts",
|
||||
0x0118 : "MinSampleValue",
|
||||
0x0119 : "MaxSampleValue",
|
||||
0x011A : "XResolution",
|
||||
0x011B : "YResolution",
|
||||
0x011C : "PlanarConfiguration",
|
||||
0x011D : "PageName",
|
||||
0x011E : "XPosition",
|
||||
0x011F : "YPosition",
|
||||
0x0120 : "FreeOffsets",
|
||||
0x0121 : "FreeByteCounts",
|
||||
0x0122 : "GrayResponseUnit",
|
||||
0x0123 : "GrayResponseCurve",
|
||||
0x0124 : "T4Options",
|
||||
0x0125 : "T6Options",
|
||||
0x0128 : "ResolutionUnit",
|
||||
0x0129 : "PageNumber",
|
||||
0x012C : "ColorResponseUnit",
|
||||
0x012D : "TransferFunction",
|
||||
0x0131 : "Software",
|
||||
0x0132 : "ModifyDate",
|
||||
0x013B : "Artist",
|
||||
0x013C : "HostComputer",
|
||||
0x013D : "Predictor",
|
||||
0x013E : "WhitePoint",
|
||||
0x013F : "PrimaryChromaticities",
|
||||
0x0140 : "ColorMap",
|
||||
0x0141 : "HalftoneHints",
|
||||
0x0142 : "TileWidth",
|
||||
0x0143 : "TileLength",
|
||||
0x0144 : "TileOffsets",
|
||||
0x0145 : "TileByteCounts",
|
||||
0x0146 : "BadFaxLines",
|
||||
0x0147 : "CleanFaxData",
|
||||
0x0148 : "ConsecutiveBadFaxLines",
|
||||
0x014A : "SubIFD",
|
||||
0x014C : "InkSet",
|
||||
0x014D : "InkNames",
|
||||
0x014E : "NumberofInks",
|
||||
0x0150 : "DotRange",
|
||||
0x0151 : "TargetPrinter",
|
||||
0x0152 : "ExtraSamples",
|
||||
0x0153 : "SampleFormat",
|
||||
0x0154 : "SMinSampleValue",
|
||||
0x0155 : "SMaxSampleValue",
|
||||
0x0156 : "TransferRange",
|
||||
0x0157 : "ClipPath",
|
||||
0x0158 : "XClipPathUnits",
|
||||
0x0159 : "YClipPathUnits",
|
||||
0x015A : "Indexed",
|
||||
0x015B : "JPEGTables",
|
||||
0x015F : "OPIProxy",
|
||||
0x0190 : "GlobalParametersIFD",
|
||||
0x0191 : "ProfileType",
|
||||
0x0192 : "FaxProfile",
|
||||
0x0193 : "CodingMethods",
|
||||
0x0194 : "VersionYear",
|
||||
0x0195 : "ModeNumber",
|
||||
0x01B1 : "Decode",
|
||||
0x01B2 : "DefaultImageColor",
|
||||
0x01B3 : "T82Options",
|
||||
0x01B5 : "JPEGTables",
|
||||
0x0200 : "JPEGProc",
|
||||
0x0201 : "ThumbnailOffset",
|
||||
0x0202 : "ThumbnailLength",
|
||||
0x0203 : "JPEGRestartInterval",
|
||||
0x0205 : "JPEGLosslessPredictors",
|
||||
0x0206 : "JPEGPointTransforms",
|
||||
0x0207 : "JPEGQTables",
|
||||
0x0208 : "JPEGDCTables",
|
||||
0x0209 : "JPEGACTables",
|
||||
0x0211 : "YCbCrCoefficients",
|
||||
0x0212 : "YCbCrSubSampling",
|
||||
0x0213 : "YCbCrPositioning",
|
||||
0x0214 : "ReferenceBlackWhite",
|
||||
0x022F : "StripRowCounts",
|
||||
0x02BC : "ApplicationNotes",
|
||||
0x03E7 : "USPTOMiscellaneous",
|
||||
0x1000 : "RelatedImageFileFormat",
|
||||
0x1001 : "RelatedImageWidth",
|
||||
0x1002 : "RelatedImageHeight",
|
||||
0x4746 : "Rating",
|
||||
0x4747 : "XP_DIP_XML",
|
||||
0x4748 : "StitchInfo",
|
||||
0x4749 : "RatingPercent",
|
||||
0x800D : "ImageID",
|
||||
0x80A3 : "WangTag1",
|
||||
0x80A4 : "WangAnnotation",
|
||||
0x80A5 : "WangTag3",
|
||||
0x80A6 : "WangTag4",
|
||||
0x80E3 : "Matteing",
|
||||
0x80E4 : "DataType",
|
||||
0x80E5 : "ImageDepth",
|
||||
0x80E6 : "TileDepth",
|
||||
0x827D : "Model2",
|
||||
0x828D : "CFARepeatPatternDim",
|
||||
0x828E : "CFAPattern2",
|
||||
0x828F : "BatteryLevel",
|
||||
0x8290 : "KodakIFD",
|
||||
0x8298 : "Copyright",
|
||||
0x829A : "ExposureTime",
|
||||
0x829D : "FNumber",
|
||||
0x82A5 : "MDFileTag",
|
||||
0x82A6 : "MDScalePixel",
|
||||
0x82A7 : "MDColorTable",
|
||||
0x82A8 : "MDLabName",
|
||||
0x82A9 : "MDSampleInfo",
|
||||
0x82AA : "MDPrepDate",
|
||||
0x82AB : "MDPrepTime",
|
||||
0x82AC : "MDFileUnits",
|
||||
0x830E : "PixelScale",
|
||||
0x8335 : "AdventScale",
|
||||
0x8336 : "AdventRevision",
|
||||
0x835C : "UIC1Tag",
|
||||
0x835D : "UIC2Tag",
|
||||
0x835E : "UIC3Tag",
|
||||
0x835F : "UIC4Tag",
|
||||
0x83BB : "IPTC-NAA",
|
||||
0x847E : "IntergraphPacketData",
|
||||
0x847F : "IntergraphFlagRegisters",
|
||||
0x8480 : "IntergraphMatrix",
|
||||
0x8481 : "INGRReserved",
|
||||
0x8482 : "ModelTiePoint",
|
||||
0x84E0 : "Site",
|
||||
0x84E1 : "ColorSequence",
|
||||
0x84E2 : "IT8Header",
|
||||
0x84E3 : "RasterPadding",
|
||||
0x84E4 : "BitsPerRunLength",
|
||||
0x84E5 : "BitsPerExtendedRunLength",
|
||||
0x84E6 : "ColorTable",
|
||||
0x84E7 : "ImageColorIndicator",
|
||||
0x84E8 : "BackgroundColorIndicator",
|
||||
0x84E9 : "ImageColorValue",
|
||||
0x84EA : "BackgroundColorValue",
|
||||
0x84EB : "PixelIntensityRange",
|
||||
0x84EC : "TransparencyIndicator",
|
||||
0x84ED : "ColorCharacterization",
|
||||
0x84EE : "HCUsage",
|
||||
0x84EF : "TrapIndicator",
|
||||
0x84F0 : "CMYKEquivalent",
|
||||
0x8546 : "SEMInfo",
|
||||
0x8568 : "AFCP_IPTC",
|
||||
0x85B8 : "PixelMagicJBIGOptions",
|
||||
0x85D8 : "ModelTransform",
|
||||
0x8602 : "WB_GRGBLevels",
|
||||
0x8606 : "LeafData",
|
||||
0x8649 : "PhotoshopSettings",
|
||||
0x8769 : "ExifOffset",
|
||||
0x8773 : "ICC_Profile",
|
||||
0x877F : "TIFF_FXExtensions",
|
||||
0x8780 : "MultiProfiles",
|
||||
0x8781 : "SharedData",
|
||||
0x8782 : "T88Options",
|
||||
0x87AC : "ImageLayer",
|
||||
0x87AF : "GeoTiffDirectory",
|
||||
0x87B0 : "GeoTiffDoubleParams",
|
||||
0x87B1 : "GeoTiffAsciiParams",
|
||||
0x8822 : "ExposureProgram",
|
||||
0x8824 : "SpectralSensitivity",
|
||||
0x8825 : "GPSInfo",
|
||||
0x8827 : "ISO",
|
||||
0x8828 : "Opto-ElectricConvFactor",
|
||||
0x8829 : "Interlace",
|
||||
0x882A : "TimeZoneOffset",
|
||||
0x882B : "SelfTimerMode",
|
||||
0x8830 : "SensitivityType",
|
||||
0x8831 : "StandardOutputSensitivity",
|
||||
0x8832 : "RecommendedExposureIndex",
|
||||
0x8833 : "ISOSpeed",
|
||||
0x8834 : "ISOSpeedLatitudeyyy",
|
||||
0x8835 : "ISOSpeedLatitudezzz",
|
||||
0x885C : "FaxRecvParams",
|
||||
0x885D : "FaxSubAddress",
|
||||
0x885E : "FaxRecvTime",
|
||||
0x888A : "LeafSubIFD",
|
||||
0x9000 : "ExifVersion",
|
||||
0x9003 : "DateTimeOriginal",
|
||||
0x9004 : "CreateDate",
|
||||
0x9101 : "ComponentsConfiguration",
|
||||
0x9102 : "CompressedBitsPerPixel",
|
||||
0x9201 : "ShutterSpeedValue",
|
||||
0x9202 : "ApertureValue",
|
||||
0x9203 : "BrightnessValue",
|
||||
0x9204 : "ExposureCompensation",
|
||||
0x9205 : "MaxApertureValue",
|
||||
0x9206 : "SubjectDistance",
|
||||
0x9207 : "MeteringMode",
|
||||
0x9208 : "LightSource",
|
||||
0x9209 : "Flash",
|
||||
0x920A : "FocalLength",
|
||||
0x920B : "FlashEnergy",
|
||||
0x920C : "SpatialFrequencyResponse",
|
||||
0x920D : "Noise",
|
||||
0x920E : "FocalPlaneXResolution",
|
||||
0x920F : "FocalPlaneYResolution",
|
||||
0x9210 : "FocalPlaneResolutionUnit",
|
||||
0x9211 : "ImageNumber",
|
||||
0x9212 : "SecurityClassification",
|
||||
0x9213 : "ImageHistory",
|
||||
0x9214 : "SubjectArea",
|
||||
0x9215 : "ExposureIndex",
|
||||
0x9216 : "TIFF-EPStandardID",
|
||||
0x9217 : "SensingMethod",
|
||||
0x923A : "CIP3DataFile",
|
||||
0x923B : "CIP3Sheet",
|
||||
0x923C : "CIP3Side",
|
||||
0x923F : "StoNits",
|
||||
0x927C : "MakerNote",
|
||||
0x9286 : "UserComment",
|
||||
0x9290 : "SubSecTime",
|
||||
0x9291 : "SubSecTimeOriginal",
|
||||
0x9292 : "SubSecTimeDigitized",
|
||||
0x932F : "MSDocumentText",
|
||||
0x9330 : "MSPropertySetStorage",
|
||||
0x9331 : "MSDocumentTextPosition",
|
||||
0x935C : "ImageSourceData",
|
||||
0x9C9B : "XPTitle",
|
||||
0x9C9C : "XPComment",
|
||||
0x9C9D : "XPAuthor",
|
||||
0x9C9E : "XPKeywords",
|
||||
0x9C9F : "XPSubject",
|
||||
0xA000 : "FlashpixVersion",
|
||||
0xA001 : "ColorSpace",
|
||||
0xA002 : "ExifImageWidth",
|
||||
0xA003 : "ExifImageHeight",
|
||||
0xA004 : "RelatedSoundFile",
|
||||
0xA005 : "InteropOffset",
|
||||
0xA20B : "FlashEnergy",
|
||||
0xA20C : "SpatialFrequencyResponse",
|
||||
0xA20D : "Noise",
|
||||
0xA20E : "FocalPlaneXResolution",
|
||||
0xA20F : "FocalPlaneYResolution",
|
||||
0xA210 : "FocalPlaneResolutionUnit",
|
||||
0xA211 : "ImageNumber",
|
||||
0xA212 : "SecurityClassification",
|
||||
0xA213 : "ImageHistory",
|
||||
0xA214 : "SubjectLocation",
|
||||
0xA215 : "ExposureIndex",
|
||||
0xA216 : "TIFF-EPStandardID",
|
||||
0xA217 : "SensingMethod",
|
||||
0xA300 : "FileSource",
|
||||
0xA301 : "SceneType",
|
||||
0xA302 : "CFAPattern",
|
||||
0xA401 : "CustomRendered",
|
||||
0xA402 : "ExposureMode",
|
||||
0xA403 : "WhiteBalance",
|
||||
0xA404 : "DigitalZoomRatio",
|
||||
0xA405 : "FocalLengthIn35mmFormat",
|
||||
0xA406 : "SceneCaptureType",
|
||||
0xA407 : "GainControl",
|
||||
0xA408 : "Contrast",
|
||||
0xA409 : "Saturation",
|
||||
0xA40A : "Sharpness",
|
||||
0xA40B : "DeviceSettingDescription",
|
||||
0xA40C : "SubjectDistanceRange",
|
||||
0xA420 : "ImageUniqueID",
|
||||
0xA430 : "OwnerName",
|
||||
0xA431 : "SerialNumber",
|
||||
0xA432 : "LensInfo",
|
||||
0xA433 : "LensMake",
|
||||
0xA434 : "LensModel",
|
||||
0xA435 : "LensSerialNumber",
|
||||
0xA480 : "GDALMetadata",
|
||||
0xA481 : "GDALNoData",
|
||||
0xA500 : "Gamma",
|
||||
0xAFC0 : "ExpandSoftware",
|
||||
0xAFC1 : "ExpandLens",
|
||||
0xAFC2 : "ExpandFilm",
|
||||
0xAFC3 : "ExpandFilterLens",
|
||||
0xAFC4 : "ExpandScanner",
|
||||
0xAFC5 : "ExpandFlashLamp",
|
||||
0xBC01 : "PixelFormat",
|
||||
0xBC02 : "Transformation",
|
||||
0xBC03 : "Uncompressed",
|
||||
0xBC04 : "ImageType",
|
||||
0xBC80 : "ImageWidth",
|
||||
0xBC81 : "ImageHeight",
|
||||
0xBC82 : "WidthResolution",
|
||||
0xBC83 : "HeightResolution",
|
||||
0xBCC0 : "ImageOffset",
|
||||
0xBCC1 : "ImageByteCount",
|
||||
0xBCC2 : "AlphaOffset",
|
||||
0xBCC3 : "AlphaByteCount",
|
||||
0xBCC4 : "ImageDataDiscard",
|
||||
0xBCC5 : "AlphaDataDiscard",
|
||||
0xC427 : "OceScanjobDesc",
|
||||
0xC428 : "OceApplicationSelector",
|
||||
0xC429 : "OceIDNumber",
|
||||
0xC42A : "OceImageLogic",
|
||||
0xC44F : "Annotations",
|
||||
0xC4A5 : "PrintIM",
|
||||
0xC580 : "USPTOOriginalContentType",
|
||||
0xC612 : "DNGVersion",
|
||||
0xC613 : "DNGBackwardVersion",
|
||||
0xC614 : "UniqueCameraModel",
|
||||
0xC615 : "LocalizedCameraModel",
|
||||
0xC616 : "CFAPlaneColor",
|
||||
0xC617 : "CFALayout",
|
||||
0xC618 : "LinearizationTable",
|
||||
0xC619 : "BlackLevelRepeatDim",
|
||||
0xC61A : "BlackLevel",
|
||||
0xC61B : "BlackLevelDeltaH",
|
||||
0xC61C : "BlackLevelDeltaV",
|
||||
0xC61D : "WhiteLevel",
|
||||
0xC61E : "DefaultScale",
|
||||
0xC61F : "DefaultCropOrigin",
|
||||
0xC620 : "DefaultCropSize",
|
||||
0xC621 : "ColorMatrix1",
|
||||
0xC622 : "ColorMatrix2",
|
||||
0xC623 : "CameraCalibration1",
|
||||
0xC624 : "CameraCalibration2",
|
||||
0xC625 : "ReductionMatrix1",
|
||||
0xC626 : "ReductionMatrix2",
|
||||
0xC627 : "AnalogBalance",
|
||||
0xC628 : "AsShotNeutral",
|
||||
0xC629 : "AsShotWhiteXY",
|
||||
0xC62A : "BaselineExposure",
|
||||
0xC62B : "BaselineNoise",
|
||||
0xC62C : "BaselineSharpness",
|
||||
0xC62D : "BayerGreenSplit",
|
||||
0xC62E : "LinearResponseLimit",
|
||||
0xC62F : "CameraSerialNumber",
|
||||
0xC630 : "DNGLensInfo",
|
||||
0xC631 : "ChromaBlurRadius",
|
||||
0xC632 : "AntiAliasStrength",
|
||||
0xC633 : "ShadowScale",
|
||||
0xC634 : "DNGPrivateData",
|
||||
0xC635 : "MakerNoteSafety",
|
||||
0xC640 : "RawImageSegmentation",
|
||||
0xC65A : "CalibrationIlluminant1",
|
||||
0xC65B : "CalibrationIlluminant2",
|
||||
0xC65C : "BestQualityScale",
|
||||
0xC65D : "RawDataUniqueID",
|
||||
0xC660 : "AliasLayerMetadata",
|
||||
0xC68B : "OriginalRawFileName",
|
||||
0xC68C : "OriginalRawFileData",
|
||||
0xC68D : "ActiveArea",
|
||||
0xC68E : "MaskedAreas",
|
||||
0xC68F : "AsShotICCProfile",
|
||||
0xC690 : "AsShotPreProfileMatrix",
|
||||
0xC691 : "CurrentICCProfile",
|
||||
0xC692 : "CurrentPreProfileMatrix",
|
||||
0xC6BF : "ColorimetricReference",
|
||||
0xC6D2 : "PanasonicTitle",
|
||||
0xC6D3 : "PanasonicTitle2",
|
||||
0xC6F3 : "CameraCalibrationSig",
|
||||
0xC6F4 : "ProfileCalibrationSig",
|
||||
0xC6F5 : "ProfileIFD",
|
||||
0xC6F6 : "AsShotProfileName",
|
||||
0xC6F7 : "NoiseReductionApplied",
|
||||
0xC6F8 : "ProfileName",
|
||||
0xC6F9 : "ProfileHueSatMapDims",
|
||||
0xC6FA : "ProfileHueSatMapData1",
|
||||
0xC6FB : "ProfileHueSatMapData2",
|
||||
0xC6FC : "ProfileToneCurve",
|
||||
0xC6FD : "ProfileEmbedPolicy",
|
||||
0xC6FE : "ProfileCopyright",
|
||||
0xC714 : "ForwardMatrix1",
|
||||
0xC715 : "ForwardMatrix2",
|
||||
0xC716 : "PreviewApplicationName",
|
||||
0xC717 : "PreviewApplicationVersion",
|
||||
0xC718 : "PreviewSettingsName",
|
||||
0xC719 : "PreviewSettingsDigest",
|
||||
0xC71A : "PreviewColorSpace",
|
||||
0xC71B : "PreviewDateTime",
|
||||
0xC71C : "RawImageDigest",
|
||||
0xC71D : "OriginalRawFileDigest",
|
||||
0xC71E : "SubTileBlockSize",
|
||||
0xC71F : "RowInterleaveFactor",
|
||||
0xC725 : "ProfileLookTableDims",
|
||||
0xC726 : "ProfileLookTableData",
|
||||
0xC740 : "OpcodeList1",
|
||||
0xC741 : "OpcodeList2",
|
||||
0xC74E : "OpcodeList3",
|
||||
0xC761 : "NoiseProfile",
|
||||
0xC763 : "TimeCodes",
|
||||
0xC764 : "FrameRate",
|
||||
0xC772 : "TStop",
|
||||
0xC789 : "ReelName",
|
||||
0xC791 : "OriginalDefaultFinalSize",
|
||||
0xC792 : "OriginalBestQualitySize",
|
||||
0xC793 : "OriginalDefaultCropSize",
|
||||
0xC7A1 : "CameraLabel",
|
||||
0xC7A3 : "ProfileHueSatMapEncoding",
|
||||
0xC7A4 : "ProfileLookTableEncoding",
|
||||
0xC7A5 : "BaselineExposureOffset",
|
||||
0xC7A6 : "DefaultBlackRender",
|
||||
0xC7A7 : "NewRawImageDigest",
|
||||
0xC7A8 : "RawToPreviewGain",
|
||||
0xC7B5 : "DefaultUserCrop",
|
||||
0xEA1C : "Padding",
|
||||
0xEA1D : "OffsetSchema",
|
||||
0xFDE8 : "OwnerName",
|
||||
0xFDE9 : "SerialNumber",
|
||||
0xFDEA : "Lens",
|
||||
0xFE00 : "KDC_IFD",
|
||||
0xFE4C : "RawFile",
|
||||
0xFE4D : "Converter",
|
||||
0xFE4E : "WhiteBalance",
|
||||
0xFE51 : "Exposure",
|
||||
0xFE52 : "Shadows",
|
||||
0xFE53 : "Brightness",
|
||||
0xFE54 : "Contrast",
|
||||
0xFE55 : "Saturation",
|
||||
0xFE56 : "Sharpness",
|
||||
0xFE57 : "Smoothness",
|
||||
0xFE58 : "MoireFilter"
|
||||
|
||||
},
|
||||
gps : {
|
||||
0x0000 : 'GPSVersionID',
|
||||
0x0001 : 'GPSLatitudeRef',
|
||||
0x0002 : 'GPSLatitude',
|
||||
0x0003 : 'GPSLongitudeRef',
|
||||
0x0004 : 'GPSLongitude',
|
||||
0x0005 : 'GPSAltitudeRef',
|
||||
0x0006 : 'GPSAltitude',
|
||||
0x0007 : 'GPSTimeStamp',
|
||||
0x0008 : 'GPSSatellites',
|
||||
0x0009 : 'GPSStatus',
|
||||
0x000A : 'GPSMeasureMode',
|
||||
0x000B : 'GPSDOP',
|
||||
0x000C : 'GPSSpeedRef',
|
||||
0x000D : 'GPSSpeed',
|
||||
0x000E : 'GPSTrackRef',
|
||||
0x000F : 'GPSTrack',
|
||||
0x0010 : 'GPSImgDirectionRef',
|
||||
0x0011 : 'GPSImgDirection',
|
||||
0x0012 : 'GPSMapDatum',
|
||||
0x0013 : 'GPSDestLatitudeRef',
|
||||
0x0014 : 'GPSDestLatitude',
|
||||
0x0015 : 'GPSDestLongitudeRef',
|
||||
0x0016 : 'GPSDestLongitude',
|
||||
0x0017 : 'GPSDestBearingRef',
|
||||
0x0018 : 'GPSDestBearing',
|
||||
0x0019 : 'GPSDestDistanceRef',
|
||||
0x001A : 'GPSDestDistance',
|
||||
0x001B : 'GPSProcessingMethod',
|
||||
0x001C : 'GPSAreaInformation',
|
||||
0x001D : 'GPSDateStamp',
|
||||
0x001E : 'GPSDifferential',
|
||||
0x001F : 'GPSHPositioningError'
|
||||
}
|
||||
};
|
||||
165
build/node_modules/exif-parser/lib/exif.js
generated
vendored
Normal file
165
build/node_modules/exif-parser/lib/exif.js
generated
vendored
Normal file
@@ -0,0 +1,165 @@
|
||||
/*jslint browser: true, devel: true, bitwise: false, debug: true, eqeq: false, es5: true, evil: false, forin: false, newcap: false, nomen: true, plusplus: true, regexp: false, unparam: false, sloppy: true, stupid: false, sub: false, todo: true, vars: true, white: true */
|
||||
|
||||
function readExifValue(format, stream) {
|
||||
switch(format) {
|
||||
case 1: return stream.nextUInt8();
|
||||
case 3: return stream.nextUInt16();
|
||||
case 4: return stream.nextUInt32();
|
||||
case 5: return [stream.nextUInt32(), stream.nextUInt32()];
|
||||
case 6: return stream.nextInt8();
|
||||
case 8: return stream.nextUInt16();
|
||||
case 9: return stream.nextUInt32();
|
||||
case 10: return [stream.nextInt32(), stream.nextInt32()];
|
||||
case 11: return stream.nextFloat();
|
||||
case 12: return stream.nextDouble();
|
||||
default: throw new Error('Invalid format while decoding: ' + format);
|
||||
}
|
||||
}
|
||||
|
||||
function getBytesPerComponent(format) {
|
||||
switch(format) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 6:
|
||||
case 7:
|
||||
return 1;
|
||||
case 3:
|
||||
case 8:
|
||||
return 2;
|
||||
case 4:
|
||||
case 9:
|
||||
case 11:
|
||||
return 4;
|
||||
case 5:
|
||||
case 10:
|
||||
case 12:
|
||||
return 8;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
function readExifTag(tiffMarker, stream) {
|
||||
var tagType = stream.nextUInt16(),
|
||||
format = stream.nextUInt16(),
|
||||
bytesPerComponent = getBytesPerComponent(format),
|
||||
components = stream.nextUInt32(),
|
||||
valueBytes = bytesPerComponent * components,
|
||||
values,
|
||||
value,
|
||||
c;
|
||||
|
||||
/* if the value is bigger then 4 bytes, the value is in the data section of the IFD
|
||||
and the value present in the tag is the offset starting from the tiff header. So we replace the stream
|
||||
with a stream that is located at the given offset in the data section. s*/
|
||||
if(valueBytes > 4) {
|
||||
stream = tiffMarker.openWithOffset(stream.nextUInt32());
|
||||
}
|
||||
//we don't want to read strings as arrays
|
||||
if(format === 2) {
|
||||
values = stream.nextString(components);
|
||||
//cut off \0 characters
|
||||
var lastNull = values.indexOf('\0');
|
||||
if(lastNull !== -1) {
|
||||
values = values.substr(0, lastNull);
|
||||
}
|
||||
}
|
||||
else if(format === 7) {
|
||||
values = stream.nextBuffer(components);
|
||||
}
|
||||
else if(format !== 0) {
|
||||
values = [];
|
||||
for(c = 0; c < components; ++c) {
|
||||
values.push(readExifValue(format, stream));
|
||||
}
|
||||
}
|
||||
//since our stream is a stateful object, we need to skip remaining bytes
|
||||
//so our offset stays correct
|
||||
if(valueBytes < 4) {
|
||||
stream.skip(4 - valueBytes);
|
||||
}
|
||||
|
||||
return [tagType, values, format];
|
||||
}
|
||||
|
||||
function readIFDSection(tiffMarker, stream, iterator) {
|
||||
var numberOfEntries = stream.nextUInt16(), tag, i;
|
||||
for(i = 0; i < numberOfEntries; ++i) {
|
||||
tag = readExifTag(tiffMarker, stream);
|
||||
iterator(tag[0], tag[1], tag[2]);
|
||||
}
|
||||
}
|
||||
|
||||
function readHeader(stream) {
|
||||
var exifHeader = stream.nextString(6);
|
||||
if(exifHeader !== 'Exif\0\0') {
|
||||
throw new Error('Invalid EXIF header');
|
||||
}
|
||||
|
||||
var tiffMarker = stream.mark();
|
||||
var tiffHeader = stream.nextUInt16();
|
||||
if(tiffHeader === 0x4949) {
|
||||
stream.setBigEndian(false);
|
||||
} else if(tiffHeader === 0x4D4D) {
|
||||
stream.setBigEndian(true);
|
||||
} else {
|
||||
throw new Error('Invalid TIFF header');
|
||||
}
|
||||
if(stream.nextUInt16() !== 0x002A) {
|
||||
throw new Error('Invalid TIFF data');
|
||||
}
|
||||
return tiffMarker;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
IFD0: 1,
|
||||
IFD1: 2,
|
||||
GPSIFD: 3,
|
||||
SubIFD: 4,
|
||||
InteropIFD: 5,
|
||||
parseTags: function(stream, iterator) {
|
||||
var tiffMarker;
|
||||
try {
|
||||
tiffMarker = readHeader(stream);
|
||||
} catch(e) {
|
||||
return false; //ignore APP1 sections with invalid headers
|
||||
}
|
||||
var subIfdOffset, gpsOffset, interopOffset;
|
||||
var ifd0Stream = tiffMarker.openWithOffset(stream.nextUInt32()),
|
||||
IFD0 = this.IFD0;
|
||||
readIFDSection(tiffMarker, ifd0Stream, function(tagType, value, format) {
|
||||
switch(tagType) {
|
||||
case 0x8825: gpsOffset = value[0]; break;
|
||||
case 0x8769: subIfdOffset = value[0]; break;
|
||||
default: iterator(IFD0, tagType, value, format); break;
|
||||
}
|
||||
});
|
||||
var ifd1Offset = ifd0Stream.nextUInt32();
|
||||
if(ifd1Offset !== 0) {
|
||||
var ifd1Stream = tiffMarker.openWithOffset(ifd1Offset);
|
||||
readIFDSection(tiffMarker, ifd1Stream, iterator.bind(null, this.IFD1));
|
||||
}
|
||||
|
||||
if(gpsOffset) {
|
||||
var gpsStream = tiffMarker.openWithOffset(gpsOffset);
|
||||
readIFDSection(tiffMarker, gpsStream, iterator.bind(null, this.GPSIFD));
|
||||
}
|
||||
|
||||
if(subIfdOffset) {
|
||||
var subIfdStream = tiffMarker.openWithOffset(subIfdOffset), InteropIFD = this.InteropIFD;
|
||||
readIFDSection(tiffMarker, subIfdStream, function(tagType, value, format) {
|
||||
if(tagType === 0xA005) {
|
||||
interopOffset = value[0];
|
||||
} else {
|
||||
iterator(InteropIFD, tagType, value, format);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if(interopOffset) {
|
||||
var interopStream = tiffMarker.openWithOffset(interopOffset);
|
||||
readIFDSection(tiffMarker, interopStream, iterator.bind(null, this.InteropIFD));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
66
build/node_modules/exif-parser/lib/jpeg.js
generated
vendored
Normal file
66
build/node_modules/exif-parser/lib/jpeg.js
generated
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
/*jslint browser: true, devel: true, bitwise: false, debug: true, eqeq: false, es5: true, evil: false, forin: false, newcap: false, nomen: true, plusplus: true, regexp: false, unparam: false, sloppy: true, stupid: false, sub: false, todo: true, vars: true, white: true */
|
||||
|
||||
module.exports = {
|
||||
parseSections: function(stream, iterator) {
|
||||
var len, markerType;
|
||||
stream.setBigEndian(true);
|
||||
//stop reading the stream at the SOS (Start of Stream) marker,
|
||||
//because its length is not stored in the header so we can't
|
||||
//know where to jump to. The only marker after that is just EOI (End Of Image) anyway
|
||||
while(stream.remainingLength() > 0 && markerType !== 0xDA) {
|
||||
if(stream.nextUInt8() !== 0xFF) {
|
||||
throw new Error('Invalid JPEG section offset');
|
||||
}
|
||||
markerType = stream.nextUInt8();
|
||||
//don't read size from markers that have no datas
|
||||
if((markerType >= 0xD0 && markerType <= 0xD9) || markerType === 0xDA) {
|
||||
len = 0;
|
||||
} else {
|
||||
len = stream.nextUInt16() - 2;
|
||||
}
|
||||
iterator(markerType, stream.branch(0, len));
|
||||
stream.skip(len);
|
||||
}
|
||||
},
|
||||
//stream should be located after SOF section size and in big endian mode, like passed to parseSections iterator
|
||||
getSizeFromSOFSection: function(stream) {
|
||||
stream.skip(1);
|
||||
return {
|
||||
height: stream.nextUInt16(),
|
||||
width: stream.nextUInt16()
|
||||
};
|
||||
},
|
||||
getSectionName: function(markerType) {
|
||||
var name, index;
|
||||
switch(markerType) {
|
||||
case 0xD8: name = 'SOI'; break;
|
||||
case 0xC4: name = 'DHT'; break;
|
||||
case 0xDB: name = 'DQT'; break;
|
||||
case 0xDD: name = 'DRI'; break;
|
||||
case 0xDA: name = 'SOS'; break;
|
||||
case 0xFE: name = 'COM'; break;
|
||||
case 0xD9: name = 'EOI'; break;
|
||||
default:
|
||||
if(markerType >= 0xE0 && markerType <= 0xEF) {
|
||||
name = 'APP';
|
||||
index = markerType - 0xE0;
|
||||
}
|
||||
else if(markerType >= 0xC0 && markerType <= 0xCF && markerType !== 0xC4 && markerType !== 0xC8 && markerType !== 0xCC) {
|
||||
name = 'SOF';
|
||||
index = markerType - 0xC0;
|
||||
}
|
||||
else if(markerType >= 0xD0 && markerType <= 0xD7) {
|
||||
name = 'RST';
|
||||
index = markerType - 0xD0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
var nameStruct = {
|
||||
name: name
|
||||
};
|
||||
if(typeof index === 'number') {
|
||||
nameStruct.index = index;
|
||||
}
|
||||
return nameStruct;
|
||||
}
|
||||
};
|
||||
204
build/node_modules/exif-parser/lib/parser.js
generated
vendored
Normal file
204
build/node_modules/exif-parser/lib/parser.js
generated
vendored
Normal file
@@ -0,0 +1,204 @@
|
||||
/*jslint browser: true, devel: true, bitwise: false, debug: true, eqeq: false, es5: true, evil: false, forin: false, newcap: false, nomen: true, plusplus: true, regexp: false, unparam: false, sloppy: true, stupid: false, sub: false, todo: true, vars: true, white: true */
|
||||
|
||||
var jpeg = require('./jpeg'),
|
||||
exif = require('./exif'),
|
||||
simplify = require('./simplify');
|
||||
|
||||
function ExifResult(startMarker, tags, imageSize, thumbnailOffset, thumbnailLength, thumbnailType, app1Offset) {
|
||||
this.startMarker = startMarker;
|
||||
this.tags = tags;
|
||||
this.imageSize = imageSize;
|
||||
this.thumbnailOffset = thumbnailOffset;
|
||||
this.thumbnailLength = thumbnailLength;
|
||||
this.thumbnailType = thumbnailType;
|
||||
this.app1Offset = app1Offset;
|
||||
}
|
||||
|
||||
ExifResult.prototype = {
|
||||
hasThumbnail: function(mime) {
|
||||
if(!this.thumbnailOffset || !this.thumbnailLength) {
|
||||
return false;
|
||||
}
|
||||
if(typeof mime !== 'string') {
|
||||
return true;
|
||||
}
|
||||
if(mime.toLowerCase().trim() === 'image/jpeg') {
|
||||
return this.thumbnailType === 6;
|
||||
}
|
||||
if(mime.toLowerCase().trim() === 'image/tiff') {
|
||||
return this.thumbnailType === 1;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
getThumbnailOffset: function() {
|
||||
return this.app1Offset + 6 + this.thumbnailOffset;
|
||||
},
|
||||
getThumbnailLength: function() {
|
||||
return this.thumbnailLength;
|
||||
},
|
||||
getThumbnailBuffer: function() {
|
||||
return this._getThumbnailStream().nextBuffer(this.thumbnailLength);
|
||||
},
|
||||
_getThumbnailStream: function() {
|
||||
return this.startMarker.openWithOffset(this.getThumbnailOffset());
|
||||
},
|
||||
getImageSize: function() {
|
||||
return this.imageSize;
|
||||
},
|
||||
getThumbnailSize: function() {
|
||||
var stream = this._getThumbnailStream(), size;
|
||||
jpeg.parseSections(stream, function(sectionType, sectionStream) {
|
||||
if(jpeg.getSectionName(sectionType).name === 'SOF') {
|
||||
size = jpeg.getSizeFromSOFSection(sectionStream);
|
||||
}
|
||||
});
|
||||
return size;
|
||||
}
|
||||
};
|
||||
|
||||
function Parser(stream) {
|
||||
this.stream = stream;
|
||||
this.flags = {
|
||||
readBinaryTags: false,
|
||||
resolveTagNames: true,
|
||||
simplifyValues: true,
|
||||
imageSize: true,
|
||||
hidePointers: true,
|
||||
returnTags: true
|
||||
};
|
||||
}
|
||||
|
||||
Parser.prototype = {
|
||||
enableBinaryFields: function(enable) {
|
||||
this.flags.readBinaryTags = !!enable;
|
||||
return this;
|
||||
},
|
||||
enablePointers: function(enable) {
|
||||
this.flags.hidePointers = !enable;
|
||||
return this;
|
||||
},
|
||||
enableTagNames: function(enable) {
|
||||
this.flags.resolveTagNames = !!enable;
|
||||
return this;
|
||||
},
|
||||
enableImageSize: function(enable) {
|
||||
this.flags.imageSize = !!enable;
|
||||
return this;
|
||||
},
|
||||
enableReturnTags: function(enable) {
|
||||
this.flags.returnTags = !!enable;
|
||||
return this;
|
||||
},
|
||||
enableSimpleValues: function(enable) {
|
||||
this.flags.simplifyValues = !!enable;
|
||||
return this;
|
||||
},
|
||||
parse: function() {
|
||||
var start = this.stream.mark(),
|
||||
stream = start.openWithOffset(0),
|
||||
flags = this.flags,
|
||||
tags,
|
||||
imageSize,
|
||||
thumbnailOffset,
|
||||
thumbnailLength,
|
||||
thumbnailType,
|
||||
app1Offset,
|
||||
tagNames,
|
||||
getTagValue, setTagValue;
|
||||
if(flags.resolveTagNames) {
|
||||
tagNames = require('./exif-tags');
|
||||
}
|
||||
if(flags.resolveTagNames) {
|
||||
tags = {};
|
||||
getTagValue = function(t) {
|
||||
return tags[t.name];
|
||||
};
|
||||
setTagValue = function(t, value) {
|
||||
tags[t.name] = value;
|
||||
};
|
||||
} else {
|
||||
tags = [];
|
||||
getTagValue = function(t) {
|
||||
var i;
|
||||
for(i = 0; i < tags.length; ++i) {
|
||||
if(tags[i].type === t.type && tags[i].section === t.section) {
|
||||
return tags.value;
|
||||
}
|
||||
}
|
||||
};
|
||||
setTagValue = function(t, value) {
|
||||
var i;
|
||||
for(i = 0; i < tags.length; ++i) {
|
||||
if(tags[i].type === t.type && tags[i].section === t.section) {
|
||||
tags.value = value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
jpeg.parseSections(stream, function(sectionType, sectionStream) {
|
||||
var validExifHeaders, sectionOffset = sectionStream.offsetFrom(start);
|
||||
if(sectionType === 0xE1) {
|
||||
validExifHeaders = exif.parseTags(sectionStream, function(ifdSection, tagType, value, format) {
|
||||
//ignore binary fields if disabled
|
||||
if(!flags.readBinaryTags && format === 7) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(tagType === 0x0201) {
|
||||
thumbnailOffset = value[0];
|
||||
if(flags.hidePointers) {return;}
|
||||
} else if(tagType === 0x0202) {
|
||||
thumbnailLength = value[0];
|
||||
if(flags.hidePointers) {return;}
|
||||
} else if(tagType === 0x0103) {
|
||||
thumbnailType = value[0];
|
||||
if(flags.hidePointers) {return;}
|
||||
}
|
||||
//if flag is set to not store tags, return here after storing pointers
|
||||
if(!flags.returnTags) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(flags.simplifyValues) {
|
||||
value = simplify.simplifyValue(value, format);
|
||||
}
|
||||
if(flags.resolveTagNames) {
|
||||
var sectionTagNames = ifdSection === exif.GPSIFD ? tagNames.gps : tagNames.exif;
|
||||
var name = sectionTagNames[tagType];
|
||||
if(!name) {
|
||||
name = tagNames.exif[tagType];
|
||||
}
|
||||
if (!tags.hasOwnProperty(name)) {
|
||||
tags[name] = value;
|
||||
}
|
||||
} else {
|
||||
tags.push({
|
||||
section: ifdSection,
|
||||
type: tagType,
|
||||
value: value
|
||||
});
|
||||
}
|
||||
});
|
||||
if(validExifHeaders) {
|
||||
app1Offset = sectionOffset;
|
||||
}
|
||||
}
|
||||
else if(flags.imageSize && jpeg.getSectionName(sectionType).name === 'SOF') {
|
||||
imageSize = jpeg.getSizeFromSOFSection(sectionStream);
|
||||
}
|
||||
});
|
||||
|
||||
if(flags.simplifyValues) {
|
||||
simplify.castDegreeValues(getTagValue, setTagValue);
|
||||
simplify.castDateValues(getTagValue, setTagValue);
|
||||
}
|
||||
|
||||
return new ExifResult(start, tags, imageSize, thumbnailOffset, thumbnailLength, thumbnailType, app1Offset);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
module.exports = Parser;
|
||||
79
build/node_modules/exif-parser/lib/simplify.js
generated
vendored
Normal file
79
build/node_modules/exif-parser/lib/simplify.js
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
var exif = require('./exif');
|
||||
var date = require('./date');
|
||||
|
||||
var degreeTags = [{
|
||||
section: exif.GPSIFD,
|
||||
type: 0x0002,
|
||||
name: 'GPSLatitude',
|
||||
refType: 0x0001,
|
||||
refName: 'GPSLatitudeRef',
|
||||
posVal: 'N'
|
||||
},
|
||||
{
|
||||
section: exif.GPSIFD,
|
||||
type: 0x0004,
|
||||
name: 'GPSLongitude',
|
||||
refType: 0x0003,
|
||||
refName: 'GPSLongitudeRef',
|
||||
posVal: 'E'
|
||||
}];
|
||||
var dateTags = [{
|
||||
section: exif.SubIFD,
|
||||
type: 0x0132,
|
||||
name: 'ModifyDate'
|
||||
},
|
||||
{
|
||||
section: exif.SubIFD,
|
||||
type: 0x9003,
|
||||
name: 'DateTimeOriginal'
|
||||
},
|
||||
{
|
||||
section: exif.SubIFD,
|
||||
type: 0x9004,
|
||||
name: 'CreateDate'
|
||||
},
|
||||
{
|
||||
section: exif.SubIFD,
|
||||
type: 0x0132,
|
||||
name : 'ModifyDate',
|
||||
}];
|
||||
|
||||
module.exports = {
|
||||
castDegreeValues: function(getTagValue, setTagValue) {
|
||||
degreeTags.forEach(function(t) {
|
||||
var degreeVal = getTagValue(t);
|
||||
if(degreeVal) {
|
||||
var degreeRef = getTagValue({section: t.section, type: t.refType, name: t.refName});
|
||||
var degreeNumRef = degreeRef === t.posVal ? 1 : -1;
|
||||
var degree = (degreeVal[0] + (degreeVal[1] / 60) + (degreeVal[2] / 3600)) * degreeNumRef;
|
||||
setTagValue(t, degree);
|
||||
}
|
||||
});
|
||||
},
|
||||
castDateValues: function(getTagValue, setTagValue) {
|
||||
dateTags.forEach(function(t) {
|
||||
var dateStrVal = getTagValue(t);
|
||||
if(dateStrVal) {
|
||||
//some easy checks to determine two common date formats
|
||||
var timestamp = date.parseExifDate(dateStrVal);
|
||||
if(typeof timestamp !== 'undefined') {
|
||||
setTagValue(t, timestamp);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
simplifyValue: function(values, format) {
|
||||
if(Array.isArray(values)) {
|
||||
values = values.map(function(value) {
|
||||
if(format === 10 || format === 5) {
|
||||
return value[0] / value[1];
|
||||
}
|
||||
return value;
|
||||
});
|
||||
if(values.length === 1) {
|
||||
values = values[0];
|
||||
}
|
||||
}
|
||||
return values;
|
||||
}
|
||||
};
|
||||
58
build/node_modules/exif-parser/package.json
generated
vendored
Normal file
58
build/node_modules/exif-parser/package.json
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"exif-parser@0.1.12",
|
||||
"/Users/asciidisco/Desktop/asciidisco.com/build"
|
||||
]
|
||||
],
|
||||
"_from": "exif-parser@0.1.12",
|
||||
"_id": "exif-parser@0.1.12",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-WKnS1ywCwfbwKg70qRZicrd2CSI=",
|
||||
"_location": "/exif-parser",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "version",
|
||||
"registry": true,
|
||||
"raw": "exif-parser@0.1.12",
|
||||
"name": "exif-parser",
|
||||
"escapedName": "exif-parser",
|
||||
"rawSpec": "0.1.12",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "0.1.12"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/jimp"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz",
|
||||
"_spec": "0.1.12",
|
||||
"_where": "/Users/asciidisco/Desktop/asciidisco.com/build",
|
||||
"author": {
|
||||
"name": "Bruno Windels",
|
||||
"email": "bruno.windels@gmail.com"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/bwindels/exif-parser/issues"
|
||||
},
|
||||
"description": "A javascript library to extract Exif metadata from images, in node and in the browser.",
|
||||
"devDependencies": {
|
||||
"browserify": "^7.0.0",
|
||||
"uglify-js": "^2.4.15"
|
||||
},
|
||||
"homepage": "https://github.com/bwindels/exif-parser#readme",
|
||||
"keywords": [
|
||||
"exif",
|
||||
"image",
|
||||
"jpeg",
|
||||
"jpg",
|
||||
"tiff",
|
||||
"gps"
|
||||
],
|
||||
"main": "index.js",
|
||||
"name": "exif-parser",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+ssh://git@github.com/bwindels/exif-parser.git"
|
||||
},
|
||||
"version": "0.1.12"
|
||||
}
|
||||
364
build/node_modules/exif-parser/test/expected-exif-tags.json
generated
vendored
Normal file
364
build/node_modules/exif-parser/test/expected-exif-tags.json
generated
vendored
Normal file
@@ -0,0 +1,364 @@
|
||||
[
|
||||
{
|
||||
"ifdSection": 1,
|
||||
"tagType": 271,
|
||||
"value": "Nokia",
|
||||
"format": 2
|
||||
},
|
||||
{
|
||||
"ifdSection": 1,
|
||||
"tagType": 272,
|
||||
"value": "Lumia 820",
|
||||
"format": 2
|
||||
},
|
||||
{
|
||||
"ifdSection": 1,
|
||||
"tagType": 274,
|
||||
"value": [
|
||||
1
|
||||
],
|
||||
"format": 3
|
||||
},
|
||||
{
|
||||
"ifdSection": 1,
|
||||
"tagType": 282,
|
||||
"value": [
|
||||
[
|
||||
72,
|
||||
1
|
||||
]
|
||||
],
|
||||
"format": 5
|
||||
},
|
||||
{
|
||||
"ifdSection": 1,
|
||||
"tagType": 283,
|
||||
"value": [
|
||||
[
|
||||
72,
|
||||
1
|
||||
]
|
||||
],
|
||||
"format": 5
|
||||
},
|
||||
{
|
||||
"ifdSection": 1,
|
||||
"tagType": 296,
|
||||
"value": [
|
||||
2
|
||||
],
|
||||
"format": 3
|
||||
},
|
||||
{
|
||||
"ifdSection": 1,
|
||||
"tagType": 305,
|
||||
"value": "Windows Phone",
|
||||
"format": 2
|
||||
},
|
||||
{
|
||||
"ifdSection": 1,
|
||||
"tagType": 531,
|
||||
"value": [
|
||||
1
|
||||
],
|
||||
"format": 3
|
||||
},
|
||||
{
|
||||
"ifdSection": 1,
|
||||
"tagType": 59932,
|
||||
"value": "b:2060",
|
||||
"format": 7
|
||||
},
|
||||
{
|
||||
"ifdSection": 2,
|
||||
"tagType": 259,
|
||||
"value": [
|
||||
6
|
||||
],
|
||||
"format": 3
|
||||
},
|
||||
{
|
||||
"ifdSection": 2,
|
||||
"tagType": 282,
|
||||
"value": [
|
||||
[
|
||||
72,
|
||||
1
|
||||
]
|
||||
],
|
||||
"format": 5
|
||||
},
|
||||
{
|
||||
"ifdSection": 2,
|
||||
"tagType": 283,
|
||||
"value": [
|
||||
[
|
||||
72,
|
||||
1
|
||||
]
|
||||
],
|
||||
"format": 5
|
||||
},
|
||||
{
|
||||
"ifdSection": 2,
|
||||
"tagType": 296,
|
||||
"value": [
|
||||
2
|
||||
],
|
||||
"format": 3
|
||||
},
|
||||
{
|
||||
"ifdSection": 2,
|
||||
"tagType": 513,
|
||||
"value": [
|
||||
12210
|
||||
],
|
||||
"format": 4
|
||||
},
|
||||
{
|
||||
"ifdSection": 2,
|
||||
"tagType": 514,
|
||||
"value": [
|
||||
18032
|
||||
],
|
||||
"format": 4
|
||||
},
|
||||
{
|
||||
"ifdSection": 3,
|
||||
"tagType": 0,
|
||||
"value": [
|
||||
2,
|
||||
2,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"ifdSection": 3,
|
||||
"tagType": 1,
|
||||
"value": "N",
|
||||
"format": 2
|
||||
},
|
||||
{
|
||||
"ifdSection": 3,
|
||||
"tagType": 2,
|
||||
"value": [
|
||||
[
|
||||
55,
|
||||
1
|
||||
],
|
||||
[
|
||||
2,
|
||||
1
|
||||
],
|
||||
[
|
||||
19521,
|
||||
1000
|
||||
]
|
||||
],
|
||||
"format": 5
|
||||
},
|
||||
{
|
||||
"ifdSection": 3,
|
||||
"tagType": 3,
|
||||
"value": "E",
|
||||
"format": 2
|
||||
},
|
||||
{
|
||||
"ifdSection": 3,
|
||||
"tagType": 4,
|
||||
"value": [
|
||||
[
|
||||
8,
|
||||
1
|
||||
],
|
||||
[
|
||||
27,
|
||||
1
|
||||
],
|
||||
[
|
||||
25886,
|
||||
1000
|
||||
]
|
||||
],
|
||||
"format": 5
|
||||
},
|
||||
{
|
||||
"ifdSection": 3,
|
||||
"tagType": 5,
|
||||
"value": [
|
||||
0
|
||||
],
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"ifdSection": 3,
|
||||
"tagType": 6,
|
||||
"value": [
|
||||
[
|
||||
10000,
|
||||
200000
|
||||
]
|
||||
],
|
||||
"format": 5
|
||||
},
|
||||
{
|
||||
"ifdSection": 3,
|
||||
"tagType": 10,
|
||||
"value": "3",
|
||||
"format": 2
|
||||
},
|
||||
{
|
||||
"ifdSection": 3,
|
||||
"tagType": 11,
|
||||
"value": [
|
||||
[
|
||||
10000,
|
||||
80000
|
||||
]
|
||||
],
|
||||
"format": 5
|
||||
},
|
||||
{
|
||||
"ifdSection": 3,
|
||||
"tagType": 59932,
|
||||
"value": "b:2060",
|
||||
"format": 7
|
||||
},
|
||||
{
|
||||
"ifdSection": 5,
|
||||
"tagType": 33434,
|
||||
"value": [
|
||||
[
|
||||
3139,
|
||||
1000000
|
||||
]
|
||||
],
|
||||
"format": 5
|
||||
},
|
||||
{
|
||||
"ifdSection": 5,
|
||||
"tagType": 33437,
|
||||
"value": [
|
||||
[
|
||||
220,
|
||||
100
|
||||
]
|
||||
],
|
||||
"format": 5
|
||||
},
|
||||
{
|
||||
"ifdSection": 5,
|
||||
"tagType": 34855,
|
||||
"value": [
|
||||
100
|
||||
],
|
||||
"format": 3
|
||||
},
|
||||
{
|
||||
"ifdSection": 5,
|
||||
"tagType": 36864,
|
||||
"value": "b:4",
|
||||
"format": 7
|
||||
},
|
||||
{
|
||||
"ifdSection": 5,
|
||||
"tagType": 36867,
|
||||
"value": "2013:05:10 15:21:35",
|
||||
"format": 2
|
||||
},
|
||||
{
|
||||
"ifdSection": 5,
|
||||
"tagType": 36868,
|
||||
"value": "2013:05:10 15:21:35",
|
||||
"format": 2
|
||||
},
|
||||
{
|
||||
"ifdSection": 5,
|
||||
"tagType": 37121,
|
||||
"value": "b:4",
|
||||
"format": 7
|
||||
},
|
||||
{
|
||||
"ifdSection": 5,
|
||||
"tagType": 37380,
|
||||
"value": [
|
||||
[
|
||||
0,
|
||||
6
|
||||
]
|
||||
],
|
||||
"format": 10
|
||||
},
|
||||
{
|
||||
"ifdSection": 5,
|
||||
"tagType": 37385,
|
||||
"value": [
|
||||
24
|
||||
],
|
||||
"format": 3
|
||||
},
|
||||
{
|
||||
"ifdSection": 5,
|
||||
"tagType": 37500,
|
||||
"value": "b:5243",
|
||||
"format": 7
|
||||
},
|
||||
{
|
||||
"ifdSection": 5,
|
||||
"tagType": 40960,
|
||||
"value": "b:4",
|
||||
"format": 7
|
||||
},
|
||||
{
|
||||
"ifdSection": 5,
|
||||
"tagType": 40961,
|
||||
"value": [
|
||||
1
|
||||
],
|
||||
"format": 3
|
||||
},
|
||||
{
|
||||
"ifdSection": 5,
|
||||
"tagType": 40962,
|
||||
"value": [
|
||||
3552
|
||||
],
|
||||
"format": 4
|
||||
},
|
||||
{
|
||||
"ifdSection": 5,
|
||||
"tagType": 40963,
|
||||
"value": [
|
||||
2000
|
||||
],
|
||||
"format": 4
|
||||
},
|
||||
{
|
||||
"ifdSection": 5,
|
||||
"tagType": 59932,
|
||||
"value": "b:2060",
|
||||
"format": 7
|
||||
},
|
||||
{
|
||||
"ifdSection": 5,
|
||||
"tagType": 59933,
|
||||
"value": [
|
||||
12
|
||||
],
|
||||
"format": 9
|
||||
},
|
||||
{
|
||||
"ifdSection": 5,
|
||||
"tagType": 1,
|
||||
"value": "R98",
|
||||
"format": 2
|
||||
},
|
||||
{
|
||||
"ifdSection": 5,
|
||||
"tagType": 2,
|
||||
"value": "b:4",
|
||||
"format": 7
|
||||
}
|
||||
]
|
||||
BIN
build/node_modules/exif-parser/test/starfish.jpg
generated
vendored
Executable file
BIN
build/node_modules/exif-parser/test/starfish.jpg
generated
vendored
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 322 KiB |
60
build/node_modules/exif-parser/test/test-date.js
generated
vendored
Normal file
60
build/node_modules/exif-parser/test/test-date.js
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
var date = require('../lib/date');
|
||||
|
||||
var minutes = 60;
|
||||
var hours = minutes * 60;
|
||||
var days = hours * 24;
|
||||
var years = days * 365;
|
||||
var leapYears = days * 366;
|
||||
|
||||
module.exports = {
|
||||
'test parse unix epoch without timezone': function(test) {
|
||||
var dateStr = '1970:01:01 00:00:00';
|
||||
var timestamp = date.parseDateWithSpecFormat(dateStr);
|
||||
test.strictEqual(timestamp, 0);
|
||||
test.done();
|
||||
},
|
||||
'test parse given date without timezone': function(test) {
|
||||
var dateStr = '1990:02:14 14:30:14';
|
||||
var timestamp = date.parseDateWithSpecFormat(dateStr);
|
||||
//between 1970 and 1990 there were 5 leap years: 1972, 1976, 1980, 1984, 1988
|
||||
var expectedTimestamp = (15 * years) + (5 * leapYears) +
|
||||
((31 + 13) * days) + (14 * hours) + (30 * minutes) + 14;
|
||||
test.strictEqual(timestamp, expectedTimestamp);
|
||||
test.done();
|
||||
},
|
||||
'test parse invalid date without timezone should not return anything': function(test) {
|
||||
var dateStr = '1990:AA:14 14:30:14';
|
||||
var timestamp = date.parseDateWithSpecFormat(dateStr);
|
||||
test.strictEqual(timestamp, undefined);
|
||||
test.done();
|
||||
},
|
||||
'test parse given date with timezone': function(test) {
|
||||
var dateStr = '2004-09-04T23:39:06-08:00';
|
||||
var timestamp = date.parseDateWithTimezoneFormat(dateStr);
|
||||
var yearsFromEpoch = 2004 - 1970;
|
||||
//1972, 1976, 1980, 1984, 1988, 1992, 1996, 2000
|
||||
var leapYearsCount = 8;
|
||||
//2004 is a leap year as well, hence 29 days for february
|
||||
var dayCount = 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 3;
|
||||
var expectedTimestamp = (yearsFromEpoch - leapYearsCount) * years +
|
||||
leapYearsCount * leapYears +
|
||||
dayCount * days +
|
||||
23 * hours +
|
||||
39 * minutes +
|
||||
6 +
|
||||
8 * hours; //for timezone
|
||||
test.strictEqual(timestamp, expectedTimestamp);
|
||||
test.done();
|
||||
},
|
||||
'test parse invalid date with timezone': function(test) {
|
||||
var dateStr = '2004-09-04T23:39:06A08:00';
|
||||
var timestamp = date.parseDateWithTimezoneFormat(dateStr);
|
||||
test.strictEqual(timestamp, undefined);
|
||||
test.done();
|
||||
},
|
||||
'test parseExifDate': function(test) {
|
||||
test.strictEqual(date.parseExifDate('1970:01:01 00:00:00'), 0);
|
||||
test.strictEqual(date.parseExifDate('1970-01-01T00:00:00-01:00'), 3600);
|
||||
test.done();
|
||||
}
|
||||
}
|
||||
26
build/node_modules/exif-parser/test/test-exif.js
generated
vendored
Normal file
26
build/node_modules/exif-parser/test/test-exif.js
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
var testCase = require('nodeunit').testCase;
|
||||
var exif = require('../lib/exif.js');
|
||||
var BufferStream = require('../lib/bufferstream.js');
|
||||
var buf = require('fs').readFileSync(__dirname + '/starfish.jpg');
|
||||
|
||||
module.exports = testCase({
|
||||
"test parseTags": function(test) {
|
||||
var expectedTags = require('./expected-exif-tags.json');
|
||||
var index = 0;
|
||||
exif.parseTags(new BufferStream(buf, 24, 23960), function(ifdSection, tagType, value, format) {
|
||||
var t = expectedTags[index];
|
||||
test.strictEqual(t.ifdSection, ifdSection);
|
||||
test.strictEqual(t.tagType, tagType);
|
||||
test.strictEqual(t.format, format);
|
||||
if(typeof t.value === 'string' && t.value.indexOf('b:') === 0) {
|
||||
test.ok(Buffer.isBuffer(value));
|
||||
test.strictEqual(parseInt(t.value.substr(2), 10), value.length);
|
||||
} else {
|
||||
test.deepEqual(t.value, value);
|
||||
}
|
||||
++index;
|
||||
});
|
||||
test.strictEqual(index, expectedTags.length, 'all tags should be passed to the iterator');
|
||||
test.done();
|
||||
}
|
||||
});
|
||||
46
build/node_modules/exif-parser/test/test-jpeg.js
generated
vendored
Normal file
46
build/node_modules/exif-parser/test/test-jpeg.js
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
var testCase = require('nodeunit').testCase;
|
||||
var jpeg = require('../lib/jpeg.js');
|
||||
var BufferStream = require('../lib/bufferstream.js');
|
||||
var buf = require('fs').readFileSync(__dirname + '/test.jpg');
|
||||
|
||||
module.exports = testCase({
|
||||
"test parseSections": function(test) {
|
||||
var expectedSections = [
|
||||
{ type: 216, offset: 2, len: 0 },
|
||||
{ type: 224, offset: 6, len: 14 },
|
||||
{ type: 226, offset: 24, len: 3158 },
|
||||
{ type: 225, offset: 3186, len: 200 },
|
||||
{ type: 225, offset: 3390, len: 374 },
|
||||
{ type: 219, offset: 3768, len: 65 },
|
||||
{ type: 219, offset: 3837, len: 65 },
|
||||
{ type: 192, offset: 3906, len: 15 },
|
||||
{ type: 196, offset: 3925, len: 29 },
|
||||
{ type: 196, offset: 3958, len: 179 },
|
||||
{ type: 196, offset: 4141, len: 29 },
|
||||
{ type: 196, offset: 4174, len: 179 },
|
||||
{ type: 218, offset: 4355, len: 0 }
|
||||
];
|
||||
var index = 0;
|
||||
var jpegStream = new BufferStream(buf), start = jpegStream.mark();
|
||||
jpeg.parseSections(jpegStream, function(type, sectionStream) {
|
||||
test.strictEqual(type, expectedSections[index].type);
|
||||
test.strictEqual(sectionStream.offsetFrom(start), expectedSections[index].offset);
|
||||
test.strictEqual(sectionStream.remainingLength(), expectedSections[index].len);
|
||||
++index;
|
||||
});
|
||||
test.strictEqual(index, expectedSections.length, 'all sections should be passed to the iterator');
|
||||
test.done();
|
||||
},
|
||||
"test getSizeFromSOFSection": function(test) {
|
||||
var size = jpeg.getSizeFromSOFSection(new BufferStream(buf, 3906, 15, true));
|
||||
test.strictEqual(size.width, 2);
|
||||
test.strictEqual(size.height, 1);
|
||||
test.done();
|
||||
},
|
||||
"test getSectionName": function(test) {
|
||||
test.deepEqual({name: 'SOI'}, jpeg.getSectionName(0xD8));
|
||||
test.deepEqual({name: 'APP', index: 15}, jpeg.getSectionName(0xEF));
|
||||
test.deepEqual({name: 'DHT'}, jpeg.getSectionName(0xC4));
|
||||
test.done();
|
||||
}
|
||||
});
|
||||
24
build/node_modules/exif-parser/test/test-simplify.js
generated
vendored
Normal file
24
build/node_modules/exif-parser/test/test-simplify.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
var simplify = require('../lib/simplify');
|
||||
|
||||
module.exports = {
|
||||
'test castDateValues': function(test) {
|
||||
var values = {
|
||||
'DateTimeOriginal': '1970:01:01 00:00:00',
|
||||
'CreateDate': '1970-01-01T00:00:00-05:00',
|
||||
'ModifyDate': '1970-01-01T00:00:00-05:00'
|
||||
};
|
||||
var setValues = {};
|
||||
function getTagValue(tag) {
|
||||
return values[tag.name];
|
||||
}
|
||||
function setTagValue(tag, value) {
|
||||
setValues[tag.name] = value;
|
||||
}
|
||||
simplify.castDateValues(getTagValue, setTagValue);
|
||||
test.strictEqual(Object.keys(setValues).length, 3);
|
||||
test.strictEqual(setValues.DateTimeOriginal, 0);
|
||||
test.strictEqual(setValues.CreateDate, 5 * 3600);
|
||||
test.strictEqual(setValues.ModifyDate, 5 * 3600);
|
||||
test.done();
|
||||
}
|
||||
}
|
||||
BIN
build/node_modules/exif-parser/test/test.jpg
generated
vendored
Normal file
BIN
build/node_modules/exif-parser/test/test.jpg
generated
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.3 KiB |
Reference in New Issue
Block a user