Use tile cache for interlace output

Doubles performance of Adam7 interlaced PNG output
This commit is contained in:
Lovell Fuller 2014-07-09 23:47:04 +01:00
parent 2126f9afc1
commit 1cce56b024
2 changed files with 30 additions and 18 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "sharp", "name": "sharp",
"version": "0.5.1", "version": "0.5.2",
"author": "Lovell Fuller <npm@lovell.info>", "author": "Lovell Fuller <npm@lovell.info>",
"contributors": [ "contributors": [
"Pierre Inglebert <pierre.inglebert@gmail.com>", "Pierre Inglebert <pierre.inglebert@gmail.com>",
@ -33,11 +33,11 @@
], ],
"dependencies": { "dependencies": {
"nan": "^1.2.0", "nan": "^1.2.0",
"bluebird": "^2.1.2" "bluebird": "^2.2.1"
}, },
"devDependencies": { "devDependencies": {
"imagemagick": "^0.1.3", "imagemagick": "^0.1.3",
"imagemagick-native": "^1.1.1", "imagemagick-native": "^1.2.2",
"gm": "^1.16.0", "gm": "^1.16.0",
"async": "^0.9.0", "async": "^0.9.0",
"benchmark": "^1.0.0" "benchmark": "^1.0.0"

View File

@ -373,46 +373,58 @@ class ResizeWorker : public NanAsyncWorker {
vips_colourspace(sharpened, &colourspaced, VIPS_INTERPRETATION_sRGB, NULL); vips_colourspace(sharpened, &colourspaced, VIPS_INTERPRETATION_sRGB, NULL);
g_object_unref(sharpened); g_object_unref(sharpened);
// Generate image tile cache when interlace output is required
VipsImage *cached = vips_image_new();
if (baton->progressive) {
if (vips_tilecache(colourspaced, &cached, "threaded", TRUE, "persistent", TRUE, "max_tiles", -1, NULL)) {
return resize_error(baton, colourspaced);
}
} else {
vips_copy(colourspaced, &cached, NULL);
}
g_object_unref(colourspaced);
// Output // Output
VipsImage *output = cached;
if (baton->file_out == "__jpeg" || (baton->file_out == "__input" && inputImageType == JPEG)) { if (baton->file_out == "__jpeg" || (baton->file_out == "__input" && inputImageType == JPEG)) {
// Write JPEG to buffer // Write JPEG to buffer
if (vips_jpegsave_buffer(colourspaced, &baton->buffer_out, &baton->buffer_out_len, "strip", TRUE, "Q", baton->quality, "optimize_coding", TRUE, "interlace", baton->progressive, NULL)) { if (vips_jpegsave_buffer(output, &baton->buffer_out, &baton->buffer_out_len, "strip", TRUE, "Q", baton->quality, "optimize_coding", TRUE, "interlace", baton->progressive, NULL)) {
return resize_error(baton, colourspaced); return resize_error(baton, output);
} }
} else if (baton->file_out == "__png" || (baton->file_out == "__input" && inputImageType == PNG)) { } else if (baton->file_out == "__png" || (baton->file_out == "__input" && inputImageType == PNG)) {
// Write PNG to buffer // Write PNG to buffer
if (vips_pngsave_buffer(colourspaced, &baton->buffer_out, &baton->buffer_out_len, "strip", TRUE, "compression", baton->compressionLevel, "interlace", baton->progressive, NULL)) { if (vips_pngsave_buffer(output, &baton->buffer_out, &baton->buffer_out_len, "strip", TRUE, "compression", baton->compressionLevel, "interlace", baton->progressive, NULL)) {
return resize_error(baton, colourspaced); return resize_error(baton, output);
} }
} else if (baton->file_out == "__webp" || (baton->file_out == "__input" && inputImageType == WEBP)) { } else if (baton->file_out == "__webp" || (baton->file_out == "__input" && inputImageType == WEBP)) {
// Write WEBP to buffer // Write WEBP to buffer
if (vips_webpsave_buffer(colourspaced, &baton->buffer_out, &baton->buffer_out_len, "strip", TRUE, "Q", baton->quality, NULL)) { if (vips_webpsave_buffer(output, &baton->buffer_out, &baton->buffer_out_len, "strip", TRUE, "Q", baton->quality, NULL)) {
return resize_error(baton, colourspaced); return resize_error(baton, output);
} }
} else if (is_jpeg(baton->file_out)) { } else if (is_jpeg(baton->file_out)) {
// Write JPEG to file // Write JPEG to file
if (vips_jpegsave(colourspaced, baton->file_out.c_str(), "strip", TRUE, "Q", baton->quality, "optimize_coding", TRUE, "interlace", baton->progressive, NULL)) { if (vips_jpegsave(output, baton->file_out.c_str(), "strip", TRUE, "Q", baton->quality, "optimize_coding", TRUE, "interlace", baton->progressive, NULL)) {
return resize_error(baton, colourspaced); return resize_error(baton, output);
} }
} else if (is_png(baton->file_out)) { } else if (is_png(baton->file_out)) {
// Write PNG to file // Write PNG to file
if (vips_pngsave(colourspaced, baton->file_out.c_str(), "strip", TRUE, "compression", baton->compressionLevel, "interlace", baton->progressive, NULL)) { if (vips_pngsave(output, baton->file_out.c_str(), "strip", TRUE, "compression", baton->compressionLevel, "interlace", baton->progressive, NULL)) {
return resize_error(baton, colourspaced); return resize_error(baton, output);
} }
} else if (is_webp(baton->file_out)) { } else if (is_webp(baton->file_out)) {
// Write WEBP to file // Write WEBP to file
if (vips_webpsave(colourspaced, baton->file_out.c_str(), "strip", TRUE, "Q", baton->quality, NULL)) { if (vips_webpsave(output, baton->file_out.c_str(), "strip", TRUE, "Q", baton->quality, NULL)) {
return resize_error(baton, colourspaced); return resize_error(baton, output);
} }
} else if (is_tiff(baton->file_out)) { } else if (is_tiff(baton->file_out)) {
// Write TIFF to file // Write TIFF to file
if (vips_tiffsave(colourspaced, baton->file_out.c_str(), "strip", TRUE, "compression", VIPS_FOREIGN_TIFF_COMPRESSION_JPEG, "Q", baton->quality, NULL)) { if (vips_tiffsave(output, baton->file_out.c_str(), "strip", TRUE, "compression", VIPS_FOREIGN_TIFF_COMPRESSION_JPEG, "Q", baton->quality, NULL)) {
return resize_error(baton, colourspaced); return resize_error(baton, output);
} }
} else { } else {
(baton->err).append("Unsupported output " + baton->file_out); (baton->err).append("Unsupported output " + baton->file_out);
} }
g_object_unref(colourspaced); g_object_unref(output);
vips_thread_shutdown(); vips_thread_shutdown();
} }