Upgrade to libvips v8.13.0-rc1 (#3230)

* Switch from decompress-zip to extract-zip

The former seems to hang when unzipping a ZIP64 file that uses
the general purpose bit flag 3 as file entry.

See: https://github.com/thejoshwolfe/yauzl#no-streaming-unzip-api

* Prefer to call via static member instead

Makes it clearer that a static method is being called.

* `flatten-orange.jpg`: save without chroma subsampling

To ensure no down-scaling of the Cr/Cb channels.
This commit is contained in:
Kleis Auke Wolthuizen 2022-06-26 23:39:29 +02:00 committed by GitHub
parent e40a881ab4
commit afc4c5bf79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 128 additions and 62 deletions

View File

@ -15,10 +15,11 @@
'_ALLOW_KEYWORD_MACROS'
],
'sources': [
'src/libvips/cplusplus/VError.cpp',
'src/libvips/cplusplus/VConnection.cpp',
'src/libvips/cplusplus/VError.cpp',
'src/libvips/cplusplus/VImage.cpp',
'src/libvips/cplusplus/VInterpolate.cpp',
'src/libvips/cplusplus/VImage.cpp'
'src/libvips/cplusplus/VRegion.cpp'
],
'include_dirs': [
'<(sharp_vendor_dir)/include',

View File

@ -140,9 +140,9 @@
"devDependencies": {
"async": "^3.2.4",
"cc": "^3.0.1",
"decompress-zip": "^0.3.3",
"documentation": "^13.2.5",
"exif-reader": "^1.0.3",
"extract-zip": "^2.0.1",
"icc": "^2.0.0",
"license-checker": "^25.0.1",
"mocha": "^10.0.0",
@ -154,19 +154,19 @@
},
"license": "Apache-2.0",
"config": {
"libvips": "8.12.2",
"libvips": "8.13.0-rc1",
"integrity": {
"darwin-arm64v8": "sha512-p46s/bbJAjkOXzPISZt9HUpG9GWjwQkYnLLRLKzsBJHLtB3X6C6Y/zXI5Hd0DOojcFkks9a0kTN+uDQ/XJY19g==",
"darwin-x64": "sha512-6vOHVZnvXwe6EXRsy29jdkUzBE6ElNpXUwd+m8vV7qy32AnXu7B9YemHsZ44vWviIwPZeXF6Nhd9EFLM0wWohw==",
"linux-arm64v8": "sha512-XwZdS63yhqLtbFtx/0eoLF/Agf5qtTrI11FMnMRpuBJWd4jHB60RAH+uzYUgoChCmKIS+AeXYMLm4d8Ns2QX8w==",
"linux-armv6": "sha512-Rh0Q0kqwPG2MjXWOkPCuPEyiUKFgKJYWLgS835D4MrXgdKr8Tft/eVrc2iGIxt2re30VpDiZ1h0Rby1aCZt2zw==",
"linux-armv7": "sha512-heTS/MsmRvu4JljINxP+vDiS9ZZfuGhr3IStb5F7Gc0/QLRhllYAg4rcO8L1eTK9sIIzG5ARvI19+YUZe7WbzA==",
"linux-x64": "sha512-SSWAwBFi0hx8V/h/v82tTFGKWTFv9FiCK3Timz5OExuI+sX1Ngrd0PVQaWXOThGNdel/fcD3Bz9YjSt4feBR1g==",
"linuxmusl-arm64v8": "sha512-Rhks+5C7p7aO6AucLT1uvzo8ohlqcqCUPgZmN+LZjsPWob/Iix3MfiDYtv/+gTvdeEfXxbCU6/YuPBwHQ7/crA==",
"linuxmusl-x64": "sha512-IOyjSQqpWVntqOUpCHVWuQwACwmmjdi15H8Pc+Ma1JkhPogTfVsFQWyL7DuOTD3Yr23EuYGzovUX00duOtfy/g==",
"win32-arm64v8": "sha512-A+Qe8Ipewtvw9ldvF6nWed2J8kphzrUE04nFeKCtNx6pfGQ/MAlCKMjt/U8VgUKNjB01zJDUW9XE0+FhGZ/UpQ==",
"win32-ia32": "sha512-cMrAvwFdDeAVnLJt0IPMPRKaIFhyXYGTprsM0DND9VUHE8F7dJMR44tS5YkXsGh1QNDtjKT6YuxAVUglmiXtpA==",
"win32-x64": "sha512-vLFIfw6aW2zABa8jpgzWDhljnE6glktrddErVyazAIoHl6BFFe/Da+LK1DbXvIYHz7fyOoKhSfCJHCiJG1Vg6w=="
"darwin-arm64v8": "sha512-tczrNbjU/+bUhTHilUNd2OL9DgwPvUX3L6LUTQHmLZlatxT5ztj6of1erNXYhgt4lLhruKcKkYYQyRicBoKsRA==",
"darwin-x64": "sha512-eonsBwyPEHxFL++bCG+rEUokSOaCbImSJ5VA//Qkv34QAO+vZWzj9RMf/ETvT3pHzrx56Wm3SwpGgJ/BIeyKgg==",
"linux-arm64v8": "sha512-/hLYMwmWG3wKyUeDvNZCMJL3mZ+/8mj+VfVbo2DsNsI6MxBnZ4aXg3qMJ17FcEa2sPDHhkVqaJl5DnXGn87gGQ==",
"linux-armv6": "sha512-25Ml2+J+KWj7yKnZVcrxZmZHFIwzbW6d/kACT7duz48NmGWDD0jnu/nroAETYiMqS1W5fHlPRiwG82/d/PeIpg==",
"linux-armv7": "sha512-7u6RS3IFptQMGRMujyvz1kh8YFPBRdEu9T1zJKYl0/cZkxeNNiljW4PenOQ6cxoPlXivUDpEOoifo4B6a3B4/A==",
"linux-x64": "sha512-v6/vcp+71p4NtoEpWUghgboVzavwX8FVa1NXBDVYMx/up4AmQEjEzOicSiLxXc97Ydhk6FJz8Qkrfp05AN0SfQ==",
"linuxmusl-arm64v8": "sha512-8DNTwBbAna/R0/ksmaO/2TKZxjdkgSppTjmM9xIAZO7tbknuDCqi0YyJiiCP5Nh5yGtpf+PcQdSu/ca21ICwAQ==",
"linuxmusl-x64": "sha512-3B12ehfury7m39sZ1lyTxzcf3hPAcCC/+4l16C0Mkoc6FGKPV/CJFtoCzNjUEsEJR5rMKOFBfsgZOoNk0KEzSQ==",
"win32-arm64v8": "sha512-45gnLXiq4EtJNnhhgSY8Kgr5L0ed637Kn2SCW7jhQu9qZS3riLSM5Kk+6L1Kqc+cyNnsFbtWWBWCZp01Tg9HSw==",
"win32-ia32": "sha512-LEodsYlTo0gkrfpHFNr9IwSMI7MTBBy/vry0MazcUAIPkiPhx3CCNbPZL7pd7vuHZ4CP5XNsArTb0RaHpMrc+w==",
"win32-x64": "sha512-5usGDnN1pmFoqfEuHmdvKF/35NbQLlnal5T2bMWDx9kvLIOy7WSahvSGAeDg9cXjHv9SONX/qdpKuJ55c6aD4g=="
},
"runtime": "napi",
"target": 5

View File

@ -366,32 +366,33 @@ namespace sharp {
}
}
} else {
if (descriptor->createChannels > 0) {
int const channels = descriptor->createChannels;
if (channels > 0) {
// Create new image
if (descriptor->createNoiseType == "gaussian") {
int const channels = descriptor->createChannels;
image = VImage::new_matrix(descriptor->createWidth, descriptor->createHeight);
std::vector<VImage> bands = {};
bands.reserve(channels);
for (int _band = 0; _band < channels; _band++) {
bands.push_back(image.gaussnoise(
descriptor->createWidth,
descriptor->createHeight,
VImage::option()->set("mean", descriptor->createNoiseMean)->set("sigma", descriptor->createNoiseSigma)));
bands.push_back(VImage::gaussnoise(descriptor->createWidth, descriptor->createHeight, VImage::option()
->set("mean", descriptor->createNoiseMean)
->set("sigma", descriptor->createNoiseSigma)));
}
image = image.bandjoin(bands);
image = VImage::bandjoin(bands).copy(VImage::option()->set("interpretation",
channels < 3 ? VIPS_INTERPRETATION_B_W: VIPS_INTERPRETATION_sRGB));
} else {
std::vector<double> background = {
descriptor->createBackground[0],
descriptor->createBackground[1],
descriptor->createBackground[2]
};
if (descriptor->createChannels == 4) {
if (channels == 4) {
background.push_back(descriptor->createBackground[3]);
}
image = VImage::new_matrix(descriptor->createWidth, descriptor->createHeight).new_from_image(background);
image = VImage::new_matrix(descriptor->createWidth, descriptor->createHeight)
.copy(VImage::option()->set("interpretation",
channels < 3 ? VIPS_INTERPRETATION_B_W : VIPS_INTERPRETATION_sRGB))
.new_from_image(background);
}
image.get_image()->Type = image.guess_interpretation();
image = image.cast(VIPS_FORMAT_UCHAR);
imageType = ImageType::RAW;
} else {

View File

@ -31,7 +31,6 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /*HAVE_CONFIG_H*/
#include <vips/intl.h>
#include <vips/vips8>

View File

@ -30,7 +30,6 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /*HAVE_CONFIG_H*/
#include <vips/intl.h>
#include <vips/vips8>

View File

@ -38,7 +38,6 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /*HAVE_CONFIG_H*/
#include <vips/intl.h>
#include <vips/vips8>
@ -733,7 +732,7 @@ VImage::write_to_buffer( const char *suffix, void **buf, size_t *size,
set( "in", *this )->
set( "target", target ) );
g_object_get( target.get_target(), "blob", &blob, NULL );
g_object_get( target.get_target(), "blob", &blob, (void *) NULL );
}
else if( (operation_name = vips_foreign_find_save_buffer( filename )) ) {
call_option_string( operation_name, option_string,
@ -778,6 +777,32 @@ VImage::write_to_target( const char *suffix, VTarget target,
set( "target", target ) );
}
VRegion
VImage::region() const
{
return VRegion::new_from_image( *this );
}
VRegion
VImage::region( VipsRect *rect ) const
{
VRegion region = VRegion::new_from_image( *this );
region.prepare( rect );
return region;
}
VRegion
VImage::region( int left, int top, int width, int height ) const
{
VRegion region = VRegion::new_from_image( *this );
region.prepare( left, top, width, height );
return region;
}
#include "vips-operators.cpp"
std::vector<VImage>

View File

@ -31,7 +31,6 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /*HAVE_CONFIG_H*/
#include <vips/intl.h>
#include <vips/vips8>

View File

@ -0,0 +1,27 @@
// Object part of VRegion class
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /*HAVE_CONFIG_H*/
#include <vips/vips8>
#include <vips/debug.h>
VIPS_NAMESPACE_START
VRegion
VRegion::new_from_image( VImage image )
{
VipsRegion *region;
if( !(region = vips_region_new( image.get_image() )) ) {
throw VError();
}
VRegion out( region );
return( out );
}
VIPS_NAMESPACE_END

View File

@ -1,5 +1,4 @@
// bodies for vips operations
// Mon Nov 1 03:31:09 PM CET 2021
// this file is generated automatically, do not edit!
VImage VImage::CMC2LCh( VOption *options ) const
@ -943,6 +942,14 @@ VipsBlob *VImage::dzsave_buffer( VOption *options ) const
return( buffer );
}
void VImage::dzsave_target( VTarget target, VOption *options ) const
{
call( "dzsave_target",
(options ? options : VImage::option())->
set( "in", *this )->
set( "target", target ) );
}
VImage VImage::embed( int x, int y, int width, int height, VOption *options ) const
{
VImage out;
@ -3521,6 +3528,14 @@ VipsBlob *VImage::tiffsave_buffer( VOption *options ) const
return( buffer );
}
void VImage::tiffsave_target( VTarget target, VOption *options ) const
{
call( "tiffsave_target",
(options ? options : VImage::option())->
set( "in", *this )->
set( "target", target ) );
}
VImage VImage::tilecache( VOption *options ) const
{
VImage out;

View File

@ -668,7 +668,7 @@ class PipelineWorker : public Napi::AsyncWorker {
xs.push_back(left);
ys.push_back(top);
}
image = image.composite(images, modes, VImage::option()->set("x", xs)->set("y", ys));
image = VImage::composite(images, modes, VImage::option()->set("x", xs)->set("y", ys));
}
// Reverse premultiplication after all transformations:

View File

@ -22,7 +22,6 @@
#include "stats.h"
static void* sharp_vips_init(void*) {
g_setenv("VIPS_MIN_STACK_SIZE", "2m", FALSE);
vips_init("sharp");
return nullptr;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 424 KiB

After

Width:  |  Height:  |  Size: 424 KiB

View File

@ -23,6 +23,7 @@ describe('Alpha transparency', function () {
.flatten({
background: { r: 255, g: 102, b: 0 }
})
.jpeg({ chromaSubsampling: '4:4:4' })
.toBuffer(function (err, data, info) {
if (err) throw err;
assert.strictEqual(400, info.width);
@ -35,6 +36,7 @@ describe('Alpha transparency', function () {
sharp(fixtures.inputPngWithTransparency)
.resize(400, 300)
.flatten({ background: '#ff6600' })
.jpeg({ chromaSubsampling: '4:4:4' })
.toBuffer(function (err, data, info) {
if (err) throw err;
assert.strictEqual(400, info.width);

View File

@ -27,7 +27,9 @@ describe('AVIF', () => {
format: 'jpeg',
hasAlpha: false,
hasProfile: false,
height: 14,
// 32 / (2048 / 858) = 13.40625
// Math.round(13.40625) = 13
height: 13,
isProgressive: false,
space: 'srgb',
width: 32
@ -70,7 +72,11 @@ describe('AVIF', () => {
format: 'heif',
hasAlpha: false,
hasProfile: false,
height: 14,
// FIXME(kleisauke): https://github.com/strukturag/libheif/issues/365
// $ vips black x.avif 32 13
// $ vipsheader x.avif
// x.avif: 32x12 uchar, 3 bands, srgb, heifload
height: 12,
isProgressive: false,
pagePrimary: 0,
pages: 1,

View File

@ -5,11 +5,9 @@ const sharp = require('../../');
const libcFamily = detectLibc.familySync();
const usingCache = libcFamily !== detectLibc.MUSL;
const usingSimd = !process.env.G_DEBUG;
const concurrency =
libcFamily === detectLibc.MUSL || process.arch === 'arm'
? 1
: undefined;
const usingSimd = !(process.env.G_DEBUG || process.env.VIPS_NOVECTOR);
const concurrency = process.env.VIPS_CONCURRENCY ||
(libcFamily === detectLibc.MUSL || process.arch === 'arm' ? 1 : undefined);
beforeEach(function () {
sharp.cache(usingCache);

View File

@ -343,7 +343,7 @@ describe('Image metadata', function () {
assert.strictEqual(depth, 'uchar');
assert.strictEqual(isProgressive, false);
assert.strictEqual(pages, 10);
assert.strictEqual(loop, 2);
assert.strictEqual(loop, 3);
assert.deepStrictEqual(delay, [...Array(9).fill(3000), 15000]);
assert.strictEqual(hasProfile, false);
assert.strictEqual(hasAlpha, true);

View File

@ -6,7 +6,7 @@ const assert = require('assert');
const eachLimit = require('async/eachLimit');
const rimraf = require('rimraf');
const DecompressZip = require('decompress-zip');
const extractZip = require('extract-zip');
const sharp = require('../../');
const fixtures = require('../fixtures');
@ -14,7 +14,8 @@ const fixtures = require('../fixtures');
// Verifies all tiles in a given dz output directory are <= size
const assertDeepZoomTiles = function (directory, expectedSize, expectedLevels, done) {
// Get levels
const levels = fs.readdirSync(directory);
const dirents = fs.readdirSync(directory, { withFileTypes: true });
const levels = dirents.filter(dirent => dirent.isDirectory()).map(dirent => dirent.name);
assert.strictEqual(expectedLevels, levels.length);
// Get tiles
const tiles = [];
@ -67,8 +68,10 @@ const assertZoomifyTiles = function (directory, expectedTileSize, expectedLevels
};
const assertGoogleTiles = function (directory, expectedTileSize, expectedLevels, done) {
const levels = fs.readdirSync(directory);
assert.strictEqual(expectedLevels, levels.length - 1); // subtract one to account for default blank tile
// Get levels
const dirents = fs.readdirSync(directory, { withFileTypes: true });
const levels = dirents.filter(dirent => dirent.isDirectory()).map(dirent => dirent.name);
assert.strictEqual(expectedLevels, levels.length);
fs.stat(path.join(directory, 'blank.png'), function (err, stat) {
if (err) throw err;
@ -94,7 +97,8 @@ const assertGoogleTiles = function (directory, expectedTileSize, expectedLevels,
// Verifies tiles at specified level in a given output directory are > size+overlap
const assertTileOverlap = function (directory, tileSize, done) {
// Get sorted levels
const levels = fs.readdirSync(directory).sort((a, b) => a - b);
const dirents = fs.readdirSync(directory, { withFileTypes: true });
const levels = dirents.filter(dirent => dirent.isDirectory()).map(dirent => dirent.name).sort((a, b) => a - b);
// Select the highest tile level
const highestLevel = levels[levels.length - 1];
// Get sorted tiles from greatest level
@ -908,14 +912,10 @@ describe('Tile', function () {
if (err) throw err;
assert.strictEqual(true, stat.isFile());
assert.strictEqual(true, stat.size > 0);
new DecompressZip(container)
.on('extract', function () {
extractZip(container, { dir: path.dirname(extractTo) })
.then(() => {
assertDeepZoomTiles(directory, 256, 13, done);
})
.on('error', function (err) {
throw err;
})
.extract({ path: path.dirname(extractTo) });
});
});
});
});
@ -942,14 +942,10 @@ describe('Tile', function () {
if (err) throw err;
assert.strictEqual(true, stat.isFile());
assert.strictEqual(true, stat.size > 0);
new DecompressZip(container)
.on('extract', function () {
extractZip(container, { dir: path.dirname(extractTo) })
.then(() => {
assertDeepZoomTiles(directory, 256, 13, done);
})
.on('error', function (err) {
throw err;
})
.extract({ path: path.dirname(extractTo) });
});
});
});
});

View File

@ -140,7 +140,6 @@ describe('Utilities', function () {
assert.strictEqual('object', typeof sharp.vendor);
assert.strictEqual('string', typeof sharp.vendor.current);
assert.strictEqual(true, Array.isArray(sharp.vendor.installed));
assert.strictEqual(true, sharp.vendor.installed.length > 0);
});
});
});