diff --git a/docs/changelog.md b/docs/changelog.md index b9429f16..be44801b 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -17,6 +17,9 @@ Requires libvips v8.8.1. * Add experimental support for Worker Threads. [#1558](https://github.com/lovell/sharp/issues/1558) +* Use libvips' built-in CMYK and sRGB profiles when required. + [#1619](https://github.com/lovell/sharp/issues/1619) + * Drop support for Node.js versions 6 and 11. [#1674](https://github.com/lovell/sharp/issues/1674) diff --git a/lib/constructor.js b/lib/constructor.js index 00334967..f6a6c6d1 100644 --- a/lib/constructor.js +++ b/lib/constructor.js @@ -1,6 +1,5 @@ 'use strict'; -const path = require('path'); const util = require('util'); const stream = require('stream'); const events = require('events'); @@ -111,8 +110,6 @@ const Sharp = function (input, options) { // input options sequentialRead: false, limitInputPixels: Math.pow(0x3FFF, 2), - // ICC profiles - iccProfilePath: path.join(__dirname, 'icc') + path.sep, // resize options topOffsetPre: -1, leftOffsetPre: -1, diff --git a/lib/icc/cmyk.icm b/lib/icc/cmyk.icm deleted file mode 100644 index 7f070779..00000000 Binary files a/lib/icc/cmyk.icm and /dev/null differ diff --git a/lib/icc/sRGB.icc b/lib/icc/sRGB.icc deleted file mode 100644 index 95e249b8..00000000 Binary files a/lib/icc/sRGB.icc and /dev/null differ diff --git a/src/pipeline.cc b/src/pipeline.cc index a4e1b4e7..e68def8c 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -70,16 +70,6 @@ class PipelineWorker : public Nan::AsyncWorker { // Increment processing task counter g_atomic_int_inc(&sharp::counterProcess); - std::map profileMap; - // Default sRGB ICC profile from https://packages.debian.org/sid/all/icc-profiles-free/filelist - profileMap.insert( - std::pair(VIPS_INTERPRETATION_sRGB, - baton->iccProfilePath + "sRGB.icc")); - // Convert to sRGB using default CMYK profile from http://www.argyllcms.com/cmyk.icm - profileMap.insert( - std::pair(VIPS_INTERPRETATION_CMYK, - baton->iccProfilePath + "cmyk.icm")); - try { // Open input vips::VImage image; @@ -321,17 +311,15 @@ class PipelineWorker : public Nan::AsyncWorker { if (sharp::HasProfile(image) && image.interpretation() != VIPS_INTERPRETATION_LABS) { // Convert to sRGB using embedded profile try { - image = image.icc_transform( - const_cast(profileMap[VIPS_INTERPRETATION_sRGB].data()), VImage::option() + image = image.icc_transform("srgb", VImage::option() ->set("embedded", TRUE) ->set("intent", VIPS_INTENT_PERCEPTUAL)); } catch(...) { // Ignore failure of embedded profile } } else if (image.interpretation() == VIPS_INTERPRETATION_CMYK) { - image = image.icc_transform( - const_cast(profileMap[VIPS_INTERPRETATION_sRGB].data()), VImage::option() - ->set("input_profile", profileMap[VIPS_INTERPRETATION_CMYK].data()) + image = image.icc_transform("srgb", VImage::option() + ->set("input_profile", "cmyk") ->set("intent", VIPS_INTENT_PERCEPTUAL)); } @@ -701,8 +689,8 @@ class PipelineWorker : public Nan::AsyncWorker { // Convert colourspace, pass the current known interpretation so libvips doesn't have to guess image = image.colourspace(baton->colourspace, VImage::option()->set("source_space", image.interpretation())); // Transform colours from embedded profile to output profile - if (baton->withMetadata && sharp::HasProfile(image) && profileMap[baton->colourspace] != std::string()) { - image = image.icc_transform(const_cast(profileMap[baton->colourspace].data()), + if (baton->withMetadata && sharp::HasProfile(image)) { + image = image.icc_transform(vips_enum_nick(VIPS_TYPE_INTERPRETATION, baton->colourspace), VImage::option()->set("embedded", TRUE)); } } @@ -1196,9 +1184,6 @@ NAN_METHOD(pipeline) { // Input baton->input = CreateInputDescriptor(AttrAs(options, "input"), buffersToPersist); - - // ICC profile to use when input CMYK image has no embedded profile - baton->iccProfilePath = AttrAsStr(options, "iccProfilePath"); baton->accessMethod = AttrTo(options, "sequentialRead") ? VIPS_ACCESS_SEQUENTIAL : VIPS_ACCESS_RANDOM; // Limit input images to a given number of pixels, where pixels = width * height diff --git a/src/pipeline.h b/src/pipeline.h index 2c834698..50e62e6b 100644 --- a/src/pipeline.h +++ b/src/pipeline.h @@ -53,7 +53,6 @@ struct Composite { struct PipelineBaton { sharp::InputDescriptor *input; - std::string iccProfilePath; int limitInputPixels; std::string formatOut; std::string fileOut; diff --git a/test/unit/stats.js b/test/unit/stats.js index 403978de..a7e623fe 100644 --- a/test/unit/stats.js +++ b/test/unit/stats.js @@ -394,6 +394,15 @@ describe('Image Stats', function () { }); }); + it('CMYK input without profile', () => + sharp(fixtures.inputJpgWithCmykNoProfile) + .stats() + .then(stats => { + assert.strictEqual(4, stats.channels.length); + assert.strictEqual(true, stats.isOpaque); + }) + ); + it('Stream in, Callback out', function (done) { const readable = fs.createReadStream(fixtures.inputJpg); const pipeline = sharp().stats(function (err, stats) {