first commit

This commit is contained in:
s.golasch
2023-08-01 13:49:46 +02:00
commit 1fc239fd54
20238 changed files with 3112246 additions and 0 deletions

2
build/node_modules/exif-parser/.npmignore generated vendored Normal file
View File

@@ -0,0 +1,2 @@
node_modules
dist

16
build/node_modules/exif-parser/CHANGELOG.md generated vendored Normal file
View 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
View 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
View 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
View 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
View File

@@ -0,0 +1,3 @@
var api = require('./index');
var global = (1,eval)('this');
global.ExifParser = api;

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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"
}

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 KiB

60
build/node_modules/exif-parser/test/test-date.js generated vendored Normal file
View 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
View 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
View 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
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB