Skip to content

Commit

Permalink
Merge cb9c598 into c387415
Browse files Browse the repository at this point in the history
  • Loading branch information
jardakotesovec committed Oct 5, 2017
2 parents c387415 + cb9c598 commit 4953a44
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 90 deletions.
102 changes: 13 additions & 89 deletions src/pipeline.cc
Original file line number Diff line number Diff line change
Expand Up @@ -279,23 +279,6 @@ class PipelineWorker : public Nan::AsyncWorker {
}
xfactor = static_cast<double>(shrunkOnLoadWidth) / static_cast<double>(targetResizeWidth);
yfactor = static_cast<double>(shrunkOnLoadHeight) / static_cast<double>(targetResizeHeight);
xshrink = std::max(1, static_cast<int>(floor(xfactor)));
yshrink = std::max(1, static_cast<int>(floor(yfactor)));
xresidual = static_cast<double>(xshrink) / xfactor;
yresidual = static_cast<double>(yshrink) / yfactor;
if (
!baton->rotateBeforePreExtract &&
(rotation == VIPS_ANGLE_D90 || rotation == VIPS_ANGLE_D270)
) {
std::swap(xresidual, yresidual);
}
}
// Help ensure a final kernel-based reduction to prevent shrink aliasing
if (xshrink > 1 && yshrink > 1 && (xresidual == 1.0 || yresidual == 1.0)) {
xshrink = xshrink / 2;
yshrink = yshrink / 2;
xresidual = static_cast<double>(xshrink) / xfactor;
yresidual = static_cast<double>(yshrink) / yfactor;
}

// Ensure we're using a device-independent colour space
Expand Down Expand Up @@ -361,13 +344,12 @@ class PipelineWorker : public Nan::AsyncWorker {
}
}

bool const shouldShrink = xshrink > 1 || yshrink > 1;
bool const shouldReduce = xresidual != 1.0 || yresidual != 1.0;
bool const shouldResize = xfactor != 1.0 || yfactor != 1.0;
bool const shouldBlur = baton->blurSigma != 0.0;
bool const shouldConv = baton->convKernelWidth * baton->convKernelHeight > 0;
bool const shouldSharpen = baton->sharpenSigma != 0.0;
bool const shouldPremultiplyAlpha = HasAlpha(image) &&
(shouldShrink || shouldReduce || shouldBlur || shouldConv || shouldSharpen || shouldOverlayWithAlpha);
(shouldResize || shouldBlur || shouldConv || shouldSharpen || shouldOverlayWithAlpha);

// Premultiply image alpha channel before all transformations to avoid
// dark fringing around bright pixels
Expand All @@ -376,79 +358,21 @@ class PipelineWorker : public Nan::AsyncWorker {
image = image.premultiply();
}

// Fast, integral box-shrink
if (shouldShrink) {
if (yshrink > 1) {
image = image.shrinkv(yshrink);
}
if (xshrink > 1) {
image = image.shrinkh(xshrink);
}
// Recalculate residual float based on dimensions of required vs shrunk images
int shrunkWidth = image.width();
int shrunkHeight = image.height();
if (!baton->rotateBeforePreExtract &&
(rotation == VIPS_ANGLE_D90 || rotation == VIPS_ANGLE_D270)) {
// Swap input output width and height when rotating by 90 or 270 degrees
std::swap(shrunkWidth, shrunkHeight);
}
xresidual = static_cast<double>(targetResizeWidth) / static_cast<double>(shrunkWidth);
yresidual = static_cast<double>(targetResizeHeight) / static_cast<double>(shrunkHeight);
// Resize
if (shouldResize) {
VipsKernel kernel = static_cast<VipsKernel>(
vips_enum_from_nick(nullptr, VIPS_TYPE_KERNEL, baton->kernel.data()));
if (
!baton->rotateBeforePreExtract &&
(rotation == VIPS_ANGLE_D90 || rotation == VIPS_ANGLE_D270)
kernel != VIPS_KERNEL_NEAREST && kernel != VIPS_KERNEL_CUBIC && kernel != VIPS_KERNEL_LANCZOS2 &&
kernel != VIPS_KERNEL_LANCZOS3
) {
std::swap(xresidual, yresidual);
throw vips::VError("Unknown kernel");
}
}

// Use affine increase or kernel reduce with the remaining float part
if (xresidual != 1.0 || yresidual != 1.0) {
// Insert tile cache to prevent over-computation of previous operations
if (baton->accessMethod == VIPS_ACCESS_SEQUENTIAL) {
image = sharp::TileCache(image, yresidual);
}
// Perform kernel-based reduction
if (yresidual < 1.0 || xresidual < 1.0) {
VipsKernel kernel = static_cast<VipsKernel>(
vips_enum_from_nick(nullptr, VIPS_TYPE_KERNEL, baton->kernel.data()));
if (
kernel != VIPS_KERNEL_NEAREST && kernel != VIPS_KERNEL_CUBIC && kernel != VIPS_KERNEL_LANCZOS2 &&
kernel != VIPS_KERNEL_LANCZOS3
) {
throw vips::VError("Unknown kernel");
}
if (yresidual < 1.0) {
image = image.reducev(1.0 / yresidual, VImage::option()
->set("kernel", kernel)
->set("centre", baton->centreSampling));
}
if (xresidual < 1.0) {
image = image.reduceh(1.0 / xresidual, VImage::option()
->set("kernel", kernel)
->set("centre", baton->centreSampling));
}
}
// Perform enlargement
if (yresidual > 1.0 || xresidual > 1.0) {
if (trunc(xresidual) == xresidual && trunc(yresidual) == yresidual && baton->interpolator == "nearest") {
// Fast, integral nearest neighbour enlargement
image = image.zoom(static_cast<int>(xresidual), static_cast<int>(yresidual));
} else {
// Floating point affine transformation
vips::VInterpolate interpolator = vips::VInterpolate::new_from_name(baton->interpolator.data());
if (yresidual > 1.0 && xresidual > 1.0) {
image = image.affine({xresidual, 0.0, 0.0, yresidual}, VImage::option()
->set("interpolate", interpolator));
} else if (yresidual > 1.0) {
image = image.affine({1.0, 0.0, 0.0, yresidual}, VImage::option()
->set("interpolate", interpolator));
} else if (xresidual > 1.0) {
image = image.affine({xresidual, 0.0, 0.0, 1.0}, VImage::option()
->set("interpolate", interpolator));
}
}
}
image = image.resize(1.0 / xfactor, VImage::option()
->set("vscale", 1.0 / yfactor)
->set("kernel", kernel)
->set("centre", baton->centreSampling));
}

// Rotate
Expand Down
Binary file modified test/fixtures/expected/embed-4-into-4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions test/unit/extract.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ describe('Partial image extraction', function () {
sharp(fixtures.inputPngWithGreyAlpha)
.extract({ left: 20, top: 10, width: 380, height: 280 })
.rotate(90)
.jpeg()
.toBuffer(function (err, data, info) {
if (err) throw err;
assert.strictEqual(280, info.width);
Expand Down
3 changes: 2 additions & 1 deletion test/unit/gamma.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,10 @@ describe('Gamma correction', function () {
sharp(fixtures.inputPngOverlayLayer1)
.resize(320)
.gamma()
.jpeg()
.toBuffer(function (err, data, info) {
if (err) throw err;
assert.strictEqual('png', info.format);
assert.strictEqual('jpeg', info.format);
assert.strictEqual(320, info.width);
fixtures.assertSimilar(fixtures.expected('gamma-alpha.jpg'), data, { threshold: 20 }, done);
});
Expand Down

0 comments on commit 4953a44

Please sign in to comment.