Add 'icc' raw profile data to metadata #129

This commit is contained in:
Lovell Fuller 2015-06-29 21:27:23 +01:00
parent cff8b45420
commit 321e0f2bfe
4 changed files with 76 additions and 4 deletions

View File

@ -344,6 +344,7 @@ Fast access to image metadata without decoding any compressed image data.
* `hasAlpha`: Boolean indicating the presence of an alpha transparency channel * `hasAlpha`: Boolean indicating the presence of an alpha transparency channel
* `orientation`: Number value of the EXIF Orientation header, if present * `orientation`: Number value of the EXIF Orientation header, if present
* `exif`: Buffer containing raw EXIF data, if present * `exif`: Buffer containing raw EXIF data, if present
* `icc`: Buffer containing raw [ICC](https://www.npmjs.com/package/icc) profile data, if present
A Promises/A+ promise is returned when `callback` is not provided. A Promises/A+ promise is returned when `callback` is not provided.

View File

@ -51,9 +51,10 @@
"semver": "^4.3.6" "semver": "^4.3.6"
}, },
"devDependencies": { "devDependencies": {
"async": "^1.2.1", "async": "^1.3.0",
"coveralls": "^2.11.2", "coveralls": "^2.11.2",
"exif-reader": "1.0.0", "exif-reader": "1.0.0",
"icc": "^0.0.2",
"istanbul": "^0.3.17", "istanbul": "^0.3.17",
"mocha": "^2.2.5", "mocha": "^2.2.5",
"mocha-jshint": "^2.2.3", "mocha-jshint": "^2.2.3",

View File

@ -40,12 +40,15 @@ struct MetadataBaton {
int orientation; int orientation;
char *exif; char *exif;
size_t exifLength; size_t exifLength;
char *icc;
size_t iccLength;
std::string err; std::string err;
MetadataBaton(): MetadataBaton():
bufferInLength(0), bufferInLength(0),
orientation(0), orientation(0),
exifLength(0) {} exifLength(0),
iccLength(0) {}
}; };
/* /*
@ -130,6 +133,16 @@ class MetadataWorker : public NanAsyncWorker {
memcpy(baton->exif, exif, exifLength); memcpy(baton->exif, exif, exifLength);
} }
} }
// ICC profile
if (vips_image_get_typeof(image, VIPS_META_ICC_NAME) == VIPS_TYPE_BLOB) {
void* icc;
size_t iccLength;
if (!vips_image_get_blob(image, VIPS_META_ICC_NAME, &icc, &iccLength)) {
baton->iccLength = iccLength;
baton->icc = new char[iccLength];
memcpy(baton->icc, icc, iccLength);
}
}
// Drop image reference // Drop image reference
g_object_unref(image); g_object_unref(image);
} }
@ -161,6 +174,9 @@ class MetadataWorker : public NanAsyncWorker {
if (baton->exifLength > 0) { if (baton->exifLength > 0) {
info->Set(NanNew<String>("exif"), NanBufferUse(baton->exif, baton->exifLength)); info->Set(NanNew<String>("exif"), NanBufferUse(baton->exif, baton->exifLength));
} }
if (baton->iccLength > 0) {
info->Set(NanNew<String>("icc"), NanBufferUse(baton->icc, baton->iccLength));
}
argv[1] = info; argv[1] = info;
} }
delete baton; delete baton;

View File

@ -3,6 +3,7 @@
var fs = require('fs'); var fs = require('fs');
var assert = require('assert'); var assert = require('assert');
var exifReader = require('exif-reader'); var exifReader = require('exif-reader');
var icc = require('icc');
var sharp = require('../../index'); var sharp = require('../../index');
var fixtures = require('../fixtures'); var fixtures = require('../fixtures');
@ -23,11 +24,12 @@ describe('Image metadata', function() {
assert.strictEqual(false, metadata.hasAlpha); assert.strictEqual(false, metadata.hasAlpha);
assert.strictEqual('undefined', typeof metadata.orientation); assert.strictEqual('undefined', typeof metadata.orientation);
assert.strictEqual('undefined', typeof metadata.exif); assert.strictEqual('undefined', typeof metadata.exif);
assert.strictEqual('undefined', typeof metadata.icc);
done(); done();
}); });
}); });
it('JPEG with EXIF', function(done) { it('JPEG with EXIF/ICC', function(done) {
sharp(fixtures.inputJpgWithExif).metadata(function(err, metadata) { sharp(fixtures.inputJpgWithExif).metadata(function(err, metadata) {
if (err) throw err; if (err) throw err;
assert.strictEqual('jpeg', metadata.format); assert.strictEqual('jpeg', metadata.format);
@ -38,12 +40,19 @@ describe('Image metadata', function() {
assert.strictEqual(true, metadata.hasProfile); assert.strictEqual(true, metadata.hasProfile);
assert.strictEqual(false, metadata.hasAlpha); assert.strictEqual(false, metadata.hasAlpha);
assert.strictEqual(8, metadata.orientation); assert.strictEqual(8, metadata.orientation);
// EXIF
assert.strictEqual('object', typeof metadata.exif); assert.strictEqual('object', typeof metadata.exif);
assert.strictEqual(true, metadata.exif instanceof Buffer); assert.strictEqual(true, metadata.exif instanceof Buffer);
var exif = exifReader(metadata.exif); var exif = exifReader(metadata.exif);
assert.strictEqual('object', typeof exif); assert.strictEqual('object', typeof exif);
assert.strictEqual('object', typeof exif.image); assert.strictEqual('object', typeof exif.image);
assert.strictEqual('number', typeof exif.image.XResolution); assert.strictEqual('number', typeof exif.image.XResolution);
// ICC
assert.strictEqual('object', typeof metadata.icc);
assert.strictEqual(true, metadata.icc instanceof Buffer);
var profile = icc.parse(metadata.icc);
assert.strictEqual('object', typeof profile);
assert.strictEqual('Generic RGB Profile', profile.description);
done(); done();
}); });
}); });
@ -58,6 +67,9 @@ describe('Image metadata', function() {
assert.strictEqual(1, metadata.channels); assert.strictEqual(1, metadata.channels);
assert.strictEqual(false, metadata.hasProfile); assert.strictEqual(false, metadata.hasProfile);
assert.strictEqual(false, metadata.hasAlpha); assert.strictEqual(false, metadata.hasAlpha);
assert.strictEqual('undefined', typeof metadata.orientation);
assert.strictEqual('undefined', typeof metadata.exif);
assert.strictEqual('undefined', typeof metadata.icc);
done(); done();
}); });
}); });
@ -72,6 +84,9 @@ describe('Image metadata', function() {
assert.strictEqual(1, metadata.channels); assert.strictEqual(1, metadata.channels);
assert.strictEqual(false, metadata.hasProfile); assert.strictEqual(false, metadata.hasProfile);
assert.strictEqual(false, metadata.hasAlpha); assert.strictEqual(false, metadata.hasAlpha);
assert.strictEqual('undefined', typeof metadata.orientation);
assert.strictEqual('undefined', typeof metadata.exif);
assert.strictEqual('undefined', typeof metadata.icc);
done(); done();
}); });
}); });
@ -86,6 +101,9 @@ describe('Image metadata', function() {
assert.strictEqual(4, metadata.channels); assert.strictEqual(4, metadata.channels);
assert.strictEqual(false, metadata.hasProfile); assert.strictEqual(false, metadata.hasProfile);
assert.strictEqual(true, metadata.hasAlpha); assert.strictEqual(true, metadata.hasAlpha);
assert.strictEqual('undefined', typeof metadata.orientation);
assert.strictEqual('undefined', typeof metadata.exif);
assert.strictEqual('undefined', typeof metadata.icc);
done(); done();
}); });
}); });
@ -101,6 +119,9 @@ describe('Image metadata', function() {
assert.strictEqual(3, metadata.channels); assert.strictEqual(3, metadata.channels);
assert.strictEqual(false, metadata.hasProfile); assert.strictEqual(false, metadata.hasProfile);
assert.strictEqual(false, metadata.hasAlpha); assert.strictEqual(false, metadata.hasAlpha);
assert.strictEqual('undefined', typeof metadata.orientation);
assert.strictEqual('undefined', typeof metadata.exif);
assert.strictEqual('undefined', typeof metadata.icc);
done(); done();
}); });
}); });
@ -115,6 +136,9 @@ describe('Image metadata', function() {
assert.strictEqual(3, metadata.channels); assert.strictEqual(3, metadata.channels);
assert.strictEqual(false, metadata.hasProfile); assert.strictEqual(false, metadata.hasProfile);
assert.strictEqual(false, metadata.hasAlpha); assert.strictEqual(false, metadata.hasAlpha);
assert.strictEqual('undefined', typeof metadata.orientation);
assert.strictEqual('undefined', typeof metadata.exif);
assert.strictEqual('undefined', typeof metadata.icc);
done(); done();
}); });
}); });
@ -130,6 +154,9 @@ describe('Image metadata', function() {
assert.strictEqual('rgb', metadata.space); assert.strictEqual('rgb', metadata.space);
assert.strictEqual(false, metadata.hasProfile); assert.strictEqual(false, metadata.hasProfile);
assert.strictEqual(true, metadata.hasAlpha); assert.strictEqual(true, metadata.hasAlpha);
assert.strictEqual('undefined', typeof metadata.orientation);
assert.strictEqual('undefined', typeof metadata.exif);
assert.strictEqual('undefined', typeof metadata.icc);
done(); done();
}); });
}); });
@ -144,6 +171,9 @@ describe('Image metadata', function() {
assert.strictEqual(3, metadata.channels); assert.strictEqual(3, metadata.channels);
assert.strictEqual(false, metadata.hasProfile); assert.strictEqual(false, metadata.hasProfile);
assert.strictEqual(false, metadata.hasAlpha); assert.strictEqual(false, metadata.hasAlpha);
assert.strictEqual('undefined', typeof metadata.orientation);
assert.strictEqual('undefined', typeof metadata.exif);
assert.strictEqual('undefined', typeof metadata.icc);
done(); done();
}); });
}); });
@ -168,6 +198,9 @@ describe('Image metadata', function() {
assert.strictEqual(3, metadata.channels); assert.strictEqual(3, metadata.channels);
assert.strictEqual(false, metadata.hasProfile); assert.strictEqual(false, metadata.hasProfile);
assert.strictEqual(false, metadata.hasAlpha); assert.strictEqual(false, metadata.hasAlpha);
assert.strictEqual('undefined', typeof metadata.orientation);
assert.strictEqual('undefined', typeof metadata.exif);
assert.strictEqual('undefined', typeof metadata.icc);
done(); done();
}).catch(function(err) { }).catch(function(err) {
throw err; throw err;
@ -186,6 +219,9 @@ describe('Image metadata', function() {
assert.strictEqual(3, metadata.channels); assert.strictEqual(3, metadata.channels);
assert.strictEqual(false, metadata.hasProfile); assert.strictEqual(false, metadata.hasProfile);
assert.strictEqual(false, metadata.hasAlpha); assert.strictEqual(false, metadata.hasAlpha);
assert.strictEqual('undefined', typeof metadata.orientation);
assert.strictEqual('undefined', typeof metadata.exif);
assert.strictEqual('undefined', typeof metadata.icc);
done(); done();
}); });
readable.pipe(pipeline); readable.pipe(pipeline);
@ -202,6 +238,9 @@ describe('Image metadata', function() {
assert.strictEqual(3, metadata.channels); assert.strictEqual(3, metadata.channels);
assert.strictEqual(false, metadata.hasProfile); assert.strictEqual(false, metadata.hasProfile);
assert.strictEqual(false, metadata.hasAlpha); assert.strictEqual(false, metadata.hasAlpha);
assert.strictEqual('undefined', typeof metadata.orientation);
assert.strictEqual('undefined', typeof metadata.exif);
assert.strictEqual('undefined', typeof metadata.icc);
image.resize(Math.floor(metadata.width / 2)).toBuffer(function(err, data, info) { image.resize(Math.floor(metadata.width / 2)).toBuffer(function(err, data, info) {
if (err) throw err; if (err) throw err;
assert.strictEqual(true, data.length > 0); assert.strictEqual(true, data.length > 0);
@ -212,7 +251,7 @@ describe('Image metadata', function() {
}); });
}); });
it('Keep EXIF metadata after a resize', function(done) { it('Keep EXIF metadata and add sRGB profile after a resize', function(done) {
sharp(fixtures.inputJpgWithExif) sharp(fixtures.inputJpgWithExif)
.resize(320, 240) .resize(320, 240)
.withMetadata() .withMetadata()
@ -222,6 +261,19 @@ describe('Image metadata', function() {
if (err) throw err; if (err) throw err;
assert.strictEqual(true, metadata.hasProfile); assert.strictEqual(true, metadata.hasProfile);
assert.strictEqual(8, metadata.orientation); assert.strictEqual(8, metadata.orientation);
assert.strictEqual('object', typeof metadata.exif);
assert.strictEqual(true, metadata.exif instanceof Buffer);
// EXIF
var exif = exifReader(metadata.exif);
assert.strictEqual('object', typeof exif);
assert.strictEqual('object', typeof exif.image);
assert.strictEqual('number', typeof exif.image.XResolution);
// ICC
assert.strictEqual('object', typeof metadata.icc);
assert.strictEqual(true, metadata.icc instanceof Buffer);
var profile = icc.parse(metadata.icc);
assert.strictEqual('object', typeof profile);
assert.strictEqual('sRGB IEC61966-2-1 black scaled', profile.description);
done(); done();
}); });
}); });
@ -237,6 +289,8 @@ describe('Image metadata', function() {
if (err) throw err; if (err) throw err;
assert.strictEqual(false, metadata.hasProfile); assert.strictEqual(false, metadata.hasProfile);
assert.strictEqual('undefined', typeof metadata.orientation); assert.strictEqual('undefined', typeof metadata.orientation);
assert.strictEqual('undefined', typeof metadata.exif);
assert.strictEqual('undefined', typeof metadata.icc);
done(); done();
}); });
}); });