From 6190ca43078cb684e3a82bc3a9361de1d25e02f6 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Tue, 7 Oct 2014 10:17:20 +0100 Subject: [PATCH] Ensure conversion to sRGB occurs before background #99 --- src/sharp.cc | 29 ++++++++++++++++++++--------- tests/unit.js | 10 ++++++++++ 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/sharp.cc b/src/sharp.cc index 60a98719..53620532 100755 --- a/src/sharp.cc +++ b/src/sharp.cc @@ -511,8 +511,9 @@ class ResizeWorker : public NanAsyncWorker { image = shrunk_on_load; } - // Import embedded colour profile, if present - if (vips_image_get_typeof(image, VIPS_META_ICC_NAME)) { + // Handle colour profile, if any, for non sRGB images + if (image->Type != VIPS_INTERPRETATION_sRGB && vips_image_get_typeof(image, VIPS_META_ICC_NAME)) { + // Import embedded profile VipsImage *profile = vips_image_new(); vips_object_local(hook, profile); if (vips_icc_import(image, &profile, NULL, "embedded", TRUE, "pcs", VIPS_PCS_XYZ, NULL)) { @@ -520,6 +521,14 @@ class ResizeWorker : public NanAsyncWorker { } g_object_unref(image); image = profile; + // Convert to sRGB colour space + VipsImage *colourspaced = vips_image_new(); + vips_object_local(hook, colourspaced); + if (vips_colourspace(profile, &colourspaced, VIPS_INTERPRETATION_sRGB, NULL)) { + return resize_error(baton, hook); + } + g_object_unref(image); + image = colourspaced; } // Flatten image to remove alpha channel @@ -710,14 +719,16 @@ class ResizeWorker : public NanAsyncWorker { image = gamma_decoded; } - // Always convert to sRGB colour space - VipsImage *colourspaced = vips_image_new(); - vips_object_local(hook, colourspaced); - if (vips_colourspace(image, &colourspaced, VIPS_INTERPRETATION_sRGB, NULL)) { - return resize_error(baton, hook); + // Convert to sRGB colour space, if not already + if (image->Type != VIPS_INTERPRETATION_sRGB) { + VipsImage *colourspaced = vips_image_new(); + vips_object_local(hook, colourspaced); + if (vips_colourspace(image, &colourspaced, VIPS_INTERPRETATION_sRGB, NULL)) { + return resize_error(baton, hook); + } + g_object_unref(image); + image = colourspaced; } - g_object_unref(image); - image = colourspaced; // Generate image tile cache when interlace output is required if (baton->progressive) { diff --git a/tests/unit.js b/tests/unit.js index ba1a988c..04732a00 100755 --- a/tests/unit.js +++ b/tests/unit.js @@ -327,6 +327,16 @@ async.series([ done(); }); }, + // Check colour space conversion from CMYK to sRGB works with background colour (yellow=fail) + function(done) { + sharp(inputJpgWithCmykProfile).resize(320, 240).background('white').embed().toFile(path.join(fixturesPath, 'output.cmyk2srgb.jpg'), function(err, info) { + if (err) throw err; + assert.strictEqual('jpeg', info.format); + assert.strictEqual(320, info.width); + assert.strictEqual(240, info.height); + done(); + }); + }, // Interpolation: nearest neighbour function(done) { sharp(inputJpg).resize(320, 240).interpolateWith(sharp.interpolator.nearest).toBuffer(function(err, data, info) {