mirror of
https://github.com/lovell/sharp.git
synced 2025-07-10 11:00:14 +02:00
Recalc after WebP shrink-on-load to avoid rounding errors #508
This commit is contained in:
parent
a2ec3642bf
commit
a5bd68ef8c
@ -4,6 +4,20 @@
|
|||||||
|
|
||||||
Requires libvips v8.3.1
|
Requires libvips v8.3.1
|
||||||
|
|
||||||
|
#### v0.15.2 - TBD
|
||||||
|
|
||||||
|
* Ensure boolean, bandbool, extractChannel ops occur before sRGB conversion.
|
||||||
|
[#504](https://github.com/lovell/sharp/pull/504)
|
||||||
|
[@mhirsch](https://github.com/mhirsch)
|
||||||
|
|
||||||
|
* Recalculate factors after WebP shrink-on-load to avoid round-to-zero errors.
|
||||||
|
[#508](https://github.com/lovell/sharp/issues/508)
|
||||||
|
[@asilvas](https://github.com/asilvas)
|
||||||
|
|
||||||
|
* Prevent boolean errors during extract operation.
|
||||||
|
[#511](https://github.com/lovell/sharp/pull/511)
|
||||||
|
[@mhirsch](https://github.com/mhirsch)
|
||||||
|
|
||||||
#### v0.15.1 - 12<sup>th</sup> July 2016
|
#### v0.15.1 - 12<sup>th</sup> July 2016
|
||||||
|
|
||||||
* Concat Stream-based input in single operation for ~+3% perf and less GC.
|
* Concat Stream-based input in single operation for ~+3% perf and less GC.
|
||||||
|
@ -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
|
// but not when applying gamma correction or pre-resize extract
|
||||||
int shrink_on_load = 1;
|
int shrink_on_load = 1;
|
||||||
if (
|
if (
|
||||||
@ -361,13 +361,6 @@ class PipelineWorker : public AsyncWorker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (shrink_on_load > 1) {
|
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
|
// Reload input using shrink-on-load
|
||||||
VOption *option = VImage::option()->set("shrink", shrink_on_load);
|
VOption *option = VImage::option()->set("shrink", shrink_on_load);
|
||||||
if (baton->bufferInLength > 1) {
|
if (baton->bufferInLength > 1) {
|
||||||
@ -389,6 +382,26 @@ class PipelineWorker : public AsyncWorker {
|
|||||||
image = VImage::webpload(const_cast<char*>((baton->fileIn).data()), option);
|
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
|
// Ensure we're using a device-independent colour space
|
||||||
|
@ -128,6 +128,27 @@ describe('Resize dimensions', function() {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('WebP shrink-on-load rounds to zero, ensure recalculation is correct', function(done) {
|
||||||
|
sharp(fixtures.inputJpg)
|
||||||
|
.resize(1080, 607)
|
||||||
|
.webp()
|
||||||
|
.toBuffer(function(err, data, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual('webp', info.format);
|
||||||
|
assert.strictEqual(1080, info.width);
|
||||||
|
assert.strictEqual(607, info.height);
|
||||||
|
sharp(data)
|
||||||
|
.resize(233, 131)
|
||||||
|
.toBuffer(function(err, data, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual('webp', info.format);
|
||||||
|
assert.strictEqual(233, info.width);
|
||||||
|
assert.strictEqual(131, info.height);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
if (sharp.format.tiff.input.file) {
|
if (sharp.format.tiff.input.file) {
|
||||||
it('TIFF embed known to cause rounding errors', function(done) {
|
it('TIFF embed known to cause rounding errors', function(done) {
|
||||||
sharp(fixtures.inputTiff)
|
sharp(fixtures.inputTiff)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user