mirror of
https://github.com/lovell/sharp.git
synced 2025-07-09 18:40:16 +02:00
Tests: separate IO suite into per-format unit files
This commit is contained in:
parent
98797445de
commit
32a34a8841
964
test/unit/io.js
964
test/unit/io.js
@ -349,162 +349,6 @@ describe('Input/output', function () {
|
|||||||
.toBuffer();
|
.toBuffer();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('JPEG quality', function (done) {
|
|
||||||
sharp(fixtures.inputJpg)
|
|
||||||
.resize(320, 240)
|
|
||||||
.jpeg({ 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)
|
|
||||||
.jpeg({ quality: 90 })
|
|
||||||
.toBuffer(function (err, buffer90) {
|
|
||||||
if (err) throw err;
|
|
||||||
assert(buffer70.length < buffer80.length);
|
|
||||||
assert(buffer80.length < buffer90.length);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Invalid JPEG quality', function () {
|
|
||||||
[-1, 88.2, 'test'].forEach(function (quality) {
|
|
||||||
it(quality.toString(), function () {
|
|
||||||
assert.throws(function () {
|
|
||||||
sharp().jpeg({ quality: quality });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Invalid JPEG quantisation table', function () {
|
|
||||||
[-1, 88.2, 'test'].forEach(function (table) {
|
|
||||||
it(table.toString(), function () {
|
|
||||||
assert.throws(function () {
|
|
||||||
sharp().jpeg({ quantisationTable: table });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Progressive JPEG image', function (done) {
|
|
||||||
sharp(fixtures.inputJpg)
|
|
||||||
.resize(320, 240)
|
|
||||||
.jpeg({ 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)
|
|
||||||
.jpeg({ progressive: true })
|
|
||||||
.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)
|
|
||||||
.png({ progressive: true })
|
|
||||||
.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('should work for webp alpha quality', function (done) {
|
|
||||||
sharp(fixtures.inputPngAlphaPremultiplicationSmall)
|
|
||||||
.webp({ alphaQuality: 80 })
|
|
||||||
.toBuffer(function (err, data, info) {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual(true, data.length > 0);
|
|
||||||
assert.strictEqual('webp', info.format);
|
|
||||||
fixtures.assertSimilar(fixtures.expected('webp-alpha-80.webp'), data, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should work for webp lossless', function (done) {
|
|
||||||
sharp(fixtures.inputPngAlphaPremultiplicationSmall)
|
|
||||||
.webp({ lossless: true })
|
|
||||||
.toBuffer(function (err, data, info) {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual(true, data.length > 0);
|
|
||||||
assert.strictEqual('webp', info.format);
|
|
||||||
fixtures.assertSimilar(fixtures.expected('webp-lossless.webp'), data, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should work for webp near-lossless', function (done) {
|
|
||||||
sharp(fixtures.inputPngAlphaPremultiplicationSmall)
|
|
||||||
.webp({ nearLossless: true, quality: 50 })
|
|
||||||
.toBuffer(function (err50, data50, info50) {
|
|
||||||
if (err50) throw err50;
|
|
||||||
assert.strictEqual(true, data50.length > 0);
|
|
||||||
assert.strictEqual('webp', info50.format);
|
|
||||||
fixtures.assertSimilar(fixtures.expected('webp-near-lossless-50.webp'), data50, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should use near-lossless when both lossless and nearLossless are specified', function (done) {
|
|
||||||
sharp(fixtures.inputPngAlphaPremultiplicationSmall)
|
|
||||||
.webp({ nearLossless: true, quality: 50, lossless: true })
|
|
||||||
.toBuffer(function (err50, data50, info50) {
|
|
||||||
if (err50) throw err50;
|
|
||||||
assert.strictEqual(true, data50.length > 0);
|
|
||||||
assert.strictEqual('webp', info50.format);
|
|
||||||
fixtures.assertSimilar(fixtures.expected('webp-near-lossless-50.webp'), data50, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
it('Invalid output format', function (done) {
|
it('Invalid output format', function (done) {
|
||||||
let isValid = false;
|
let isValid = false;
|
||||||
try {
|
try {
|
||||||
@ -531,22 +375,6 @@ describe('Input/output', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('TIFF file input with invalid page fails gracefully', function (done) {
|
|
||||||
sharp(fixtures.inputTiffMultipage, { page: 2 })
|
|
||||||
.toBuffer(function (err) {
|
|
||||||
assert.strictEqual(true, !!err);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('TIFF buffer input with invalid page fails gracefully', function (done) {
|
|
||||||
sharp(fs.readFileSync(fixtures.inputTiffMultipage), { page: 2 })
|
|
||||||
.toBuffer(function (err) {
|
|
||||||
assert.strictEqual(true, !!err);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Output filename with unknown extension', function () {
|
describe('Output filename with unknown extension', function () {
|
||||||
it('Match JPEG input', function (done) {
|
it('Match JPEG input', function (done) {
|
||||||
sharp(fixtures.inputJpg)
|
sharp(fixtures.inputJpg)
|
||||||
@ -628,669 +456,6 @@ describe('Input/output', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Without chroma subsampling generates larger file', function (done) {
|
|
||||||
// First generate with chroma subsampling (default)
|
|
||||||
sharp(fixtures.inputJpg)
|
|
||||||
.resize(320, 240)
|
|
||||||
.jpeg({ chromaSubsampling: '4:2:0' })
|
|
||||||
.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)
|
|
||||||
.jpeg({ chromaSubsampling: '4:4:4' })
|
|
||||||
.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();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Invalid JPEG chromaSubsampling value throws error', function () {
|
|
||||||
assert.throws(function () {
|
|
||||||
sharp().jpeg({ chromaSubsampling: '4:2:2' });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Trellis quantisation', function (done) {
|
|
||||||
// First generate without
|
|
||||||
sharp(fixtures.inputJpg)
|
|
||||||
.resize(320, 240)
|
|
||||||
.jpeg({ 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)
|
|
||||||
.jpeg({ trellisQuantization: true })
|
|
||||||
.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', function (done) {
|
|
||||||
// First generate without
|
|
||||||
sharp(fixtures.inputJpg)
|
|
||||||
.resize(320, 240)
|
|
||||||
.jpeg({ 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)
|
|
||||||
.jpeg({ overshootDeringing: true })
|
|
||||||
.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 generates different output length', function (done) {
|
|
||||||
// First generate without
|
|
||||||
sharp(fixtures.inputJpg)
|
|
||||||
.resize(320, 240)
|
|
||||||
.jpeg({ 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)
|
|
||||||
.jpeg({ optimizeScans: true })
|
|
||||||
.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.notStrictEqual(withData.length, withoutData.length);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Optimise coding generates smaller output length', function (done) {
|
|
||||||
// First generate with optimize coding enabled (default)
|
|
||||||
sharp(fixtures.inputJpg)
|
|
||||||
.resize(320, 240)
|
|
||||||
.jpeg()
|
|
||||||
.toBuffer(function (err, withOptimiseCoding, withInfo) {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual(true, withOptimiseCoding.length > 0);
|
|
||||||
assert.strictEqual(withOptimiseCoding.length, withInfo.size);
|
|
||||||
assert.strictEqual('jpeg', withInfo.format);
|
|
||||||
assert.strictEqual(320, withInfo.width);
|
|
||||||
assert.strictEqual(240, withInfo.height);
|
|
||||||
// Then generate with coding disabled
|
|
||||||
sharp(fixtures.inputJpg)
|
|
||||||
.resize(320, 240)
|
|
||||||
.jpeg({ optimizeCoding: false })
|
|
||||||
.toBuffer(function (err, withoutOptimiseCoding, withoutInfo) {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual(true, withoutOptimiseCoding.length > 0);
|
|
||||||
assert.strictEqual(withoutOptimiseCoding.length, withoutInfo.size);
|
|
||||||
assert.strictEqual('jpeg', withoutInfo.format);
|
|
||||||
assert.strictEqual(320, withoutInfo.width);
|
|
||||||
assert.strictEqual(240, withoutInfo.height);
|
|
||||||
// Verify optimised image is of a smaller size
|
|
||||||
assert.strictEqual(true, withOptimiseCoding.length < withoutOptimiseCoding.length);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Specifying quantisation table provides different JPEG', function (done) {
|
|
||||||
// First generate with default quantisation table
|
|
||||||
sharp(fixtures.inputJpg)
|
|
||||||
.resize(320, 240)
|
|
||||||
.jpeg({ optimiseCoding: false })
|
|
||||||
.toBuffer(function (err, withDefaultQuantisationTable, withInfo) {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual(true, withDefaultQuantisationTable.length > 0);
|
|
||||||
assert.strictEqual(withDefaultQuantisationTable.length, withInfo.size);
|
|
||||||
assert.strictEqual('jpeg', withInfo.format);
|
|
||||||
assert.strictEqual(320, withInfo.width);
|
|
||||||
assert.strictEqual(240, withInfo.height);
|
|
||||||
// Then generate with different quantisation table
|
|
||||||
sharp(fixtures.inputJpg)
|
|
||||||
.resize(320, 240)
|
|
||||||
.jpeg({ optimiseCoding: false, quantisationTable: 3 })
|
|
||||||
.toBuffer(function (err, withQuantTable3, withoutInfo) {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual(true, withQuantTable3.length > 0);
|
|
||||||
assert.strictEqual(withQuantTable3.length, withoutInfo.size);
|
|
||||||
assert.strictEqual('jpeg', withoutInfo.format);
|
|
||||||
assert.strictEqual(320, withoutInfo.width);
|
|
||||||
assert.strictEqual(240, withoutInfo.height);
|
|
||||||
|
|
||||||
// Verify image is same (as mozjpeg may not be present) size or less
|
|
||||||
assert.strictEqual(true, withQuantTable3.length <= withDefaultQuantisationTable.length);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Convert SVG to PNG at default 72DPI', function (done) {
|
|
||||||
sharp(fixtures.inputSvg)
|
|
||||||
.resize(1024)
|
|
||||||
.extract({ left: 290, top: 760, width: 40, height: 40 })
|
|
||||||
.toFormat('png')
|
|
||||||
.toBuffer(function (err, data, info) {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual('png', info.format);
|
|
||||||
assert.strictEqual(40, info.width);
|
|
||||||
assert.strictEqual(40, info.height);
|
|
||||||
fixtures.assertSimilar(fixtures.expected('svg72.png'), data, function (err) {
|
|
||||||
if (err) throw err;
|
|
||||||
sharp(data).metadata(function (err, info) {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual(72, info.density);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Convert SVG to PNG at 1200DPI', function (done) {
|
|
||||||
sharp(fixtures.inputSvg, { density: 1200 })
|
|
||||||
.resize(1024)
|
|
||||||
.extract({ left: 290, top: 760, width: 40, height: 40 })
|
|
||||||
.toFormat('png')
|
|
||||||
.toBuffer(function (err, data, info) {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual('png', info.format);
|
|
||||||
assert.strictEqual(40, info.width);
|
|
||||||
assert.strictEqual(40, info.height);
|
|
||||||
fixtures.assertSimilar(fixtures.expected('svg1200.png'), data, function (err) {
|
|
||||||
if (err) throw err;
|
|
||||||
sharp(data).metadata(function (err, info) {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual(1200, info.density);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Convert SVG to PNG at 14.4DPI', function (done) {
|
|
||||||
sharp(fixtures.inputSvg, { density: 14.4 })
|
|
||||||
.toFormat('png')
|
|
||||||
.toBuffer(function (err, data, info) {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual('png', info.format);
|
|
||||||
assert.strictEqual(20, info.width);
|
|
||||||
assert.strictEqual(20, info.height);
|
|
||||||
fixtures.assertSimilar(fixtures.expected('svg14.4.png'), data, function (err) {
|
|
||||||
if (err) throw err;
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Convert SVG with embedded images to PNG, respecting dimensions, autoconvert to PNG', function (done) {
|
|
||||||
sharp(fixtures.inputSvgWithEmbeddedImages)
|
|
||||||
.toBuffer(function (err, data, info) {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual('png', info.format);
|
|
||||||
assert.strictEqual(480, info.width);
|
|
||||||
assert.strictEqual(360, info.height);
|
|
||||||
assert.strictEqual(4, info.channels);
|
|
||||||
fixtures.assertSimilar(fixtures.expected('svg-embedded.png'), data, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Load TIFF from Buffer', function (done) {
|
|
||||||
const 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();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Load multi-page TIFF\'s from file', function (done) {
|
|
||||||
sharp(fixtures.inputTiffMultipage) // defaults to page 0
|
|
||||||
.jpeg()
|
|
||||||
.toBuffer(function (err, defaultData, defaultInfo) {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual(true, defaultData.length > 0);
|
|
||||||
assert.strictEqual(defaultData.length, defaultInfo.size);
|
|
||||||
assert.strictEqual('jpeg', defaultInfo.format);
|
|
||||||
|
|
||||||
sharp(fixtures.inputTiffMultipage, { page: 1 }) // 50%-scale copy of page 0
|
|
||||||
.jpeg()
|
|
||||||
.toBuffer(function (err, scaledData, scaledInfo) {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual(true, scaledData.length > 0);
|
|
||||||
assert.strictEqual(scaledData.length, scaledInfo.size);
|
|
||||||
assert.strictEqual('jpeg', scaledInfo.format);
|
|
||||||
assert.strictEqual(defaultInfo.width, scaledInfo.width * 2);
|
|
||||||
assert.strictEqual(defaultInfo.height, scaledInfo.height * 2);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Load multi-page TIFF\'s from Buffer', function (done) {
|
|
||||||
const inputTiffBuffer = fs.readFileSync(fixtures.inputTiffMultipage);
|
|
||||||
sharp(inputTiffBuffer) // defaults to page 0
|
|
||||||
.jpeg()
|
|
||||||
.toBuffer(function (err, defaultData, defaultInfo) {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual(true, defaultData.length > 0);
|
|
||||||
assert.strictEqual(defaultData.length, defaultInfo.size);
|
|
||||||
assert.strictEqual('jpeg', defaultInfo.format);
|
|
||||||
|
|
||||||
sharp(inputTiffBuffer, { page: 1 }) // 50%-scale copy of page 0
|
|
||||||
.jpeg()
|
|
||||||
.toBuffer(function (err, scaledData, scaledInfo) {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual(true, scaledData.length > 0);
|
|
||||||
assert.strictEqual(scaledData.length, scaledInfo.size);
|
|
||||||
assert.strictEqual('jpeg', scaledInfo.format);
|
|
||||||
assert.strictEqual(defaultInfo.width, scaledInfo.width * 2);
|
|
||||||
assert.strictEqual(defaultInfo.height, scaledInfo.height * 2);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Save TIFF to Buffer', function (done) {
|
|
||||||
sharp(fixtures.inputTiff)
|
|
||||||
.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('tiff', info.format);
|
|
||||||
assert.strictEqual(320, info.width);
|
|
||||||
assert.strictEqual(240, info.height);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Invalid WebP quality throws error', function () {
|
|
||||||
assert.throws(function () {
|
|
||||||
sharp().webp({ quality: 101 });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Invalid WebP alpha quality throws error', function () {
|
|
||||||
assert.throws(function () {
|
|
||||||
sharp().webp({ alphaQuality: 101 });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Invalid TIFF quality throws error', function () {
|
|
||||||
assert.throws(function () {
|
|
||||||
sharp().tiff({ quality: 101 });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Missing TIFF quality does not throw error', function () {
|
|
||||||
assert.doesNotThrow(function () {
|
|
||||||
sharp().tiff();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Not squashing TIFF to a bit depth of 1 should not change the file size', function (done) {
|
|
||||||
const startSize = fs.statSync(fixtures.inputTiff8BitDepth).size;
|
|
||||||
sharp(fixtures.inputTiff8BitDepth)
|
|
||||||
.toColourspace('b-w') // can only squash 1 band uchar images
|
|
||||||
.tiff({
|
|
||||||
squash: false,
|
|
||||||
compression: 'none',
|
|
||||||
predictor: 'none'
|
|
||||||
})
|
|
||||||
.toFile(fixtures.outputTiff, (err, info) => {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual('tiff', info.format);
|
|
||||||
assert(info.size === startSize);
|
|
||||||
rimraf(fixtures.outputTiff, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Squashing TIFF to a bit depth of 1 should significantly reduce file size', function (done) {
|
|
||||||
const startSize = fs.statSync(fixtures.inputTiff8BitDepth).size;
|
|
||||||
sharp(fixtures.inputTiff8BitDepth)
|
|
||||||
.toColourspace('b-w') // can only squash 1 band uchar images
|
|
||||||
.tiff({
|
|
||||||
squash: true,
|
|
||||||
compression: 'none',
|
|
||||||
predictor: 'none'
|
|
||||||
})
|
|
||||||
.toFile(fixtures.outputTiff, (err, info) => {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual('tiff', info.format);
|
|
||||||
assert(info.size < (startSize / 2));
|
|
||||||
rimraf(fixtures.outputTiff, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Invalid TIFF squash value throws error', function () {
|
|
||||||
assert.throws(function () {
|
|
||||||
sharp().tiff({ squash: 'true' });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('TIFF setting xres and yres on file', function (done) {
|
|
||||||
const res = 1000.0; // inputTiff has a dpi of 300 (res*2.54)
|
|
||||||
sharp(fixtures.inputTiff)
|
|
||||||
.tiff({
|
|
||||||
xres: (res),
|
|
||||||
yres: (res)
|
|
||||||
})
|
|
||||||
.toFile(fixtures.outputTiff, (err, info) => {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual('tiff', info.format);
|
|
||||||
sharp(fixtures.outputTiff).metadata(function (err, metadata) {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual(metadata.density, res * 2.54); // convert to dpi
|
|
||||||
rimraf(fixtures.outputTiff, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('TIFF setting xres and yres on buffer', function (done) {
|
|
||||||
const res = 1000.0; // inputTiff has a dpi of 300 (res*2.54)
|
|
||||||
sharp(fixtures.inputTiff)
|
|
||||||
.tiff({
|
|
||||||
xres: (res),
|
|
||||||
yres: (res)
|
|
||||||
})
|
|
||||||
.toBuffer(function (err, data, info) {
|
|
||||||
if (err) throw err;
|
|
||||||
sharp(data).metadata(function (err, metadata) {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual(metadata.density, res * 2.54); // convert to dpi
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('TIFF invalid xres value should throw an error', function () {
|
|
||||||
assert.throws(function () {
|
|
||||||
sharp().tiff({ xres: '1000.0' });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('TIFF invalid yres value should throw an error', function () {
|
|
||||||
assert.throws(function () {
|
|
||||||
sharp().tiff({ yres: '1000.0' });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('TIFF lzw compression with horizontal predictor shrinks test file', function (done) {
|
|
||||||
const startSize = fs.statSync(fixtures.inputTiffUncompressed).size;
|
|
||||||
sharp(fixtures.inputTiffUncompressed)
|
|
||||||
.tiff({
|
|
||||||
compression: 'lzw',
|
|
||||||
predictor: 'horizontal'
|
|
||||||
})
|
|
||||||
.toFile(fixtures.outputTiff, (err, info) => {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual('tiff', info.format);
|
|
||||||
assert(info.size < startSize);
|
|
||||||
rimraf(fixtures.outputTiff, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('TIFF ccittfax4 compression shrinks b-w test file', function (done) {
|
|
||||||
const startSize = fs.statSync(fixtures.inputTiff).size;
|
|
||||||
sharp(fixtures.inputTiff)
|
|
||||||
.toColourspace('b-w')
|
|
||||||
.tiff({
|
|
||||||
squash: true,
|
|
||||||
compression: 'ccittfax4'
|
|
||||||
})
|
|
||||||
.toFile(fixtures.outputTiff, (err, info) => {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual('tiff', info.format);
|
|
||||||
assert(info.size < startSize);
|
|
||||||
rimraf(fixtures.outputTiff, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('TIFF deflate compression with horizontal predictor shrinks test file', function (done) {
|
|
||||||
const startSize = fs.statSync(fixtures.inputTiffUncompressed).size;
|
|
||||||
sharp(fixtures.inputTiffUncompressed)
|
|
||||||
.tiff({
|
|
||||||
compression: 'deflate',
|
|
||||||
predictor: 'horizontal'
|
|
||||||
})
|
|
||||||
.toFile(fixtures.outputTiff, (err, info) => {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual('tiff', info.format);
|
|
||||||
assert(info.size < startSize);
|
|
||||||
rimraf(fixtures.outputTiff, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('TIFF deflate compression with float predictor shrinks test file', function (done) {
|
|
||||||
const startSize = fs.statSync(fixtures.inputTiffUncompressed).size;
|
|
||||||
sharp(fixtures.inputTiffUncompressed)
|
|
||||||
.tiff({
|
|
||||||
compression: 'deflate',
|
|
||||||
predictor: 'float'
|
|
||||||
})
|
|
||||||
.toFile(fixtures.outputTiff, (err, info) => {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual('tiff', info.format);
|
|
||||||
assert(info.size < startSize);
|
|
||||||
rimraf(fixtures.outputTiff, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('TIFF deflate compression without predictor shrinks test file', function (done) {
|
|
||||||
const startSize = fs.statSync(fixtures.inputTiffUncompressed).size;
|
|
||||||
sharp(fixtures.inputTiffUncompressed)
|
|
||||||
.tiff({
|
|
||||||
compression: 'deflate',
|
|
||||||
predictor: 'none'
|
|
||||||
})
|
|
||||||
.toFile(fixtures.outputTiff, (err, info) => {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual('tiff', info.format);
|
|
||||||
assert(info.size < startSize);
|
|
||||||
rimraf(fixtures.outputTiff, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('TIFF jpeg compression shrinks test file', function (done) {
|
|
||||||
const startSize = fs.statSync(fixtures.inputTiffUncompressed).size;
|
|
||||||
sharp(fixtures.inputTiffUncompressed)
|
|
||||||
.tiff({
|
|
||||||
compression: 'jpeg'
|
|
||||||
})
|
|
||||||
.toFile(fixtures.outputTiff, (err, info) => {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual('tiff', info.format);
|
|
||||||
assert(info.size < startSize);
|
|
||||||
rimraf(fixtures.outputTiff, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('TIFF none compression does not throw error', function () {
|
|
||||||
assert.doesNotThrow(function () {
|
|
||||||
sharp().tiff({ compression: 'none' });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('TIFF lzw compression does not throw error', function () {
|
|
||||||
assert.doesNotThrow(function () {
|
|
||||||
sharp().tiff({ compression: 'lzw' });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('TIFF deflate compression does not throw error', function () {
|
|
||||||
assert.doesNotThrow(function () {
|
|
||||||
sharp().tiff({ compression: 'deflate' });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('TIFF invalid compression option throws', function () {
|
|
||||||
assert.throws(function () {
|
|
||||||
sharp().tiff({ compression: 0 });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('TIFF invalid compression option throws', function () {
|
|
||||||
assert.throws(function () {
|
|
||||||
sharp().tiff({ compression: 'a' });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('TIFF invalid predictor option throws', function () {
|
|
||||||
assert.throws(function () {
|
|
||||||
sharp().tiff({ predictor: 'a' });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('TIFF horizontal predictor does not throw error', function () {
|
|
||||||
assert.doesNotThrow(function () {
|
|
||||||
sharp().tiff({ predictor: 'horizontal' });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('TIFF float predictor does not throw error', function () {
|
|
||||||
assert.doesNotThrow(function () {
|
|
||||||
sharp().tiff({ predictor: 'float' });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('TIFF none predictor does not throw error', function () {
|
|
||||||
assert.doesNotThrow(function () {
|
|
||||||
sharp().tiff({ predictor: 'none' });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('TIFF tiled pyramid image without compression enlarges test file', function (done) {
|
|
||||||
const startSize = fs.statSync(fixtures.inputTiffUncompressed).size;
|
|
||||||
sharp(fixtures.inputTiffUncompressed)
|
|
||||||
.tiff({
|
|
||||||
compression: 'none',
|
|
||||||
pyramid: true,
|
|
||||||
tile: true,
|
|
||||||
tileHeight: 256,
|
|
||||||
tileWidth: 256
|
|
||||||
})
|
|
||||||
.toFile(fixtures.outputTiff, (err, info) => {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual('tiff', info.format);
|
|
||||||
assert(info.size > startSize);
|
|
||||||
rimraf(fixtures.outputTiff, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('TIFF pyramid true value does not throw error', function () {
|
|
||||||
assert.doesNotThrow(function () {
|
|
||||||
sharp().tiff({ pyramid: true });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Invalid TIFF pyramid value throws error', function () {
|
|
||||||
assert.throws(function () {
|
|
||||||
sharp().tiff({ pyramid: 'true' });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Invalid TIFF tile value throws error', function () {
|
|
||||||
assert.throws(function () {
|
|
||||||
sharp().tiff({ tile: 'true' });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('TIFF tile true value does not throw error', function () {
|
|
||||||
assert.doesNotThrow(function () {
|
|
||||||
sharp().tiff({ tile: true });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Valid TIFF tileHeight value does not throw error', function () {
|
|
||||||
assert.doesNotThrow(function () {
|
|
||||||
sharp().tiff({ tileHeight: 512 });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Valid TIFF tileWidth value does not throw error', function () {
|
|
||||||
assert.doesNotThrow(function () {
|
|
||||||
sharp().tiff({ tileWidth: 512 });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Invalid TIFF tileHeight value throws error', function () {
|
|
||||||
assert.throws(function () {
|
|
||||||
sharp().tiff({ tileHeight: '256' });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Invalid TIFF tileWidth value throws error', function () {
|
|
||||||
assert.throws(function () {
|
|
||||||
sharp().tiff({ tileWidth: '256' });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Invalid TIFF tileHeight value throws error', function () {
|
|
||||||
assert.throws(function () {
|
|
||||||
sharp().tiff({ tileHeight: 0 });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Invalid TIFF tileWidth value throws error', function () {
|
|
||||||
assert.throws(function () {
|
|
||||||
sharp().tiff({ tileWidth: 0 });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Input and output formats match when not forcing', function (done) {
|
it('Input and output formats match when not forcing', function (done) {
|
||||||
sharp(fixtures.inputJpg)
|
sharp(fixtures.inputJpg)
|
||||||
.resize(320, 240)
|
.resize(320, 240)
|
||||||
@ -1392,53 +557,6 @@ describe('Input/output', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
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) {
|
|
||||||
if (err) throw err;
|
|
||||||
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);
|
|
||||||
assert.strictEqual(1, info.channels);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it('3 channel colour image without transparency', function (done) {
|
|
||||||
sharp(fixtures.inputJpg)
|
|
||||||
.resize(32, 24)
|
|
||||||
.toFormat('raw')
|
|
||||||
.toBuffer(function (err, data, info) {
|
|
||||||
if (err) throw err;
|
|
||||||
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) {
|
|
||||||
if (err) throw err;
|
|
||||||
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 () {
|
describe('Limit pixel count of input image', function () {
|
||||||
it('Invalid fails - negative', function (done) {
|
it('Invalid fails - negative', function (done) {
|
||||||
let isValid = false;
|
let isValid = false;
|
||||||
@ -1530,88 +648,6 @@ describe('Input/output', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Raw pixel input', function () {
|
|
||||||
it('Missing options', function () {
|
|
||||||
assert.throws(function () {
|
|
||||||
sharp({ raw: {} });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it('Incomplete options', function () {
|
|
||||||
assert.throws(function () {
|
|
||||||
sharp({ raw: { width: 1, height: 1 } });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it('Invalid channels', function () {
|
|
||||||
assert.throws(function () {
|
|
||||||
sharp({ raw: { width: 1, height: 1, channels: 5 } });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it('Invalid height', function () {
|
|
||||||
assert.throws(function () {
|
|
||||||
sharp({ raw: { width: 1, height: 0, channels: 4 } });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it('Invalid width', function () {
|
|
||||||
assert.throws(function () {
|
|
||||||
sharp({ raw: { width: 'zoinks', height: 1, channels: 4 } });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it('RGB', function (done) {
|
|
||||||
// Convert to raw pixel data
|
|
||||||
sharp(fixtures.inputJpg)
|
|
||||||
.resize(256)
|
|
||||||
.raw()
|
|
||||||
.toBuffer(function (err, data, info) {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual(256, info.width);
|
|
||||||
assert.strictEqual(209, info.height);
|
|
||||||
assert.strictEqual(3, info.channels);
|
|
||||||
// Convert back to JPEG
|
|
||||||
sharp(data, {
|
|
||||||
raw: {
|
|
||||||
width: info.width,
|
|
||||||
height: info.height,
|
|
||||||
channels: info.channels
|
|
||||||
} })
|
|
||||||
.jpeg()
|
|
||||||
.toBuffer(function (err, data, info) {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual(256, info.width);
|
|
||||||
assert.strictEqual(209, info.height);
|
|
||||||
assert.strictEqual(3, info.channels);
|
|
||||||
fixtures.assertSimilar(fixtures.inputJpg, data, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it('RGBA', function (done) {
|
|
||||||
// Convert to raw pixel data
|
|
||||||
sharp(fixtures.inputPngOverlayLayer1)
|
|
||||||
.resize(256)
|
|
||||||
.raw()
|
|
||||||
.toBuffer(function (err, data, info) {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual(256, info.width);
|
|
||||||
assert.strictEqual(192, info.height);
|
|
||||||
assert.strictEqual(4, info.channels);
|
|
||||||
// Convert back to PNG
|
|
||||||
sharp(data, {
|
|
||||||
raw: {
|
|
||||||
width: info.width,
|
|
||||||
height: info.height,
|
|
||||||
channels: info.channels
|
|
||||||
} })
|
|
||||||
.png()
|
|
||||||
.toBuffer(function (err, data, info) {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual(256, info.width);
|
|
||||||
assert.strictEqual(192, info.height);
|
|
||||||
assert.strictEqual(4, info.channels);
|
|
||||||
fixtures.assertSimilar(fixtures.inputPngOverlayLayer1, data, { threshold: 7 }, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('create new image', function () {
|
describe('create new image', function () {
|
||||||
it('RGB', function (done) {
|
it('RGB', function (done) {
|
||||||
const create = {
|
const create = {
|
||||||
|
262
test/unit/jpeg.js
Normal file
262
test/unit/jpeg.js
Normal file
@ -0,0 +1,262 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const assert = require('assert');
|
||||||
|
|
||||||
|
const sharp = require('../../');
|
||||||
|
const fixtures = require('../fixtures');
|
||||||
|
|
||||||
|
describe('JPEG', function () {
|
||||||
|
it('JPEG quality', function (done) {
|
||||||
|
sharp(fixtures.inputJpg)
|
||||||
|
.resize(320, 240)
|
||||||
|
.jpeg({ 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)
|
||||||
|
.jpeg({ quality: 90 })
|
||||||
|
.toBuffer(function (err, buffer90) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert(buffer70.length < buffer80.length);
|
||||||
|
assert(buffer80.length < buffer90.length);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Invalid JPEG quality', function () {
|
||||||
|
[-1, 88.2, 'test'].forEach(function (quality) {
|
||||||
|
it(quality.toString(), function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp().jpeg({ quality: quality });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Invalid JPEG quantisation table', function () {
|
||||||
|
[-1, 88.2, 'test'].forEach(function (table) {
|
||||||
|
it(table.toString(), function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp().jpeg({ quantisationTable: table });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Progressive JPEG image', function (done) {
|
||||||
|
sharp(fixtures.inputJpg)
|
||||||
|
.resize(320, 240)
|
||||||
|
.jpeg({ 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)
|
||||||
|
.jpeg({ progressive: true })
|
||||||
|
.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('Without chroma subsampling generates larger file', function (done) {
|
||||||
|
// First generate with chroma subsampling (default)
|
||||||
|
sharp(fixtures.inputJpg)
|
||||||
|
.resize(320, 240)
|
||||||
|
.jpeg({ chromaSubsampling: '4:2:0' })
|
||||||
|
.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)
|
||||||
|
.jpeg({ chromaSubsampling: '4:4:4' })
|
||||||
|
.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();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Invalid JPEG chromaSubsampling value throws error', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp().jpeg({ chromaSubsampling: '4:2:2' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Trellis quantisation', function (done) {
|
||||||
|
// First generate without
|
||||||
|
sharp(fixtures.inputJpg)
|
||||||
|
.resize(320, 240)
|
||||||
|
.jpeg({ 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)
|
||||||
|
.jpeg({ trellisQuantization: true })
|
||||||
|
.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', function (done) {
|
||||||
|
// First generate without
|
||||||
|
sharp(fixtures.inputJpg)
|
||||||
|
.resize(320, 240)
|
||||||
|
.jpeg({ 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)
|
||||||
|
.jpeg({ overshootDeringing: true })
|
||||||
|
.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 generates different output length', function (done) {
|
||||||
|
// First generate without
|
||||||
|
sharp(fixtures.inputJpg)
|
||||||
|
.resize(320, 240)
|
||||||
|
.jpeg({ 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)
|
||||||
|
.jpeg({ optimizeScans: true })
|
||||||
|
.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.notStrictEqual(withData.length, withoutData.length);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Optimise coding generates smaller output length', function (done) {
|
||||||
|
// First generate with optimize coding enabled (default)
|
||||||
|
sharp(fixtures.inputJpg)
|
||||||
|
.resize(320, 240)
|
||||||
|
.jpeg()
|
||||||
|
.toBuffer(function (err, withOptimiseCoding, withInfo) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(true, withOptimiseCoding.length > 0);
|
||||||
|
assert.strictEqual(withOptimiseCoding.length, withInfo.size);
|
||||||
|
assert.strictEqual('jpeg', withInfo.format);
|
||||||
|
assert.strictEqual(320, withInfo.width);
|
||||||
|
assert.strictEqual(240, withInfo.height);
|
||||||
|
// Then generate with coding disabled
|
||||||
|
sharp(fixtures.inputJpg)
|
||||||
|
.resize(320, 240)
|
||||||
|
.jpeg({ optimizeCoding: false })
|
||||||
|
.toBuffer(function (err, withoutOptimiseCoding, withoutInfo) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(true, withoutOptimiseCoding.length > 0);
|
||||||
|
assert.strictEqual(withoutOptimiseCoding.length, withoutInfo.size);
|
||||||
|
assert.strictEqual('jpeg', withoutInfo.format);
|
||||||
|
assert.strictEqual(320, withoutInfo.width);
|
||||||
|
assert.strictEqual(240, withoutInfo.height);
|
||||||
|
// Verify optimised image is of a smaller size
|
||||||
|
assert.strictEqual(true, withOptimiseCoding.length < withoutOptimiseCoding.length);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Specifying quantisation table provides different JPEG', function (done) {
|
||||||
|
// First generate with default quantisation table
|
||||||
|
sharp(fixtures.inputJpg)
|
||||||
|
.resize(320, 240)
|
||||||
|
.jpeg({ optimiseCoding: false })
|
||||||
|
.toBuffer(function (err, withDefaultQuantisationTable, withInfo) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(true, withDefaultQuantisationTable.length > 0);
|
||||||
|
assert.strictEqual(withDefaultQuantisationTable.length, withInfo.size);
|
||||||
|
assert.strictEqual('jpeg', withInfo.format);
|
||||||
|
assert.strictEqual(320, withInfo.width);
|
||||||
|
assert.strictEqual(240, withInfo.height);
|
||||||
|
// Then generate with different quantisation table
|
||||||
|
sharp(fixtures.inputJpg)
|
||||||
|
.resize(320, 240)
|
||||||
|
.jpeg({ optimiseCoding: false, quantisationTable: 3 })
|
||||||
|
.toBuffer(function (err, withQuantTable3, withoutInfo) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(true, withQuantTable3.length > 0);
|
||||||
|
assert.strictEqual(withQuantTable3.length, withoutInfo.size);
|
||||||
|
assert.strictEqual('jpeg', withoutInfo.format);
|
||||||
|
assert.strictEqual(320, withoutInfo.width);
|
||||||
|
assert.strictEqual(240, withoutInfo.height);
|
||||||
|
|
||||||
|
// Verify image is same (as mozjpeg may not be present) size or less
|
||||||
|
assert.strictEqual(true, withQuantTable3.length <= withDefaultQuantisationTable.length);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -6,7 +6,7 @@ const assert = require('assert');
|
|||||||
const sharp = require('../../');
|
const sharp = require('../../');
|
||||||
const fixtures = require('../fixtures');
|
const fixtures = require('../fixtures');
|
||||||
|
|
||||||
describe('PNG output', function () {
|
describe('PNG', function () {
|
||||||
it('compression level is valid', function () {
|
it('compression level is valid', function () {
|
||||||
assert.doesNotThrow(function () {
|
assert.doesNotThrow(function () {
|
||||||
sharp().png({ compressionLevel: 0 });
|
sharp().png({ compressionLevel: 0 });
|
||||||
@ -77,6 +77,32 @@ describe('PNG output', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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)
|
||||||
|
.png({ progressive: true })
|
||||||
|
.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();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('Valid PNG libimagequant palette value does not throw error', function () {
|
it('Valid PNG libimagequant palette value does not throw error', function () {
|
||||||
assert.doesNotThrow(function () {
|
assert.doesNotThrow(function () {
|
||||||
sharp().png({ palette: false });
|
sharp().png({ palette: false });
|
||||||
|
145
test/unit/raw.js
Normal file
145
test/unit/raw.js
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const assert = require('assert');
|
||||||
|
|
||||||
|
const sharp = require('../../');
|
||||||
|
const fixtures = require('../fixtures');
|
||||||
|
|
||||||
|
describe('Raw pixel data', function () {
|
||||||
|
describe('Raw pixel input', function () {
|
||||||
|
it('Missing options', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp({ raw: {} });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Incomplete options', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp({ raw: { width: 1, height: 1 } });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Invalid channels', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp({ raw: { width: 1, height: 1, channels: 5 } });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Invalid height', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp({ raw: { width: 1, height: 0, channels: 4 } });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Invalid width', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp({ raw: { width: 'zoinks', height: 1, channels: 4 } });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('RGB', function (done) {
|
||||||
|
// Convert to raw pixel data
|
||||||
|
sharp(fixtures.inputJpg)
|
||||||
|
.resize(256)
|
||||||
|
.raw()
|
||||||
|
.toBuffer(function (err, data, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(256, info.width);
|
||||||
|
assert.strictEqual(209, info.height);
|
||||||
|
assert.strictEqual(3, info.channels);
|
||||||
|
// Convert back to JPEG
|
||||||
|
sharp(data, {
|
||||||
|
raw: {
|
||||||
|
width: info.width,
|
||||||
|
height: info.height,
|
||||||
|
channels: info.channels
|
||||||
|
} })
|
||||||
|
.jpeg()
|
||||||
|
.toBuffer(function (err, data, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(256, info.width);
|
||||||
|
assert.strictEqual(209, info.height);
|
||||||
|
assert.strictEqual(3, info.channels);
|
||||||
|
fixtures.assertSimilar(fixtures.inputJpg, data, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('RGBA', function (done) {
|
||||||
|
// Convert to raw pixel data
|
||||||
|
sharp(fixtures.inputPngOverlayLayer1)
|
||||||
|
.resize(256)
|
||||||
|
.raw()
|
||||||
|
.toBuffer(function (err, data, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(256, info.width);
|
||||||
|
assert.strictEqual(192, info.height);
|
||||||
|
assert.strictEqual(4, info.channels);
|
||||||
|
// Convert back to PNG
|
||||||
|
sharp(data, {
|
||||||
|
raw: {
|
||||||
|
width: info.width,
|
||||||
|
height: info.height,
|
||||||
|
channels: info.channels
|
||||||
|
} })
|
||||||
|
.png()
|
||||||
|
.toBuffer(function (err, data, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(256, info.width);
|
||||||
|
assert.strictEqual(192, info.height);
|
||||||
|
assert.strictEqual(4, info.channels);
|
||||||
|
fixtures.assertSimilar(fixtures.inputPngOverlayLayer1, data, { threshold: 7 }, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
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) {
|
||||||
|
if (err) throw err;
|
||||||
|
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);
|
||||||
|
assert.strictEqual(1, info.channels);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('3 channel colour image without transparency', function (done) {
|
||||||
|
sharp(fixtures.inputJpg)
|
||||||
|
.resize(32, 24)
|
||||||
|
.toFormat('raw')
|
||||||
|
.toBuffer(function (err, data, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
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) {
|
||||||
|
if (err) throw err;
|
||||||
|
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();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
77
test/unit/svg.js
Normal file
77
test/unit/svg.js
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const assert = require('assert');
|
||||||
|
|
||||||
|
const sharp = require('../../');
|
||||||
|
const fixtures = require('../fixtures');
|
||||||
|
|
||||||
|
describe('SVG input', function () {
|
||||||
|
it('Convert SVG to PNG at default 72DPI', function (done) {
|
||||||
|
sharp(fixtures.inputSvg)
|
||||||
|
.resize(1024)
|
||||||
|
.extract({ left: 290, top: 760, width: 40, height: 40 })
|
||||||
|
.toFormat('png')
|
||||||
|
.toBuffer(function (err, data, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual('png', info.format);
|
||||||
|
assert.strictEqual(40, info.width);
|
||||||
|
assert.strictEqual(40, info.height);
|
||||||
|
fixtures.assertSimilar(fixtures.expected('svg72.png'), data, function (err) {
|
||||||
|
if (err) throw err;
|
||||||
|
sharp(data).metadata(function (err, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(72, info.density);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Convert SVG to PNG at 1200DPI', function (done) {
|
||||||
|
sharp(fixtures.inputSvg, { density: 1200 })
|
||||||
|
.resize(1024)
|
||||||
|
.extract({ left: 290, top: 760, width: 40, height: 40 })
|
||||||
|
.toFormat('png')
|
||||||
|
.toBuffer(function (err, data, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual('png', info.format);
|
||||||
|
assert.strictEqual(40, info.width);
|
||||||
|
assert.strictEqual(40, info.height);
|
||||||
|
fixtures.assertSimilar(fixtures.expected('svg1200.png'), data, function (err) {
|
||||||
|
if (err) throw err;
|
||||||
|
sharp(data).metadata(function (err, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(1200, info.density);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Convert SVG to PNG at 14.4DPI', function (done) {
|
||||||
|
sharp(fixtures.inputSvg, { density: 14.4 })
|
||||||
|
.toFormat('png')
|
||||||
|
.toBuffer(function (err, data, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual('png', info.format);
|
||||||
|
assert.strictEqual(20, info.width);
|
||||||
|
assert.strictEqual(20, info.height);
|
||||||
|
fixtures.assertSimilar(fixtures.expected('svg14.4.png'), data, function (err) {
|
||||||
|
if (err) throw err;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Convert SVG with embedded images to PNG, respecting dimensions, autoconvert to PNG', function (done) {
|
||||||
|
sharp(fixtures.inputSvgWithEmbeddedImages)
|
||||||
|
.toBuffer(function (err, data, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual('png', info.format);
|
||||||
|
assert.strictEqual(480, info.width);
|
||||||
|
assert.strictEqual(360, info.height);
|
||||||
|
assert.strictEqual(4, info.channels);
|
||||||
|
fixtures.assertSimilar(fixtures.expected('svg-embedded.png'), data, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
424
test/unit/tiff.js
Normal file
424
test/unit/tiff.js
Normal file
@ -0,0 +1,424 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const fs = require('fs');
|
||||||
|
const assert = require('assert');
|
||||||
|
const rimraf = require('rimraf');
|
||||||
|
|
||||||
|
const sharp = require('../../');
|
||||||
|
const fixtures = require('../fixtures');
|
||||||
|
|
||||||
|
describe('TIFF', function () {
|
||||||
|
it('Load TIFF from Buffer', function (done) {
|
||||||
|
const 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();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Load multi-page TIFF from file', function (done) {
|
||||||
|
sharp(fixtures.inputTiffMultipage) // defaults to page 0
|
||||||
|
.jpeg()
|
||||||
|
.toBuffer(function (err, defaultData, defaultInfo) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(true, defaultData.length > 0);
|
||||||
|
assert.strictEqual(defaultData.length, defaultInfo.size);
|
||||||
|
assert.strictEqual('jpeg', defaultInfo.format);
|
||||||
|
|
||||||
|
sharp(fixtures.inputTiffMultipage, { page: 1 }) // 50%-scale copy of page 0
|
||||||
|
.jpeg()
|
||||||
|
.toBuffer(function (err, scaledData, scaledInfo) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(true, scaledData.length > 0);
|
||||||
|
assert.strictEqual(scaledData.length, scaledInfo.size);
|
||||||
|
assert.strictEqual('jpeg', scaledInfo.format);
|
||||||
|
assert.strictEqual(defaultInfo.width, scaledInfo.width * 2);
|
||||||
|
assert.strictEqual(defaultInfo.height, scaledInfo.height * 2);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Load multi-page TIFF from Buffer', function (done) {
|
||||||
|
const inputTiffBuffer = fs.readFileSync(fixtures.inputTiffMultipage);
|
||||||
|
sharp(inputTiffBuffer) // defaults to page 0
|
||||||
|
.jpeg()
|
||||||
|
.toBuffer(function (err, defaultData, defaultInfo) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(true, defaultData.length > 0);
|
||||||
|
assert.strictEqual(defaultData.length, defaultInfo.size);
|
||||||
|
assert.strictEqual('jpeg', defaultInfo.format);
|
||||||
|
|
||||||
|
sharp(inputTiffBuffer, { page: 1 }) // 50%-scale copy of page 0
|
||||||
|
.jpeg()
|
||||||
|
.toBuffer(function (err, scaledData, scaledInfo) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(true, scaledData.length > 0);
|
||||||
|
assert.strictEqual(scaledData.length, scaledInfo.size);
|
||||||
|
assert.strictEqual('jpeg', scaledInfo.format);
|
||||||
|
assert.strictEqual(defaultInfo.width, scaledInfo.width * 2);
|
||||||
|
assert.strictEqual(defaultInfo.height, scaledInfo.height * 2);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Save TIFF to Buffer', function (done) {
|
||||||
|
sharp(fixtures.inputTiff)
|
||||||
|
.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('tiff', info.format);
|
||||||
|
assert.strictEqual(320, info.width);
|
||||||
|
assert.strictEqual(240, info.height);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Invalid TIFF quality throws error', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp().tiff({ quality: 101 });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Missing TIFF quality does not throw error', function () {
|
||||||
|
assert.doesNotThrow(function () {
|
||||||
|
sharp().tiff();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Not squashing TIFF to a bit depth of 1 should not change the file size', function (done) {
|
||||||
|
const startSize = fs.statSync(fixtures.inputTiff8BitDepth).size;
|
||||||
|
sharp(fixtures.inputTiff8BitDepth)
|
||||||
|
.toColourspace('b-w') // can only squash 1 band uchar images
|
||||||
|
.tiff({
|
||||||
|
squash: false,
|
||||||
|
compression: 'none',
|
||||||
|
predictor: 'none'
|
||||||
|
})
|
||||||
|
.toFile(fixtures.outputTiff, (err, info) => {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual('tiff', info.format);
|
||||||
|
assert(info.size === startSize);
|
||||||
|
rimraf(fixtures.outputTiff, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Squashing TIFF to a bit depth of 1 should significantly reduce file size', function (done) {
|
||||||
|
const startSize = fs.statSync(fixtures.inputTiff8BitDepth).size;
|
||||||
|
sharp(fixtures.inputTiff8BitDepth)
|
||||||
|
.toColourspace('b-w') // can only squash 1 band uchar images
|
||||||
|
.tiff({
|
||||||
|
squash: true,
|
||||||
|
compression: 'none',
|
||||||
|
predictor: 'none'
|
||||||
|
})
|
||||||
|
.toFile(fixtures.outputTiff, (err, info) => {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual('tiff', info.format);
|
||||||
|
assert(info.size < (startSize / 2));
|
||||||
|
rimraf(fixtures.outputTiff, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Invalid TIFF squash value throws error', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp().tiff({ squash: 'true' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('TIFF setting xres and yres on file', function (done) {
|
||||||
|
const res = 1000.0; // inputTiff has a dpi of 300 (res*2.54)
|
||||||
|
sharp(fixtures.inputTiff)
|
||||||
|
.tiff({
|
||||||
|
xres: (res),
|
||||||
|
yres: (res)
|
||||||
|
})
|
||||||
|
.toFile(fixtures.outputTiff, (err, info) => {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual('tiff', info.format);
|
||||||
|
sharp(fixtures.outputTiff).metadata(function (err, metadata) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(metadata.density, res * 2.54); // convert to dpi
|
||||||
|
rimraf(fixtures.outputTiff, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('TIFF setting xres and yres on buffer', function (done) {
|
||||||
|
const res = 1000.0; // inputTiff has a dpi of 300 (res*2.54)
|
||||||
|
sharp(fixtures.inputTiff)
|
||||||
|
.tiff({
|
||||||
|
xres: (res),
|
||||||
|
yres: (res)
|
||||||
|
})
|
||||||
|
.toBuffer(function (err, data, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
sharp(data).metadata(function (err, metadata) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(metadata.density, res * 2.54); // convert to dpi
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('TIFF invalid xres value should throw an error', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp().tiff({ xres: '1000.0' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('TIFF invalid yres value should throw an error', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp().tiff({ yres: '1000.0' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('TIFF lzw compression with horizontal predictor shrinks test file', function (done) {
|
||||||
|
const startSize = fs.statSync(fixtures.inputTiffUncompressed).size;
|
||||||
|
sharp(fixtures.inputTiffUncompressed)
|
||||||
|
.tiff({
|
||||||
|
compression: 'lzw',
|
||||||
|
predictor: 'horizontal'
|
||||||
|
})
|
||||||
|
.toFile(fixtures.outputTiff, (err, info) => {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual('tiff', info.format);
|
||||||
|
assert(info.size < startSize);
|
||||||
|
rimraf(fixtures.outputTiff, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('TIFF ccittfax4 compression shrinks b-w test file', function (done) {
|
||||||
|
const startSize = fs.statSync(fixtures.inputTiff).size;
|
||||||
|
sharp(fixtures.inputTiff)
|
||||||
|
.toColourspace('b-w')
|
||||||
|
.tiff({
|
||||||
|
squash: true,
|
||||||
|
compression: 'ccittfax4'
|
||||||
|
})
|
||||||
|
.toFile(fixtures.outputTiff, (err, info) => {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual('tiff', info.format);
|
||||||
|
assert(info.size < startSize);
|
||||||
|
rimraf(fixtures.outputTiff, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('TIFF deflate compression with horizontal predictor shrinks test file', function (done) {
|
||||||
|
const startSize = fs.statSync(fixtures.inputTiffUncompressed).size;
|
||||||
|
sharp(fixtures.inputTiffUncompressed)
|
||||||
|
.tiff({
|
||||||
|
compression: 'deflate',
|
||||||
|
predictor: 'horizontal'
|
||||||
|
})
|
||||||
|
.toFile(fixtures.outputTiff, (err, info) => {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual('tiff', info.format);
|
||||||
|
assert(info.size < startSize);
|
||||||
|
rimraf(fixtures.outputTiff, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('TIFF deflate compression with float predictor shrinks test file', function (done) {
|
||||||
|
const startSize = fs.statSync(fixtures.inputTiffUncompressed).size;
|
||||||
|
sharp(fixtures.inputTiffUncompressed)
|
||||||
|
.tiff({
|
||||||
|
compression: 'deflate',
|
||||||
|
predictor: 'float'
|
||||||
|
})
|
||||||
|
.toFile(fixtures.outputTiff, (err, info) => {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual('tiff', info.format);
|
||||||
|
assert(info.size < startSize);
|
||||||
|
rimraf(fixtures.outputTiff, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('TIFF deflate compression without predictor shrinks test file', function (done) {
|
||||||
|
const startSize = fs.statSync(fixtures.inputTiffUncompressed).size;
|
||||||
|
sharp(fixtures.inputTiffUncompressed)
|
||||||
|
.tiff({
|
||||||
|
compression: 'deflate',
|
||||||
|
predictor: 'none'
|
||||||
|
})
|
||||||
|
.toFile(fixtures.outputTiff, (err, info) => {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual('tiff', info.format);
|
||||||
|
assert(info.size < startSize);
|
||||||
|
rimraf(fixtures.outputTiff, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('TIFF jpeg compression shrinks test file', function (done) {
|
||||||
|
const startSize = fs.statSync(fixtures.inputTiffUncompressed).size;
|
||||||
|
sharp(fixtures.inputTiffUncompressed)
|
||||||
|
.tiff({
|
||||||
|
compression: 'jpeg'
|
||||||
|
})
|
||||||
|
.toFile(fixtures.outputTiff, (err, info) => {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual('tiff', info.format);
|
||||||
|
assert(info.size < startSize);
|
||||||
|
rimraf(fixtures.outputTiff, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('TIFF none compression does not throw error', function () {
|
||||||
|
assert.doesNotThrow(function () {
|
||||||
|
sharp().tiff({ compression: 'none' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('TIFF lzw compression does not throw error', function () {
|
||||||
|
assert.doesNotThrow(function () {
|
||||||
|
sharp().tiff({ compression: 'lzw' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('TIFF deflate compression does not throw error', function () {
|
||||||
|
assert.doesNotThrow(function () {
|
||||||
|
sharp().tiff({ compression: 'deflate' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('TIFF invalid compression option throws', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp().tiff({ compression: 0 });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('TIFF invalid compression option throws', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp().tiff({ compression: 'a' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('TIFF invalid predictor option throws', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp().tiff({ predictor: 'a' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('TIFF horizontal predictor does not throw error', function () {
|
||||||
|
assert.doesNotThrow(function () {
|
||||||
|
sharp().tiff({ predictor: 'horizontal' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('TIFF float predictor does not throw error', function () {
|
||||||
|
assert.doesNotThrow(function () {
|
||||||
|
sharp().tiff({ predictor: 'float' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('TIFF none predictor does not throw error', function () {
|
||||||
|
assert.doesNotThrow(function () {
|
||||||
|
sharp().tiff({ predictor: 'none' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('TIFF tiled pyramid image without compression enlarges test file', function (done) {
|
||||||
|
const startSize = fs.statSync(fixtures.inputTiffUncompressed).size;
|
||||||
|
sharp(fixtures.inputTiffUncompressed)
|
||||||
|
.tiff({
|
||||||
|
compression: 'none',
|
||||||
|
pyramid: true,
|
||||||
|
tile: true,
|
||||||
|
tileHeight: 256,
|
||||||
|
tileWidth: 256
|
||||||
|
})
|
||||||
|
.toFile(fixtures.outputTiff, (err, info) => {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual('tiff', info.format);
|
||||||
|
assert(info.size > startSize);
|
||||||
|
rimraf(fixtures.outputTiff, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('TIFF pyramid true value does not throw error', function () {
|
||||||
|
assert.doesNotThrow(function () {
|
||||||
|
sharp().tiff({ pyramid: true });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Invalid TIFF pyramid value throws error', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp().tiff({ pyramid: 'true' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Invalid TIFF tile value throws error', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp().tiff({ tile: 'true' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('TIFF tile true value does not throw error', function () {
|
||||||
|
assert.doesNotThrow(function () {
|
||||||
|
sharp().tiff({ tile: true });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Valid TIFF tileHeight value does not throw error', function () {
|
||||||
|
assert.doesNotThrow(function () {
|
||||||
|
sharp().tiff({ tileHeight: 512 });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Valid TIFF tileWidth value does not throw error', function () {
|
||||||
|
assert.doesNotThrow(function () {
|
||||||
|
sharp().tiff({ tileWidth: 512 });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Invalid TIFF tileHeight value throws error', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp().tiff({ tileHeight: '256' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Invalid TIFF tileWidth value throws error', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp().tiff({ tileWidth: '256' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Invalid TIFF tileHeight value throws error', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp().tiff({ tileHeight: 0 });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Invalid TIFF tileWidth value throws error', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp().tiff({ tileWidth: 0 });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('TIFF file input with invalid page fails gracefully', function (done) {
|
||||||
|
sharp(fixtures.inputTiffMultipage, { page: 2 })
|
||||||
|
.toBuffer(function (err) {
|
||||||
|
assert.strictEqual(true, !!err);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('TIFF buffer input with invalid page fails gracefully', function (done) {
|
||||||
|
sharp(fs.readFileSync(fixtures.inputTiffMultipage), { page: 2 })
|
||||||
|
.toBuffer(function (err) {
|
||||||
|
assert.strictEqual(true, !!err);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
78
test/unit/webp.js
Normal file
78
test/unit/webp.js
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const assert = require('assert');
|
||||||
|
|
||||||
|
const sharp = require('../../');
|
||||||
|
const fixtures = require('../fixtures');
|
||||||
|
|
||||||
|
describe('WebP', function () {
|
||||||
|
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 WebP quality throws error', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp().webp({ quality: 101 });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Invalid WebP alpha quality throws error', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp().webp({ alphaQuality: 101 });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should work for webp alpha quality', function (done) {
|
||||||
|
sharp(fixtures.inputPngAlphaPremultiplicationSmall)
|
||||||
|
.webp({ alphaQuality: 80 })
|
||||||
|
.toBuffer(function (err, data, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(true, data.length > 0);
|
||||||
|
assert.strictEqual('webp', info.format);
|
||||||
|
fixtures.assertSimilar(fixtures.expected('webp-alpha-80.webp'), data, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should work for webp lossless', function (done) {
|
||||||
|
sharp(fixtures.inputPngAlphaPremultiplicationSmall)
|
||||||
|
.webp({ lossless: true })
|
||||||
|
.toBuffer(function (err, data, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(true, data.length > 0);
|
||||||
|
assert.strictEqual('webp', info.format);
|
||||||
|
fixtures.assertSimilar(fixtures.expected('webp-lossless.webp'), data, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should work for webp near-lossless', function (done) {
|
||||||
|
sharp(fixtures.inputPngAlphaPremultiplicationSmall)
|
||||||
|
.webp({ nearLossless: true, quality: 50 })
|
||||||
|
.toBuffer(function (err50, data50, info50) {
|
||||||
|
if (err50) throw err50;
|
||||||
|
assert.strictEqual(true, data50.length > 0);
|
||||||
|
assert.strictEqual('webp', info50.format);
|
||||||
|
fixtures.assertSimilar(fixtures.expected('webp-near-lossless-50.webp'), data50, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should use near-lossless when both lossless and nearLossless are specified', function (done) {
|
||||||
|
sharp(fixtures.inputPngAlphaPremultiplicationSmall)
|
||||||
|
.webp({ nearLossless: true, quality: 50, lossless: true })
|
||||||
|
.toBuffer(function (err50, data50, info50) {
|
||||||
|
if (err50) throw err50;
|
||||||
|
assert.strictEqual(true, data50.length > 0);
|
||||||
|
assert.strictEqual('webp', info50.format);
|
||||||
|
fixtures.assertSimilar(fixtures.expected('webp-near-lossless-50.webp'), data50, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user