From 282021860935a708e5dd9883ec7fedbccc2ff2b1 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Thu, 4 Sep 2014 11:38:05 +0100 Subject: [PATCH] Add format property to output info Output format may be derived from input format --- README.md | 10 +++++----- src/sharp.cc | 31 ++++++++++++++++++++++++------- tests/unit.js | 32 +++++++++++++++++++++++++++++++- 3 files changed, 60 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index d1f6bca6..80af4aa0 100755 --- a/README.md +++ b/README.md @@ -331,8 +331,8 @@ An advanced setting for the _zlib_ compression level of the lossless PNG output `callback`, if present, is called with two arguments `(err, info)` where: -* `err` contains an error message, if any -* `info` contains the final resized image dimensions in its `width` and `height` properties +* `err` contains an error message, if any. +* `info` contains the output image `format`, `width` and `height`. A Promises/A+ promise is returned when `callback` is not provided. @@ -342,9 +342,9 @@ Write image data to a Buffer, the format of which will match the input image by `callback`, if present, gets three arguments `(err, buffer, info)` where: -* `err` is an error message, if any -* `buffer` is the resultant image data -* `info` contains the final resized image dimensions in its `width` and `height` properties +* `err` is an error message, if any. +* `buffer` is the output image data. +* `info` contains the output image `format`, `width` and `height`. A Promises/A+ promise is returned when `callback` is not provided. diff --git a/src/sharp.cc b/src/sharp.cc index d955c2d3..78516d5a 100755 --- a/src/sharp.cc +++ b/src/sharp.cc @@ -16,6 +16,7 @@ struct resize_baton { void* buffer_in; size_t buffer_in_len; std::string output; + std::string output_format; void* buffer_out; size_t buffer_out_len; int width; @@ -38,6 +39,7 @@ struct resize_baton { resize_baton(): buffer_in_len(0), + output_format(""), buffer_out_len(0), crop(false), gravity(0), @@ -609,39 +611,53 @@ class ResizeWorker : public NanAsyncWorker { VipsImage *output = cached; if (baton->output == "__jpeg" || (baton->output == "__input" && inputImageType == JPEG)) { // Write JPEG to buffer - if (vips_jpegsave_buffer(output, &baton->buffer_out, &baton->buffer_out_len, "strip", !baton->withMetadata, "Q", baton->quality, "optimize_coding", TRUE, "interlace", baton->progressive, NULL)) { + if (vips_jpegsave_buffer(output, &baton->buffer_out, &baton->buffer_out_len, "strip", !baton->withMetadata, + "Q", baton->quality, "optimize_coding", TRUE, "interlace", baton->progressive, NULL)) { return resize_error(baton, output); } + baton->output_format = "jpeg"; } else if (baton->output == "__png" || (baton->output == "__input" && inputImageType == PNG)) { // Write PNG to buffer - if (vips_pngsave_buffer(output, &baton->buffer_out, &baton->buffer_out_len, "strip", !baton->withMetadata, "compression", baton->compressionLevel, "interlace", baton->progressive, NULL)) { + if (vips_pngsave_buffer(output, &baton->buffer_out, &baton->buffer_out_len, "strip", !baton->withMetadata, + "compression", baton->compressionLevel, "interlace", baton->progressive, NULL)) { return resize_error(baton, output); } + baton->output_format = "png"; } else if (baton->output == "__webp" || (baton->output == "__input" && inputImageType == WEBP)) { // Write WEBP to buffer - if (vips_webpsave_buffer(output, &baton->buffer_out, &baton->buffer_out_len, "strip", !baton->withMetadata, "Q", baton->quality, NULL)) { + if (vips_webpsave_buffer(output, &baton->buffer_out, &baton->buffer_out_len, "strip", !baton->withMetadata, + "Q", baton->quality, NULL)) { return resize_error(baton, output); } + baton->output_format = "webp"; } else if (is_jpeg(baton->output)) { // Write JPEG to file - if (vips_jpegsave(output, baton->output.c_str(), "strip", !baton->withMetadata, "Q", baton->quality, "optimize_coding", TRUE, "interlace", baton->progressive, NULL)) { + if (vips_jpegsave(output, baton->output.c_str(), "strip", !baton->withMetadata, + "Q", baton->quality, "optimize_coding", TRUE, "interlace", baton->progressive, NULL)) { return resize_error(baton, output); } + baton->output_format = "jpeg"; } else if (is_png(baton->output)) { // Write PNG to file - if (vips_pngsave(output, baton->output.c_str(), "strip", !baton->withMetadata, "compression", baton->compressionLevel, "interlace", baton->progressive, NULL)) { + if (vips_pngsave(output, baton->output.c_str(), "strip", !baton->withMetadata, + "compression", baton->compressionLevel, "interlace", baton->progressive, NULL)) { return resize_error(baton, output); } + baton->output_format = "png"; } else if (is_webp(baton->output)) { // Write WEBP to file - if (vips_webpsave(output, baton->output.c_str(), "strip", !baton->withMetadata, "Q", baton->quality, NULL)) { + if (vips_webpsave(output, baton->output.c_str(), "strip", !baton->withMetadata, + "Q", baton->quality, NULL)) { return resize_error(baton, output); } + baton->output_format = "webp"; } else if (is_tiff(baton->output)) { // Write TIFF to file - if (vips_tiffsave(output, baton->output.c_str(), "strip", !baton->withMetadata, "compression", VIPS_FOREIGN_TIFF_COMPRESSION_JPEG, "Q", baton->quality, NULL)) { + if (vips_tiffsave(output, baton->output.c_str(), "strip", !baton->withMetadata, + "compression", VIPS_FOREIGN_TIFF_COMPRESSION_JPEG, "Q", baton->quality, NULL)) { return resize_error(baton, output); } + baton->output_format = "tiff"; } else { (baton->err).append("Unsupported output " + baton->output); } @@ -662,6 +678,7 @@ class ResizeWorker : public NanAsyncWorker { } else { // Info Object Local info = NanNew(); + info->Set(NanNew("format"), NanNew(baton->output_format)); info->Set(NanNew("width"), NanNew(baton->width)); info->Set(NanNew("height"), NanNew(baton->height)); diff --git a/tests/unit.js b/tests/unit.js index 85bb858e..62d12245 100755 --- a/tests/unit.js +++ b/tests/unit.js @@ -41,6 +41,7 @@ async.series([ sharp(inputJpg).resize(320, 240).toBuffer(function(err, data, info) { if (err) throw err; assert.strictEqual(true, data.length > 0); + assert.strictEqual('jpeg', info.format); assert.strictEqual(320, info.width); assert.strictEqual(240, info.height); done(); @@ -51,6 +52,7 @@ async.series([ sharp(inputJpg).resize(320).toBuffer(function(err, data, info) { if (err) throw err; assert.strictEqual(true, data.length > 0); + assert.strictEqual('jpeg', info.format); assert.strictEqual(320, info.width); assert.strictEqual(261, info.height); done(); @@ -61,6 +63,7 @@ async.series([ sharp(inputJpg).resize(null, 320).toBuffer(function(err, data, info) { if (err) throw err; assert.strictEqual(true, data.length > 0); + assert.strictEqual('jpeg', info.format); assert.strictEqual(391, info.width); assert.strictEqual(320, info.height); done(); @@ -71,6 +74,7 @@ async.series([ sharp(inputJpg).toBuffer(function(err, data, info) { if (err) throw err; assert.strictEqual(true, data.length > 0); + assert.strictEqual('jpeg', info.format); assert.strictEqual(2725, info.width); assert.strictEqual(2225, info.height); done(); @@ -81,6 +85,7 @@ async.series([ sharp(inputJpg).resize(3000).toBuffer(function(err, data, info) { if (err) throw err; assert.strictEqual(true, data.length > 0); + assert.strictEqual('jpeg', info.format); assert.strictEqual(3000, info.width); assert.strictEqual(2449, info.height); done(); @@ -105,6 +110,7 @@ async.series([ sharp(inputTiff).resize(240, 320).embedBlack().jpeg().toBuffer(function(err, data, info) { if (err) throw err; assert.strictEqual(true, data.length > 0); + assert.strictEqual('jpeg', info.format); assert.strictEqual(240, info.width); assert.strictEqual(320, info.height); done(); @@ -114,6 +120,7 @@ async.series([ sharp(inputTiff).resize(240, 320).jpeg().toBuffer(function(err, data, info) { if (err) throw err; assert.strictEqual(true, data.length > 0); + assert.strictEqual('jpeg', info.format); assert.strictEqual(240, info.width); assert.strictEqual(320, info.height); done(); @@ -124,6 +131,7 @@ async.series([ sharp(inputJpg).resize(320, 320).max().toBuffer(function(err, data, info) { if (err) throw err; assert.strictEqual(true, data.length > 0); + assert.strictEqual('jpeg', info.format); assert.strictEqual(320, info.width); assert.strictEqual(261, info.height); done(); @@ -134,6 +142,7 @@ async.series([ sharp(inputTiff).resize(320, 320).max().jpeg().toBuffer(function(err, data, info) { if (err) throw err; assert.strictEqual(true, data.length > 0); + assert.strictEqual('jpeg', info.format); assert.strictEqual(243, info.width); assert.strictEqual(320, info.height); done(); @@ -144,6 +153,7 @@ async.series([ sharp(inputJpg).resize(320).max().toBuffer(function(err, data, info) { if (err) throw err; assert.strictEqual(true, data.length > 0); + assert.strictEqual('jpeg', info.format); assert.strictEqual(320, info.width); assert.strictEqual(261, info.height); done(); @@ -161,6 +171,7 @@ async.series([ sharp(inputJpg).rotate(90).resize(320, 240).toBuffer(function(err, data, info) { if (err) throw err; assert.strictEqual(true, data.length > 0); + assert.strictEqual('jpeg', info.format); assert.strictEqual(320, info.width); assert.strictEqual(240, info.height); done(); @@ -171,6 +182,7 @@ async.series([ sharp(inputJpgWithExif).resize(320).toBuffer(function(err, data, info) { if (err) throw err; assert.strictEqual(true, data.length > 0); + assert.strictEqual('jpeg', info.format); assert.strictEqual(320, info.width); assert.strictEqual(426, info.height); done(); @@ -181,6 +193,7 @@ async.series([ sharp(inputJpgWithExif).rotate().resize(320).toBuffer(function(err, data, info) { if (err) throw err; assert.strictEqual(true, data.length > 0); + assert.strictEqual('jpeg', info.format); assert.strictEqual(320, info.width); assert.strictEqual(240, info.height); done(); @@ -191,6 +204,7 @@ async.series([ sharp(inputJpg).rotate().resize(320).toBuffer(function(err, data, info) { if (err) throw err; assert.strictEqual(true, data.length > 0); + assert.strictEqual('jpeg', info.format); assert.strictEqual(320, info.width); assert.strictEqual(261, info.height); done(); @@ -211,6 +225,7 @@ async.series([ sharp(inputJpg).resize(2800).withoutEnlargement().toBuffer(function(err, data, info) { if (err) throw err; assert.strictEqual(true, data.length > 0); + assert.strictEqual('jpeg', info.format); assert.strictEqual(2725, info.width); assert.strictEqual(2225, info.height); done(); @@ -221,6 +236,7 @@ async.series([ sharp(inputJpg).resize(null, 2300).withoutEnlargement().toBuffer(function(err, data, info) { if (err) throw err; assert.strictEqual(true, data.length > 0); + assert.strictEqual('jpeg', info.format); assert.strictEqual(2725, info.width); assert.strictEqual(2225, info.height); done(); @@ -232,6 +248,7 @@ async.series([ sharp(data).toBuffer(function(err, data, info) { if (err) throw err; assert.strictEqual(true, data.length > 0); + assert.strictEqual('jpeg', info.format); assert.strictEqual(320, info.width); assert.strictEqual(240, info.height); done(); @@ -252,7 +269,9 @@ async.series([ }, // Check colour space conversion occurs from TIFF to WebP (this used to segfault) function(done) { - sharp(inputTiff).webp().toBuffer().then(function() { + sharp(inputTiff).webp().toBuffer(function(err, data, info) { + if (err) throw err; + assert.strictEqual('webp', info.format); done(); }); }, @@ -261,6 +280,7 @@ async.series([ sharp(inputJpg).resize(320, 240).interpolateWith(sharp.interpolator.nearest).toBuffer(function(err, data, info) { if (err) throw err; assert.strictEqual(true, data.length > 0); + assert.strictEqual('jpeg', info.format); assert.strictEqual(320, info.width); assert.strictEqual(240, info.height); done(); @@ -271,6 +291,7 @@ async.series([ sharp(inputJpg).resize(320, 240).interpolateWith(sharp.interpolator.bilinear).toBuffer(function(err, data, info) { if (err) throw err; assert.strictEqual(true, data.length > 0); + assert.strictEqual('jpeg', info.format); assert.strictEqual(320, info.width); assert.strictEqual(240, info.height); done(); @@ -281,6 +302,7 @@ async.series([ sharp(inputJpg).resize(320, 240).interpolateWith(sharp.interpolator.bicubic).toBuffer(function(err, data, info) { if (err) throw err; assert.strictEqual(true, data.length > 0); + assert.strictEqual('jpeg', info.format); assert.strictEqual(320, info.width); assert.strictEqual(240, info.height); done(); @@ -291,6 +313,7 @@ async.series([ sharp(inputJpg).resize(320, 240).interpolateWith(sharp.interpolator.nohalo).toBuffer(function(err, data, info) { if (err) throw err; assert.strictEqual(true, data.length > 0); + assert.strictEqual('jpeg', info.format); assert.strictEqual(320, info.width); assert.strictEqual(240, info.height); done(); @@ -301,6 +324,7 @@ async.series([ sharp(inputJpg).resize(320, 240).interpolateWith(sharp.interpolator.locallyBoundedBicubic).toBuffer(function(err, data, info) { if (err) throw err; assert.strictEqual(true, data.length > 0); + assert.strictEqual('jpeg', info.format); assert.strictEqual(320, info.width); assert.strictEqual(240, info.height); done(); @@ -311,6 +335,7 @@ async.series([ sharp(inputJpg).resize(320, 240).interpolateWith(sharp.interpolator.vertexSplitQuadraticBasisSpline).toBuffer(function(err, data, info) { if (err) throw err; assert.strictEqual(true, data.length > 0); + assert.strictEqual('jpeg', info.format); assert.strictEqual(320, info.width); assert.strictEqual(240, info.height); done(); @@ -323,6 +348,7 @@ async.series([ sharp(outputJpg).toBuffer(function(err, data, info) { if (err) throw err; assert.strictEqual(true, data.length > 0); + assert.strictEqual('jpeg', info.format); assert.strictEqual(320, info.width); assert.strictEqual(240, info.height); fs.unlinkSync(outputJpg); @@ -339,6 +365,7 @@ async.series([ sharp(outputJpg).toBuffer(function(err, data, info) { if (err) throw err; assert.strictEqual(true, data.length > 0); + assert.strictEqual('jpeg', info.format); assert.strictEqual(320, info.width); assert.strictEqual(240, info.height); fs.unlinkSync(outputJpg); @@ -352,6 +379,7 @@ async.series([ var readable = fs.createReadStream(inputJpg); var pipeline = sharp().resize(320, 240).toFile(outputJpg, function(err, info) { if (err) throw err; + assert.strictEqual('jpeg', info.format); assert.strictEqual(320, info.width); assert.strictEqual(240, info.height); fs.unlinkSync(outputJpg); @@ -364,6 +392,7 @@ async.series([ var readable = fs.createReadStream(inputJpg); var pipeline = sharp().resize(320, 240).toBuffer(function(err, data, info) { if (err) throw err; + assert.strictEqual('jpeg', info.format); assert.strictEqual(320, info.width); assert.strictEqual(240, info.height); done(); @@ -378,6 +407,7 @@ async.series([ sharp(outputJpg).toBuffer(function(err, data, info) { if (err) throw err; assert.strictEqual(true, data.length > 0); + assert.strictEqual('jpeg', info.format); assert.strictEqual(320, info.width); assert.strictEqual(240, info.height); fs.unlinkSync(outputJpg);