mirror of
https://github.com/lovell/sharp.git
synced 2025-12-19 07:15:08 +01:00
Upgrade to libvips 8.10.5, AVIF support in prebuilt binaries
Remove experimental status from HEIF, changing defaults to prefer royalty-free AV1 over patent-encumbered HEVC
This commit is contained in:
BIN
test/fixtures/cosmos_frame12924_yuv420_10bpc_bt2020_pq_q50.avif
vendored
Normal file
BIN
test/fixtures/cosmos_frame12924_yuv420_10bpc_bt2020_pq_q50.avif
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
BIN
test/fixtures/expected/tint-cmyk.jpg
vendored
BIN
test/fixtures/expected/tint-cmyk.jpg
vendored
Binary file not shown.
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
1
test/fixtures/index.js
vendored
1
test/fixtures/index.js
vendored
@@ -109,6 +109,7 @@ module.exports = {
|
||||
inputSvg: getPath('check.svg'), // http://dev.w3.org/SVG/tools/svgweb/samples/svg-files/check.svg
|
||||
inputSvgSmallViewBox: getPath('circle.svg'),
|
||||
inputSvgWithEmbeddedImages: getPath('struct-image-04-t.svg'), // https://dev.w3.org/SVG/profiles/1.2T/test/svg/struct-image-04-t.svg
|
||||
inputAvif: getPath('cosmos_frame12924_yuv420_10bpc_bt2020_pq_q50.avif'), // CC by-nc-nd https://github.com/AOMediaCodec/av1-avif/tree/master/testFiles/Netflix
|
||||
|
||||
inputJPGBig: getPath('flowers.jpeg'),
|
||||
|
||||
|
||||
84
test/unit/avif.js
Normal file
84
test/unit/avif.js
Normal file
@@ -0,0 +1,84 @@
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
|
||||
const sharp = require('../../');
|
||||
const { inputAvif, inputJpg } = require('../fixtures');
|
||||
|
||||
describe('AVIF', () => {
|
||||
it('called without options does not throw an error', () => {
|
||||
assert.doesNotThrow(() => {
|
||||
sharp().avif();
|
||||
});
|
||||
});
|
||||
|
||||
it('can passthrough AVIF', async () => {
|
||||
const data = await sharp(inputAvif)
|
||||
.resize(32)
|
||||
.toBuffer();
|
||||
const metadata = await sharp(data)
|
||||
.metadata();
|
||||
const { size, ...metadataWithoutSize } = metadata;
|
||||
assert.deepStrictEqual(metadataWithoutSize, {
|
||||
channels: 3,
|
||||
depth: 'uchar',
|
||||
format: 'heif',
|
||||
hasAlpha: false,
|
||||
hasProfile: false,
|
||||
height: 12,
|
||||
isProgressive: false,
|
||||
pageHeight: 12,
|
||||
pagePrimary: 0,
|
||||
pages: 1,
|
||||
space: 'srgb',
|
||||
width: 32
|
||||
});
|
||||
});
|
||||
|
||||
it('can convert AVIF to JPEG', async () => {
|
||||
const data = await sharp(inputAvif)
|
||||
.resize(32)
|
||||
.jpeg()
|
||||
.toBuffer();
|
||||
const metadata = await sharp(data)
|
||||
.metadata();
|
||||
const { size, ...metadataWithoutSize } = metadata;
|
||||
assert.deepStrictEqual(metadataWithoutSize, {
|
||||
channels: 3,
|
||||
chromaSubsampling: '4:2:0',
|
||||
density: 72,
|
||||
depth: 'uchar',
|
||||
format: 'jpeg',
|
||||
hasAlpha: false,
|
||||
hasProfile: false,
|
||||
height: 13,
|
||||
isProgressive: false,
|
||||
space: 'srgb',
|
||||
width: 32
|
||||
});
|
||||
});
|
||||
|
||||
it('can convert JPEG to AVIF', async () => {
|
||||
const data = await sharp(inputJpg)
|
||||
.resize(32)
|
||||
.avif()
|
||||
.toBuffer();
|
||||
const metadata = await sharp(data)
|
||||
.metadata();
|
||||
const { size, ...metadataWithoutSize } = metadata;
|
||||
assert.deepStrictEqual(metadataWithoutSize, {
|
||||
channels: 3,
|
||||
depth: 'uchar',
|
||||
format: 'heif',
|
||||
hasAlpha: false,
|
||||
hasProfile: false,
|
||||
height: 26,
|
||||
isProgressive: false,
|
||||
pageHeight: 26,
|
||||
pagePrimary: 0,
|
||||
pages: 1,
|
||||
space: 'srgb',
|
||||
width: 32
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -4,76 +4,65 @@ const assert = require('assert');
|
||||
|
||||
const sharp = require('../../');
|
||||
|
||||
const formatHeifOutputBuffer = sharp.format.heif.output.buffer;
|
||||
|
||||
describe('HEIF (experimental)', () => {
|
||||
describe('Stubbed without support for HEIF', () => {
|
||||
before(() => {
|
||||
sharp.format.heif.output.buffer = false;
|
||||
});
|
||||
after(() => {
|
||||
sharp.format.heif.output.buffer = formatHeifOutputBuffer;
|
||||
});
|
||||
|
||||
it('should throw an error', () => {
|
||||
assert.throws(() => {
|
||||
sharp().heif();
|
||||
});
|
||||
describe('HEIF', () => {
|
||||
it('called without options does not throw an error', () => {
|
||||
assert.doesNotThrow(() => {
|
||||
sharp().heif();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Stubbed with support for HEIF', () => {
|
||||
before(() => {
|
||||
sharp.format.heif.output.buffer = true;
|
||||
it('valid quality does not throw an error', () => {
|
||||
assert.doesNotThrow(() => {
|
||||
sharp().heif({ quality: 80 });
|
||||
});
|
||||
after(() => {
|
||||
sharp.format.heif.output.buffer = formatHeifOutputBuffer;
|
||||
});
|
||||
it('invalid quality should throw an error', () => {
|
||||
assert.throws(() => {
|
||||
sharp().heif({ quality: 101 });
|
||||
});
|
||||
|
||||
it('called without options does not throw an error', () => {
|
||||
assert.doesNotThrow(() => {
|
||||
sharp().heif();
|
||||
});
|
||||
});
|
||||
it('non-numeric quality should throw an error', () => {
|
||||
assert.throws(() => {
|
||||
sharp().heif({ quality: 'fail' });
|
||||
});
|
||||
it('valid quality does not throw an error', () => {
|
||||
assert.doesNotThrow(() => {
|
||||
sharp().heif({ quality: 50 });
|
||||
});
|
||||
});
|
||||
it('valid lossless does not throw an error', () => {
|
||||
assert.doesNotThrow(() => {
|
||||
sharp().heif({ lossless: true });
|
||||
});
|
||||
it('invalid quality should throw an error', () => {
|
||||
assert.throws(() => {
|
||||
sharp().heif({ quality: 101 });
|
||||
});
|
||||
});
|
||||
it('non-boolean lossless should throw an error', () => {
|
||||
assert.throws(() => {
|
||||
sharp().heif({ lossless: 'fail' });
|
||||
});
|
||||
it('non-numeric quality should throw an error', () => {
|
||||
assert.throws(() => {
|
||||
sharp().heif({ quality: 'fail' });
|
||||
});
|
||||
});
|
||||
it('valid compression does not throw an error', () => {
|
||||
assert.doesNotThrow(() => {
|
||||
sharp().heif({ compression: 'hevc' });
|
||||
});
|
||||
it('valid lossless does not throw an error', () => {
|
||||
assert.doesNotThrow(() => {
|
||||
sharp().heif({ lossless: true });
|
||||
});
|
||||
});
|
||||
it('unknown compression should throw an error', () => {
|
||||
assert.throws(() => {
|
||||
sharp().heif({ compression: 'fail' });
|
||||
});
|
||||
it('non-boolean lossless should throw an error', () => {
|
||||
assert.throws(() => {
|
||||
sharp().heif({ lossless: 'fail' });
|
||||
});
|
||||
});
|
||||
it('invalid compression should throw an error', () => {
|
||||
assert.throws(() => {
|
||||
sharp().heif({ compression: 1 });
|
||||
});
|
||||
it('valid compression does not throw an error', () => {
|
||||
assert.doesNotThrow(() => {
|
||||
sharp().heif({ compression: 'avc' });
|
||||
});
|
||||
});
|
||||
it('valid speed does not throw an error', () => {
|
||||
assert.doesNotThrow(() => {
|
||||
sharp().heif({ speed: 6 });
|
||||
});
|
||||
it('unknown compression should throw an error', () => {
|
||||
assert.throws(() => {
|
||||
sharp().heif({ compression: 'fail' });
|
||||
});
|
||||
});
|
||||
it('out of range speed should throw an error', () => {
|
||||
assert.throws(() => {
|
||||
sharp().heif({ speed: 9 });
|
||||
});
|
||||
it('invalid compression should throw an error', () => {
|
||||
assert.throws(() => {
|
||||
sharp().heif({ compression: 1 });
|
||||
});
|
||||
});
|
||||
it('invalid speed should throw an error', () => {
|
||||
assert.throws(() => {
|
||||
sharp().heif({ compression: 'fail' });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -302,7 +302,6 @@ describe('Input/output', function () {
|
||||
});
|
||||
|
||||
it('Fail when input is empty Buffer', function (done) {
|
||||
if (sharp.format.magick.input.buffer) return this.skip(); // can be removed with libvips 8.10.1+
|
||||
sharp(Buffer.alloc(0)).toBuffer().then(function () {
|
||||
assert(false);
|
||||
done();
|
||||
|
||||
@@ -279,10 +279,10 @@ describe('Image Stats', function () {
|
||||
// red channel
|
||||
assert.strictEqual(0, stats.channels[0].min);
|
||||
assert.strictEqual(true, isInRange(stats.channels[0].max, 254, 255));
|
||||
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].sum, 82506996));
|
||||
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].squaresSum, 11213984832));
|
||||
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].mean, 104.36947963892487));
|
||||
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].stdev, 57.379896254993135));
|
||||
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].sum, 83291370));
|
||||
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].squaresSum, 11379783198));
|
||||
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].mean, 105.36169496842616));
|
||||
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].stdev, 57.39412151419967));
|
||||
assert.strictEqual(true, isInteger(stats.channels[0].minX));
|
||||
assert.strictEqual(true, isInRange(stats.channels[0].minX, 0, 1024));
|
||||
assert.strictEqual(true, isInteger(stats.channels[0].minY));
|
||||
@@ -295,10 +295,10 @@ describe('Image Stats', function () {
|
||||
// green channel
|
||||
assert.strictEqual(0, stats.channels[1].min);
|
||||
assert.strictEqual(true, isInRange(stats.channels[1].max, 254, 255));
|
||||
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].sum, 120089056));
|
||||
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].squaresSum, 20533721114));
|
||||
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].mean, 151.90993361398964));
|
||||
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].stdev, 53.83370206587037));
|
||||
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].sum, 120877425));
|
||||
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].squaresSum, 20774687595));
|
||||
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].mean, 152.9072025279307));
|
||||
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].stdev, 53.84143349689916));
|
||||
assert.strictEqual(true, isInteger(stats.channels[1].minX));
|
||||
assert.strictEqual(true, isInRange(stats.channels[1].minX, 0, 1024));
|
||||
assert.strictEqual(true, isInteger(stats.channels[1].minY));
|
||||
@@ -311,10 +311,10 @@ describe('Image Stats', function () {
|
||||
// blue channel
|
||||
assert.strictEqual(0, stats.channels[2].min);
|
||||
assert.strictEqual(true, isInRange(stats.channels[2].max, 254, 255));
|
||||
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].sum, 138153653));
|
||||
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].squaresSum, 28172033081));
|
||||
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].mean, 174.76123932359133));
|
||||
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].stdev, 71.38276338513747));
|
||||
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].sum, 138938859));
|
||||
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].squaresSum, 28449125593));
|
||||
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].mean, 175.75450711423252));
|
||||
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].stdev, 71.39929031070358));
|
||||
assert.strictEqual(true, isInteger(stats.channels[2].minX));
|
||||
assert.strictEqual(true, isInRange(stats.channels[2].minX, 0, 1024));
|
||||
assert.strictEqual(true, isInteger(stats.channels[2].minY));
|
||||
|
||||
Reference in New Issue
Block a user