diff --git a/.travis.yml b/.travis.yml
index e399971c..c1d8c664 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,88 +1,72 @@
matrix:
include:
- - name: "Linux (glibc) - Node 8"
+ - name: "Linux (glibc 2.17+) - Node.js 10"
os: linux
- dist: trusty
- sudo: false
- language: node_js
- node_js: "8"
- - name: "Linux (glibc) - Node 10"
- os: linux
- dist: trusty
- sudo: false
+ dist: xenial
language: node_js
node_js: "10"
- - name: "Linux (glibc) - Node 12"
+ - name: "Linux (glibc 2.17+) - Node.js 12"
os: linux
- dist: trusty
- sudo: false
+ dist: xenial
language: node_js
node_js: "12"
- - name: "Linux (glibc) - Node 13"
+ - name: "Linux (glibc 2.17+) - Node.js 13"
os: linux
- dist: trusty
- sudo: false
+ dist: xenial
language: node_js
node_js: "13"
after_success:
- npm install coveralls
- cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js
- - name: "Linux (musl) - Node 8"
+ - name: "Linux (musl 1.1.20+) - Node.js 10"
os: linux
- dist: trusty
- sudo: true
+ dist: bionic
language: minimal
before_install:
- - sudo docker run -dit --name sharp --env CI --env PREBUILD_TOKEN --volume "${PWD}:/mnt/sharp" --workdir /mnt/sharp node:8-alpine
+ - sudo docker run -dit --name sharp --env CI --env PREBUILD_TOKEN --volume "${PWD}:/mnt/sharp" --workdir /mnt/sharp node:10.17.0-alpine3.9 # https://github.com/nodejs/docker-node/issues/1158
- sudo docker exec sharp apk add build-base git python2 --update-cache
install: sudo docker exec sharp sh -c "npm install --unsafe-perm"
script: sudo docker exec sharp sh -c "npm test"
- - name: "Linux (musl) - Node 10"
+ - name: "Linux (musl 1.1.20+) - Node.js 12"
os: linux
- dist: trusty
- sudo: true
- language: minimal
- before_install:
- - sudo docker run -dit --name sharp --env CI --env PREBUILD_TOKEN --volume "${PWD}:/mnt/sharp" --workdir /mnt/sharp node:10-alpine
- - sudo docker exec sharp apk add build-base git python2 --update-cache
- install: sudo docker exec sharp sh -c "npm install --unsafe-perm"
- script: sudo docker exec sharp sh -c "npm test"
- - name: "Linux (musl) - Node 12"
- os: linux
- dist: trusty
- sudo: true
+ dist: bionic
language: minimal
before_install:
- sudo docker run -dit --name sharp --env CI --env PREBUILD_TOKEN --volume "${PWD}:/mnt/sharp" --workdir /mnt/sharp node:12.0-alpine
- sudo docker exec sharp apk add build-base git python2 --update-cache
install: sudo docker exec sharp sh -c "npm install --unsafe-perm"
script: sudo docker exec sharp sh -c "npm test"
- - name: "Linux (musl) - Node 13"
+ - name: "Linux (musl 1.1.20+) - Node.js 13"
os: linux
- dist: trusty
- sudo: true
+ dist: bionic
language: minimal
before_install:
- sudo docker run -dit --name sharp --env CI --env PREBUILD_TOKEN --volume "${PWD}:/mnt/sharp" --workdir /mnt/sharp node:13.0-alpine
- sudo docker exec sharp apk add build-base git python2 --update-cache
install: sudo docker exec sharp sh -c "npm install --unsafe-perm"
script: sudo docker exec sharp sh -c "npm test"
- - name: "OS X - Node 8"
- os: osx
- osx_image: xcode9.2
- language: node_js
- node_js: "8"
- - name: "OS X - Node 10"
+ - name: "Linux ARM64v8 (glibc 2.29+) - Node.js 10"
+ arch: arm64
+ os: linux
+ dist: bionic
+ language: minimal
+ before_install:
+ - sudo docker run -dit --name sharp --env CI --volume "${PWD}:/mnt/sharp" --workdir /mnt/sharp arm64v8/debian:bullseye
+ - sudo docker exec sharp apt-get update
+ - sudo docker exec sharp apt-get install -y build-essential git python2 nodejs npm
+ install: sudo docker exec sharp sh -c "npm install --unsafe-perm"
+ script: sudo docker exec sharp sh -c "npm test"
+ - name: "OS X (10.12+) - Node.js 10"
os: osx
osx_image: xcode9.2
language: node_js
node_js: "10"
- - name: "OS X - Node 12"
+ - name: "OS X (10.12+) - Node.js 12"
os: osx
osx_image: xcode9.2
language: node_js
node_js: "12"
- - name: "OS X - Node 13"
+ - name: "OS X (10.12+) - Node.js 13"
os: osx
osx_image: xcode10
language: node_js
diff --git a/README.md b/README.md
index 409cd496..3f0ef595 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,7 @@ As well as image resizing, operations such as
rotation, extraction, compositing and gamma correction are available.
Most modern 64-bit OS X, Windows and Linux systems running
-Node versions 8, 10, 12 and 13
+Node versions 10, 12 and 13
do not require any additional install or runtime dependencies.
## Examples
diff --git a/appveyor.yml b/appveyor.yml
index 12bc7e73..3d9f7ffe 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,10 +1,9 @@
-os: Visual Studio 2015
+os: Visual Studio 2017
version: "{build}"
build: off
platform: x64
environment:
matrix:
- - nodejs_version: "8"
- nodejs_version: "10"
- nodejs_version: "12"
- nodejs_version: "13"
diff --git a/binding.gyp b/binding.gyp
index 3a189384..1e7c83ce 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -11,6 +11,7 @@
],
'sources': [
'src/libvips/cplusplus/VError.cpp',
+ 'src/libvips/cplusplus/VConnection.cpp',
'src/libvips/cplusplus/VInterpolate.cpp',
'src/libvips/cplusplus/VImage.cpp'
],
@@ -127,7 +128,6 @@
'../vendor/lib/libgobject-2.0.so',
# Dependencies of dependencies, included for openSUSE support
'../vendor/lib/libcairo.so',
- '../vendor/lib/libcroco-0.6.so',
'../vendor/lib/libexif.so',
'../vendor/lib/libexpat.so',
'../vendor/lib/libffi.so',
diff --git a/docs/api-channel.md b/docs/api-channel.md
index 7e278111..4dccddf9 100644
--- a/docs/api-channel.md
+++ b/docs/api-channel.md
@@ -32,6 +32,10 @@ sharp('rgb.jpg')
Returns **Sharp**
+**Meta**
+
+- **since**: 0.21.2
+
## extractChannel
Extract a single channel from a multi-channel image.
diff --git a/docs/api-composite.md b/docs/api-composite.md
index c571edd6..91ac1782 100644
--- a/docs/api-composite.md
+++ b/docs/api-composite.md
@@ -61,6 +61,10 @@ sharp('input.png')
Returns **Sharp**
+**Meta**
+
+- **since**: 0.22.0
+
[1]: https://libvips.github.io/libvips/API/current/libvips-conversion.html#VipsBlendMode
[2]: https://www.cairographics.org/operators/
diff --git a/docs/api-operation.md b/docs/api-operation.md
index 7cd0600c..b4b62824 100644
--- a/docs/api-operation.md
+++ b/docs/api-operation.md
@@ -287,6 +287,10 @@ sharp(input)
Returns **Sharp**
+**Meta**
+
+- **since**: 0.21.1
+
## modulate
Transforms the image using brightness, saturation and hue rotation.
@@ -322,6 +326,10 @@ sharp(input)
Returns **Sharp**
+**Meta**
+
+- **since**: 0.22.1
+
[1]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number
[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
diff --git a/docs/api-output.md b/docs/api-output.md
index e40f4990..28b1de49 100644
--- a/docs/api-output.md
+++ b/docs/api-output.md
@@ -268,6 +268,10 @@ Most versions of libheif support only the patent-encumbered HEVC compression for
Returns **Sharp**
+**Meta**
+
+- **since**: 0.23.0
+
## raw
Force output to be raw, uncompressed uint8 pixel data.
diff --git a/docs/changelog.md b/docs/changelog.md
index 99347473..bff8e849 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -1,14 +1,21 @@
# Changelog
+### v0.24 - "*wit*"
+
+Requires libvips v8.9.0.
+
+#### v0.24.0 - TBD
+
+* Drop support for Node.js 8.
+ [#1910](https://github.com/lovell/sharp/issues/1910)
+
+* Ensure correct colour output for 16-bit, 2-channel PNG input with ICC profile.
+ [#2013](https://github.com/lovell/sharp/issues/2013)
+
### v0.23 - "*vision*"
Requires libvips v8.8.1.
-#### v0.23.5 - TBD
-
-* Ensure correct colour output for 16-bit, 2-channel PNG input with ICC profile.
- [#2013](https://github.com/lovell/sharp/issues/2013)
-
#### v0.23.4 - 5th December 2019
* Handle zero-length Buffer objects when using Node.js v13.2.0+.
diff --git a/docs/index.md b/docs/index.md
index 7574cf75..2f56b2de 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -17,7 +17,7 @@ As well as image resizing, operations such as
rotation, extraction, compositing and gamma correction are available.
Most modern 64-bit OS X, Windows and Linux systems running
-Node versions 8, 10, 12 and 13
+Node versions 10, 12 and 13
do not require any additional install or runtime dependencies.
[](https://coveralls.io/r/lovell/sharp?branch=master)
diff --git a/docs/install.md b/docs/install.md
index acbf2014..a1b5fa96 100644
--- a/docs/install.md
+++ b/docs/install.md
@@ -10,12 +10,12 @@ yarn add sharp
## Prerequisites
-* Node.js v8.5.0+
+* Node.js v10.13.0+
### Building from source
Pre-compiled binaries for sharp are provided for use with
-Node versions 8, 10, 12 and 13 on
+Node versions 10, 12 and 13 on
64-bit Windows, OS X and Linux platforms.
Sharp will be built from source at install time when:
diff --git a/install/libvips.js b/install/libvips.js
index a913878e..7b58041d 100644
--- a/install/libvips.js
+++ b/install/libvips.js
@@ -66,8 +66,11 @@ try {
if (platformAndArch === 'freebsd-x64' || platformAndArch === 'openbsd-x64' || platformAndArch === 'sunos-x64') {
throw new Error(`BSD/SunOS systems require manual installation of libvips >= ${minimumLibvipsVersion}`);
}
- if (detectLibc.family === detectLibc.GLIBC && detectLibc.version && semver.lt(`${detectLibc.version}.0`, '2.17.0')) {
- throw new Error(`Use with glibc version ${detectLibc.version} requires manual installation of libvips >= ${minimumLibvipsVersion}`);
+ if (detectLibc.family === detectLibc.GLIBC && detectLibc.version) {
+ const minimumGlibcVersion = arch === 'arm64' ? '2.29.0' : '2.17.0';
+ if (semver.lt(`${detectLibc.version}.0`, minimumGlibcVersion)) {
+ throw new Error(`Use with glibc ${detectLibc.version} requires manual installation of libvips >= ${minimumLibvipsVersion}`);
+ }
}
// Download to per-process temporary file
const tarFilename = ['libvips', minimumLibvipsVersion, platformAndArch].join('-') + '.tar.gz';
@@ -84,7 +87,7 @@ try {
if (err) {
fail(err);
} else if (response.statusCode === 404) {
- fail(new Error(`Prebuilt libvips binaries are not yet available for ${platformAndArch}`));
+ fail(new Error(`Prebuilt libvips ${minimumLibvipsVersion} binaries are not yet available for ${platformAndArch}`));
} else if (response.statusCode !== 200) {
fail(new Error(`Status ${response.statusCode} ${response.statusMessage}`));
} else {
diff --git a/lib/channel.js b/lib/channel.js
index 6acc5ef5..cf6560f9 100644
--- a/lib/channel.js
+++ b/lib/channel.js
@@ -32,6 +32,8 @@ function removeAlpha () {
/**
* Ensure alpha channel, if missing. The added alpha channel will be fully opaque. This is a no-op if the image already has an alpha channel.
*
+ * @since 0.21.2
+ *
* @example
* sharp('rgb.jpg')
* .ensureAlpha()
diff --git a/lib/composite.js b/lib/composite.js
index cdcf57ee..c4345160 100644
--- a/lib/composite.js
+++ b/lib/composite.js
@@ -53,6 +53,8 @@ const blend = {
* https://libvips.github.io/libvips/API/current/libvips-conversion.html#VipsBlendMode
* and https://www.cairographics.org/operators/
*
+ * @since 0.22.0
+ *
* @example
* sharp('input.png')
* .rotate(180)
diff --git a/lib/operation.js b/lib/operation.js
index 90244fc1..9e0caa84 100644
--- a/lib/operation.js
+++ b/lib/operation.js
@@ -379,6 +379,8 @@ function linear (a, b) {
/**
* Recomb the image with the specified matrix.
*
+ * @since 0.21.1
+ *
* @example
* sharp(input)
* .recomb([
@@ -416,6 +418,8 @@ function recomb (inputMatrix) {
/**
* Transforms the image using brightness, saturation and hue rotation.
*
+ * @since 0.22.1
+ *
* @example
* sharp(input)
* .modulate({
diff --git a/lib/output.js b/lib/output.js
index 09c3b520..a49b0591 100644
--- a/lib/output.js
+++ b/lib/output.js
@@ -444,6 +444,8 @@ function tiff (options) {
*
* Most versions of libheif support only the patent-encumbered HEVC compression format.
*
+ * @since 0.23.0
+ *
* @param {Object} [options] - output options
* @param {Number} [options.quality=80] - quality, integer 1-100
* @param {Boolean} [options.compression='hevc'] - compression format: hevc, avc, jpeg, av1
diff --git a/package.json b/package.json
index 5a0d08a4..211baf70 100644
--- a/package.json
+++ b/package.json
@@ -111,7 +111,7 @@
"nan": "^2.14.0",
"npmlog": "^4.1.2",
"prebuild-install": "^5.3.3",
- "semver": "^6.3.0",
+ "semver": "^7.1.1",
"simple-get": "^3.1.0",
"tar": "^5.0.5",
"tunnel-agent": "^0.6.0"
@@ -126,7 +126,7 @@
"license-checker": "^25.0.1",
"mocha": "^6.2.2",
"mock-fs": "^4.10.4",
- "nyc": "^14.1.1",
+ "nyc": "^15.0.0",
"prebuild": "^9.1.1",
"prebuild-ci": "^3.1.0",
"rimraf": "^3.0.0",
@@ -134,10 +134,10 @@
},
"license": "Apache-2.0",
"config": {
- "libvips": "8.8.1"
+ "libvips": "8.9.0-rc4"
},
"engines": {
- "node": ">=8.5.0"
+ "node": ">=10.13.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
diff --git a/src/common.cc b/src/common.cc
index 8c9b4824..387d2a5e 100644
--- a/src/common.cc
+++ b/src/common.cc
@@ -197,7 +197,7 @@ namespace sharp {
std::string const loader = load;
if (EndsWith(loader, "JpegFile")) {
imageType = ImageType::JPEG;
- } else if (EndsWith(loader, "Png")) {
+ } else if (EndsWith(loader, "PngFile")) {
imageType = ImageType::PNG;
} else if (EndsWith(loader, "WebpFile")) {
imageType = ImageType::WEBP;
diff --git a/src/common.h b/src/common.h
index 29977de3..6a1629a4 100644
--- a/src/common.h
+++ b/src/common.h
@@ -25,8 +25,8 @@
// Verify platform and compiler compatibility
-#if (VIPS_MAJOR_VERSION < 8 || (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION < 8))
-#error libvips version 8.8.0+ is required - see sharp.pixelplumbing.com/page/install
+#if (VIPS_MAJOR_VERSION < 8 || (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION < 9))
+#error libvips version 8.9.0+ is required - see sharp.pixelplumbing.com/page/install
#endif
#if ((!defined(__clang__)) && defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6)))
diff --git a/src/libvips/cplusplus/VConnection.cpp b/src/libvips/cplusplus/VConnection.cpp
new file mode 100644
index 00000000..be7afc5a
--- /dev/null
+++ b/src/libvips/cplusplus/VConnection.cpp
@@ -0,0 +1,178 @@
+/* Object part of the VSource and VTarget class
+ */
+
+/*
+
+ Copyright (C) 1991-2001 The National Gallery
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA
+
+ */
+
+/*
+
+ These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
+
+ */
+
+#ifdef HAVE_CONFIG_H
+#include
+#endif /*HAVE_CONFIG_H*/
+#include
+
+#include
+
+#include
+
+/*
+#define VIPS_DEBUG
+#define VIPS_DEBUG_VERBOSE
+ */
+
+VIPS_NAMESPACE_START
+
+VSource
+VSource::new_from_descriptor( int descriptor )
+{
+ VipsSource *input;
+
+ if( !(input = vips_source_new_from_descriptor( descriptor )) )
+ throw VError();
+
+ VSource out( input );
+
+ return( out );
+}
+
+VSource
+VSource::new_from_file( const char *filename )
+{
+ VipsSource *input;
+
+ if( !(input = vips_source_new_from_file( filename )) )
+ throw VError();
+
+ VSource out( input );
+
+ return( out );
+}
+
+VSource
+VSource::new_from_blob( VipsBlob *blob )
+{
+ VipsSource *input;
+
+ if( !(input = vips_source_new_from_blob( blob )) )
+ throw VError();
+
+ VSource out( input );
+
+ return( out );
+}
+
+VSource
+VSource::new_from_memory( const void *data,
+ size_t size )
+{
+ VipsSource *input;
+
+ if( !(input = vips_source_new_from_memory( data, size )) )
+ throw VError();
+
+ VSource out( input );
+
+ return( out );
+}
+
+VSource
+VSource::new_from_options( const char *options )
+{
+ VipsSource *input;
+
+ if( !(input = vips_source_new_from_options( options )) )
+ throw VError();
+
+ VSource out( input );
+
+ return( out );
+}
+
+VOption *
+VOption::set( const char *name, const VSource value )
+{
+ Pair *pair = new Pair( name );
+
+ pair->input = true;
+ g_value_init( &pair->value, VIPS_TYPE_SOURCE );
+ g_value_set_object( &pair->value, value.get_source() );
+ options.push_back( pair );
+
+ return( this );
+}
+
+VTarget
+VTarget::new_to_descriptor( int descriptor )
+{
+ VipsTarget *output;
+
+ if( !(output = vips_target_new_to_descriptor( descriptor )) )
+ throw VError();
+
+ VTarget out( output );
+
+ return( out );
+}
+
+VTarget
+VTarget::new_to_file( const char *filename )
+{
+ VipsTarget *output;
+
+ if( !(output = vips_target_new_to_file( filename )) )
+ throw VError();
+
+ VTarget out( output );
+
+ return( out );
+}
+
+VTarget
+VTarget::new_to_memory()
+{
+ VipsTarget *output;
+
+ if( !(output = vips_target_new_to_memory()) )
+ throw VError();
+
+ VTarget out( output );
+
+ return( out );
+}
+
+VOption *
+VOption::set( const char *name, const VTarget value )
+{
+ Pair *pair = new Pair( name );
+
+ pair->input = true;
+ g_value_init( &pair->value, VIPS_TYPE_TARGET );
+ g_value_set_object( &pair->value, value.get_target() );
+ options.push_back( pair );
+
+ return( this );
+}
+
+VIPS_NAMESPACE_END
diff --git a/src/libvips/cplusplus/VImage.cpp b/src/libvips/cplusplus/VImage.cpp
index 205b46cb..5abe632c 100644
--- a/src/libvips/cplusplus/VImage.cpp
+++ b/src/libvips/cplusplus/VImage.cpp
@@ -169,7 +169,7 @@ VOption::set( const char *name, const char *value )
// input image
VOption *
-VOption::set( const char *name, VImage value )
+VOption::set( const char *name, const VImage value )
{
Pair *pair = new Pair( name );
@@ -592,7 +592,30 @@ VImage
VImage::new_from_buffer( const std::string &buf, const char *option_string,
VOption *options )
{
- return( new_from_buffer( buf.c_str(), buf.size(), option_string, options ) );
+ return( new_from_buffer( buf.c_str(), buf.size(),
+ option_string, options ) );
+}
+
+VImage
+VImage::new_from_source( VSource source, const char *option_string,
+ VOption *options )
+{
+ const char *operation_name;
+ VImage out;
+
+ if( !(operation_name = vips_foreign_find_load_source(
+ source.get_source() )) ) {
+ delete options;
+ throw( VError() );
+ }
+
+ options = (options ? options : VImage::option())->
+ set( "source", source )->
+ set( "out", &out );
+
+ call_option_string( operation_name, option_string, options );
+
+ return( out );
}
VImage
@@ -679,6 +702,26 @@ VImage::write_to_buffer( const char *suffix, void **buf, size_t *size,
}
}
+void
+VImage::write_to_target( const char *suffix, VTarget target,
+ VOption *options ) const
+{
+ char filename[VIPS_PATH_MAX];
+ char option_string[VIPS_PATH_MAX];
+ const char *operation_name;
+
+ vips__filename_split8( suffix, filename, option_string );
+ if( !(operation_name = vips_foreign_find_save_target( filename )) ) {
+ delete options;
+ throw VError();
+ }
+
+ call_option_string( operation_name, option_string,
+ (options ? options : VImage::option())->
+ set( "in", *this )->
+ set( "target", target ) );
+}
+
#include "vips-operators.cpp"
std::vector
diff --git a/src/libvips/cplusplus/VInterpolate.cpp b/src/libvips/cplusplus/VInterpolate.cpp
index 265bf66e..cb59715c 100644
--- a/src/libvips/cplusplus/VInterpolate.cpp
+++ b/src/libvips/cplusplus/VInterpolate.cpp
@@ -61,7 +61,7 @@ VInterpolate::new_from_name( const char *name, VOption *options )
}
VOption *
-VOption::set( const char *name, VInterpolate value )
+VOption::set( const char *name, const VInterpolate value )
{
Pair *pair = new Pair( name );
diff --git a/src/libvips/cplusplus/vips-operators.cpp b/src/libvips/cplusplus/vips-operators.cpp
index beae5057..12694762 100644
--- a/src/libvips/cplusplus/vips-operators.cpp
+++ b/src/libvips/cplusplus/vips-operators.cpp
@@ -1,5 +1,5 @@
// bodies for vips operations
-// Wed Apr 24 15:50:21 CEST 2019
+// Wed 01 Jan 2020 12:22:12 PM CET
// this file is generated automatically, do not edit!
VImage VImage::CMC2LCh( VOption *options ) const
@@ -491,6 +491,19 @@ VImage VImage::canny( VOption *options ) const
return( out );
}
+VImage VImage::case_image( std::vector cases, VOption *options ) const
+{
+ VImage out;
+
+ call( "case",
+ (options ? options : VImage::option())->
+ set( "index", *this )->
+ set( "out", &out )->
+ set( "cases", cases ) );
+
+ return( out );
+}
+
VImage VImage::cast( VipsBandFormat format, VOption *options ) const
{
VImage out;
@@ -1615,6 +1628,18 @@ VImage VImage::jpegload_buffer( VipsBlob *buffer, VOption *options )
return( out );
}
+VImage VImage::jpegload_source( VSource source, VOption *options )
+{
+ VImage out;
+
+ call( "jpegload_source",
+ (options ? options : VImage::option())->
+ set( "out", &out )->
+ set( "source", source ) );
+
+ return( out );
+}
+
void VImage::jpegsave( const char *filename, VOption *options ) const
{
call( "jpegsave",
@@ -1642,6 +1667,14 @@ void VImage::jpegsave_mime( VOption *options ) const
set( "in", *this ) );
}
+void VImage::jpegsave_target( VTarget target, VOption *options ) const
+{
+ call( "jpegsave_target",
+ (options ? options : VImage::option())->
+ set( "in", *this )->
+ set( "target", target ) );
+}
+
VImage VImage::labelregions( VOption *options ) const
{
VImage mask;
@@ -2286,6 +2319,18 @@ VImage VImage::pngload_buffer( VipsBlob *buffer, VOption *options )
return( out );
}
+VImage VImage::pngload_source( VSource source, VOption *options )
+{
+ VImage out;
+
+ call( "pngload_source",
+ (options ? options : VImage::option())->
+ set( "out", &out )->
+ set( "source", source ) );
+
+ return( out );
+}
+
void VImage::pngsave( const char *filename, VOption *options ) const
{
call( "pngsave",
@@ -2306,6 +2351,14 @@ VipsBlob *VImage::pngsave_buffer( VOption *options ) const
return( buffer );
}
+void VImage::pngsave_target( VTarget target, VOption *options ) const
+{
+ call( "pngsave_target",
+ (options ? options : VImage::option())->
+ set( "in", *this )->
+ set( "target", target ) );
+}
+
VImage VImage::ppmload( const char *filename, VOption *options )
{
VImage out;
@@ -2413,6 +2466,30 @@ VImage VImage::radload( const char *filename, VOption *options )
return( out );
}
+VImage VImage::radload_buffer( VipsBlob *buffer, VOption *options )
+{
+ VImage out;
+
+ call( "radload_buffer",
+ (options ? options : VImage::option())->
+ set( "out", &out )->
+ set( "buffer", buffer ) );
+
+ return( out );
+}
+
+VImage VImage::radload_source( VSource source, VOption *options )
+{
+ VImage out;
+
+ call( "radload_source",
+ (options ? options : VImage::option())->
+ set( "out", &out )->
+ set( "source", source ) );
+
+ return( out );
+}
+
void VImage::radsave( const char *filename, VOption *options ) const
{
call( "radsave",
@@ -2433,6 +2510,14 @@ VipsBlob *VImage::radsave_buffer( VOption *options ) const
return( buffer );
}
+void VImage::radsave_target( VTarget target, VOption *options ) const
+{
+ call( "radsave_target",
+ (options ? options : VImage::option())->
+ set( "in", *this )->
+ set( "target", target ) );
+}
+
VImage VImage::rank( int width, int height, int index, VOption *options ) const
{
VImage out;
@@ -2977,6 +3062,30 @@ VImage VImage::svgload_buffer( VipsBlob *buffer, VOption *options )
return( out );
}
+VImage VImage::svgload_source( VSource source, VOption *options )
+{
+ VImage out;
+
+ call( "svgload_source",
+ (options ? options : VImage::option())->
+ set( "out", &out )->
+ set( "source", source ) );
+
+ return( out );
+}
+
+VImage VImage::switch_image( std::vector tests, VOption *options )
+{
+ VImage out;
+
+ call( "switch",
+ (options ? options : VImage::option())->
+ set( "out", &out )->
+ set( "tests", tests ) );
+
+ return( out );
+}
+
void VImage::system( const char *cmd_format, VOption *options )
{
call( "system",
@@ -3035,6 +3144,19 @@ VImage VImage::thumbnail_image( int width, VOption *options ) const
return( out );
}
+VImage VImage::thumbnail_source( VSource source, int width, VOption *options )
+{
+ VImage out;
+
+ call( "thumbnail_source",
+ (options ? options : VImage::option())->
+ set( "out", &out )->
+ set( "source", source )->
+ set( "width", width ) );
+
+ return( out );
+}
+
VImage VImage::tiffload( const char *filename, VOption *options )
{
VImage out;
@@ -3059,6 +3181,18 @@ VImage VImage::tiffload_buffer( VipsBlob *buffer, VOption *options )
return( out );
}
+VImage VImage::tiffload_source( VSource source, VOption *options )
+{
+ VImage out;
+
+ call( "tiffload_source",
+ (options ? options : VImage::option())->
+ set( "out", &out )->
+ set( "source", source ) );
+
+ return( out );
+}
+
void VImage::tiffsave( const char *filename, VOption *options ) const
{
call( "tiffsave",
@@ -3170,6 +3304,18 @@ VImage VImage::webpload_buffer( VipsBlob *buffer, VOption *options )
return( out );
}
+VImage VImage::webpload_source( VSource source, VOption *options )
+{
+ VImage out;
+
+ call( "webpload_source",
+ (options ? options : VImage::option())->
+ set( "out", &out )->
+ set( "source", source ) );
+
+ return( out );
+}
+
void VImage::webpsave( const char *filename, VOption *options ) const
{
call( "webpsave",
@@ -3190,6 +3336,14 @@ VipsBlob *VImage::webpsave_buffer( VOption *options ) const
return( buffer );
}
+void VImage::webpsave_target( VTarget target, VOption *options ) const
+{
+ call( "webpsave_target",
+ (options ? options : VImage::option())->
+ set( "in", *this )->
+ set( "target", target ) );
+}
+
VImage VImage::worley( int width, int height, VOption *options )
{
VImage out;
diff --git a/src/pipeline.cc b/src/pipeline.cc
index d542688e..be329e7c 100644
--- a/src/pipeline.cc
+++ b/src/pipeline.cc
@@ -916,11 +916,9 @@ class PipelineWorker : public Nan::AsyncWorker {
} else if (baton->formatOut == "heif" || (mightMatchInput && isHeif) ||
(willMatchInput && inputImageType == ImageType::HEIF)) {
// Write HEIF to file
- #ifdef VIPS_TYPE_FOREIGN_HEIF_COMPRESSION
if (sharp::IsAvif(baton->fileOut)) {
baton->heifCompression = VIPS_FOREIGN_HEIF_COMPRESSION_AV1;
}
- #endif
image.heifsave(const_cast(baton->fileOut.data()), VImage::option()
->set("strip", !baton->withMetadata)
->set("Q", baton->heifQuality)
@@ -966,29 +964,26 @@ class PipelineWorker : public Nan::AsyncWorker {
};
suffix = AssembleSuffixString(extname, options);
}
-
// Remove alpha channel from tile background if image does not contain an alpha channel
if (!HasAlpha(image)) {
baton->tileBackground.pop_back();
}
// Write DZ to file
vips::VOption *options = VImage::option()
- ->set("strip", !baton->withMetadata)
- ->set("tile_size", baton->tileSize)
- ->set("overlap", baton->tileOverlap)
- ->set("container", baton->tileContainer)
- ->set("layout", baton->tileLayout)
- ->set("suffix", const_cast(suffix.data()))
- ->set("angle", CalculateAngleRotation(baton->tileAngle))
- ->set("background", baton->tileBackground)
- ->set("skip_blanks", baton->tileSkipBlanks);
-
+ ->set("strip", !baton->withMetadata)
+ ->set("tile_size", baton->tileSize)
+ ->set("overlap", baton->tileOverlap)
+ ->set("container", baton->tileContainer)
+ ->set("layout", baton->tileLayout)
+ ->set("suffix", const_cast(suffix.data()))
+ ->set("angle", CalculateAngleRotation(baton->tileAngle))
+ ->set("background", baton->tileBackground)
+ ->set("skip_blanks", baton->tileSkipBlanks);
// libvips chooses a default depth based on layout. Instead of replicating that logic here by
// not passing anything - libvips will handle choice
if (baton->tileDepth < VIPS_FOREIGN_DZ_DEPTH_LAST) {
options->set("depth", baton->tileDepth);
}
-
image.dzsave(const_cast(baton->fileOut.data()), options);
baton->formatOut = "dz";
} else if (baton->formatOut == "v" || (mightMatchInput && isV) ||
@@ -1004,7 +999,12 @@ class PipelineWorker : public Nan::AsyncWorker {
}
}
} catch (vips::VError const &err) {
- (baton->err).append(err.what());
+ char const *what = err.what();
+ if (what && what[0]) {
+ (baton->err).append(what);
+ } else {
+ (baton->err).append("Unknown error");
+ }
}
// Clean up libvips' per-request data and threads
vips_error_clear();
@@ -1377,11 +1377,9 @@ NAN_METHOD(pipeline) {
AttrAsStr(options, "tiffPredictor").data()));
baton->heifQuality = AttrTo(options, "heifQuality");
baton->heifLossless = AttrTo(options, "heifLossless");
- #ifdef VIPS_TYPE_FOREIGN_HEIF_COMPRESSION
baton->heifCompression = static_cast(
vips_enum_from_nick(nullptr, VIPS_TYPE_FOREIGN_HEIF_COMPRESSION,
AttrAsStr(options, "heifCompression").data()));
- #endif
// Tile output
baton->tileSize = AttrTo(options, "tileSize");
baton->tileOverlap = AttrTo(options, "tileOverlap");
diff --git a/test/unit/stats.js b/test/unit/stats.js
index 88726242..bb840835 100644
--- a/test/unit/stats.js
+++ b/test/unit/stats.js
@@ -242,11 +242,11 @@ describe('Image Stats', function () {
// red channel
assert.strictEqual(0, stats.channels[0].min);
- assert.strictEqual(255, stats.channels[0].max);
- 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, 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, isInteger(stats.channels[0].minX));
assert.strictEqual(true, isInRange(stats.channels[0].minX, 0, 1024));
assert.strictEqual(true, isInteger(stats.channels[0].minY));
@@ -258,11 +258,11 @@ describe('Image Stats', function () {
// green channel
assert.strictEqual(0, stats.channels[1].min);
- assert.strictEqual(255, stats.channels[1].max);
- 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, 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, isInteger(stats.channels[1].minX));
assert.strictEqual(true, isInRange(stats.channels[1].minX, 0, 1024));
assert.strictEqual(true, isInteger(stats.channels[1].minY));
@@ -274,11 +274,11 @@ describe('Image Stats', function () {
// blue channel
assert.strictEqual(0, stats.channels[2].min);
- assert.strictEqual(255, stats.channels[2].max);
- 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, 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, isInteger(stats.channels[2].minX));
assert.strictEqual(true, isInRange(stats.channels[2].minX, 0, 1024));
assert.strictEqual(true, isInteger(stats.channels[2].minY));
diff --git a/test/unit/toBuffer.js b/test/unit/toBuffer.js
index 2f79c04c..25637a85 100644
--- a/test/unit/toBuffer.js
+++ b/test/unit/toBuffer.js
@@ -10,8 +10,8 @@ describe('toBuffer', () => {
const image = sharp(fixtures.inputJpg);
image.toBuffer({ resolveWithObject: true }).then((obj) => {
image.toBuffer().then((buff) => {
- assert.strict.equal(Buffer.isBuffer(buff), true);
- assert.strict.equal(typeof obj, 'object');
+ assert.strictEqual(Buffer.isBuffer(buff), true);
+ assert.strictEqual(typeof obj, 'object');
done();
});
});