Skip to content

Commit

Permalink
Ensure trim op works with CMYK input #3636
Browse files Browse the repository at this point in the history
  • Loading branch information
lovell committed Apr 20, 2023
1 parent a39f959 commit 8408e99
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 19 deletions.
3 changes: 3 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ Requires libvips v8.14.2
* Add support for `modulate` operation when using non-sRGB pipeline colourspace.
[#3620](https://github.com/lovell/sharp/issues/3620)

* Ensure `trim` operation works with CMYK images (regression in 0.31.0).
[#3636](https://github.com/lovell/sharp/issues/3636)

### v0.32.0 - 24th March 2023

* Default to using sequential rather than random access read where possible.
Expand Down
28 changes: 9 additions & 19 deletions src/operations.cc
Original file line number Diff line number Diff line change
Expand Up @@ -269,30 +269,20 @@ namespace sharp {
if (image.width() < 3 && image.height() < 3) {
throw VError("Image to trim must be at least 3x3 pixels");
}

// Scale up 8-bit values to match 16-bit input image
double multiplier = sharp::Is16Bit(image.interpretation()) ? 256.0 : 1.0;
threshold *= multiplier;

std::vector<double> backgroundAlpha(1);
if (background.size() == 0) {
// Top-left pixel provides the default background colour if none is given
background = image.extract_area(0, 0, 1, 1)(0, 0);
multiplier = 1.0;
}
if (HasAlpha(image) && background.size() == 4) {
// Just discard the alpha because flattening the background colour with
// itself (effectively what find_trim() does) gives the same result
backgroundAlpha[0] = background[3] * multiplier;
} else if (sharp::Is16Bit(image.interpretation())) {
for (size_t i = 0; i < background.size(); i++) {
background[i] *= 256.0;
}
threshold *= 256.0;
}
if (image.bands() > 2) {
background = {
background[0] * multiplier,
background[1] * multiplier,
background[2] * multiplier
};
std::vector<double> backgroundAlpha({ background.back() });
if (HasAlpha(image)) {
background.pop_back();
} else {
background[0] = background[0] * multiplier;
background.resize(image.bands());
}
int left, top, width, height;
left = image.find_trim(&top, &width, &height, VImage::option()
Expand Down
26 changes: 26 additions & 0 deletions test/unit/trim.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,32 @@ describe('Trim borders', function () {
assert.strictEqual(trimOffsetLeft, -12);
});

it('Ensure CMYK image can be trimmed', async () => {
const cmyk = await sharp({
create: {
width: 16,
height: 8,
channels: 3,
background: 'red'
}
})
.extend({ left: 12, right: 24, background: 'blue' })
.toColourspace('cmyk')
.jpeg()
.toBuffer();

const { info } = await sharp(cmyk)
.trim()
.raw()
.toBuffer({ resolveWithObject: true });

const { width, height, trimOffsetTop, trimOffsetLeft } = info;
assert.strictEqual(width, 16);
assert.strictEqual(height, 8);
assert.strictEqual(trimOffsetTop, 0);
assert.strictEqual(trimOffsetLeft, -12);
});

it('Ensure trim of image with all pixels same is no-op', async () => {
const { info } = await sharp({
create: {
Expand Down

0 comments on commit 8408e99

Please sign in to comment.