Recalculate residual float value for affine after shrink #26

Switch to static casts for double values

Add unit tests that previously would have failed
This commit is contained in:
Lovell Fuller 2014-05-18 11:37:55 +01:00
parent 6622045172
commit 308d1971d8
2 changed files with 41 additions and 7 deletions

View File

@ -135,17 +135,17 @@ class ResizeWorker : public NanAsyncWorker {
double factor;
if (baton->width > 0 && baton->height > 0) {
// Fixed width and height
double xfactor = (double)(in->Xsize) / (double)(baton->width);
double yfactor = (double)(in->Ysize) / (double)(baton->height);
double xfactor = static_cast<double>(in->Xsize) / static_cast<double>(baton->width);
double yfactor = static_cast<double>(in->Ysize) / static_cast<double>(baton->height);
factor = baton->crop ? std::min(xfactor, yfactor) : std::max(xfactor, yfactor);
} else if (baton->width > 0) {
// Fixed width, auto height
factor = (double)(in->Xsize) / (double)(baton->width);
baton->height = floor((double)(in->Ysize) / factor);
factor = static_cast<double>(in->Xsize) / static_cast<double>(baton->width);
baton->height = floor(static_cast<double>(in->Ysize) / factor);
} else if (baton->height > 0) {
// Fixed height, auto width
factor = (double)(in->Ysize) / (double)(baton->height);
baton->width = floor((double)(in->Xsize) / factor);
factor = static_cast<double>(in->Ysize) / static_cast<double>(baton->height);
baton->width = floor(static_cast<double>(in->Xsize) / factor);
} else {
// Identity transform
factor = 1;
@ -156,7 +156,7 @@ class ResizeWorker : public NanAsyncWorker {
if (shrink < 1) {
shrink = 1;
}
double residual = shrink / (double)factor;
double residual = static_cast<double>(shrink) / factor;
// Try to use libjpeg shrink-on-load
int shrink_on_load = 1;
@ -199,6 +199,14 @@ class ResizeWorker : public NanAsyncWorker {
if (vips_shrink(shrunk_on_load, &shrunk, shrink, shrink, NULL)) {
return resize_error(baton, shrunk_on_load);
}
// Recalculate residual float based on dimensions of required vs shrunk images
double residualx = static_cast<double>(baton->width) / static_cast<double>(shrunk->Xsize);
double residualy = static_cast<double>(baton->height) / static_cast<double>(shrunk->Ysize);
if (baton->crop) {
residual = std::max(residualx, residualy);
} else {
residual = std::min(residualx, residualy);
}
} else {
vips_copy(shrunk_on_load, &shrunk, NULL);
}

View File

@ -9,6 +9,9 @@ var fixturesPath = path.join(__dirname, "fixtures");
var inputJpg = path.join(fixturesPath, "2569067123_aca715a2ee_o.jpg"); // http://www.flickr.com/photos/grizdave/2569067123/
var outputJpg = path.join(fixturesPath, "output.jpg");
var inputTiff = path.join(fixturesPath, "G31D.TIF"); // http://www.fileformat.info/format/tiff/sample/e6c9a6e5253348f4aef6d17b534360ab/index.htm
var outputTiff = path.join(fixturesPath, "output.tiff");
async.series([
// Resize with exact crop
function(done) {
@ -83,6 +86,29 @@ async.series([
});
});
});
},
// TIFF with dimensions known to cause rounding errors
function(done) {
sharp(inputTiff).resize(240, 320).embedBlack().write(outputJpg, function(err) {
if (err) throw err;
imagemagick.identify(outputJpg, function(err, features) {
if (err) throw err;
assert.strictEqual(240, features.width);
assert.strictEqual(320, features.height);
done();
});
});
},
function(done) {
sharp(inputTiff).resize(240, 320).write(outputJpg, function(err) {
if (err) throw err;
imagemagick.identify(outputJpg, function(err, features) {
if (err) throw err;
assert.strictEqual(240, features.width);
assert.strictEqual(320, features.height);
done();
});
});
}
]);