diff --git a/lib/output.js b/lib/output.js index 055317ebb..2e63f53f3 100644 --- a/lib/output.js +++ b/lib/output.js @@ -229,7 +229,8 @@ const tiff = function tiff (options) { if (is.string(options.compression) && is.inArray(options.compression, ['lzw', 'deflate', 'jpeg', 'none'])) { this.options.tiffCompression = options.compression; } else { - throw new Error('Invalid compression option [' + options.compression + ']. Should be one of: lzw, deflate, jpeg, none'); + const message = `Invalid compression option "${options.compression}". Should be one of: lzw, deflate, jpeg, none`; + throw new Error(message); } } // predictor @@ -237,7 +238,8 @@ const tiff = function tiff (options) { if (is.string(options.predictor) && is.inArray(options.predictor, ['none', 'horizontal', 'float'])) { this.options.tiffPredictor = options.predictor; } else { - throw new Error('Invalid predictor option [' + options.predictor + ']. Should be one of: none, horizontal, float'); + const message = `Invalid predictor option "${options.predictor}". Should be one of: none, horizontal, float`; + throw new Error(message); } } return this._updateFormatOut('tiff', options); diff --git a/test/unit/io.js b/test/unit/io.js index 1f3508751..2a31d5a92 100644 --- a/test/unit/io.js +++ b/test/unit/io.js @@ -861,12 +861,15 @@ describe('Input/output', function () { }); }); - it('TIFF lzw compression shrinks test file', function (done) { + 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', force: true, + // note: lzw compression is imperfect and sometimes + // generates larger files, as it does with this input + // if no predictor is used. predictor: 'horizontal' }) .toFile(fixtures.outputTiff, (err, info) => { @@ -878,6 +881,56 @@ describe('Input/output', function () { }); }); + it('TIFF deflate compression with hoizontal predictor shrinks test file', function (done) { + const startSize = fs.statSync(fixtures.inputTiffUncompressed).size; + sharp(fixtures.inputTiffUncompressed) + .tiff({ + compression: 'deflate', + force: true, + predictor: 'horizontal' + }) + .toFile(fixtures.outputTiff, (err, info) => { + if (err) throw err; + assert.strictEqual('tiff', info.format); + assert(info.size < startSize); + fs.unlinkSync(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', + force: true, + predictor: 'none' + }) + .toFile(fixtures.outputTiff, (err, info) => { + if (err) throw err; + assert.strictEqual('tiff', info.format); + assert(info.size < startSize); + fs.unlinkSync(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', + force: true + }) + .toFile(fixtures.outputTiff, (err, info) => { + if (err) throw err; + assert.strictEqual('tiff', info.format); + assert(info.size < startSize); + fs.unlinkSync(fixtures.outputTiff); + done(); + }); + }); + it('TIFF none compression does not throw error', function () { assert.doesNotThrow(function () { sharp().tiff({ compression: 'none' });