Compare commits

...

11 Commits

Author SHA1 Message Date
Lovell Fuller
531a0402f7 Changelog updates ahead of v0.14.1
Note effect of C++11 ABI changes on upgrades
2016-04-16 21:16:37 +01:00
Lovell Fuller
cb10f9a9c8 Support gyp-based (re)build without npm env vars #412 2016-04-16 20:35:28 +01:00
Lovell Fuller
c808139b02 Changelog additions and version bumps ahead of v0.14.1 2016-04-14 21:57:44 +01:00
Lovell Fuller
e0d58266be Allow use of embed with 1 and 2 channel images #411 2016-04-14 21:39:17 +01:00
Felix Bünemann
1b7c5816fc Speed up slow pixel limit tests (#404)
This replaces the single color 20000x14000 PNG with a 20000x14000
Grayscale JPG. On a Broadwell Core i7 @ 3.1 GHz this speeds up the
"Disabling limit works" test from ~6.2s to ~0.15s because it can use
jpeg resize-on-load optimizations.

This should fix occasional timeouts on Travis CI.
2016-04-08 22:21:28 +01:00
Felix Bünemann
b224874332 Add support for writing dz format to zip container (#402)
To enable this you can either use the `.zip` or `.szi` file extensions
or use `.tile({container: 'zip'})` with the `.dzi` extension.
2016-04-08 19:58:13 +01:00
Samy Al Zahrani
ef61da3051 Ensure dimensions of final output image are provided (#399)
Add a failing test for vips::VError exception
* fix buffer size mismatch
* Loosen error message assertion
* Update image
2016-04-08 08:58:51 +01:00
Samy Al Zahrani
f214269aa1 Enable RTTI for clang-based builds
This allows for a more verbose error message on mac os x

```

libc++abi.dylib: terminating with uncaught exception of type vips::VError

```

becomes

```

libc++abi.dylib: terminating with uncaught exception of type vips::VError: VipsImage: memory area too small --- should be 1191960 bytes, you passed 1189440

```
2016-04-06 15:23:17 +01:00
Lovell Fuller
6bc2ea8dc7 No longer publish deprecated preinstall script to npm 2016-04-04 12:49:48 +01:00
Lovell Fuller
71fb839e2b Speed up limitInputPixels test case
Update changelog
2016-04-04 12:48:53 +01:00
kentongray
8c9c070caf Ability to disable limitInputPixels #250
Update docs
Added a giant image for testing
Adding myself to contributors
Added tests to verify giant image can be opened
Extend test-win time limit (because of large images)
2016-04-04 08:35:11 +01:00
21 changed files with 266 additions and 34 deletions

View File

@@ -13,3 +13,4 @@ mkdocs.yml
lib
include
packaging
preinstall.sh

View File

@@ -167,6 +167,7 @@
'CLANG_CXX_LIBRARY': 'libc++',
'MACOSX_DEPLOYMENT_TARGET': '10.7',
'GCC_ENABLE_CPP_EXCEPTIONS': 'YES',
'GCC_ENABLE_CPP_RTTI': 'YES',
'OTHER_CPLUSPLUSFLAGS': [
'-fexceptions',
'-Wall',

View File

@@ -12,6 +12,9 @@ var tmp = require('os').tmpdir();
var distBaseUrl = 'https://dl.bintray.com/lovell/sharp/';
// Use NPM-provided environment variable where available, falling back to require-based method for Electron
var minimumLibvipsVersion = process.env.npm_package_config_libvips || require('./package.json').config.libvips;
var vipsHeaderPath = path.join(__dirname, 'include', 'vips', 'vips.h');
// -- Helpers
@@ -75,7 +78,7 @@ module.exports.download_vips = function() {
}
// Arch/platform-specific .tar.gz
var platform = (process.arch === 'arm') ? 'arm' : process.platform.substr(0, 3);
var tarFilename = ['libvips', process.env.npm_package_config_libvips, platform].join('-') + '.tar.gz';
var tarFilename = ['libvips', minimumLibvipsVersion, platform].join('-') + '.tar.gz';
var tarPath = path.join(__dirname, 'packaging', tarFilename);
if (isFile(tarPath)) {
unpack(tarPath);
@@ -114,13 +117,13 @@ module.exports.use_global_vips = function() {
if (globalVipsVersion) {
useGlobalVips = semver.gte(
globalVipsVersion,
process.env.npm_package_config_libvips
minimumLibvipsVersion
);
}
if (process.platform === 'darwin' && !useGlobalVips) {
if (globalVipsVersion) {
error(
'Found libvips ' + globalVipsVersion + ' but require ' + process.env.npm_package_config_libvips +
'Found libvips ' + globalVipsVersion + ' but require ' + minimumLibvipsVersion +
'\nPlease upgrade libvips by running: brew update && brew upgrade'
);
} else {

View File

@@ -113,7 +113,8 @@ This will reduce memory usage and can improve performance on some systems.
Do not process input images where the number of pixels (width * height) exceeds this limit.
`pixels` is the integral Number of pixels, with a value between 1 and the default 268402689 (0x3FFF * 0x3FFF).
`pixels` is either an integral Number of pixels, with a value between 1 and the default 268402689 (0x3FFF * 0x3FFF) or
a boolean. `false` will disable checking while `true` will revert to the default limit.
### Resizing
@@ -526,14 +527,17 @@ The default behaviour, when `withMetadata` is not used, is to strip all metadata
#### tile(options)
The size, overlap and directory layout to use when generating square Deep Zoom image pyramid tiles.
The size, overlap, container and directory layout to use when generating square Deep Zoom image pyramid tiles.
`options` is an Object with one or more of the following attributes:
* `size` is an integral Number between 1 and 8192. The default value is 256 pixels.
* `overlap` is an integral Number between 0 and 8192. The default value is 0 pixels.
* `container` is a String, with value `fs` or `zip`. The default value is `fs`.
* `layout` is a String, with value `dz`, `zoomify` or `google`. The default value is `dz`.
You can also use the file extension .zip or .szi to write to a ZIP container instead of the filesystem.
```javascript
sharp('input.tiff')
.tile({

View File

@@ -4,6 +4,30 @@
Requires libvips v8.2.3
#### v0.14.1 - 16<sup>th</sup> April 2016
* Allow removal of limitation on input pixel count via limitInputPixels. Use with care.
[#250](https://github.com/lovell/sharp/issues/250)
[#316](https://github.com/lovell/sharp/pull/316)
[@anandthakker](https://github.com/anandthakker)
[@kentongray](https://github.com/kentongray)
* Use final output image for metadata passed to callback.
[#399](https://github.com/lovell/sharp/pull/399)
[@salzhrani](https://github.com/salzhrani)
* Add support for writing tiled images to a zip container.
[#402](https://github.com/lovell/sharp/pull/402)
[@felixbuenemann](https://github.com/felixbuenemann)
* Allow use of embed with 1 and 2 channel images.
[#411](https://github.com/lovell/sharp/issues/411)
[@janaz](https://github.com/janaz)
* Improve Electron compatibility by allowing node-gyp rebuilds without npm.
[#412](https://github.com/lovell/sharp/issues/412)
[@nouh](https://github.com/nouh)
#### v0.14.0 - 2<sup>nd</sup> April 2016
* Add ability to extend (pad) the edges of an image.

View File

@@ -52,9 +52,15 @@ For Linux-based operating systems such as Alpine that use musl libc,
the smaller stack size means libvips' cache should be disabled
via `sharp.cache(false)` to avoid a stack overflow.
Beware of Linux OS upgrades that introduce v5.1+ of the `g++` compiler due to
[changes](https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html)
in the C++11 ABI.
This module assumes the previous behaviour, which can be enforced by setting the
`_GLIBCXX_USE_CXX11_ABI=0` environment variable at libvips' compile time.
### Mac OS
[![OS X 10.9.5 Build Status](https://travis-ci.org/lovell/sharp-osx-ci.png?branch=master)](https://travis-ci.org/lovell/sharp-osx-ci)
[![OS X 10.9.5 Build Status](https://travis-ci.org/lovell/sharp.png?branch=master)](https://travis-ci.org/lovell/sharp)
libvips must be installed before `npm install` is run.
This can be achieved via homebrew:

View File

@@ -660,6 +660,14 @@ Sharp.prototype.tile = function(tile) {
throw new Error('Invalid tile overlap (0 to 8192) ' + tile.overlap);
}
}
// Container
if (isDefined(tile.container)) {
if (isString(tile.container) && contains(tile.container, ['fs', 'zip'])) {
this.options.tileContainer = tile.container;
} else {
throw new Error('Invalid tile container ' + tile.container);
}
}
// Layout
if (isDefined(tile.layout)) {
if (isString(tile.layout) && contains(tile.layout, ['dz', 'google', 'zoomify'])) {
@@ -722,10 +730,17 @@ Sharp.prototype.resize = function(width, height) {
/*
Limit the total number of pixels for input images
Assumes the image dimensions contained in the file header can be trusted
Assumes the image dimensions contained in the file header can be trusted.
Alternatively can use boolean to disable or reset to default (maximum pixels)
*/
Sharp.prototype.limitInputPixels = function(limit) {
if (typeof limit === 'number' && !Number.isNaN(limit) && limit % 1 === 0 && limit > 0) {
//if we pass in false we represent the integer as 0 to disable
if(limit === false) {
limit = 0;
} else if(limit === true) {
limit = maximum.pixels;
}
if (typeof limit === 'number' && !Number.isNaN(limit) && limit % 1 === 0 && limit >= 0) {
this.options.limitInputPixels = limit;
} else {
throw new Error('Invalid pixel limit (1 to ' + maximum.pixels + ') ' + limit);

View File

@@ -1,6 +1,6 @@
{
"name": "sharp",
"version": "0.14.0",
"version": "0.14.1",
"author": "Lovell Fuller <npm@lovell.info>",
"contributors": [
"Pierre Inglebert <pierre.inglebert@gmail.com>",
@@ -19,13 +19,16 @@
"Bernhard K. Weisshuhn <bkw@codingforce.com>",
"Chris Riley <criley@primedia.com>",
"David Carley <dacarley@gmail.com>",
"John Tobin <john@limelightmobileinc.com>"
"John Tobin <john@limelightmobileinc.com>",
"Kenton Gray <kentongray@gmail.com>",
"Felix Bünemann <Felix.Buenemann@gmail.com>",
"Samy Al Zahrani <samyalzahrany@gmail.com>"
],
"description": "High performance Node.js module to resize JPEG, PNG, WebP and TIFF images using the libvips library",
"scripts": {
"clean": "rm -rf node_modules/ build/ include/ lib/ coverage/ test/fixtures/output.*",
"test": "VIPS_WARNING=0 node ./node_modules/istanbul/lib/cli.js cover ./node_modules/mocha/bin/_mocha -- --slow=5000 --timeout=30000 ./test/unit/*.js",
"test-win": "node ./node_modules/mocha/bin/mocha --slow=5000 --timeout=30000 ./test/unit/*.js",
"test-win": "node ./node_modules/mocha/bin/mocha --slow=5000 --timeout=60000 ./test/unit/*.js",
"test-leak": "./test/leak/leak.sh",
"test-packaging": "./packaging/test.sh",
"test-clean": "rm -rf coverage/ test/fixtures/output.* && npm install && npm test"
@@ -48,24 +51,25 @@
"vips"
],
"dependencies": {
"bluebird": "^3.3.4",
"bluebird": "^3.3.5",
"color": "^0.11.1",
"nan": "^2.2.1",
"semver": "^5.1.0",
"request": "^2.69.0",
"request": "^2.71.0",
"tar": "^2.2.1"
},
"devDependencies": {
"async": "^1.5.2",
"bufferutil": "^1.2.1",
"coveralls": "^2.11.9",
"exif-reader": "^1.0.0",
"icc": "^0.0.2",
"istanbul": "^0.4.2",
"istanbul": "^0.4.3",
"mocha": "^2.4.5",
"mocha-jshint": "^2.3.1",
"node-cpplint": "^0.4.0",
"rimraf": "^2.5.2",
"bufferutil": "^1.2.1"
"unzip": "^0.1.11"
},
"license": "Apache-2.0",
"config": {

View File

@@ -52,6 +52,9 @@ namespace sharp {
bool IsDz(std::string const &str) {
return EndsWith(str, ".dzi") || EndsWith(str, ".DZI");
}
bool IsDzZip(std::string const &str) {
return EndsWith(str, ".zip") || EndsWith(str, ".ZIP") || EndsWith(str, ".szi") || EndsWith(str, ".SZI");
}
/*
Provide a string identifier for the given image type.

View File

@@ -35,6 +35,7 @@ namespace sharp {
bool IsWebp(std::string const &str);
bool IsTiff(std::string const &str);
bool IsDz(std::string const &str);
bool IsDzZip(std::string const &str);
/*
Provide a string identifier for the given image type.

View File

@@ -65,6 +65,7 @@ using sharp::IsPng;
using sharp::IsWebp;
using sharp::IsTiff;
using sharp::IsDz;
using sharp::IsDzZip;
using sharp::FreeCallback;
using sharp::CalculateCrop;
using sharp::counterProcess;
@@ -103,14 +104,19 @@ class PipelineWorker : public AsyncWorker {
// From buffer
if (baton->rawWidth > 0 && baton->rawHeight > 0 && baton->rawChannels > 0) {
// Raw, uncompressed pixel data
image = VImage::new_from_memory(baton->bufferIn, baton->bufferInLength,
baton->rawWidth, baton->rawHeight, baton->rawChannels, VIPS_FORMAT_UCHAR);
if (baton->rawChannels < 3) {
image.get_image()->Type = VIPS_INTERPRETATION_B_W;
} else {
image.get_image()->Type = VIPS_INTERPRETATION_sRGB;
try {
image = VImage::new_from_memory(baton->bufferIn, baton->bufferInLength,
baton->rawWidth, baton->rawHeight, baton->rawChannels, VIPS_FORMAT_UCHAR);
if (baton->rawChannels < 3) {
image.get_image()->Type = VIPS_INTERPRETATION_B_W;
} else {
image.get_image()->Type = VIPS_INTERPRETATION_sRGB;
}
inputImageType = ImageType::RAW;
} catch(VError const &err) {
(baton->err).append(err.what());
inputImageType = ImageType::UNKNOWN;
}
inputImageType = ImageType::RAW;
} else {
// Compressed data
inputImageType = DetermineImageType(baton->bufferIn, baton->bufferInLength);
@@ -158,7 +164,8 @@ class PipelineWorker : public AsyncWorker {
}
// Limit input images to a given number of pixels, where pixels = width * height
if (image.width() * image.height() > baton->limitInputPixels) {
// Ignore if 0
if (baton->limitInputPixels > 0 && image.width() * image.height() > baton->limitInputPixels) {
(baton->err).append("Input image exceeds pixel limit");
return Error();
}
@@ -489,11 +496,21 @@ class PipelineWorker : public AsyncWorker {
// Scale up 8-bit values to match 16-bit input image
double multiplier = (image.interpretation() == VIPS_INTERPRETATION_RGB16) ? 256.0 : 1.0;
// Create background colour
std::vector<double> background {
baton->background[0] * multiplier,
baton->background[1] * multiplier,
baton->background[2] * multiplier
};
std::vector<double> background;
if (image.bands() > 2) {
background = {
multiplier * baton->background[0],
multiplier * baton->background[1],
multiplier * baton->background[2]
};
} else {
// Convert sRGB to greyscale
background = { multiplier * (
0.2126 * baton->background[0] +
0.7152 * baton->background[1] +
0.0722 * baton->background[2]
)};
}
// Add alpha channel to background colour
if (baton->background[3] < 255.0 || HasAlpha(image)) {
background.push_back(baton->background[3] * multiplier);
@@ -655,7 +672,8 @@ class PipelineWorker : public AsyncWorker {
// Number of channels used in output image
baton->channels = image.bands();
baton->width = image.width();
baton->height = image.height();
// Output
if (baton->fileOut == "") {
// Buffer output
@@ -736,7 +754,8 @@ class PipelineWorker : public AsyncWorker {
bool isWebp = IsWebp(baton->fileOut);
bool isTiff = IsTiff(baton->fileOut);
bool isDz = IsDz(baton->fileOut);
bool matchInput = baton->formatOut == "input" && !(isJpeg || isPng || isWebp || isTiff || isDz);
bool isDzZip = IsDzZip(baton->fileOut);
bool matchInput = baton->formatOut == "input" && !(isJpeg || isPng || isWebp || isTiff || isDz || isDzZip);
if (baton->formatOut == "jpeg" || isJpeg || (matchInput && inputImageType == ImageType::JPEG)) {
// Write JPEG to file
image.jpegsave(const_cast<char*>(baton->fileOut.data()), VImage::option()
@@ -777,12 +796,16 @@ class PipelineWorker : public AsyncWorker {
);
baton->formatOut = "tiff";
baton->channels = std::min(baton->channels, 3);
} else if (baton->formatOut == "dz" || IsDz(baton->fileOut)) {
} else if (baton->formatOut == "dz" || isDz || isDzZip) {
if (isDzZip) {
baton->tileContainer = VIPS_FOREIGN_DZ_CONTAINER_ZIP;
}
// Write DZ to file
image.dzsave(const_cast<char*>(baton->fileOut.data()), VImage::option()
->set("strip", !baton->withMetadata)
->set("tile_size", baton->tileSize)
->set("overlap", baton->tileOverlap)
->set("container", baton->tileContainer)
->set("layout", baton->tileLayout)
);
baton->formatOut = "dz";
@@ -1051,6 +1074,12 @@ NAN_METHOD(pipeline) {
// Tile output
baton->tileSize = attrAs<int32_t>(options, "tileSize");
baton->tileOverlap = attrAs<int32_t>(options, "tileOverlap");
std::string tileContainer = attrAsStr(options, "tileContainer");
if (tileContainer == "zip") {
baton->tileContainer = VIPS_FOREIGN_DZ_CONTAINER_ZIP;
} else {
baton->tileContainer = VIPS_FOREIGN_DZ_CONTAINER_FS;
}
std::string tileLayout = attrAsStr(options, "tileLayout");
if (tileLayout == "google") {
baton->tileLayout = VIPS_FOREIGN_DZ_LAYOUT_GOOGLE;

View File

@@ -81,6 +81,7 @@ struct PipelineBaton {
int withMetadataOrientation;
int tileSize;
int tileOverlap;
VipsForeignDzContainer tileContainer;
VipsForeignDzLayout tileLayout;
PipelineBaton():
@@ -130,6 +131,7 @@ struct PipelineBaton {
withMetadataOrientation(-1),
tileSize(256),
tileOverlap(0),
tileContainer(VIPS_FOREIGN_DZ_CONTAINER_FS),
tileLayout(VIPS_FOREIGN_DZ_LAYOUT_DZ) {
background[0] = 0.0;
background[1] = 0.0;

Binary file not shown.

After

Width:  |  Height:  |  Size: 703 B

BIN
test/fixtures/flowers.jpeg vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

BIN
test/fixtures/giant-image.jpg vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

View File

@@ -66,6 +66,7 @@ module.exports = {
inputJpgWithCmykNoProfile: getPath('Channel_digital_image_CMYK_color_no_profile.jpg'),
inputJpgWithCorruptHeader: getPath('corrupt-header.jpg'),
inputJpgWithLowContrast: getPath('low-contrast.jpg'), // http://www.flickr.com/photos/grizdave/2569067123/
inputJpgLarge: getPath('giant-image.jpg'),
inputPng: getPath('50020484-00001.png'), // http://c.searspartsdirect.com/lis_png/PLDM/50020484-00001.png
inputPngWithTransparency: getPath('blackbug.png'), // public domain
@@ -89,6 +90,8 @@ module.exports = {
inputSvs: getPath('CMU-1-Small-Region.svs'), // http://openslide.cs.cmu.edu/download/openslide-testdata/Aperio/CMU-1-Small-Region.svs
inputJPGBig: getPath('flowers.jpeg'),
outputJpg: getPath('output.jpg'),
outputPng: getPath('output.png'),
outputWebP: getPath('output.webp'),

View File

@@ -53,7 +53,7 @@ describe('Alpha transparency', function() {
assert.strictEqual(true, info.size > 0);
assert.strictEqual(32, info.width);
assert.strictEqual(32, info.height);
fixtures.assertSimilar(fixtures.expected('flatten-rgb16-orange.jpg'), data, done);
fixtures.assertSimilar(fixtures.expected('flatten-rgb16-orange.jpg'), data, { threshold: 6 }, done);
});
});

View File

@@ -88,6 +88,22 @@ describe('Embed', function() {
});
});
it('PNG with 2 channels', function(done) {
sharp(fixtures.inputPngWithGreyAlpha)
.resize(32, 16)
.embed()
.background({r: 0, g: 0, b: 0, a: 0})
.toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('png', info.format);
assert.strictEqual(32, info.width);
assert.strictEqual(16, info.height);
assert.strictEqual(4, info.channels);
fixtures.assertSimilar(fixtures.expected('embed-2channel.png'), data, done);
});
});
it('Enlarge and embed', function(done) {
sharp(fixtures.inputPngWithOneColor)
.embed()

View File

@@ -38,7 +38,7 @@ describe('Gamma correction', function() {
assert.strictEqual('jpeg', info.format);
assert.strictEqual(129, info.width);
assert.strictEqual(111, info.height);
fixtures.assertSimilar(fixtures.expected('gamma-3.0.jpg'), data, done);
fixtures.assertSimilar(fixtures.expected('gamma-3.0.jpg'), data, { threshold: 6 }, done);
});
});
@@ -49,7 +49,7 @@ describe('Gamma correction', function() {
.toBuffer(function(err, data, info) {
assert.strictEqual('png', info.format);
assert.strictEqual(320, info.width);
fixtures.assertSimilar(fixtures.expected('gamma-alpha.jpg'), data, done);
fixtures.assertSimilar(fixtures.expected('gamma-alpha.jpg'), data, { threshold: 11 }, done);
});
});

View File

@@ -876,6 +876,25 @@ describe('Input/output', function() {
});
});
it('Disabling limit works', function(done) {
sharp(fixtures.inputJpgLarge)
.limitInputPixels(false)
.resize(2)
.toBuffer(function(err) {
assert.strictEqual(true, !err);
done();
});
});
it('Enabling default limit works and fails with a large image', function(done) {
sharp(fixtures.inputJpgLarge)
.limitInputPixels(true)
.toBuffer(function(err) {
assert.strictEqual(true, !!err);
done();
});
});
it('Smaller than input fails', function(done) {
sharp(fixtures.inputJpg).metadata(function(err, metadata) {
if (err) throw err;
@@ -1012,4 +1031,32 @@ describe('Input/output', function() {
});
});
it('Info event data', function(done) {
var readable = fs.createReadStream(fixtures.inputJPGBig);
var inPipeline = sharp()
.resize(840)
.raw()
.on('info', function(info) {
assert.strictEqual(840, info.width);
assert.strictEqual(472, info.height);
assert.strictEqual(3, info.channels);
});
var badPipeline = sharp(null, {raw: {width: 840, height: 473, channels: 3}})
.toFormat('jpeg')
.toBuffer(function(err, data, info) {
assert.strictEqual(err.message.indexOf('memory area too small') > 0, true);
readable = fs.createReadStream(fixtures.inputJPGBig);
var goodPipeline = sharp(null, {raw: {width: 840, height: 472, channels: 3}})
.toFormat('jpeg')
.toBuffer(function(err, data, info) {
if (err) throw err;
done();
});
inPipeline = sharp()
.resize(840)
.raw();
readable.pipe(inPipeline).pipe(goodPipeline);
});
readable.pipe(inPipeline).pipe(badPipeline);
});
});

View File

@@ -6,6 +6,7 @@ var assert = require('assert');
var async = require('async');
var rimraf = require('rimraf');
var unzip = require('unzip');
var sharp = require('../../index');
var fixtures = require('../fixtures');
@@ -88,6 +89,26 @@ describe('Tile', function() {
});
});
it('Valid container values pass', function() {
['fs', 'zip'].forEach(function(container) {
assert.doesNotThrow(function() {
sharp().tile({
container: container
});
});
});
});
it('Invalid container values fail', function() {
['zoinks', 1].forEach(function(container) {
assert.throws(function() {
sharp().tile({
container: container
});
});
});
});
it('Valid layout values pass', function() {
['dz', 'google', 'zoomify'].forEach(function(layout) {
assert.doesNotThrow(function() {
@@ -190,6 +211,58 @@ describe('Tile', function() {
});
});
it('Write to ZIP container using file extension', function(done) {
var container = fixtures.path('output.dz.container.zip');
var extractTo = fixtures.path('output.dz.container');
var directory = path.join(extractTo, 'output.dz.container_files');
rimraf(directory, function() {
sharp(fixtures.inputJpg)
.toFile(container, function(err, info) {
if (err) throw err;
assert.strictEqual('dz', info.format);
fs.stat(container, function(err, stat) {
if (err) throw err;
assert.strictEqual(true, stat.isFile());
assert.strictEqual(true, stat.size > 0);
fs.createReadStream(container)
.pipe(unzip.Extract({path: path.dirname(extractTo)}))
.on('error', function(err) { throw err; })
.on('close', function() {
assertDeepZoomTiles(directory, 256, 13, done);
});
});
});
});
});
it('Write to ZIP container using container tile option', function(done) {
var container = fixtures.path('output.dz.containeropt.zip');
var extractTo = fixtures.path('output.dz.containeropt');
var directory = path.join(extractTo, 'output.dz.containeropt_files');
rimraf(directory, function() {
sharp(fixtures.inputJpg)
.tile({
container: 'zip'
})
.toFile(fixtures.path('output.dz.containeropt.dzi'), function(err, info) {
// Vips overrides .dzi extension to .zip used by container var below
if (err) throw err;
assert.strictEqual('dz', info.format);
fs.stat(container, function(err, stat) {
if (err) throw err;
assert.strictEqual(true, stat.isFile());
assert.strictEqual(true, stat.size > 0);
fs.createReadStream(container)
.pipe(unzip.Extract({path: path.dirname(extractTo)}))
.on('error', function(err) { throw err; })
.on('close', function() {
assertDeepZoomTiles(directory, 256, 13, done);
});
});
});
});
});
}
});