Recalc after WebP shrink-on-load to avoid rounding errors #508

This commit is contained in:
Lovell Fuller
2016-07-21 15:18:14 +01:00
parent a2ec3642bf
commit a5bd68ef8c
3 changed files with 56 additions and 8 deletions

View File

@@ -338,7 +338,7 @@ class PipelineWorker : public AsyncWorker {
}
}
// If integral x and y shrink are equal, try to use libjpeg shrink-on-load,
// If integral x and y shrink are equal, try to use shrink-on-load for JPEG and WebP,
// but not when applying gamma correction or pre-resize extract
int shrink_on_load = 1;
if (
@@ -361,13 +361,6 @@ class PipelineWorker : public AsyncWorker {
}
}
if (shrink_on_load > 1) {
// Recalculate integral shrink and double residual
xfactor = std::max(xfactor, 1.0);
yfactor = std::max(yfactor, 1.0);
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;
// Reload input using shrink-on-load
VOption *option = VImage::option()->set("shrink", shrink_on_load);
if (baton->bufferInLength > 1) {
@@ -389,6 +382,26 @@ class PipelineWorker : public AsyncWorker {
image = VImage::webpload(const_cast<char*>((baton->fileIn).data()), option);
}
}
// Recalculate integral shrink and double residual
int shrunkOnLoadWidth = image.width();
int shrunkOnLoadHeight = 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(shrunkOnLoadWidth, shrunkOnLoadHeight);
}
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);
}
}
// Ensure we're using a device-independent colour space