mirror of
https://github.com/lovell/sharp.git
synced 2025-07-09 10:30:15 +02:00
Load TIFF from Buffer/Stream Interlaced PNG output no longer needs tilecache Option to disable PNG adaptive row filtering
419 lines
13 KiB
JavaScript
Executable File
419 lines
13 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');
|
|
|
|
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('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('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('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('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('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', function(done) {
|
|
sharp(fixtures.inputJpg)
|
|
.sequentialRead()
|
|
.resize(320, 240)
|
|
.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();
|
|
});
|
|
});
|
|
|
|
it('Not sequential read', function(done) {
|
|
sharp(fixtures.inputJpg)
|
|
.sequentialRead(false)
|
|
.resize(320, 240)
|
|
.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();
|
|
});
|
|
});
|
|
|
|
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) {
|
|
var failed = true;
|
|
try {
|
|
sharp(new Buffer(0));
|
|
failed = false;
|
|
} catch (err) {
|
|
assert(err instanceof Error);
|
|
}
|
|
assert(failed);
|
|
done();
|
|
});
|
|
|
|
it('Fail when input is invalid Buffer', function(done) {
|
|
var failed = true;
|
|
try {
|
|
sharp(new Buffer([0x1, 0x2, 0x3, 0x4]));
|
|
failed = false;
|
|
} catch (err) {
|
|
assert(err instanceof Error);
|
|
}
|
|
assert(failed);
|
|
done();
|
|
});
|
|
|
|
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('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();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('Invalid quality', function(done) {
|
|
var isValid = true;
|
|
try {
|
|
sharp(fixtures.inputJpg).quality(-1);
|
|
} catch (err) {
|
|
isValid = false;
|
|
}
|
|
assert.strictEqual(false, isValid);
|
|
done();
|
|
});
|
|
|
|
it('Progressive image', function(done) {
|
|
sharp(fixtures.inputJpg)
|
|
.resize(320, 240)
|
|
.png()
|
|
.progressive(false)
|
|
.toBuffer(function(err, nonProgressive, info) {
|
|
if (err) throw err;
|
|
assert.strictEqual(true, nonProgressive.length > 0);
|
|
assert.strictEqual('png', info.format);
|
|
assert.strictEqual(320, info.width);
|
|
assert.strictEqual(240, info.height);
|
|
sharp(nonProgressive)
|
|
.progressive()
|
|
.toBuffer(function(err, progressive, info) {
|
|
if (err) throw err;
|
|
assert.strictEqual(true, progressive.length > 0);
|
|
assert.strictEqual(true, progressive.length > nonProgressive.length);
|
|
assert.strictEqual('png', info.format);
|
|
assert.strictEqual(320, info.width);
|
|
assert.strictEqual(240, info.height);
|
|
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('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('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('png', info.format);
|
|
assert.strictEqual(320, info.width);
|
|
assert.strictEqual(80, info.height);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('WebP', function(done) {
|
|
sharp(fixtures.inputWebP).resize(320, 80).toFile(fixtures.outputZoinks, function(err, info) {
|
|
if (err) throw err;
|
|
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('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.41.0')) {
|
|
it('withoutAdaptiveFiltering generates smaller file [libvips 7.41.0+]', function(done) {
|
|
// First generate with adaptive filtering
|
|
sharp(fixtures.inputPng)
|
|
.resize(320, 240)
|
|
.withoutAdaptiveFiltering(false)
|
|
.toBuffer(function(err, dataAdaptive, info) {
|
|
if (err) throw err;
|
|
assert.strictEqual(true, dataAdaptive.length > 0);
|
|
assert.strictEqual('png', info.format);
|
|
assert.strictEqual(320, info.width);
|
|
assert.strictEqual(240, info.height);
|
|
// Then generate without
|
|
sharp(fixtures.inputPng)
|
|
.resize(320, 240)
|
|
.withoutAdaptiveFiltering()
|
|
.toBuffer(function(err, dataWithoutAdaptive, info) {
|
|
if (err) throw err;
|
|
assert.strictEqual(true, dataWithoutAdaptive.length > 0);
|
|
assert.strictEqual('png', info.format);
|
|
assert.strictEqual(320, info.width);
|
|
assert.strictEqual(240, info.height);
|
|
assert.strictEqual(true, dataWithoutAdaptive.length < dataAdaptive.length);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
});
|
|
|
|
if (semver.gte(sharp.libvipsVersion(), '7.40.0')) {
|
|
it('Load TIFF from Buffer [libvips 7.40.0+]', 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('jpeg', info.format);
|
|
assert.strictEqual(320, info.width);
|
|
assert.strictEqual(240, info.height);
|
|
done();
|
|
});
|
|
});
|
|
}
|
|
|
|
});
|