From ab7408c96fae16d6264853d890354457205e629b Mon Sep 17 00:00:00 2001 From: Maurus Cuelenaere Date: Sun, 15 Feb 2015 16:14:46 +0100 Subject: [PATCH] Add support for loading images through ImageMagick as a buffer --- index.js | 6 ++++-- src/common.cc | 15 +++++++++++++++ test/unit/io.js | 18 ++++++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 025b8ddf..86887bbe 100755 --- a/index.js +++ b/index.js @@ -83,11 +83,13 @@ var Sharp = function(input) { (input[0] === 0x52 && input[1] === 0x49) || // TIFF (input[0] === 0x4D && input[1] === 0x4D && input[2] === 0x00 && (input[3] === 0x2A || input[3] === 0x2B)) || - (input[0] === 0x49 && input[1] === 0x49 && (input[2] === 0x2A || input[2] === 0x2B) && input[3] === 0x00) + (input[0] === 0x49 && input[1] === 0x49 && (input[2] === 0x2A || input[2] === 0x2B) && input[3] === 0x00) || + // GIF + (input[0] === 0x47 && input[1] === 0x49 && input[2] === 0x46 && input[3] === 0x38 && (input[4] === 0x37 || input[4] === 0x39) && input[5] === 0x61) ) { this.options.bufferIn = input; } else { - throw new Error('Buffer contains an unsupported image format. JPEG, PNG, WebP and TIFF are currently supported.'); + throw new Error('Buffer contains an unsupported image format. JPEG, PNG, WebP, TIFF and GIF are currently supported.'); } } else { // input=stream diff --git a/src/common.cc b/src/common.cc index a8c670d3..19f96ed2 100755 --- a/src/common.cc +++ b/src/common.cc @@ -43,6 +43,15 @@ namespace sharp { ); } + static bool buffer_is_gif(char *buffer, size_t len) { + return ( + len >= 6 && ( + (buffer[0] == 'G' && buffer[1] == 'I' && buffer[2] == 'F' && + buffer[3] == '8' && (buffer[4] == '7' || buffer[4] == '9') && buffer[5] == 'a') + ) + ); + } + /* Determine image format of a buffer. */ @@ -57,6 +66,8 @@ namespace sharp { imageType = ImageType::WEBP; } else if (buffer_is_tiff(static_cast(buffer), length)) { imageType = ImageType::TIFF; + } else if (buffer_is_gif(static_cast(buffer), length)) { + imageType = ImageType::MAGICK; } } return imageType; @@ -75,6 +86,10 @@ namespace sharp { vips_webpload_buffer(buffer, length, &image, "access", access, NULL); } else if (imageType == ImageType::TIFF) { vips_tiffload_buffer(buffer, length, &image, "access", access, NULL); +#if (VIPS_MAJOR_VERSION >= 8 && VIPS_MINOR_VERSION >= 0) + } else if (imageType == ImageType::MAGICK) { + vips_magickload_buffer(buffer, length, &image, "access", access, NULL); +#endif } return image; } diff --git a/test/unit/io.js b/test/unit/io.js index 1501b6f3..101a13c4 100755 --- a/test/unit/io.js +++ b/test/unit/io.js @@ -537,6 +537,24 @@ describe('Input/output', function() { }); } + if (semver.gte(sharp.libvipsVersion(), '8.0.0')) { + it('Load GIF from Buffer [libvips ' + sharp.libvipsVersion() + '>=8.0.0]', function(done) { + var inputGifBuffer = fs.readFileSync(fixtures.inputGif); + sharp(inputGifBuffer) + .resize(320, 240) + .jpeg() + .toBuffer(function(err, data, info) { + if (err) throw err; + assert.strictEqual(true, data.length > 0); + assert.strictEqual(data.length, info.size); + assert.strictEqual('jpeg', info.format); + assert.strictEqual(320, info.width); + assert.strictEqual(240, info.height); + done(); + }); + }); + } + if (semver.gte(sharp.libvipsVersion(), '7.42.0')) { describe('Ouput raw, uncompressed image data [libvips ' + sharp.libvipsVersion() + '>=7.42.0]', function() { it('1 channel greyscale image', function(done) {