From aed3ca63b3d10aab58271c94557681f6a7f1ed69 Mon Sep 17 00:00:00 2001 From: Pierre Inglebert Date: Wed, 23 Apr 2014 10:03:11 +0200 Subject: [PATCH 1/9] use NanNull, NanNew & NanSymbol for 0.11.11+ compat --- src/sharp.cc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/sharp.cc b/src/sharp.cc index b8409ef4..c468e37b 100755 --- a/src/sharp.cc +++ b/src/sharp.cc @@ -300,10 +300,10 @@ class ResizeWorker : public NanAsyncWorker { void HandleOKCallback () { NanScope(); - Handle argv[2] = { Null(), Null() }; + Handle argv[2] = { NanNull(), NanNull() }; if (!baton->err.empty()) { // Error - argv[0] = String::New(baton->err.data(), baton->err.size()); + argv[0] = NanNew(baton->err.data(), baton->err.size()); } else if (baton->buffer_out_len > 0) { // Buffer argv[1] = NanNewBufferHandle((char *)baton->buffer_out, baton->buffer_out_len); @@ -331,12 +331,12 @@ NAN_METHOD(resize) { baton->width = args[3]->Int32Value(); baton->height = args[4]->Int32Value(); Local canvas = args[5]->ToString(); - if (canvas->Equals(String::NewSymbol("c"))) { + if (canvas->Equals(NanSymbol("c"))) { baton->crop = true; - } else if (canvas->Equals(String::NewSymbol("w"))) { + } else if (canvas->Equals(NanSymbol("w"))) { baton->crop = false; baton->extend = VIPS_EXTEND_WHITE; - } else if (canvas->Equals(String::NewSymbol("b"))) { + } else if (canvas->Equals(NanSymbol("b"))) { baton->crop = false; baton->extend = VIPS_EXTEND_BLACK; } @@ -359,10 +359,10 @@ NAN_METHOD(cache) { } // Get cache statistics - Local cache = Object::New(); - cache->Set(String::NewSymbol("current"), Number::New(vips_tracked_get_mem() / 1048576)); - cache->Set(String::NewSymbol("high"), Number::New(vips_tracked_get_mem_highwater() / 1048576)); - cache->Set(String::NewSymbol("limit"), Number::New(vips_cache_get_max_mem() / 1048576)); + Local cache = NanNew(); + cache->Set(NanSymbol("current"), NanNew(vips_tracked_get_mem() / 1048576)); + cache->Set(NanSymbol("high"), NanNew(vips_tracked_get_mem_highwater() / 1048576)); + cache->Set(NanSymbol("limit"), NanNew(vips_cache_get_max_mem() / 1048576)); NanReturnValue(cache); } From 92fd34c627b51feb635a75b88b37562220e9c078 Mon Sep 17 00:00:00 2001 From: Pierre Inglebert Date: Thu, 24 Apr 2014 11:27:34 +0200 Subject: [PATCH 2/9] remove unnecessary gitignore file --- .gitignore | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitignore b/.gitignore index 761d3d84..73142c35 100644 --- a/.gitignore +++ b/.gitignore @@ -13,5 +13,3 @@ results build node_modules tests/fixtures/output.* - -npm-debug.log From 817c0a2a5a17b947eda32741f6935776678e3555 Mon Sep 17 00:00:00 2001 From: Pierre Inglebert Date: Thu, 24 Apr 2014 11:28:02 +0200 Subject: [PATCH 3/9] do not publish tests files --- .npmignore | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .npmignore diff --git a/.npmignore b/.npmignore new file mode 100644 index 00000000..499622ef --- /dev/null +++ b/.npmignore @@ -0,0 +1,18 @@ +lib-cov +*.seed +*.log +*.csv +*.dat +*.out +*.pid +*.gz + +pids +logs +results +build +node_modules + +.gitignore +tests +.travis.yml \ No newline at end of file From d635c297a2cc0cd7ea8c43c3823cf1e876bea9b6 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Sat, 3 May 2014 22:14:21 +0100 Subject: [PATCH 4/9] Replace use of deprecated libvips conv method. Ensure unref of mask to fix minor memory leak of ~150 bytes/image. --- src/sharp.cc | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/sharp.cc b/src/sharp.cc index c468e37b..70392353 100755 --- a/src/sharp.cc +++ b/src/sharp.cc @@ -241,14 +241,16 @@ class ResizeWorker : public NanAsyncWorker { // Mild sharpen VipsImage *sharpened = vips_image_new(); if (baton->sharpen) { - INTMASK* sharpen = im_create_imaskv("sharpen", 3, 3, - -1, -1, -1, - -1, 32, -1, - -1, -1, -1); - sharpen->scale = 24; - if (im_conv(canvased, sharpened, sharpen)) { + VipsImage *sharpen = vips_image_new_matrixv(3, 3, + -1.0, -1.0, -1.0, + -1.0, 32.0, -1.0, + -1.0, -1.0, -1.0); + vips_image_set_double(sharpen, "scale", 24); + if (vips_conv(canvased, &sharpened, sharpen, NULL)) { + g_object_unref(sharpen); return resize_error(baton, canvased); } + g_object_unref(sharpen); } else { vips_copy(canvased, &sharpened, NULL); } From e275f6f5dd08d78386105c36cecb011f65b69e80 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Sat, 10 May 2014 14:39:34 +0100 Subject: [PATCH 5/9] Add warning about liborc memory leaks. #21 --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 95200d62..efacb871 100755 --- a/README.md +++ b/README.md @@ -28,6 +28,8 @@ This module is powered by the blazingly fast [libvips](https://github.com/jcupit * Node.js v0.10+ * [libvips](https://github.com/jcupitt/libvips) v7.38.5+ +_libvips_ will take advantage of [liborc](http://code.entropywave.com/orc/) if present, however versions of _liborc_ prior to 0.4.19 suffer memory leaks. + ### Install libvips on Mac OS brew install homebrew/science/vips --with-webp --with-graphicsmagick @@ -46,12 +48,12 @@ The _gettext_ dependency of _libvips_ [can lead](https://github.com/lovell/sharp Compiling from source is recommended: - sudo apt-get install automake build-essential git gobject-introspection gtk-doc-tools libfftw3-dev libglib2.0-dev libjpeg-turbo8-dev libpng12-dev libwebp-dev libtiff5-dev liborc-0.4-dev libxml2-dev swig + sudo apt-get install automake build-essential git gobject-introspection gtk-doc-tools libfftw3-dev libglib2.0-dev libjpeg-turbo8-dev libpng12-dev libwebp-dev libtiff5-dev libxml2-dev swig git clone https://github.com/jcupitt/libvips.git cd libvips git checkout 7.38 ./bootstrap.sh - ./configure --enable-debug=no --enable-cxx=no --without-python + ./configure --enable-debug=no --enable-cxx=no --without-python --without-orc make sudo make install sudo ldconfig From 10496881f10aa94b4136fc454ef04d3e9da06301 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Sat, 10 May 2014 19:45:12 +0100 Subject: [PATCH 6/9] Add quality and compressionLevel options for output image. #24 --- README.md | 16 ++- index.js | 278 +++++++++++++++++++++++++++----------------------- src/sharp.cc | 20 ++-- tests/unit.js | 161 ++++++++++++++++------------- 4 files changed, 264 insertions(+), 211 deletions(-) diff --git a/README.md b/README.md index efacb871..b9a3773d 100755 --- a/README.md +++ b/README.md @@ -94,11 +94,11 @@ sharp('input.jpg').resize(null, 200).progressive().toBuffer(function(err, buffer ``` ```javascript -sharp('input.png').resize(300).sharpen().webp(function(err, buffer) { +sharp('input.png').resize(300).sharpen().quality(90).webp(function(err, buffer) { if (err) { throw err; } - // buffer contains sharpened WebP image data (converted from PNG), 300 pixels wide + // buffer contains 300 pixels wide, sharpened, 90% quality WebP image data }); ``` @@ -159,6 +159,18 @@ Perform a mild sharpen of the resultant image. This typically reduces performanc Use progressive (interlace) scan for JPEG and PNG output. This typically reduces compression performance by 30% but results in an image that can be rendered sooner when decompressed. +### quality(quality) + +The output quality to use for lossy JPEG, WebP and TIFF output formats. The default quality is `80`. + +`quality` is a Number between 1 and 100. + +### compressionLevel(compressionLevel) + +An advanced setting for the _zlib_ compression level of the lossless PNG output format. The default level is `6`. + +`compressionLevel` is a Number between -1 and 9. + ### sequentialRead() An advanced setting that switches the libvips access method to `VIPS_ACCESS_SEQUENTIAL`. This will reduce memory usage and can improve performance on some systems. diff --git a/index.js b/index.js index 00e8067d..05b1228b 100755 --- a/index.js +++ b/index.js @@ -1,128 +1,150 @@ -/*jslint node: true */ -'use strict'; - -var sharp = require('./build/Release/sharp'); - -var Sharp = function(input) { - if (!(this instanceof Sharp)) { - return new Sharp(input); - } - this.options = { - width: -1, - height: -1, - canvas: 'c', - sharpen: false, - progressive: false, - sequentialRead: false, - output: '__jpeg' - }; - if (typeof input === 'string') { - this.options.inFile = input; - } else if (typeof input ==='object' && input instanceof Buffer) { - this.options.inBuffer = input; - } else { - throw 'Unsupported input ' + typeof input; - } - return this; -}; -module.exports = Sharp; - -Sharp.prototype.crop = function() { - this.options.canvas = 'c'; - return this; -}; - -Sharp.prototype.embedWhite = function() { - this.options.canvas = 'w'; - return this; -}; - -Sharp.prototype.embedBlack = function() { - this.options.canvas = 'b'; - return this; -}; - -Sharp.prototype.sharpen = function(sharpen) { - this.options.sharpen = (typeof sharpen === 'boolean') ? sharpen : true; - return this; -}; - -Sharp.prototype.progressive = function(progressive) { - this.options.progressive = (typeof progressive === 'boolean') ? progressive : true; - return this; -}; - -Sharp.prototype.sequentialRead = function(sequentialRead) { - this.options.sequentialRead = (typeof sequentialRead === 'boolean') ? sequentialRead : true; - return this; -}; - -Sharp.prototype.resize = function(width, height) { - if (!width) { - this.options.width = -1; - } else { - if (!Number.isNaN(width)) { - this.options.width = width; - } else { - throw 'Invalid width ' + width; - } - } - if (!height) { - this.options.height = -1; - } else { - if (!Number.isNaN(height)) { - this.options.height = height; - } else { - throw 'Invalid height ' + height; - } - } - return this; -}; - -Sharp.prototype.write = function(output, callback) { - if (!output || output.length === 0) { - throw 'Invalid output'; - } else { - this._sharp(output, callback); - } - return this; -}; - -Sharp.prototype.toBuffer = function(callback) { - return this._sharp('__input', callback); -}; - -Sharp.prototype.jpeg = function(callback) { - return this._sharp('__jpeg', callback); -}; - -Sharp.prototype.png = function(callback) { - return this._sharp('__png', callback); -}; - -Sharp.prototype.webp = function(callback) { - return this._sharp('__webp', callback); -}; - -Sharp.prototype._sharp = function(output, callback) { - sharp.resize( - this.options.inFile, - this.options.inBuffer, - output, - this.options.width, - this.options.height, - this.options.canvas, - this.options.sharpen, - this.options.progressive, - this.options.sequentialRead, - callback - ); - return this; -}; - -module.exports.cache = function(limit) { - if (Number.isNaN(limit)) { - limit = null; - } - return sharp.cache(limit); -}; +/*jslint node: true */ +'use strict'; + +var sharp = require('./build/Release/sharp'); + +var Sharp = function(input) { + if (!(this instanceof Sharp)) { + return new Sharp(input); + } + this.options = { + width: -1, + height: -1, + canvas: 'c', + sharpen: false, + progressive: false, + sequentialRead: false, + quality: 80, + compressionLevel: 6, + output: '__jpeg' + }; + if (typeof input === 'string') { + this.options.inFile = input; + } else if (typeof input ==='object' && input instanceof Buffer) { + this.options.inBuffer = input; + } else { + throw 'Unsupported input ' + typeof input; + } + return this; +}; +module.exports = Sharp; + +Sharp.prototype.crop = function() { + this.options.canvas = 'c'; + return this; +}; + +Sharp.prototype.embedWhite = function() { + this.options.canvas = 'w'; + return this; +}; + +Sharp.prototype.embedBlack = function() { + this.options.canvas = 'b'; + return this; +}; + +Sharp.prototype.sharpen = function(sharpen) { + this.options.sharpen = (typeof sharpen === 'boolean') ? sharpen : true; + return this; +}; + +Sharp.prototype.progressive = function(progressive) { + this.options.progressive = (typeof progressive === 'boolean') ? progressive : true; + return this; +}; + +Sharp.prototype.sequentialRead = function(sequentialRead) { + this.options.sequentialRead = (typeof sequentialRead === 'boolean') ? sequentialRead : true; + return this; +}; + +Sharp.prototype.quality = function(quality) { + if (!Number.isNaN(quality) && quality >= 1 && quality <= 100) { + this.options.quality = quality; + } else { + throw 'Invalid quality (1 to 100) ' + quality; + } + return this; +}; + +Sharp.prototype.compressionLevel = function(compressionLevel) { + if (!Number.isNaN(compressionLevel) && compressionLevel >= -1 && compressionLevel <= 9) { + this.options.compressionLevel = compressionLevel; + } else { + throw 'Invalid compressionLevel (-1 to 9) ' + compressionLevel; + } + return this; +}; + +Sharp.prototype.resize = function(width, height) { + if (!width) { + this.options.width = -1; + } else { + if (!Number.isNaN(width)) { + this.options.width = width; + } else { + throw 'Invalid width ' + width; + } + } + if (!height) { + this.options.height = -1; + } else { + if (!Number.isNaN(height)) { + this.options.height = height; + } else { + throw 'Invalid height ' + height; + } + } + return this; +}; + +Sharp.prototype.write = function(output, callback) { + if (!output || output.length === 0) { + throw 'Invalid output'; + } else { + this._sharp(output, callback); + } + return this; +}; + +Sharp.prototype.toBuffer = function(callback) { + return this._sharp('__input', callback); +}; + +Sharp.prototype.jpeg = function(callback) { + return this._sharp('__jpeg', callback); +}; + +Sharp.prototype.png = function(callback) { + return this._sharp('__png', callback); +}; + +Sharp.prototype.webp = function(callback) { + return this._sharp('__webp', callback); +}; + +Sharp.prototype._sharp = function(output, callback) { + sharp.resize( + this.options.inFile, + this.options.inBuffer, + output, + this.options.width, + this.options.height, + this.options.canvas, + this.options.sharpen, + this.options.progressive, + this.options.sequentialRead, + this.options.quality, + this.options.compressionLevel, + callback + ); + return this; +}; + +module.exports.cache = function(limit) { + if (Number.isNaN(limit)) { + limit = null; + } + return sharp.cache(limit); +}; diff --git a/src/sharp.cc b/src/sharp.cc index 70392353..5c025fec 100755 --- a/src/sharp.cc +++ b/src/sharp.cc @@ -24,6 +24,8 @@ struct resize_baton { bool sharpen; bool progessive; VipsAccess access_method; + int quality; + int compressionLevel; std::string err; resize_baton(): buffer_in_len(0), buffer_out_len(0) {} @@ -259,37 +261,37 @@ class ResizeWorker : public NanAsyncWorker { // Output if (baton->file_out == "__jpeg" || (baton->file_out == "__input" && inputImageType == JPEG)) { // Write JPEG to buffer - if (vips_jpegsave_buffer(sharpened, &baton->buffer_out, &baton->buffer_out_len, "strip", TRUE, "Q", 80, "optimize_coding", TRUE, "interlace", baton->progessive, NULL)) { + if (vips_jpegsave_buffer(sharpened, &baton->buffer_out, &baton->buffer_out_len, "strip", TRUE, "Q", baton->quality, "optimize_coding", TRUE, "interlace", baton->progessive, NULL)) { return resize_error(baton, sharpened); } } else if (baton->file_out == "__png" || (baton->file_out == "__input" && inputImageType == PNG)) { // Write PNG to buffer - if (vips_pngsave_buffer(sharpened, &baton->buffer_out, &baton->buffer_out_len, "strip", TRUE, "compression", 6, "interlace", baton->progessive, NULL)) { + if (vips_pngsave_buffer(sharpened, &baton->buffer_out, &baton->buffer_out_len, "strip", TRUE, "compression", baton->compressionLevel, "interlace", baton->progessive, NULL)) { return resize_error(baton, sharpened); } } else if (baton->file_out == "__webp" || (baton->file_out == "__input" && inputImageType == WEBP)) { // Write WEBP to buffer - if (vips_webpsave_buffer(sharpened, &baton->buffer_out, &baton->buffer_out_len, "strip", TRUE, "Q", 80, NULL)) { + if (vips_webpsave_buffer(sharpened, &baton->buffer_out, &baton->buffer_out_len, "strip", TRUE, "Q", baton->quality, NULL)) { return resize_error(baton, sharpened); } } else if (is_jpeg(baton->file_out)) { // Write JPEG to file - if (vips_jpegsave(sharpened, baton->file_out.c_str(), "strip", TRUE, "Q", 80, "optimize_coding", TRUE, "interlace", baton->progessive, NULL)) { + if (vips_jpegsave(sharpened, baton->file_out.c_str(), "strip", TRUE, "Q", baton->quality, "optimize_coding", TRUE, "interlace", baton->progessive, NULL)) { return resize_error(baton, sharpened); } } else if (is_png(baton->file_out)) { // Write PNG to file - if (vips_pngsave(sharpened, baton->file_out.c_str(), "strip", TRUE, "compression", 6, "interlace", baton->progessive, NULL)) { + if (vips_pngsave(sharpened, baton->file_out.c_str(), "strip", TRUE, "compression", baton->compressionLevel, "interlace", baton->progessive, NULL)) { return resize_error(baton, sharpened); } } else if (is_webp(baton->file_out)) { // Write WEBP to file - if (vips_webpsave(sharpened, baton->file_out.c_str(), "strip", TRUE, "Q", 80, NULL)) { + if (vips_webpsave(sharpened, baton->file_out.c_str(), "strip", TRUE, "Q", baton->quality, NULL)) { return resize_error(baton, sharpened); } } else if (is_tiff(baton->file_out)) { // Write TIFF to file - if (vips_tiffsave(sharpened, baton->file_out.c_str(), "strip", TRUE, "compression", VIPS_FOREIGN_TIFF_COMPRESSION_JPEG, "Q", 80, NULL)) { + if (vips_tiffsave(sharpened, baton->file_out.c_str(), "strip", TRUE, "compression", VIPS_FOREIGN_TIFF_COMPRESSION_JPEG, "Q", baton->quality, NULL)) { return resize_error(baton, sharpened); } } else { @@ -345,8 +347,10 @@ NAN_METHOD(resize) { baton->sharpen = args[6]->BooleanValue(); baton->progessive = args[7]->BooleanValue(); baton->access_method = args[8]->BooleanValue() ? VIPS_ACCESS_SEQUENTIAL : VIPS_ACCESS_RANDOM; + baton->quality = args[9]->Int32Value(); + baton->compressionLevel = args[10]->Int32Value(); - NanCallback *callback = new NanCallback(args[9].As()); + NanCallback *callback = new NanCallback(args[11].As()); NanAsyncQueueWorker(new ResizeWorker(callback, baton)); NanReturnUndefined(); diff --git a/tests/unit.js b/tests/unit.js index 05222755..d4d27919 100755 --- a/tests/unit.js +++ b/tests/unit.js @@ -1,73 +1,88 @@ -var sharp = require("../index"); -var path = require("path"); -var imagemagick = require("imagemagick"); -var assert = require("assert"); -var async = require("async"); - -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"); - -async.series([ - // Resize with exact crop - function(done) { - sharp(inputJpg).resize(320, 240).write(outputJpg, function(err) { - if (err) throw err; - imagemagick.identify(outputJpg, function(err, features) { - if (err) throw err; - assert.strictEqual(320, features.width); - assert.strictEqual(240, features.height); - done(); - }); - }); - }, - // Resize to fixed width - function(done) { - sharp(inputJpg).resize(320).write(outputJpg, function(err) { - if (err) throw err; - imagemagick.identify(outputJpg, function(err, features) { - if (err) throw err; - assert.strictEqual(320, features.width); - assert.strictEqual(261, features.height); - done(); - }); - }); - }, - // Resize to fixed height - function(done) { - sharp(inputJpg).resize(null, 320).write(outputJpg, function(err) { - if (err) throw err; - imagemagick.identify(outputJpg, function(err, features) { - if (err) throw err; - assert.strictEqual(391, features.width); - assert.strictEqual(320, features.height); - done(); - }); - }); - }, - // Identity transform - function(done) { - sharp(inputJpg).write(outputJpg, function(err) { - if (err) throw err; - imagemagick.identify(outputJpg, function(err, features) { - if (err) throw err; - assert.strictEqual(2725, features.width); - assert.strictEqual(2225, features.height); - done(); - }); - }); - }, - // Upscale - function(done) { - sharp(inputJpg).resize(3000).write(outputJpg, function(err) { - if (err) throw err; - imagemagick.identify(outputJpg, function(err, features) { - if (err) throw err; - assert.strictEqual(3000, features.width); - assert.strictEqual(2449, features.height); - done(); - }); - }); - } -]); +var sharp = require("../index"); +var path = require("path"); +var imagemagick = require("imagemagick"); +var assert = require("assert"); +var async = require("async"); + +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"); + +async.series([ + // Resize with exact crop + function(done) { + sharp(inputJpg).resize(320, 240).write(outputJpg, function(err) { + if (err) throw err; + imagemagick.identify(outputJpg, function(err, features) { + if (err) throw err; + assert.strictEqual(320, features.width); + assert.strictEqual(240, features.height); + done(); + }); + }); + }, + // Resize to fixed width + function(done) { + sharp(inputJpg).resize(320).write(outputJpg, function(err) { + if (err) throw err; + imagemagick.identify(outputJpg, function(err, features) { + if (err) throw err; + assert.strictEqual(320, features.width); + assert.strictEqual(261, features.height); + done(); + }); + }); + }, + // Resize to fixed height + function(done) { + sharp(inputJpg).resize(null, 320).write(outputJpg, function(err) { + if (err) throw err; + imagemagick.identify(outputJpg, function(err, features) { + if (err) throw err; + assert.strictEqual(391, features.width); + assert.strictEqual(320, features.height); + done(); + }); + }); + }, + // Identity transform + function(done) { + sharp(inputJpg).write(outputJpg, function(err) { + if (err) throw err; + imagemagick.identify(outputJpg, function(err, features) { + if (err) throw err; + assert.strictEqual(2725, features.width); + assert.strictEqual(2225, features.height); + done(); + }); + }); + }, + // Upscale + function(done) { + sharp(inputJpg).resize(3000).write(outputJpg, function(err) { + if (err) throw err; + imagemagick.identify(outputJpg, function(err, features) { + if (err) throw err; + assert.strictEqual(3000, features.width); + assert.strictEqual(2449, features.height); + done(); + }); + }); + }, + // Quality + function(done) { + sharp(inputJpg).resize(320, 240).quality(70).jpeg(function(err, buffer70) { + if (err) throw err; + sharp(inputJpg).resize(320, 240).jpeg(function(err, buffer80) { + if (err) throw err; + sharp(inputJpg).resize(320, 240).quality(90).jpeg(function(err, buffer90) { + assert(buffer70.length < buffer80.length); + assert(buffer80.length < buffer90.length); + done(); + }); + }); + }); + } + +]); From 2e106f8e2e2255fe8784413ab130e95f9ee1528e Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Sat, 10 May 2014 20:23:08 +0100 Subject: [PATCH 7/9] Version bumps --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 8e5b75a8..f6675d9f 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sharp", - "version": "0.3.0", + "version": "0.4.0", "author": "Lovell Fuller ", "contributors": [ "Pierre Inglebert " @@ -31,13 +31,13 @@ "buffer" ], "dependencies": { - "nan": "^0.8.0" + "nan": "^1.0.0" }, "devDependencies": { "imagemagick": "^0.1.3", "imagemagick-native": "^0.2.9", - "gm": "^1.14.2", - "async": "^0.7.0", + "gm": "^1.16.0", + "async": "^0.8.0", "benchmark": "^1.0.0" }, "license": "Apache 2.0", From acdfe025021f881cc52cd9bfbe4d3c76f1bf6ab8 Mon Sep 17 00:00:00 2001 From: Pierre Inglebert Date: Mon, 12 May 2014 21:30:44 +0200 Subject: [PATCH 8/9] make travis test on node 0.11 --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 907ee96d..3429d4d3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,7 @@ language: node_js node_js: - "0.10" + - "0.11" before_install: - sudo add-apt-repository ppa:lyrasis/precise-backports -y - sudo apt-get update -qq From eb6a221ceeb5dad756b00f69dbed1a68d5ad6ddb Mon Sep 17 00:00:00 2001 From: Pierre Inglebert Date: Tue, 13 May 2014 08:03:24 +0200 Subject: [PATCH 9/9] use master branch of image-magick-native until the 0.11 compatible is out --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f6675d9f..a1f78e7a 100755 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ }, "devDependencies": { "imagemagick": "^0.1.3", - "imagemagick-native": "^0.2.9", + "imagemagick-native": "git://github.com/mash/node-imagemagick-native.git#master", "gm": "^1.16.0", "async": "^0.8.0", "benchmark": "^1.0.0"