From 984a9e653e4105cbb77fdd4cb17a8bbb5afe05eb Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Sun, 7 Mar 2021 15:55:38 +0000 Subject: [PATCH] Upgrade to libvips 8.10.6-alpha1 - Prebuilt binaries now include mozjpeg and libimagequant (BSD 2-Clause) - Prebuilt binaries limit AVIF support to the most common 8-bit depth - Add `mozjpeg` option to `jpeg` method, sets mozjpeg defaults - Reduce the default PNG `compressionLevel` to the more commonly used 6 --- docs/api-output.md | 48 ++++++++----- docs/changelog.md | 14 ++++ docs/install.md | 7 +- lib/constructor.js | 2 +- lib/output.js | 67 ++++++++++++------ package.json | 2 +- src/common.h | 4 +- src/pipeline.h | 2 +- ...frame12924_yuv420_10bpc_bt2020_pq_q50.avif | Bin 17264 -> 0 bytes test/fixtures/index.js | 2 +- ...smos12920_cicp1-13-6_yuv444_full_qp10.avif | Bin 0 -> 285949 bytes test/unit/jpeg.js | 20 ++++++ test/unit/png.js | 4 +- test/unit/tiff.js | 4 +- 14 files changed, 123 insertions(+), 53 deletions(-) delete mode 100644 test/fixtures/cosmos_frame12924_yuv420_10bpc_bt2020_pq_q50.avif create mode 100644 test/fixtures/sdr_cosmos12920_cicp1-13-6_yuv444_full_qp10.avif diff --git a/docs/api-output.md b/docs/api-output.md index db8229f1..c2a5344a 100644 --- a/docs/api-output.md +++ b/docs/api-output.md @@ -157,8 +157,6 @@ Returns **Sharp** Use these JPEG options for output image. -Some of these options require the use of a globally-installed libvips compiled with support for mozjpeg. - ### Parameters - `options` **[Object][6]?** output options @@ -167,12 +165,13 @@ Some of these options require the use of a globally-installed libvips compiled w - `options.chromaSubsampling` **[string][2]** set to '4:4:4' to prevent chroma subsampling otherwise defaults to '4:2:0' chroma subsampling (optional, default `'4:2:0'`) - `options.optimiseCoding` **[boolean][7]** optimise Huffman coding tables (optional, default `true`) - `options.optimizeCoding` **[boolean][7]** alternative spelling of optimiseCoding (optional, default `true`) - - `options.trellisQuantisation` **[boolean][7]** apply trellis quantisation, requires libvips compiled with support for mozjpeg (optional, default `false`) - - `options.overshootDeringing` **[boolean][7]** apply overshoot deringing, requires libvips compiled with support for mozjpeg (optional, default `false`) - - `options.optimiseScans` **[boolean][7]** optimise progressive scans, forces progressive, requires libvips compiled with support for mozjpeg (optional, default `false`) - - `options.optimizeScans` **[boolean][7]** alternative spelling of optimiseScans, requires libvips compiled with support for mozjpeg (optional, default `false`) - - `options.quantisationTable` **[number][9]** quantization table to use, integer 0-8, requires libvips compiled with support for mozjpeg (optional, default `0`) - - `options.quantizationTable` **[number][9]** alternative spelling of quantisationTable, requires libvips compiled with support for mozjpeg (optional, default `0`) + - `options.mozjpeg` **[boolean][7]** use mozjpeg defaults, equivalent to `{ trellisQuantisation: true, overshootDeringing: true, optimiseScans: true, quantisationTable: 3 }` (optional, default `false`) + - `options.trellisQuantisation` **[boolean][7]** apply trellis quantisation (optional, default `false`) + - `options.overshootDeringing` **[boolean][7]** apply overshoot deringing (optional, default `false`) + - `options.optimiseScans` **[boolean][7]** optimise progressive scans, forces progressive (optional, default `false`) + - `options.optimizeScans` **[boolean][7]** alternative spelling of optimiseScans (optional, default `false`) + - `options.quantisationTable` **[number][9]** quantization table to use, integer 0-8 (optional, default `0`) + - `options.quantizationTable` **[number][9]** alternative spelling of quantisationTable (optional, default `0`) - `options.force` **[boolean][7]** force JPEG output, otherwise attempt to use input format (optional, default `true`) ### Examples @@ -187,6 +186,13 @@ const data = await sharp(input) .toBuffer(); ``` +```javascript +// Use mozjpeg to reduce output JPEG file size (slower) +const data = await sharp(input) + .jpeg({ mozjpeg: true }) + .toBuffer(); +``` + - Throws **[Error][4]** Invalid options Returns **Sharp** @@ -195,33 +201,39 @@ Returns **Sharp** Use these PNG options for output image. -PNG output is always full colour at 8 or 16 bits per pixel. +By default, PNG output is full colour at 8 or 16 bits per pixel. Indexed PNG input at 1, 2 or 4 bits per pixel is converted to 8 bits per pixel. - -Some of these options require the use of a globally-installed libvips compiled with support for libimagequant (GPL). +Set `palette` to `true` for slower, indexed PNG output. ### Parameters - `options` **[Object][6]?** - `options.progressive` **[boolean][7]** use progressive (interlace) scan (optional, default `false`) - - `options.compressionLevel` **[number][9]** zlib compression level, 0-9 (optional, default `9`) + - `options.compressionLevel` **[number][9]** zlib compression level, 0 (fastest, largest) to 9 (slowest, smallest) (optional, default `6`) - `options.adaptiveFiltering` **[boolean][7]** use adaptive row filtering (optional, default `false`) - - `options.palette` **[boolean][7]** quantise to a palette-based image with alpha transparency support, requires libvips compiled with support for libimagequant (optional, default `false`) - - `options.quality` **[number][9]** use the lowest number of colours needed to achieve given quality, sets `palette` to `true`, requires libvips compiled with support for libimagequant (optional, default `100`) - - `options.colours` **[number][9]** maximum number of palette entries, sets `palette` to `true`, requires libvips compiled with support for libimagequant (optional, default `256`) - - `options.colors` **[number][9]** alternative spelling of `options.colours`, sets `palette` to `true`, requires libvips compiled with support for libimagequant (optional, default `256`) - - `options.dither` **[number][9]** level of Floyd-Steinberg error diffusion, sets `palette` to `true`, requires libvips compiled with support for libimagequant (optional, default `1.0`) + - `options.palette` **[boolean][7]** quantise to a palette-based image with alpha transparency support (optional, default `false`) + - `options.quality` **[number][9]** use the lowest number of colours needed to achieve given quality, sets `palette` to `true` (optional, default `100`) + - `options.colours` **[number][9]** maximum number of palette entries, sets `palette` to `true` (optional, default `256`) + - `options.colors` **[number][9]** alternative spelling of `options.colours`, sets `palette` to `true` (optional, default `256`) + - `options.dither` **[number][9]** level of Floyd-Steinberg error diffusion, sets `palette` to `true` (optional, default `1.0`) - `options.force` **[boolean][7]** force PNG output, otherwise attempt to use input format (optional, default `true`) ### Examples ```javascript -// Convert any input to PNG output +// Convert any input to full colour PNG output const data = await sharp(input) .png() .toBuffer(); ``` +```javascript +// Convert any input to indexed PNG output (slower) +const data = await sharp(input) + .png({ palette: true }) + .toBuffer(); +``` + - Throws **[Error][4]** Invalid options Returns **Sharp** diff --git a/docs/changelog.md b/docs/changelog.md index a213fb99..4ce8b643 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,5 +1,19 @@ # Changelog +## v0.28 - *bijou* + +Requires libvips v8.10.6 + +### v0.28.0 - TBD + +* Prebuilt binaries now include mozjpeg and libimagequant (BSD 2-Clause). + +* Prebuilt binaries limit AVIF support to the most common 8-bit depth. + +* Add `mozjpeg` option to `jpeg` method, sets mozjpeg defaults. + +* Reduce the default PNG `compressionLevel` to the more commonly used 6. + ## v0.27 - *avif* Requires libvips v8.10.5 diff --git a/docs/install.md b/docs/install.md index ec6e7f63..6145672f 100644 --- a/docs/install.md +++ b/docs/install.md @@ -20,10 +20,11 @@ Node.js v10+ on the most common platforms: * macOS x64 (>= 10.13) * Linux x64 (glibc >= 2.17, musl >=1.1.24 <1.2.0) * Linux ARM64 (glibc >= 2.29) +* Linux ARM64 (musl >= 1.1.24) * Windows x64 * Windows x86 -A ~9MB tarball containing libvips and its most commonly used dependencies +An ~8MB tarball containing libvips and its most commonly used dependencies is downloaded via HTTPS and stored within `node_modules/sharp/vendor` during `npm install`. This provides support for the @@ -31,16 +32,16 @@ JPEG, PNG, WebP, AVIF, TIFF, GIF (input) and SVG (input) image formats. The following platforms have prebuilt libvips but not sharp: +* macOS ARM64 * Linux ARMv6 * Linux ARMv7 (glibc >= 2.28) * Windows ARM64 The following platforms require compilation of both libvips and sharp from source: -* macOS ARM64 * Linux x86 * Linux x64 (glibc <= 2.16, includes RHEL/CentOS 6) -* Linux ARM64 (glibc <= 2.28, musl) +* Linux ARM64 (glibc <= 2.28) * Linux PowerPC * FreeBSD * OpenBSD diff --git a/lib/constructor.js b/lib/constructor.js index 817fc27e..54f2c878 100644 --- a/lib/constructor.js +++ b/lib/constructor.js @@ -244,7 +244,7 @@ const Sharp = function (input, options) { jpegOptimiseCoding: true, jpegQuantisationTable: 0, pngProgressive: false, - pngCompressionLevel: 9, + pngCompressionLevel: 6, pngAdaptiveFiltering: false, pngPalette: false, pngQuality: 100, diff --git a/lib/output.js b/lib/output.js index 6d309105..56de2da4 100644 --- a/lib/output.js +++ b/lib/output.js @@ -198,8 +198,6 @@ function toFormat (format, options) { /** * Use these JPEG options for output image. * - * Some of these options require the use of a globally-installed libvips compiled with support for mozjpeg. - * * @example * // Convert any input to very high quality JPEG output * const data = await sharp(input) @@ -209,18 +207,25 @@ function toFormat (format, options) { * }) * .toBuffer(); * + * @example + * // Use mozjpeg to reduce output JPEG file size (slower) + * const data = await sharp(input) + * .jpeg({ mozjpeg: true }) + * .toBuffer(); + * * @param {Object} [options] - output options * @param {number} [options.quality=80] - quality, integer 1-100 * @param {boolean} [options.progressive=false] - use progressive (interlace) scan * @param {string} [options.chromaSubsampling='4:2:0'] - set to '4:4:4' to prevent chroma subsampling otherwise defaults to '4:2:0' chroma subsampling * @param {boolean} [options.optimiseCoding=true] - optimise Huffman coding tables * @param {boolean} [options.optimizeCoding=true] - alternative spelling of optimiseCoding - * @param {boolean} [options.trellisQuantisation=false] - apply trellis quantisation, requires libvips compiled with support for mozjpeg - * @param {boolean} [options.overshootDeringing=false] - apply overshoot deringing, requires libvips compiled with support for mozjpeg - * @param {boolean} [options.optimiseScans=false] - optimise progressive scans, forces progressive, requires libvips compiled with support for mozjpeg - * @param {boolean} [options.optimizeScans=false] - alternative spelling of optimiseScans, requires libvips compiled with support for mozjpeg - * @param {number} [options.quantisationTable=0] - quantization table to use, integer 0-8, requires libvips compiled with support for mozjpeg - * @param {number} [options.quantizationTable=0] - alternative spelling of quantisationTable, requires libvips compiled with support for mozjpeg + * @param {boolean} [options.mozjpeg=false] - use mozjpeg defaults, equivalent to `{ trellisQuantisation: true, overshootDeringing: true, optimiseScans: true, quantisationTable: 3 }` + * @param {boolean} [options.trellisQuantisation=false] - apply trellis quantisation + * @param {boolean} [options.overshootDeringing=false] - apply overshoot deringing + * @param {boolean} [options.optimiseScans=false] - optimise progressive scans, forces progressive + * @param {boolean} [options.optimizeScans=false] - alternative spelling of optimiseScans + * @param {number} [options.quantisationTable=0] - quantization table to use, integer 0-8 + * @param {number} [options.quantizationTable=0] - alternative spelling of quantisationTable * @param {boolean} [options.force=true] - force JPEG output, otherwise attempt to use input format * @returns {Sharp} * @throws {Error} Invalid options @@ -244,6 +249,23 @@ function jpeg (options) { throw is.invalidParameterError('chromaSubsampling', 'one of: 4:2:0, 4:4:4', options.chromaSubsampling); } } + const optimiseCoding = is.bool(options.optimizeCoding) ? options.optimizeCoding : options.optimiseCoding; + if (is.defined(optimiseCoding)) { + this._setBooleanOption('jpegOptimiseCoding', optimiseCoding); + } + if (is.defined(options.mozjpeg)) { + if (is.bool(options.mozjpeg)) { + if (options.mozjpeg) { + this.options.jpegTrellisQuantisation = true; + this.options.jpegOvershootDeringing = true; + this.options.jpegOptimiseScans = true; + this.options.jpegProgressive = true; + this.options.jpegQuantisationTable = 3; + } + } else { + throw is.invalidParameterError('mozjpeg', 'boolean', options.mozjpeg); + } + } const trellisQuantisation = is.bool(options.trellisQuantization) ? options.trellisQuantization : options.trellisQuantisation; if (is.defined(trellisQuantisation)) { this._setBooleanOption('jpegTrellisQuantisation', trellisQuantisation); @@ -258,10 +280,6 @@ function jpeg (options) { this.options.jpegProgressive = true; } } - const optimiseCoding = is.bool(options.optimizeCoding) ? options.optimizeCoding : options.optimiseCoding; - if (is.defined(optimiseCoding)) { - this._setBooleanOption('jpegOptimiseCoding', optimiseCoding); - } const quantisationTable = is.number(options.quantizationTable) ? options.quantizationTable : options.quantisationTable; if (is.defined(quantisationTable)) { if (is.integer(quantisationTable) && is.inRange(quantisationTable, 0, 8)) { @@ -277,26 +295,31 @@ function jpeg (options) { /** * Use these PNG options for output image. * - * PNG output is always full colour at 8 or 16 bits per pixel. + * By default, PNG output is full colour at 8 or 16 bits per pixel. * Indexed PNG input at 1, 2 or 4 bits per pixel is converted to 8 bits per pixel. - * - * Some of these options require the use of a globally-installed libvips compiled with support for libimagequant (GPL). + * Set `palette` to `true` for slower, indexed PNG output. * * @example - * // Convert any input to PNG output + * // Convert any input to full colour PNG output * const data = await sharp(input) * .png() * .toBuffer(); * + * @example + * // Convert any input to indexed PNG output (slower) + * const data = await sharp(input) + * .png({ palette: true }) + * .toBuffer(); + * * @param {Object} [options] * @param {boolean} [options.progressive=false] - use progressive (interlace) scan - * @param {number} [options.compressionLevel=9] - zlib compression level, 0-9 + * @param {number} [options.compressionLevel=6] - zlib compression level, 0 (fastest, largest) to 9 (slowest, smallest) * @param {boolean} [options.adaptiveFiltering=false] - use adaptive row filtering - * @param {boolean} [options.palette=false] - quantise to a palette-based image with alpha transparency support, requires libvips compiled with support for libimagequant - * @param {number} [options.quality=100] - use the lowest number of colours needed to achieve given quality, sets `palette` to `true`, requires libvips compiled with support for libimagequant - * @param {number} [options.colours=256] - maximum number of palette entries, sets `palette` to `true`, requires libvips compiled with support for libimagequant - * @param {number} [options.colors=256] - alternative spelling of `options.colours`, sets `palette` to `true`, requires libvips compiled with support for libimagequant - * @param {number} [options.dither=1.0] - level of Floyd-Steinberg error diffusion, sets `palette` to `true`, requires libvips compiled with support for libimagequant + * @param {boolean} [options.palette=false] - quantise to a palette-based image with alpha transparency support + * @param {number} [options.quality=100] - use the lowest number of colours needed to achieve given quality, sets `palette` to `true` + * @param {number} [options.colours=256] - maximum number of palette entries, sets `palette` to `true` + * @param {number} [options.colors=256] - alternative spelling of `options.colours`, sets `palette` to `true` + * @param {number} [options.dither=1.0] - level of Floyd-Steinberg error diffusion, sets `palette` to `true` * @param {boolean} [options.force=true] - force PNG output, otherwise attempt to use input format * @returns {Sharp} * @throws {Error} Invalid options diff --git a/package.json b/package.json index 65f9ba81..6665e762 100644 --- a/package.json +++ b/package.json @@ -143,7 +143,7 @@ }, "license": "Apache-2.0", "config": { - "libvips": "8.10.5", + "libvips": "8.10.6-alpha1", "runtime": "napi", "target": 3 }, diff --git a/src/common.h b/src/common.h index b8a0d929..74eadded 100644 --- a/src/common.h +++ b/src/common.h @@ -26,8 +26,8 @@ #if (VIPS_MAJOR_VERSION < 8) || \ (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION < 10) || \ - (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION == 10 && VIPS_MICRO_VERSION < 5) -#error "libvips version 8.10.5+ is required - please see https://sharp.pixelplumbing.com/install" + (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION == 10 && VIPS_MICRO_VERSION < 6) +#error "libvips version 8.10.6+ is required - please see https://sharp.pixelplumbing.com/install" #endif #if ((!defined(__clang__)) && defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6))) diff --git a/src/pipeline.h b/src/pipeline.h index ae6eb73f..37fb5e8a 100644 --- a/src/pipeline.h +++ b/src/pipeline.h @@ -258,7 +258,7 @@ struct PipelineBaton { jpegOptimiseScans(false), jpegOptimiseCoding(true), pngProgressive(false), - pngCompressionLevel(9), + pngCompressionLevel(6), pngAdaptiveFiltering(false), pngPalette(false), pngQuality(100), diff --git a/test/fixtures/cosmos_frame12924_yuv420_10bpc_bt2020_pq_q50.avif b/test/fixtures/cosmos_frame12924_yuv420_10bpc_bt2020_pq_q50.avif deleted file mode 100644 index 487d801352215fd2ae3ed8ebec5b2f7f6bb675bd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17264 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

y4 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