You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 7-8.RSVP
Socket
Socket
Sign inDemoInstall

exif

Package Overview
Dependencies
Maintainers
2
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.4.0 to 0.5.0

.project

378

lib/exif/ExifImage.js

@@ -1,5 +0,8 @@

var fs = require('fs'),
util = require('util'),
BufferExtender = require('./Buffer');
var fs = require('fs');
var util = require('util');
var BufferExtender = require('./Buffer'); // bad idea
var debug = require('debug')('exif');
var DEFAULT_MAX_ENTRIES=128;
/**

@@ -13,3 +16,20 @@ * Represents an image with Exif information. When instantiating it you have to

* a Buffer.
* - tiffOffsets (boolean) an object named "offsets" is added to exifData
* and contains lot of offsets needed to get thumbnail and other things.
* - fixThumbnailOffset: node-exif corrects the thumbnail offset in order to have an offset from the start of the buffer/file.
* - maxEntries: Specifies the maximum entries to be parsed
* - ifd0MaxEntries
* - ifd1MaxEntries
* - maxGpsEntries
* - maxInteroperabilityEntries
* - agfaMaxEntries
* - epsonMaxEntries
* - fujifilmMaxEntries
* - olympusMaxEntries
* - panasonicMaxEntries
* - sanyoMaxEntries
* - noPadding
*
* If you unspecify the image, you might call exifImage.loadImage(image, callback) to get exif datas.
*
* @param options Configuration options as described above

@@ -20,13 +40,17 @@ * @param callback Function to call when data is extracted or an error occured

function ExifImage (options, callback) {
if (!(this instanceof ExifImage)) {
return new ExifImage(options, callback);
}
var self = this;
options = options || {};
this.options=options;
if (!options)
var options = {};
// Default option values
["ifd0MaxEntries", "ifd1MaxEntries", "maxGpsEntries", "maxInteroperabilityEntries", "agfaMaxEntries", "epsonMaxEntries",
"fujifilmMaxEntries", "olympusMaxEntries", "panasonicMaxEntries", "sanyoMaxEntries"].forEach(function(p) {
if (options[p]===undefined) {
options[p]=DEFAULT_MAX_ENTRIES;
}
});
this.image;
this.imageType;
this.isBigEndian;
this.makernoteOffset;
this.exifData = {

@@ -40,16 +64,30 @@ image : {}, // Information about the main image

};
this.offsets={};
if (options.tiffOffsets) {
exifData.offsets=offsets;
}
debug("New ExifImage options=",options);
if (!options.image) {
throw new Error('You have to provide an image, it is pretty hard to extract Exif data from nothing...');
} else if (typeof callback !== 'function') {
// If options image is not specified, the developper must call loadImage() to parse the image.
// callback(new Error('You have to provide an image, it is pretty hard to extract Exif data from nothing...'));
return;
}
if (typeof callback !== 'function') {
throw new Error('You have to provide a callback function.');
} else {
this.loadImage(options.image, function (error, image) {
if (error)
callback(error);
else
callback(false, image);
}
var self=this;
setImmediate(function() {
self.loadImage(options.image, function (error, exifData) {
if (error) {
return callback(error);
}
callback(null, exifData);
});
}
});
}

@@ -59,64 +97,82 @@

/**
* Load image and parse exifDatas
*
* @param [String|Buffer] image the image
* @param callback a callback which is called when exif datas are parsed.
* @return Nothing
*/
ExifImage.prototype.loadImage = function (image, callback) {
var self = this;
debug("loadImage image=", image);
if (image.constructor.name === 'Buffer') {
this.processImage(image, callback);
} else if (image.constructor.name === 'String') {
this.processImage("Buffer", image, callback);
return;
}
if (image.constructor.name === 'String') {
fs.readFile(image, function (error, data) {
if (error)
if (error) {
callback(new Error('Encountered the following error while trying to read given image: '+error));
else
self.processImage(data, callback);
return;
}
self.processImage("File: "+image, data, options, callback);
});
} else {
callback(new Error('Given image is neither a buffer nor a file, please provide one of these.'));
return;
}
callback(new Error('Given image is neither a buffer nor a file, please provide one of these.'));
};
ExifImage.prototype.processImage = function (data, callback) {
ExifImage.prototype.processImage = function (source, data, callback) {
var self = this;
var offset = 0;
if (data[offset++] == 0xFF && data[offset++] == 0xD8) {
self.imageType = 'JPEG';
} else {
callback(new Error('The given image is not a JPEG and thus unsupported right now.'));
if (data[offset++] != 0xFF || data[offset++] != 0xD8) {
var e=new Error('The given image is not a JPEG and thus unsupported right now.');
e.source=source;
e.code="NOT_A_JPEG";
callback(e);
return;
}
try {
this.imageType = 'JPEG';
while (offset < data.length) {
while (offset < data.length) {
if (data[offset++] != 0xFF) {
callback(false, self.exifData);
return;
}
if (data[offset++] != 0xFF) {
break;
}
if (data[offset++] == 0xE1) {
var exifData = self.extractExifData(data, offset + 2, data.getShort(offset, true) - 2);
callback(false, exifData);
if (data[offset++] == 0xE1) {
try {
this.extractExifData(data, offset + 2, data.getShort(offset, true) - 2);
} catch (error) {
error.code="PARSING_ERROR";
error.source=source;
debug("Extract exif data error source=", source, "offset=", offset, "error=",error);
callback(error);
return;
} else {
offset += data.getShort(offset, true);
}
debug("Extract exif data success source=", source, "exifData=",this.exifData);
callback(null, this.exifData);
return;
}
} catch (error) {
callback(error);
offset += data.getShort(offset, true);
}
callback(new Error('No Exif segment found in the given image.'));
var e2=new Error('No Exif segment found in the given image.');
e2.source=source;
e2.code="NO_EXIF_SEGMENT";
callback(e2);
};

@@ -126,5 +182,8 @@

var self = this;
var exifData=this.exifData;
var tiffOffset = start + 6;
var ifdOffset, numberOfEntries;
var noPadding = (this.options.noPadding!==false);
this.offsets.tiff=tiffOffset;

@@ -140,4 +199,6 @@ // Exif data always starts with Exif\0\0

this.isBigEndian = false;
} else if (data.getShort(tiffOffset) == 0x4D4D) {
this.isBigEndian = true;
} else {

@@ -147,2 +208,4 @@ throw new Error('Invalid TIFF data! Expected 0x4949 or 0x4D4D at offset '+(tiffOffset)+' but found 0x'+data[tiffOffset].toString(16).toUpperCase()+data[tiffOffset + 1].toString(16).toUpperCase()+".");

debug("BigEndian=",this.isBigEndian);
// Valid TIFF headers always have 0x002A here

@@ -159,11 +222,28 @@ if (data.getShort(tiffOffset + 2, this.isBigEndian) != 0x002A) {

ifdOffset = tiffOffset + data.getLong(tiffOffset + 4, this.isBigEndian);
this.offsets.ifd0=ifdOffset;
numberOfEntries = data.getShort(ifdOffset, this.isBigEndian);
if (this.options.ifd0MaxEntries) {
numberOfEntries=Math.min(numberOfEntries, this.options.ifd0MaxEntries);
}
debug("IFD0 ifdOffset=",ifdOffset, "numberOfEntries=", numberOfEntries);
// Each IFD entry consists of 12 bytes which we loop through and extract
// the data from
for (var i = 0; i < numberOfEntries; i++) {
var exifEntry = self.extractExifEntry(data, (ifdOffset + 2 + (i * 12)), tiffOffset, this.isBigEndian, ExifImage.TAGS.exif);
if (exifEntry && exifEntry.tagName !== null) this.exifData.image[exifEntry.tagName] = exifEntry.value;
var exifEntry = this.extractExifEntry(data, (ifdOffset + 2 + (i * 12)), tiffOffset, this.isBigEndian, ExifImage.TAGS.exif);
if (!exifEntry) {
continue;
}
if (exifEntry.tagId===0xEA1C && noPadding) {
continue;
}
exifData.image[exifEntry.tagName] = exifEntry.value;
}
debug("IFD0 parsed", exifData.image);
/********************************* IFD1 **********************************/

@@ -175,12 +255,36 @@

if (nextIfdOffset != 0x00000000) {
ifdOffset = tiffOffset + nextIfdOffset;
this.offsets.ifd1=ifdOffset;
numberOfEntries = data.getShort(ifdOffset, this.isBigEndian);
if (this.options.ifd1MaxEntries) {
numberOfEntries=Math.min(numberOfEntries, this.options.ifd1MaxEntries);
}
debug("IFD1 ifdOffset=",ifdOffset, "numberOfEntries=", numberOfEntries);
// Each IFD entry consists of 12 bytes which we loop through and extract
// the data from
for (var i = 0; i < numberOfEntries; i++) {
var exifEntry = self.extractExifEntry(data, (ifdOffset + 2 + (i * 12)), tiffOffset, this.isBigEndian, ExifImage.TAGS.exif);
if (exifEntry && exifEntry.tagName !== null) this.exifData.thumbnail[exifEntry.tagName] = exifEntry.value;
var exifEntry = this.extractExifEntry(data, (ifdOffset + 2 + (i * 12)), tiffOffset, this.isBigEndian, ExifImage.TAGS.exif);
if (!exifEntry) {
continue;
}
if (exifEntry.tagId===0xEA1C && noPadding) {
continue;
}
exifData.thumbnail[exifEntry.tagName] = exifEntry.value;
}
if (this.options.fixThumbnailOffset) {
var thumbnailOffset=exifData.thumbnail[ExifImage.TAGS.exif[0x0201]];
if (thumbnailOffset) {
debug("IFD1 fix thumbnail offset, add=",this.offsets.tiff);
exifData.thumbnail[ExifImage.TAGS.exif[0x0201]]+=this.offsets.tiff;
}
}
debug("IFD1 parsed", exifData.thumbnail);
}

@@ -192,14 +296,30 @@

// it if available
if (typeof this.exifData.image[ExifImage.TAGS.exif[0x8769]] != "undefined") {
if (exifData.image[ExifImage.TAGS.exif[0x8769]]) {
ifdOffset = tiffOffset + this.exifData.image[ExifImage.TAGS.exif[0x8769]];
ifdOffset = tiffOffset + exifData.image[ExifImage.TAGS.exif[0x8769]];
this.offsets.tags=ifdOffset;
numberOfEntries = data.getShort(ifdOffset, this.isBigEndian);
if (this.options.maxEntries) {
numberOfEntries=Math.min(numberOfEntries, this.options.maxEntries);
}
debug("EXIF IFD ifdOffset=",ifdOffset, "numberOfEntries=", numberOfEntries);
// Each IFD entry consists of 12 bytes which we loop through and extract
// the data from
for (var i = 0; i < numberOfEntries; i++) {
var exifEntry = self.extractExifEntry(data, (ifdOffset + 2 + (i * 12)), tiffOffset, this.isBigEndian, ExifImage.TAGS.exif);
if (exifEntry && exifEntry.tagName !== null) this.exifData.exif[exifEntry.tagName] = exifEntry.value;
var exifEntry = this.extractExifEntry(data, (ifdOffset + 2 + (i * 12)), tiffOffset, this.isBigEndian, ExifImage.TAGS.exif);
if (!exifEntry) {
continue;
}
if (exifEntry.tagId===0xEA1C && noPadding) {
continue;
}
exifData.exif[exifEntry.tagName] = exifEntry.value;
}
debug("EXIF IFD parsed",exifData.exif);
}

@@ -211,6 +331,13 @@

// it if available
if (typeof this.exifData.image[ExifImage.TAGS.exif[0x8825]] != "undefined") {
if (exifData.image[ExifImage.TAGS.exif[0x8825]]) {
ifdOffset = tiffOffset + this.exifData.image[ExifImage.TAGS.exif[0x8825]];
ifdOffset = tiffOffset + exifData.image[ExifImage.TAGS.exif[0x8825]];
this.offsets.gps=ifdOffset;
numberOfEntries = data.getShort(ifdOffset, this.isBigEndian);
if (this.options.maxGpsEntries) {
numberOfEntries=Math.min(numberOfEntries, this.options.maxGpsEntries);
}
debug("GPS IFD ifdOffset=", ifdOffset, "numberOfEntries=", numberOfEntries);

@@ -220,7 +347,16 @@ // Each IFD entry consists of 12 bytes which we loop through and extract

for (var i = 0; i < numberOfEntries; i++) {
var exifEntry = self.extractExifEntry(data, (ifdOffset + 2 + (i * 12)), tiffOffset, this.isBigEndian, ExifImage.TAGS.gps);
if (exifEntry && exifEntry.tagName !== null) this.exifData.gps[exifEntry.tagName] = exifEntry.value;
var exifEntry = this.extractExifEntry(data, (ifdOffset + 2 + (i * 12)), tiffOffset, this.isBigEndian, ExifImage.TAGS.gps);
if (!exifEntry) {
continue;
}
if (exifEntry.tagId===0xEA1C && noPadding) {
continue;
}
exifData.gps[exifEntry.tagName] = exifEntry.value;
}
}
debug("GPS IFD parsed",exifData.gps);
}

@@ -231,6 +367,13 @@ /************************* Interoperability IFD **************************/

// extract information from it if available
if (typeof this.exifData.exif[ExifImage.TAGS.exif[0xA005]] != "undefined") {
if (exifData.exif[ExifImage.TAGS.exif[0xA005]]) {
ifdOffset = tiffOffset + this.exifData.exif[ExifImage.TAGS.exif[0xA005]];
ifdOffset = tiffOffset + exifData.exif[ExifImage.TAGS.exif[0xA005]];
this.offsets.interoperability=ifdOffset;
numberOfEntries = data.getShort(ifdOffset, this.isBigEndian);
if (this.options.maxInteroperabilityEntries) {
numberOfEntries=Math.min(numberOfEntries, this.options.maxInteroperabilityEntries);
}
debug("Interoperability IFD ifdOffset=", ifdOffset, "numberOfEntries=", numberOfEntries);

@@ -240,6 +383,15 @@ // Each IFD entry consists of 12 bytes which we loop through and extract

for (var i = 0; i < numberOfEntries; i++) {
var exifEntry = self.extractExifEntry(data, (ifdOffset + 2 + (i * 12)), tiffOffset, this.isBigEndian, ExifImage.TAGS.exif);
if (exifEntry && exifEntry.tagName !== null) this.exifData.interoperability[exifEntry.tagName] = exifEntry.value;
}
var exifEntry = this.extractExifEntry(data, (ifdOffset + 2 + (i * 12)), tiffOffset, this.isBigEndian, ExifImage.TAGS.exif);
if (!exifEntry) {
break;
}
if (exifEntry.tagId===0xEA1C && noPadding) {
continue;
}
exifData.interoperability[exifEntry.tagName] = exifEntry.value;
}
debug("Interoperability IFD parsed",exifData.gps);
}

@@ -252,32 +404,42 @@

// start the extraction
if (typeof this.exifData.exif[ExifImage.TAGS.exif[0x927C]] != "undefined") {
if (typeof exifData.exif[ExifImage.TAGS.exif[0x927C]] != "undefined") {
var type;
// Check the header to see what kind of Makernote we are dealing with
if (this.exifData.exif[ExifImage.TAGS.exif[0x927C]].getString(0, 7) === "OLYMP\x00\x01" || this.exifData.exif[ExifImage.TAGS.exif[0x927C]].getString(0, 7) === "OLYMP\x00\x02") {
this.extractMakernotes = require('./makernotes/olympus').extractMakernotes;
} else if (this.exifData.exif[ExifImage.TAGS.exif[0x927C]].getString(0, 7) === "AGFA \x00\x01") {
this.extractMakernotes = require('./makernotes/agfa').extractMakernotes;
} else if (this.exifData.exif[ExifImage.TAGS.exif[0x927C]].getString(0, 8) === "EPSON\x00\x01\x00") {
this.extractMakernotes = require('./makernotes/epson').extractMakernotes;
} else if (this.exifData.exif[ExifImage.TAGS.exif[0x927C]].getString(0, 8) === "FUJIFILM") {
this.extractMakernotes = require('./makernotes/fujifilm').extractMakernotes;
} else if (this.exifData.exif[ExifImage.TAGS.exif[0x927C]].getString(0, 9) === "Panasonic") {
this.extractMakernotes = require('./makernotes/panasonic').extractMakernotes;
} else if (this.exifData.exif[ExifImage.TAGS.exif[0x927C]].getString(0, 5) === "SANYO") {
this.extractMakernotes = require('./makernotes/sanyo').extractMakernotes;
} else {
if (exifData.exif[ExifImage.TAGS.exif[0x927C]].getString(0, 7) === "OLYMP\x00\x01" || exifData.exif[ExifImage.TAGS.exif[0x927C]].getString(0, 7) === "OLYMP\x00\x02") {
type="olympus"
} else if (exifData.exif[ExifImage.TAGS.exif[0x927C]].getString(0, 7) === "AGFA \x00\x01") {
type="agfa";
} else if (exifData.exif[ExifImage.TAGS.exif[0x927C]].getString(0, 8) === "EPSON\x00\x01\x00") {
type="epson";
} else if (exifData.exif[ExifImage.TAGS.exif[0x927C]].getString(0, 8) === "FUJIFILM") {
type="fujifilm";
} else if (exifData.exif[ExifImage.TAGS.exif[0x927C]].getString(0, 9) === "Panasonic") {
type="panasonic";
} else if (exifData.exif[ExifImage.TAGS.exif[0x927C]].getString(0, 5) === "SANYO") {
type="sanyo";
}
debug("Makernote IFD ifdOffset=", ifdOffset, "type=", type);
if (type) {
var extractMakernotes = require('./makernotes/'+type).extractMakernotes;
exifData.makernote = extractMakernotes.call(this, data, this.makernoteOffset, tiffOffset);
} else {
// Makernotes are available but the format is not recognized so
// an error message is pushed instead, this ain't the best
// solution but should do for now
this.exifData.makernote['error'] = 'Unable to extract Makernote information as it is in an unsupported or unrecognized format.';
exifData.makernote['error'] = 'Unable to extract Makernote information as it is in an unsupported or unrecognized format.';
}
if (typeof this.exifData.makernote['error'] == "undefined") {
this.exifData.makernote = this.extractMakernotes(data, self.makernoteOffset, tiffOffset);
}
debug("Makernote IFD parsed",exifData.makernote);
}
return this.exifData;
};

@@ -287,5 +449,2 @@

var self = this;
var tagName;
var entry = {

@@ -305,3 +464,4 @@ tag : data.slice(entryOffset, entryOffset + 2),

if (tags && tags[entry.tagId] && typeof tags[entry.tagId] == "function") {
if (!(entry.tagName = tags[entry.tagId](entry))) {
entry.tagName = tags[entry.tagId].call(this, entry);
if (!entry.tagName) {
return false;

@@ -313,2 +473,5 @@ }

entry.tagName = tags[entry.tagId];
if (entry.tagName===undefined) {
return false;
}

@@ -388,9 +551,12 @@ // The tagId is not recognized

// If this is the Makernote tag save its offset for later use
if (entry.tagName === "MakerNote") self.makernoteOffset = entry.valueOffset;
if (entry.tagName === "MakerNote") {
this.offsets.makernoteOffset = entry.valueOffset;
}
// If the value array has only one element we don't need an array
if (entry.value.length == 1) entry.value = entry.value[0];
if (entry.value.length == 1) {
entry.value = entry.value[0];
}
return entry;
};

@@ -397,0 +563,0 @@

@@ -6,4 +6,2 @@ /**

var makernoteData = {};
// List of vendor specific Makernote tags found on

@@ -137,7 +135,14 @@ // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Olympus.html

// Get the number of entries and extract them
var numberOfEntries = data.getShort(ifdOffset, this.isBigEndian, tiffOffset);
var numberOfEntries = data.getShort(ifdOffset, this.isBigEndian);
if (this.options.agfaMaxEntries) {
numberOfEntries=Math.min(numberOfEntries, this.options.agfaMaxEntries);
}
var makernoteData = {};
for (var i = 0; i < numberOfEntries; i++) {
var exifEntry = this.extractExifEntry(data, (ifdOffset + 2 + (i * 12)), tiffOffset, this.isBigEndian, tags);
if (exifEntry && exifEntry.tagName !== null) makernoteData[exifEntry.tagName] = exifEntry.value;
if (exifEntry && exifEntry.tagName !== null) {
makernoteData[exifEntry.tagName] = exifEntry.value;
}
}

@@ -144,0 +149,0 @@

@@ -6,4 +6,2 @@ /**

var makernoteData = {};
// List of vendor specific Makernote tags found on

@@ -137,7 +135,14 @@ // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Olympus.html

// Get the number of entries and extract them
var numberOfEntries = data.getShort(ifdOffset, this.isBigEndian, tiffOffset);
var numberOfEntries = data.getShort(ifdOffset, this.isBigEndian);
if (this.options.epsonMaxEntries) {
numberOfEntries=Math.min(numberOfEntries, this.options.epsonMaxEntries);
}
var makernoteData = {};
for (var i = 0; i < numberOfEntries; i++) {
var exifEntry = this.extractExifEntry(data, (ifdOffset + 2 + (i * 12)), tiffOffset, this.isBigEndian, tags);
if (exifEntry && exifEntry.tagName !== null) makernoteData[exifEntry.tagName] = exifEntry.value;
if (exifEntry && exifEntry.tagName !== null) {
makernoteData[exifEntry.tagName] = exifEntry.value;
}
}

@@ -144,0 +149,0 @@

@@ -9,4 +9,2 @@ /**

var makernoteData = {};
// List of vendor specific Makernote tags found on

@@ -66,4 +64,9 @@ // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/FujiFilm.html

// Get the number of entries and extract them
var numberOfEntries = data.getShort(ifdOffset, false, tiffOffset);
var numberOfEntries = data.getShort(ifdOffset, false);
if (this.options.fujifilmMaxEntries) {
numberOfEntries=Math.min(numberOfEntries, this.options.fujifilmMaxEntries);
}
var makernoteData = {};
for (var i = 0; i < numberOfEntries; i++) {

@@ -70,0 +73,0 @@ var exifEntry = this.extractExifEntry(data, (ifdOffset + 2 + (i * 12)), makernoteOffset, false, tags);

@@ -6,4 +6,2 @@ /**

var makernoteData = {};
// List of vendor specific Makernote tags found on

@@ -137,4 +135,9 @@ // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Olympus.html

// Get the number of entries and extract them
var numberOfEntries = data.getShort(ifdOffset, this.isBigEndian, tiffOffset);
var numberOfEntries = data.getShort(ifdOffset, this.isBigEndian);
if (this.options.olympusMaxEntries) {
numberOfEntries=Math.min(numberOfEntries, this.options.olympusMaxEntries);
}
var makernoteData = {};
for (var i = 0; i < numberOfEntries; i++) {

@@ -141,0 +144,0 @@ var exifEntry = this.extractExifEntry(data, (ifdOffset + 2 + (i * 12)), tiffOffset, this.isBigEndian, tags);

@@ -6,4 +6,2 @@ /**

var makernoteData = {};
// List of vendor specific Makernote tags found on

@@ -117,7 +115,15 @@ // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Panasonic.html

// Get the number of entries and extract them
var numberOfEntries = data.getShort(ifdOffset, this.isBigEndian, tiffOffset);
var numberOfEntries = data.getShort(ifdOffset, this.isBigEndian);
if (this.options.panasonicMaxEntries) {
numberOfEntries=Math.min(numberOfEntries, this.options.panasonicMaxEntries);
}
var makernoteData = {};
for (var i = 0; i < numberOfEntries; i++) {
var exifEntry = this.extractExifEntry(data, (ifdOffset + 2 + (i * 12)), makernoteOffset, false, tags);
if (exifEntry && exifEntry.tagName !== null) makernoteData[exifEntry.tagName] = exifEntry.value;
if( ! exifEntry ) break; // stop if exifEntry starts to return false, prevents a process out of memory
if (exifEntry && exifEntry.tagName) {
makernoteData[exifEntry.tagName] = exifEntry.value;
}
}

@@ -124,0 +130,0 @@

@@ -6,4 +6,2 @@ /**

var makernoteData = {};
// List of vendor specific Makernote tags found on

@@ -58,7 +56,14 @@ // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Sanyo.html

// Get the number of entries and extract them
var numberOfEntries = data.getShort(ifdOffset, this.isBigEndian, tiffOffset);
var numberOfEntries = data.getShort(ifdOffset, this.isBigEndian);
if (this.options.sanyoMaxEntries) {
numberOfEntries=Math.min(numberOfEntries, this.options.sanyoMaxEntries);
}
var makernoteData = {};
for (var i = 0; i < numberOfEntries; i++) {
var exifEntry = this.extractExifEntry(data, (ifdOffset + 2 + (i * 12)), tiffOffset, this.isBigEndian, tags);
if (exifEntry && exifEntry.tagName !== null) makernoteData[exifEntry.tagName] = exifEntry.value;
if (exifEntry && exifEntry.tagName) {
makernoteData[exifEntry.tagName] = exifEntry.value;
}
}

@@ -65,0 +70,0 @@

{
"name" : "exif",
"version" : "0.4.0",
"description" : "A node.js library to extract Exif metadata from images.",
"author" : "Daniel Leinich <leinich@gmx.net>",
"keywords" : ["exif", "image", "jpeg", "jpg", "tiff", "makernotes", "gps"],
"main" : "./lib/exif",
"repository" : {
"type" : "git",
"url" : "http://github.com/gomfunkel/node-exif.git"
}
"name" : "exif",
"version" : "0.5.0",
"description" : "A node.js library to extract Exif metadata from images.",
"author" : "Daniel Leinich <leinich@gmx.net>",
"keywords" : ["exif", "image", "jpeg", "jpg", "tiff", "makernotes", "gps"],
"main" : "./lib/exif",
"repository" : {
"type" : "git",
"url" : "http://github.com/gomfunkel/node-exif.git"
},
"dependencies": {
"debug": "2.2"
}
}

@@ -5,2 +5,6 @@ # node-exif

## node-exif CLI
Rodrigo Espinosa proposes the npm package [exif-cli](https://github.com/RodrigoEspinosa/exif-cli) to execute node-exif from a shell.
## Table of Contents

@@ -18,3 +22,3 @@

npm install exif
If you don't have npm installed or don't want to use it:

@@ -31,3 +35,3 @@

var ExifImage = require('exif').ExifImage;
try {

@@ -59,4 +63,4 @@ new ExifImage({ image : 'myImage.jpg' }, function (error, exifData) {

```
{
image: {
{
image: {
Make: 'FUJIFILM',

@@ -72,5 +76,5 @@ Model: 'FinePix40i',

Copyright: ' ',
ExifOffset: 250
ExifOffset: 250
},
thumbnail: {
thumbnail: {
Compression: 6,

@@ -83,5 +87,5 @@ Orientation: 1,

ThumbnailLength: 8691,
YCbCrPositioning: 2
YCbCrPositioning: 2
},
exif: {
exif: {
FNumber: 2.8,

@@ -114,10 +118,10 @@ ExposureProgram: 2,

FileSource: <Buffer 03>,
SceneType: <Buffer 01>
SceneType: <Buffer 01>
},
gps: {},
interoperability: {
InteropIndex: 'R98',
InteropIndex: 'R98',
InteropVersion: <Buffer 30 31 30 30>
},
makernote: {
makernote: {
Version: <Buffer 30 31 33 30>,

@@ -135,4 +139,4 @@ Quality: 'NORMAL ',

FocusWarning: 0,
ExposureWarning: 0
}
ExposureWarning: 0
}
}

@@ -146,5 +150,5 @@ ```

There are a lot of things still to be done and to be made better. If you have any special requests please open an issue with a feature request.
## License
_node-exif_ is licensed under the MIT License. (See LICENSE)
_node-exif_ is licensed under the MIT License. (See LICENSE)

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc