From d72c1bbf022b0c56e242211f25c584c4eb6a4e6b Mon Sep 17 00:00:00 2001 From: Daniel Beardsley Date: Tue, 30 Jul 2013 03:08:23 -0700 Subject: [PATCH] JPEGStream: add progressive mode option Progressive jpegs have several very useful advantages over baseline jpegs: * Slightly smaller for the same quality (3-7%) * Load much faster in most browsers. This adds the `options.progressive` option to the canvas.jpegCreateStream() function. --- lib/canvas.js | 1 + lib/jpegstream.js | 2 +- src/Canvas.cc | 8 +++++--- src/JPEGStream.h | 4 +++- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/lib/canvas.js b/lib/canvas.js index b2d09e0..e238f34 100644 --- a/lib/canvas.js +++ b/lib/canvas.js @@ -185,6 +185,7 @@ Canvas.prototype.createSyncJPEGStream = function(options){ return new JPEGStream(this, { bufsize: options.bufsize || 4096 , quality: options.quality || 75 + , progressive: options.progressive || false }); }; diff --git a/lib/jpegstream.js b/lib/jpegstream.js index 3e7ec93..1db8670 100644 --- a/lib/jpegstream.js +++ b/lib/jpegstream.js @@ -40,7 +40,7 @@ var JPEGStream = module.exports = function JPEGStream(canvas, options, sync) { // TODO: implement async if ('streamJPEG' == method) method = 'streamJPEGSync'; process.nextTick(function(){ - canvas[method](options.bufsize, options.quality, function(err, chunk, len){ + canvas[method](options.bufsize, options.quality, options.progressive, function(err, chunk, len){ if (err) { self.emit('error', err); self.readable = false; diff --git a/src/Canvas.cc b/src/Canvas.cc index 2f7563a..8799abc 100644 --- a/src/Canvas.cc +++ b/src/Canvas.cc @@ -350,15 +350,17 @@ NAN_METHOD(Canvas::StreamJPEGSync) { return NanThrowTypeError("buffer size required"); if (!args[1]->IsNumber()) return NanThrowTypeError("quality setting required"); - if (!args[2]->IsFunction()) + if (!args[2]->IsBoolean()) + return NanThrowTypeError("progressive setting required"); + if (!args[3]->IsFunction()) return NanThrowTypeError("callback function required"); Canvas *canvas = ObjectWrap::Unwrap(args.This()); closure_t closure; - closure.fn = Handle::Cast(args[2]); + closure.fn = Handle::Cast(args[3]); TryCatch try_catch; - write_to_jpeg_stream(canvas->surface(), args[0]->NumberValue(), args[1]->NumberValue(), &closure); + write_to_jpeg_stream(canvas->surface(), args[0]->NumberValue(), args[1]->NumberValue(), args[2]->BooleanValue(), &closure); if (try_catch.HasCaught()) NanReturnValue(try_catch.ReThrow()); diff --git a/src/JPEGStream.h b/src/JPEGStream.h index e32e1a1..0e0738c 100644 --- a/src/JPEGStream.h +++ b/src/JPEGStream.h @@ -96,7 +96,7 @@ jpeg_closure_dest(j_compress_ptr cinfo, closure_t * closure, int bufsize){ } void -write_to_jpeg_stream(cairo_surface_t *surface, int bufsize, int quality, closure_t *closure){ +write_to_jpeg_stream(cairo_surface_t *surface, int bufsize, int quality, bool progressive, closure_t *closure){ int w = cairo_image_surface_get_width(surface); int h = cairo_image_surface_get_height(surface); struct jpeg_compress_struct cinfo; @@ -110,6 +110,8 @@ write_to_jpeg_stream(cairo_surface_t *surface, int bufsize, int quality, closure cinfo.image_width = w; cinfo.image_height = h; jpeg_set_defaults(&cinfo); + if (progressive) + jpeg_simple_progression(&cinfo); jpeg_set_quality(&cinfo, quality, (quality<25)?0:1); jpeg_closure_dest(&cinfo, closure, bufsize);