mirror of
https://github.com/lovell/sharp.git
synced 2025-07-09 10:30:15 +02:00
846 lines
29 KiB
JavaScript
Executable File
846 lines
29 KiB
JavaScript
Executable File
'use strict';
|
|
|
|
var fs = require('fs');
|
|
var assert = require('assert');
|
|
|
|
var semver = require('semver');
|
|
|
|
var sharp = require('../../index');
|
|
var fixtures = require('../fixtures');
|
|
|
|
sharp.cache(0);
|
|
|
|
describe('Input/output', function() {
|
|
|
|
it('Read from File and write to Stream', function(done) {
|
|
var writable = fs.createWriteStream(fixtures.outputJpg);
|
|
writable.on('finish', function() {
|
|
sharp(fixtures.outputJpg).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);
|
|
fs.unlinkSync(fixtures.outputJpg);
|
|
done();
|
|
});
|
|
});
|
|
sharp(fixtures.inputJpg).resize(320, 240).pipe(writable);
|
|
});
|
|
|
|
it('Read from Buffer and write to Stream', function(done) {
|
|
var inputJpgBuffer = fs.readFileSync(fixtures.inputJpg);
|
|
var writable = fs.createWriteStream(fixtures.outputJpg);
|
|
writable.on('finish', function() {
|
|
sharp(fixtures.outputJpg).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);
|
|
fs.unlinkSync(fixtures.outputJpg);
|
|
done();
|
|
});
|
|
});
|
|
sharp(inputJpgBuffer).resize(320, 240).pipe(writable);
|
|
});
|
|
|
|
it('Read from Stream and write to File', function(done) {
|
|
var readable = fs.createReadStream(fixtures.inputJpg);
|
|
var pipeline = sharp().resize(320, 240).toFile(fixtures.outputJpg, function(err, info) {
|
|
if (err) throw err;
|
|
assert.strictEqual(true, info.size > 0);
|
|
assert.strictEqual('jpeg', info.format);
|
|
assert.strictEqual(320, info.width);
|
|
assert.strictEqual(240, info.height);
|
|
fs.unlinkSync(fixtures.outputJpg);
|
|
done();
|
|
});
|
|
readable.pipe(pipeline);
|
|
});
|
|
|
|
it('Read from Stream and write to Buffer', function(done) {
|
|
var readable = fs.createReadStream(fixtures.inputJpg);
|
|
var pipeline = sharp().resize(320, 240).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();
|
|
});
|
|
readable.pipe(pipeline);
|
|
});
|
|
|
|
it('Read from Stream and write to Buffer via Promise', function(done) {
|
|
var readable = fs.createReadStream(fixtures.inputJpg);
|
|
var pipeline = sharp().resize(1, 1);
|
|
pipeline.toBuffer().then(function(data) {
|
|
assert.strictEqual(true, data.length > 0);
|
|
done();
|
|
}).catch(function(err) {
|
|
throw err;
|
|
});
|
|
readable.pipe(pipeline);
|
|
});
|
|
|
|
it('Read from Stream and write to Stream', function(done) {
|
|
var readable = fs.createReadStream(fixtures.inputJpg);
|
|
var writable = fs.createWriteStream(fixtures.outputJpg);
|
|
writable.on('finish', function() {
|
|
sharp(fixtures.outputJpg).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);
|
|
fs.unlinkSync(fixtures.outputJpg);
|
|
done();
|
|
});
|
|
});
|
|
var pipeline = sharp().resize(320, 240);
|
|
readable.pipe(pipeline).pipe(writable);
|
|
});
|
|
|
|
it('Handle Stream to Stream error ', function(done) {
|
|
var pipeline = sharp().resize(320, 240);
|
|
var anErrorWasEmitted = false;
|
|
pipeline.on('error', function(err) {
|
|
anErrorWasEmitted = !!err;
|
|
}).on('end', function() {
|
|
assert(anErrorWasEmitted);
|
|
fs.unlinkSync(fixtures.outputJpg);
|
|
done();
|
|
});
|
|
var readableButNotAnImage = fs.createReadStream(__filename);
|
|
var writable = fs.createWriteStream(fixtures.outputJpg);
|
|
readableButNotAnImage.pipe(pipeline).pipe(writable);
|
|
});
|
|
|
|
it('Handle File to Stream error', function(done) {
|
|
var readableButNotAnImage = sharp(__filename).resize(320, 240);
|
|
var anErrorWasEmitted = false;
|
|
readableButNotAnImage.on('error', function(err) {
|
|
anErrorWasEmitted = !!err;
|
|
}).on('end', function() {
|
|
assert(anErrorWasEmitted);
|
|
fs.unlinkSync(fixtures.outputJpg);
|
|
done();
|
|
});
|
|
var writable = fs.createWriteStream(fixtures.outputJpg);
|
|
readableButNotAnImage.pipe(writable);
|
|
});
|
|
|
|
it('Sequential read, force JPEG', function(done) {
|
|
sharp(fixtures.inputJpg)
|
|
.sequentialRead()
|
|
.resize(320, 240)
|
|
.toFormat(sharp.format.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();
|
|
});
|
|
});
|
|
|
|
it('Not sequential read, force JPEG', function(done) {
|
|
sharp(fixtures.inputJpg)
|
|
.sequentialRead(false)
|
|
.resize(320, 240)
|
|
.toFormat('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();
|
|
});
|
|
});
|
|
|
|
it('Fail when output File is input File', function(done) {
|
|
sharp(fixtures.inputJpg).toFile(fixtures.inputJpg, function(err) {
|
|
assert(!!err);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('Fail when output File is input File via Promise', function(done) {
|
|
sharp(fixtures.inputJpg).toFile(fixtures.inputJpg).then(function(data) {
|
|
assert(false);
|
|
done();
|
|
}).catch(function(err) {
|
|
assert(!!err);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('Fail when output File is empty', function(done) {
|
|
sharp(fixtures.inputJpg).toFile('', function(err) {
|
|
assert(!!err);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('Fail when output File is empty via Promise', function(done) {
|
|
sharp(fixtures.inputJpg).toFile('').then(function(data) {
|
|
assert(false);
|
|
done();
|
|
}).catch(function(err) {
|
|
assert(!!err);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('Fail when input is empty Buffer', function(done) {
|
|
sharp(new Buffer(0)).toBuffer().then(function () {
|
|
assert(false);
|
|
done();
|
|
}).catch(function (err) {
|
|
assert(err instanceof Error);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('Fail when input is invalid Buffer', function(done) {
|
|
sharp(new Buffer([0x1, 0x2, 0x3, 0x4])).toBuffer().then(function () {
|
|
assert(false);
|
|
done();
|
|
}).catch(function (err) {
|
|
assert(err instanceof Error);
|
|
done();
|
|
});
|
|
});
|
|
|
|
describe('Fail for unsupported input', function() {
|
|
it('Numeric', function() {
|
|
assert.throws(function() {
|
|
sharp(1);
|
|
});
|
|
});
|
|
it('Boolean', function() {
|
|
assert.throws(function() {
|
|
sharp(true);
|
|
});
|
|
});
|
|
it('Empty Object', function() {
|
|
assert.throws(function() {
|
|
sharp({});
|
|
});
|
|
});
|
|
it('Error Object', function() {
|
|
assert.throws(function() {
|
|
sharp(new Error());
|
|
});
|
|
});
|
|
});
|
|
|
|
it('Promises/A+', function(done) {
|
|
sharp(fixtures.inputJpg).resize(320, 240).toBuffer().then(function(data) {
|
|
sharp(data).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();
|
|
});
|
|
}).catch(function(err) {
|
|
throw err;
|
|
});
|
|
});
|
|
|
|
it('JPEG quality', function(done) {
|
|
sharp(fixtures.inputJpg).resize(320, 240).quality(70).toBuffer(function(err, buffer70) {
|
|
if (err) throw err;
|
|
sharp(fixtures.inputJpg).resize(320, 240).toBuffer(function(err, buffer80) {
|
|
if (err) throw err;
|
|
sharp(fixtures.inputJpg).resize(320, 240).quality(90).toBuffer(function(err, buffer90) {
|
|
if (err) throw err;
|
|
assert(buffer70.length < buffer80.length);
|
|
assert(buffer80.length < buffer90.length);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('Invalid quality', function() {
|
|
it('Negative integer', function() {
|
|
assert.throws(function() {
|
|
sharp(fixtures.inputJpg).quality(-1);
|
|
});
|
|
});
|
|
it('Non integral', function() {
|
|
assert.throws(function() {
|
|
sharp(fixtures.inputJpg).quality(88.2);
|
|
});
|
|
});
|
|
it('String', function() {
|
|
assert.throws(function() {
|
|
sharp(fixtures.inputJpg).quality('test');
|
|
});
|
|
});
|
|
});
|
|
|
|
it('Progressive JPEG image', function(done) {
|
|
sharp(fixtures.inputJpg)
|
|
.resize(320, 240)
|
|
.progressive(false)
|
|
.toBuffer(function(err, nonProgressiveData, nonProgressiveInfo) {
|
|
if (err) throw err;
|
|
assert.strictEqual(true, nonProgressiveData.length > 0);
|
|
assert.strictEqual(nonProgressiveData.length, nonProgressiveInfo.size);
|
|
assert.strictEqual('jpeg', nonProgressiveInfo.format);
|
|
assert.strictEqual(320, nonProgressiveInfo.width);
|
|
assert.strictEqual(240, nonProgressiveInfo.height);
|
|
sharp(fixtures.inputJpg)
|
|
.resize(320, 240)
|
|
.progressive()
|
|
.toBuffer(function(err, progressiveData, progressiveInfo) {
|
|
if (err) throw err;
|
|
assert.strictEqual(true, progressiveData.length > 0);
|
|
assert.strictEqual(progressiveData.length, progressiveInfo.size);
|
|
assert.strictEqual(false, progressiveData.length === nonProgressiveData.length);
|
|
assert.strictEqual('jpeg', progressiveInfo.format);
|
|
assert.strictEqual(320, progressiveInfo.width);
|
|
assert.strictEqual(240, progressiveInfo.height);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('Progressive PNG image', function(done) {
|
|
sharp(fixtures.inputJpg)
|
|
.resize(320, 240)
|
|
.png()
|
|
.progressive(false)
|
|
.toBuffer(function(err, nonProgressiveData, nonProgressiveInfo) {
|
|
if (err) throw err;
|
|
assert.strictEqual(true, nonProgressiveData.length > 0);
|
|
assert.strictEqual(nonProgressiveData.length, nonProgressiveInfo.size);
|
|
assert.strictEqual('png', nonProgressiveInfo.format);
|
|
assert.strictEqual(320, nonProgressiveInfo.width);
|
|
assert.strictEqual(240, nonProgressiveInfo.height);
|
|
sharp(nonProgressiveData)
|
|
.progressive()
|
|
.toBuffer(function(err, progressiveData, progressiveInfo) {
|
|
if (err) throw err;
|
|
assert.strictEqual(true, progressiveData.length > 0);
|
|
assert.strictEqual(progressiveData.length, progressiveInfo.size);
|
|
assert.strictEqual(true, progressiveData.length > nonProgressiveData.length);
|
|
assert.strictEqual('png', progressiveInfo.format);
|
|
assert.strictEqual(320, progressiveInfo.width);
|
|
assert.strictEqual(240, progressiveInfo.height);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
if (sharp.format.webp.output.buffer) {
|
|
it('WebP output', function(done) {
|
|
sharp(fixtures.inputJpg)
|
|
.resize(320, 240)
|
|
.toFormat(sharp.format.webp)
|
|
.toBuffer(function(err, data, info) {
|
|
if (err) throw err;
|
|
assert.strictEqual(true, data.length > 0);
|
|
assert.strictEqual('webp', info.format);
|
|
assert.strictEqual(320, info.width);
|
|
assert.strictEqual(240, info.height);
|
|
done();
|
|
});
|
|
});
|
|
}
|
|
|
|
it('Invalid output format', function(done) {
|
|
var isValid = false;
|
|
try {
|
|
sharp().toFormat('zoinks');
|
|
isValid = true;
|
|
} catch (e) {}
|
|
assert(!isValid);
|
|
done();
|
|
});
|
|
|
|
it('File input with corrupt header fails gracefully', function(done) {
|
|
sharp(fixtures.inputJpgWithCorruptHeader)
|
|
.toBuffer(function(err) {
|
|
assert.strictEqual(true, !!err);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('Buffer input with corrupt header fails gracefully', function(done) {
|
|
sharp(fs.readFileSync(fixtures.inputJpgWithCorruptHeader))
|
|
.toBuffer(function(err) {
|
|
assert.strictEqual(true, !!err);
|
|
done();
|
|
});
|
|
});
|
|
|
|
describe('Output filename without extension uses input format', function() {
|
|
|
|
it('JPEG', function(done) {
|
|
sharp(fixtures.inputJpg).resize(320, 80).toFile(fixtures.outputZoinks, function(err, info) {
|
|
if (err) throw err;
|
|
assert.strictEqual(true, info.size > 0);
|
|
assert.strictEqual('jpeg', info.format);
|
|
assert.strictEqual(320, info.width);
|
|
assert.strictEqual(80, info.height);
|
|
fs.unlinkSync(fixtures.outputZoinks);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('PNG', function(done) {
|
|
sharp(fixtures.inputPng).resize(320, 80).toFile(fixtures.outputZoinks, function(err, info) {
|
|
if (err) throw err;
|
|
assert.strictEqual(true, info.size > 0);
|
|
assert.strictEqual('png', info.format);
|
|
assert.strictEqual(320, info.width);
|
|
assert.strictEqual(80, info.height);
|
|
fs.unlinkSync(fixtures.outputZoinks);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('Transparent PNG', function(done) {
|
|
sharp(fixtures.inputPngWithTransparency).resize(320, 80).toFile(fixtures.outputZoinks, function(err, info) {
|
|
if (err) throw err;
|
|
assert.strictEqual(true, info.size > 0);
|
|
assert.strictEqual('png', info.format);
|
|
assert.strictEqual(320, info.width);
|
|
assert.strictEqual(80, info.height);
|
|
done();
|
|
});
|
|
});
|
|
|
|
if (sharp.format.webp.input.file) {
|
|
it('WebP', function(done) {
|
|
sharp(fixtures.inputWebP).resize(320, 80).toFile(fixtures.outputZoinks, function(err, info) {
|
|
if (err) throw err;
|
|
assert.strictEqual(true, info.size > 0);
|
|
assert.strictEqual('webp', info.format);
|
|
assert.strictEqual(320, info.width);
|
|
assert.strictEqual(80, info.height);
|
|
fs.unlinkSync(fixtures.outputZoinks);
|
|
done();
|
|
});
|
|
});
|
|
}
|
|
|
|
it('TIFF', function(done) {
|
|
sharp(fixtures.inputTiff).resize(320, 80).toFile(fixtures.outputZoinks, function(err, info) {
|
|
if (err) throw err;
|
|
assert.strictEqual(true, info.size > 0);
|
|
assert.strictEqual('tiff', info.format);
|
|
assert.strictEqual(320, info.width);
|
|
assert.strictEqual(80, info.height);
|
|
fs.unlinkSync(fixtures.outputZoinks);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('Fail with GIF', function(done) {
|
|
sharp(fixtures.inputGif).resize(320, 80).toFile(fixtures.outputZoinks, function(err) {
|
|
assert(!!err);
|
|
done();
|
|
});
|
|
});
|
|
|
|
});
|
|
|
|
describe('PNG output', function() {
|
|
|
|
it('compression level is valid', function(done) {
|
|
var isValid = false;
|
|
try {
|
|
sharp().compressionLevel(0);
|
|
isValid = true;
|
|
} catch (e) {}
|
|
assert(isValid);
|
|
done();
|
|
});
|
|
|
|
it('compression level is invalid', function(done) {
|
|
var isValid = false;
|
|
try {
|
|
sharp().compressionLevel(-1);
|
|
isValid = true;
|
|
} catch (e) {}
|
|
assert(!isValid);
|
|
done();
|
|
});
|
|
|
|
if (semver.gte(sharp.libvipsVersion(), '7.42.0')) {
|
|
it('withoutAdaptiveFiltering generates smaller file [libvips ' + sharp.libvipsVersion() + '>=7.42.0]', function(done) {
|
|
// First generate with adaptive filtering
|
|
sharp(fixtures.inputPng)
|
|
.resize(320, 240)
|
|
.withoutAdaptiveFiltering(false)
|
|
.toBuffer(function(err, adaptiveData, adaptiveInfo) {
|
|
if (err) throw err;
|
|
assert.strictEqual(true, adaptiveData.length > 0);
|
|
assert.strictEqual(adaptiveData.length, adaptiveInfo.size);
|
|
assert.strictEqual('png', adaptiveInfo.format);
|
|
assert.strictEqual(320, adaptiveInfo.width);
|
|
assert.strictEqual(240, adaptiveInfo.height);
|
|
// Then generate without
|
|
sharp(fixtures.inputPng)
|
|
.resize(320, 240)
|
|
.withoutAdaptiveFiltering()
|
|
.toBuffer(function(err, withoutAdaptiveData, withoutAdaptiveInfo) {
|
|
if (err) throw err;
|
|
assert.strictEqual(true, withoutAdaptiveData.length > 0);
|
|
assert.strictEqual(withoutAdaptiveData.length, withoutAdaptiveInfo.size);
|
|
assert.strictEqual('png', withoutAdaptiveInfo.format);
|
|
assert.strictEqual(320, withoutAdaptiveInfo.width);
|
|
assert.strictEqual(240, withoutAdaptiveInfo.height);
|
|
assert.strictEqual(true, withoutAdaptiveData.length < adaptiveData.length);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
});
|
|
|
|
it('Without chroma subsampling generates larger file', function(done) {
|
|
// First generate with chroma subsampling (default)
|
|
sharp(fixtures.inputJpg)
|
|
.resize(320, 240)
|
|
.withoutChromaSubsampling(false)
|
|
.toBuffer(function(err, withChromaSubsamplingData, withChromaSubsamplingInfo) {
|
|
if (err) throw err;
|
|
assert.strictEqual(true, withChromaSubsamplingData.length > 0);
|
|
assert.strictEqual(withChromaSubsamplingData.length, withChromaSubsamplingInfo.size);
|
|
assert.strictEqual('jpeg', withChromaSubsamplingInfo.format);
|
|
assert.strictEqual(320, withChromaSubsamplingInfo.width);
|
|
assert.strictEqual(240, withChromaSubsamplingInfo.height);
|
|
// Then generate without
|
|
sharp(fixtures.inputJpg)
|
|
.resize(320, 240)
|
|
.withoutChromaSubsampling()
|
|
.toBuffer(function(err, withoutChromaSubsamplingData, withoutChromaSubsamplingInfo) {
|
|
if (err) throw err;
|
|
assert.strictEqual(true, withoutChromaSubsamplingData.length > 0);
|
|
assert.strictEqual(withoutChromaSubsamplingData.length, withoutChromaSubsamplingInfo.size);
|
|
assert.strictEqual('jpeg', withoutChromaSubsamplingInfo.format);
|
|
assert.strictEqual(320, withoutChromaSubsamplingInfo.width);
|
|
assert.strictEqual(240, withoutChromaSubsamplingInfo.height);
|
|
assert.strictEqual(true, withChromaSubsamplingData.length < withoutChromaSubsamplingData.length);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
if (semver.gte(sharp.libvipsVersion(), '8.0.0')) {
|
|
it('Trellis quantisation [libvips ' + sharp.libvipsVersion() + '>=8.0.0]', function(done) {
|
|
// First generate without
|
|
sharp(fixtures.inputJpg)
|
|
.resize(320, 240)
|
|
.trellisQuantisation(false)
|
|
.toBuffer(function(err, withoutData, withoutInfo) {
|
|
if (err) throw err;
|
|
assert.strictEqual(true, withoutData.length > 0);
|
|
assert.strictEqual(withoutData.length, withoutInfo.size);
|
|
assert.strictEqual('jpeg', withoutInfo.format);
|
|
assert.strictEqual(320, withoutInfo.width);
|
|
assert.strictEqual(240, withoutInfo.height);
|
|
// Then generate with
|
|
sharp(fixtures.inputJpg)
|
|
.resize(320, 240)
|
|
.trellisQuantization()
|
|
.toBuffer(function(err, withData, withInfo) {
|
|
if (err) throw err;
|
|
assert.strictEqual(true, withData.length > 0);
|
|
assert.strictEqual(withData.length, withInfo.size);
|
|
assert.strictEqual('jpeg', withInfo.format);
|
|
assert.strictEqual(320, withInfo.width);
|
|
assert.strictEqual(240, withInfo.height);
|
|
// Verify image is same (as mozjpeg may not be present) size or less
|
|
assert.strictEqual(true, withData.length <= withoutData.length);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
it('Overshoot deringing [libvips ' + sharp.libvipsVersion() + '>=8.0.0]', function(done) {
|
|
// First generate without
|
|
sharp(fixtures.inputJpg)
|
|
.resize(320, 240)
|
|
.overshootDeringing(false)
|
|
.toBuffer(function(err, withoutData, withoutInfo) {
|
|
if (err) throw err;
|
|
assert.strictEqual(true, withoutData.length > 0);
|
|
assert.strictEqual(withoutData.length, withoutInfo.size);
|
|
assert.strictEqual('jpeg', withoutInfo.format);
|
|
assert.strictEqual(320, withoutInfo.width);
|
|
assert.strictEqual(240, withoutInfo.height);
|
|
// Then generate with
|
|
sharp(fixtures.inputJpg)
|
|
.resize(320, 240)
|
|
.overshootDeringing()
|
|
.toBuffer(function(err, withData, withInfo) {
|
|
if (err) throw err;
|
|
assert.strictEqual(true, withData.length > 0);
|
|
assert.strictEqual(withData.length, withInfo.size);
|
|
assert.strictEqual('jpeg', withInfo.format);
|
|
assert.strictEqual(320, withInfo.width);
|
|
assert.strictEqual(240, withInfo.height);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
it('Optimise scans [libvips ' + sharp.libvipsVersion() + '>=8.0.0]', function(done) {
|
|
// First generate without
|
|
sharp(fixtures.inputJpg)
|
|
.resize(320, 240)
|
|
.optimiseScans(false)
|
|
.toBuffer(function(err, withoutData, withoutInfo) {
|
|
if (err) throw err;
|
|
assert.strictEqual(true, withoutData.length > 0);
|
|
assert.strictEqual(withoutData.length, withoutInfo.size);
|
|
assert.strictEqual('jpeg', withoutInfo.format);
|
|
assert.strictEqual(320, withoutInfo.width);
|
|
assert.strictEqual(240, withoutInfo.height);
|
|
// Then generate with
|
|
sharp(fixtures.inputJpg)
|
|
.resize(320, 240)
|
|
.optimizeScans()
|
|
.toBuffer(function(err, withData, withInfo) {
|
|
if (err) throw err;
|
|
assert.strictEqual(true, withData.length > 0);
|
|
assert.strictEqual(withData.length, withInfo.size);
|
|
assert.strictEqual('jpeg', withInfo.format);
|
|
assert.strictEqual(320, withInfo.width);
|
|
assert.strictEqual(240, withInfo.height);
|
|
// Verify image is of a different size (progressive output even without mozjpeg)
|
|
assert.strictEqual(true, withData.length != withoutData.length);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
if (sharp.format.magick.input.file) {
|
|
it('Convert SVG, if supported, to PNG', function(done) {
|
|
sharp(fixtures.inputSvg)
|
|
.resize(100, 100)
|
|
.toFormat('png')
|
|
.toFile(fixtures.path('output.svg.png'), function(err, info) {
|
|
if (err) {
|
|
assert.strictEqual(0, err.message.indexOf('Input file is of an unsupported image format'));
|
|
} else {
|
|
assert.strictEqual(true, info.size > 0);
|
|
assert.strictEqual('png', info.format);
|
|
assert.strictEqual(100, info.width);
|
|
assert.strictEqual(100, info.height);
|
|
}
|
|
done();
|
|
});
|
|
});
|
|
}
|
|
|
|
if (sharp.format.magick.input.file) {
|
|
it('Convert PSD to PNG', function(done) {
|
|
sharp(fixtures.inputPsd)
|
|
.resize(320, 240)
|
|
.toFormat(sharp.format.png)
|
|
.toFile(fixtures.path('output.psd.png'), function(err, info) {
|
|
if (err) throw err;
|
|
assert.strictEqual(true, info.size > 0);
|
|
assert.strictEqual('png', info.format);
|
|
assert.strictEqual(320, info.width);
|
|
assert.strictEqual(240, info.height);
|
|
done();
|
|
});
|
|
});
|
|
}
|
|
|
|
if (sharp.format.tiff.input.buffer) {
|
|
it('Load TIFF from Buffer', function(done) {
|
|
var inputTiffBuffer = fs.readFileSync(fixtures.inputTiff);
|
|
sharp(inputTiffBuffer)
|
|
.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 (sharp.format.magick.input.buffer) {
|
|
it('Load GIF from Buffer', 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 (sharp.format.openslide.input.file) {
|
|
it('Load Aperio SVS file via Openslide', function(done) {
|
|
sharp(fixtures.inputSvs)
|
|
.resize(320, 240)
|
|
.jpeg()
|
|
.toBuffer(function(err, data, info) {
|
|
if (err) throw err;
|
|
assert.strictEqual(true, data.length > 0);
|
|
assert.strictEqual('jpeg', info.format);
|
|
assert.strictEqual(320, info.width);
|
|
assert.strictEqual(240, info.height);
|
|
done();
|
|
});
|
|
});
|
|
}
|
|
|
|
if (sharp.format.raw.output.buffer) {
|
|
describe('Ouput raw, uncompressed image data', function() {
|
|
it('1 channel greyscale image', function(done) {
|
|
sharp(fixtures.inputJpg)
|
|
.greyscale()
|
|
.resize(32, 24)
|
|
.raw()
|
|
.toBuffer(function(err, data, info) {
|
|
assert.strictEqual(32 * 24 * 1, info.size);
|
|
assert.strictEqual(data.length, info.size);
|
|
assert.strictEqual('raw', info.format);
|
|
assert.strictEqual(32, info.width);
|
|
assert.strictEqual(24, info.height);
|
|
done();
|
|
});
|
|
});
|
|
it('3 channel colour image without transparency', function(done) {
|
|
sharp(fixtures.inputJpg)
|
|
.resize(32, 24)
|
|
.toFormat('raw')
|
|
.toBuffer(function(err, data, info) {
|
|
assert.strictEqual(32 * 24 * 3, info.size);
|
|
assert.strictEqual(data.length, info.size);
|
|
assert.strictEqual('raw', info.format);
|
|
assert.strictEqual(32, info.width);
|
|
assert.strictEqual(24, info.height);
|
|
done();
|
|
});
|
|
});
|
|
it('4 channel colour image with transparency', function(done) {
|
|
sharp(fixtures.inputPngWithTransparency)
|
|
.resize(32, 24)
|
|
.toFormat(sharp.format.raw)
|
|
.toBuffer(function(err, data, info) {
|
|
assert.strictEqual(32 * 24 * 4, info.size);
|
|
assert.strictEqual(data.length, info.size);
|
|
assert.strictEqual('raw', info.format);
|
|
assert.strictEqual(32, info.width);
|
|
assert.strictEqual(24, info.height);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
describe('Limit pixel count of input image', function() {
|
|
|
|
it('Invalid fails - negative', function(done) {
|
|
var isValid = false;
|
|
try {
|
|
sharp().limitInputPixels(-1);
|
|
isValid = true;
|
|
} catch (e) {}
|
|
assert(!isValid);
|
|
done();
|
|
});
|
|
|
|
it('Invalid fails - float', function(done) {
|
|
var isValid = false;
|
|
try {
|
|
sharp().limitInputPixels(12.3);
|
|
isValid = true;
|
|
} catch (e) {}
|
|
assert(!isValid);
|
|
done();
|
|
});
|
|
|
|
it('Invalid fails - string', function(done) {
|
|
var isValid = false;
|
|
try {
|
|
sharp().limitInputPixels('fail');
|
|
isValid = true;
|
|
} catch (e) {}
|
|
assert(!isValid);
|
|
done();
|
|
});
|
|
|
|
it('Same size as input works', function(done) {
|
|
sharp(fixtures.inputJpg).metadata(function(err, metadata) {
|
|
if (err) throw err;
|
|
sharp(fixtures.inputJpg)
|
|
.limitInputPixels(metadata.width * metadata.height)
|
|
.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;
|
|
sharp(fixtures.inputJpg)
|
|
.limitInputPixels(metadata.width * metadata.height - 1)
|
|
.toBuffer(function(err) {
|
|
assert.strictEqual(true, !!err);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
});
|
|
|
|
it('Queue length change events', function(done) {
|
|
var eventCounter = 0;
|
|
var queueListener = function(queueLength) {
|
|
assert.strictEqual(true, queueLength === 0 || queueLength === 1);
|
|
eventCounter++;
|
|
};
|
|
sharp.queue.on('change', queueListener);
|
|
sharp(fixtures.inputJpg)
|
|
.resize(320, 240)
|
|
.toBuffer(function(err) {
|
|
process.nextTick(function() {
|
|
sharp.queue.removeListener('change', queueListener);
|
|
if (err) throw err;
|
|
assert.strictEqual(2, eventCounter);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
});
|