mirror of
https://github.com/lovell/sharp.git
synced 2025-07-09 10:30:15 +02:00
Expose raw TIFFTAG_PHOTOSHOP metadata #1600
This commit is contained in:
parent
400ef71b6f
commit
d31a91a599
@ -44,6 +44,7 @@ A `Promise` is returned when `callback` is not provided.
|
|||||||
- `icc`: Buffer containing raw [ICC][3] profile data, if present
|
- `icc`: Buffer containing raw [ICC][3] profile data, if present
|
||||||
- `iptc`: Buffer containing raw IPTC data, if present
|
- `iptc`: Buffer containing raw IPTC data, if present
|
||||||
- `xmp`: Buffer containing raw XMP data, if present
|
- `xmp`: Buffer containing raw XMP data, if present
|
||||||
|
- `tifftagPhotoshop`: Buffer containing raw TIFFTAG_PHOTOSHOP data, if present
|
||||||
|
|
||||||
### Parameters
|
### Parameters
|
||||||
|
|
||||||
|
@ -8,6 +8,9 @@ Requires libvips v8.8.1.
|
|||||||
|
|
||||||
* Handle zero-length Buffer objects when using Node.js v13.2.0+.
|
* Handle zero-length Buffer objects when using Node.js v13.2.0+.
|
||||||
|
|
||||||
|
* Expose raw TIFFTAG_PHOTOSHOP metadata.
|
||||||
|
[#1600](https://github.com/lovell/sharp/issues/1600)
|
||||||
|
|
||||||
* Improve thread safety by using copy-on-write when updating metadata.
|
* Improve thread safety by using copy-on-write when updating metadata.
|
||||||
[#1986](https://github.com/lovell/sharp/issues/1986)
|
[#1986](https://github.com/lovell/sharp/issues/1986)
|
||||||
|
|
||||||
|
@ -207,6 +207,7 @@ function clone () {
|
|||||||
* - `icc`: Buffer containing raw [ICC](https://www.npmjs.com/package/icc) profile data, if present
|
* - `icc`: Buffer containing raw [ICC](https://www.npmjs.com/package/icc) profile data, if present
|
||||||
* - `iptc`: Buffer containing raw IPTC data, if present
|
* - `iptc`: Buffer containing raw IPTC data, if present
|
||||||
* - `xmp`: Buffer containing raw XMP data, if present
|
* - `xmp`: Buffer containing raw XMP data, if present
|
||||||
|
* - `tifftagPhotoshop`: Buffer containing raw TIFFTAG_PHOTOSHOP data, if present
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* const image = sharp(inputJpg);
|
* const image = sharp(inputJpg);
|
||||||
|
@ -116,6 +116,14 @@ class MetadataWorker : public Nan::AsyncWorker {
|
|||||||
memcpy(baton->xmp, xmp, xmpLength);
|
memcpy(baton->xmp, xmp, xmpLength);
|
||||||
baton->xmpLength = xmpLength;
|
baton->xmpLength = xmpLength;
|
||||||
}
|
}
|
||||||
|
// TIFFTAG_PHOTOSHOP
|
||||||
|
if (image.get_typeof(VIPS_META_PHOTOSHOP_NAME) == VIPS_TYPE_BLOB) {
|
||||||
|
size_t tifftagPhotoshopLength;
|
||||||
|
void const *tifftagPhotoshop = image.get_blob(VIPS_META_PHOTOSHOP_NAME, &tifftagPhotoshopLength);
|
||||||
|
baton->tifftagPhotoshop = static_cast<char *>(g_malloc(tifftagPhotoshopLength));
|
||||||
|
memcpy(baton->tifftagPhotoshop, tifftagPhotoshop, tifftagPhotoshopLength);
|
||||||
|
baton->tifftagPhotoshopLength = tifftagPhotoshopLength;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean up
|
// Clean up
|
||||||
@ -189,6 +197,12 @@ class MetadataWorker : public Nan::AsyncWorker {
|
|||||||
New("xmp").ToLocalChecked(),
|
New("xmp").ToLocalChecked(),
|
||||||
Nan::NewBuffer(baton->xmp, baton->xmpLength, sharp::FreeCallback, nullptr).ToLocalChecked());
|
Nan::NewBuffer(baton->xmp, baton->xmpLength, sharp::FreeCallback, nullptr).ToLocalChecked());
|
||||||
}
|
}
|
||||||
|
if (baton->tifftagPhotoshopLength > 0) {
|
||||||
|
Set(info,
|
||||||
|
New("tifftagPhotoshop").ToLocalChecked(),
|
||||||
|
Nan::NewBuffer(baton->tifftagPhotoshop, baton->tifftagPhotoshopLength, sharp::FreeCallback, nullptr)
|
||||||
|
.ToLocalChecked());
|
||||||
|
}
|
||||||
argv[1] = info;
|
argv[1] = info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +48,8 @@ struct MetadataBaton {
|
|||||||
size_t iptcLength;
|
size_t iptcLength;
|
||||||
char *xmp;
|
char *xmp;
|
||||||
size_t xmpLength;
|
size_t xmpLength;
|
||||||
|
char *tifftagPhotoshop;
|
||||||
|
size_t tifftagPhotoshopLength;
|
||||||
std::string err;
|
std::string err;
|
||||||
|
|
||||||
MetadataBaton():
|
MetadataBaton():
|
||||||
@ -71,7 +73,9 @@ struct MetadataBaton {
|
|||||||
iptc(nullptr),
|
iptc(nullptr),
|
||||||
iptcLength(0),
|
iptcLength(0),
|
||||||
xmp(nullptr),
|
xmp(nullptr),
|
||||||
xmpLength(0) {}
|
xmpLength(0),
|
||||||
|
tifftagPhotoshop(nullptr),
|
||||||
|
tifftagPhotoshopLength(0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
NAN_METHOD(metadata);
|
NAN_METHOD(metadata);
|
||||||
|
1
test/fixtures/index.js
vendored
1
test/fixtures/index.js
vendored
@ -97,6 +97,7 @@ module.exports = {
|
|||||||
inputTiffCielab: getPath('cielab-dagams.tiff'), // https://github.com/lovell/sharp/issues/646
|
inputTiffCielab: getPath('cielab-dagams.tiff'), // https://github.com/lovell/sharp/issues/646
|
||||||
inputTiffUncompressed: getPath('uncompressed_tiff.tiff'), // https://code.google.com/archive/p/imagetestsuite/wikis/TIFFTestSuite.wiki file: 0c84d07e1b22b76f24cccc70d8788e4a.tif
|
inputTiffUncompressed: getPath('uncompressed_tiff.tiff'), // https://code.google.com/archive/p/imagetestsuite/wikis/TIFFTestSuite.wiki file: 0c84d07e1b22b76f24cccc70d8788e4a.tif
|
||||||
inputTiff8BitDepth: getPath('8bit_depth.tiff'),
|
inputTiff8BitDepth: getPath('8bit_depth.tiff'),
|
||||||
|
inputTifftagPhotoshop: getPath('tifftag-photoshop.tiff'), // https://github.com/lovell/sharp/issues/1600
|
||||||
inputGif: getPath('Crash_test.gif'), // http://upload.wikimedia.org/wikipedia/commons/e/e3/Crash_test.gif
|
inputGif: getPath('Crash_test.gif'), // http://upload.wikimedia.org/wikipedia/commons/e/e3/Crash_test.gif
|
||||||
inputGifGreyPlusAlpha: getPath('grey-plus-alpha.gif'), // http://i.imgur.com/gZ5jlmE.gif
|
inputGifGreyPlusAlpha: getPath('grey-plus-alpha.gif'), // http://i.imgur.com/gZ5jlmE.gif
|
||||||
inputGifAnimated: getPath('rotating-squares.gif'), // CC0 https://loading.io/spinner/blocks/-rotating-squares-preloader-gif
|
inputGifAnimated: getPath('rotating-squares.gif'), // CC0 https://loading.io/spinner/blocks/-rotating-squares-preloader-gif
|
||||||
|
BIN
test/fixtures/tifftag-photoshop.tiff
vendored
Normal file
BIN
test/fixtures/tifftag-photoshop.tiff
vendored
Normal file
Binary file not shown.
@ -515,6 +515,21 @@ describe('Image metadata', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('16-bit TIFF with TIFFTAG_PHOTOSHOP metadata', () =>
|
||||||
|
sharp(fixtures.inputTifftagPhotoshop)
|
||||||
|
.metadata()
|
||||||
|
.then(metadata => {
|
||||||
|
assert.strictEqual(metadata.format, 'tiff');
|
||||||
|
assert.strictEqual(metadata.width, 317);
|
||||||
|
assert.strictEqual(metadata.height, 211);
|
||||||
|
assert.strictEqual(metadata.space, 'rgb16');
|
||||||
|
assert.strictEqual(metadata.channels, 3);
|
||||||
|
assert.strictEqual(typeof metadata.tifftagPhotoshop, 'object');
|
||||||
|
assert.strictEqual(metadata.tifftagPhotoshop instanceof Buffer, true);
|
||||||
|
assert.strictEqual(metadata.tifftagPhotoshop.length, 6634);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
it('File input with corrupt header fails gracefully', function (done) {
|
it('File input with corrupt header fails gracefully', function (done) {
|
||||||
sharp(fixtures.inputJpgWithCorruptHeader)
|
sharp(fixtures.inputJpgWithCorruptHeader)
|
||||||
.metadata(function (err) {
|
.metadata(function (err) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user