@revizly/sharp 0.33.3-revizly5 → 0.33.4-revizly2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/install/check.js +2 -2
- package/lib/colour.js +0 -2
- package/lib/index.d.ts +8 -0
- package/lib/input.js +8 -8
- package/lib/libvips.js +10 -4
- package/lib/resize.js +8 -3
- package/lib/utility.js +3 -0
- package/package.json +13 -13
- package/src/common.cc +9 -8
- package/src/common.h +6 -6
- package/src/operations.cc +2 -2
- package/src/pipeline.cc +46 -44
package/install/check.js
CHANGED
@@ -10,8 +10,8 @@ try {
|
|
10
10
|
log(msg);
|
11
11
|
log('Attempting to build from source via node-gyp');
|
12
12
|
try {
|
13
|
-
require('node-addon-api');
|
14
|
-
log(
|
13
|
+
const addonApi = require('node-addon-api');
|
14
|
+
log(`Found node-addon-api ${addonApi.version || ''}`);
|
15
15
|
} catch (err) {
|
16
16
|
log('Please add node-addon-api to your dependencies');
|
17
17
|
return;
|
package/lib/colour.js
CHANGED
@@ -71,8 +71,6 @@ function grayscale (grayscale) {
|
|
71
71
|
* All operations will use this colourspace before converting to the output colourspace,
|
72
72
|
* as defined by {@link #tocolourspace|toColourspace}.
|
73
73
|
*
|
74
|
-
* This feature is experimental and has not yet been fully-tested with all operations.
|
75
|
-
*
|
76
74
|
* @since 0.29.0
|
77
75
|
*
|
78
76
|
* @example
|
package/lib/index.d.ts
CHANGED
@@ -1479,6 +1479,14 @@ declare namespace sharp {
|
|
1479
1479
|
tile?: boolean | undefined;
|
1480
1480
|
/** Set to true to avoid premultipling the image below. Equivalent to the --premultiplied vips option. */
|
1481
1481
|
premultiplied?: boolean | undefined;
|
1482
|
+
/** number representing the DPI for vector overlay image. (optional, default 72)*/
|
1483
|
+
density?: number | undefined;
|
1484
|
+
/** Set to true to read all frames/pages of an animated image. (optional, default false) */
|
1485
|
+
animated?: boolean | undefined;
|
1486
|
+
/** see sharp() constructor, (optional, default 'warning') */
|
1487
|
+
failOn?: FailOnOptions | undefined;
|
1488
|
+
/** see sharp() constructor, (optional, default 268402689) */
|
1489
|
+
limitInputPixels?: number | boolean | undefined;
|
1482
1490
|
}
|
1483
1491
|
|
1484
1492
|
interface TileOptions {
|
package/lib/input.js
CHANGED
@@ -296,17 +296,17 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
|
|
296
296
|
}
|
297
297
|
}
|
298
298
|
if (is.defined(inputOptions.text.width)) {
|
299
|
-
if (is.
|
299
|
+
if (is.integer(inputOptions.text.width) && inputOptions.text.width > 0) {
|
300
300
|
inputDescriptor.textWidth = inputOptions.text.width;
|
301
301
|
} else {
|
302
|
-
throw is.invalidParameterError('text.
|
302
|
+
throw is.invalidParameterError('text.width', 'positive integer', inputOptions.text.width);
|
303
303
|
}
|
304
304
|
}
|
305
305
|
if (is.defined(inputOptions.text.height)) {
|
306
|
-
if (is.
|
306
|
+
if (is.integer(inputOptions.text.height) && inputOptions.text.height > 0) {
|
307
307
|
inputDescriptor.textHeight = inputOptions.text.height;
|
308
308
|
} else {
|
309
|
-
throw is.invalidParameterError('text.height', '
|
309
|
+
throw is.invalidParameterError('text.height', 'positive integer', inputOptions.text.height);
|
310
310
|
}
|
311
311
|
}
|
312
312
|
if (is.defined(inputOptions.text.align)) {
|
@@ -324,10 +324,10 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
|
|
324
324
|
}
|
325
325
|
}
|
326
326
|
if (is.defined(inputOptions.text.dpi)) {
|
327
|
-
if (is.
|
327
|
+
if (is.integer(inputOptions.text.dpi) && is.inRange(inputOptions.text.dpi, 1, 1000000)) {
|
328
328
|
inputDescriptor.textDpi = inputOptions.text.dpi;
|
329
329
|
} else {
|
330
|
-
throw is.invalidParameterError('text.dpi', '
|
330
|
+
throw is.invalidParameterError('text.dpi', 'integer between 1 and 1000000', inputOptions.text.dpi);
|
331
331
|
}
|
332
332
|
}
|
333
333
|
if (is.defined(inputOptions.text.rgba)) {
|
@@ -338,10 +338,10 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
|
|
338
338
|
}
|
339
339
|
}
|
340
340
|
if (is.defined(inputOptions.text.spacing)) {
|
341
|
-
if (is.
|
341
|
+
if (is.integer(inputOptions.text.spacing) && is.inRange(inputOptions.text.spacing, -1000000, 1000000)) {
|
342
342
|
inputDescriptor.textSpacing = inputOptions.text.spacing;
|
343
343
|
} else {
|
344
|
-
throw is.invalidParameterError('text.spacing', '
|
344
|
+
throw is.invalidParameterError('text.spacing', 'integer between -1000000 and 1000000', inputOptions.text.spacing);
|
345
345
|
}
|
346
346
|
}
|
347
347
|
if (is.defined(inputOptions.text.wrap)) {
|
package/lib/libvips.js
CHANGED
@@ -162,15 +162,21 @@ const pkgConfigPath = () => {
|
|
162
162
|
}
|
163
163
|
};
|
164
164
|
|
165
|
+
const skipSearch = (status, reason) => {
|
166
|
+
log(`Detected ${reason}, skipping search for globally-installed libvips`);
|
167
|
+
return status;
|
168
|
+
};
|
169
|
+
|
165
170
|
const useGlobalLibvips = () => {
|
166
171
|
if (Boolean(process.env.SHARP_IGNORE_GLOBAL_LIBVIPS) === true) {
|
167
|
-
|
168
|
-
|
172
|
+
return skipSearch(false, 'SHARP_IGNORE_GLOBAL_LIBVIPS');
|
173
|
+
}
|
174
|
+
if (Boolean(process.env.SHARP_FORCE_GLOBAL_LIBVIPS) === true) {
|
175
|
+
return skipSearch(true, 'SHARP_FORCE_GLOBAL_LIBVIPS');
|
169
176
|
}
|
170
177
|
/* istanbul ignore next */
|
171
178
|
if (isRosetta()) {
|
172
|
-
|
173
|
-
return false;
|
179
|
+
return skipSearch(false, 'Rosetta');
|
174
180
|
}
|
175
181
|
const globalVipsVersion = globalLibvipsVersion();
|
176
182
|
return !!globalVipsVersion && /* istanbul ignore next */
|
package/lib/resize.js
CHANGED
@@ -68,6 +68,7 @@ const strategy = {
|
|
68
68
|
*/
|
69
69
|
const kernel = {
|
70
70
|
nearest: 'nearest',
|
71
|
+
linear: 'linear',
|
71
72
|
cubic: 'cubic',
|
72
73
|
mitchell: 'mitchell',
|
73
74
|
lanczos2: 'lanczos2',
|
@@ -135,18 +136,22 @@ function isResizeExpected (options) {
|
|
135
136
|
*
|
136
137
|
* Some of these values are based on the [object-position](https://developer.mozilla.org/en-US/docs/Web/CSS/object-position) CSS property.
|
137
138
|
*
|
138
|
-
* The
|
139
|
+
* The strategy-based approach initially resizes so one dimension is at its target length
|
139
140
|
* then repeatedly ranks edge regions, discarding the edge with the lowest score based on the selected strategy.
|
140
141
|
* - `entropy`: focus on the region with the highest [Shannon entropy](https://en.wikipedia.org/wiki/Entropy_%28information_theory%29).
|
141
142
|
* - `attention`: focus on the region with the highest luminance frequency, colour saturation and presence of skin tones.
|
142
143
|
*
|
143
|
-
* Possible
|
144
|
+
* Possible downsizing kernels are:
|
144
145
|
* - `nearest`: Use [nearest neighbour interpolation](http://en.wikipedia.org/wiki/Nearest-neighbor_interpolation).
|
146
|
+
* - `linear`: Use a [triangle filter](https://en.wikipedia.org/wiki/Triangular_function).
|
145
147
|
* - `cubic`: Use a [Catmull-Rom spline](https://en.wikipedia.org/wiki/Centripetal_Catmull%E2%80%93Rom_spline).
|
146
148
|
* - `mitchell`: Use a [Mitchell-Netravali spline](https://www.cs.utexas.edu/~fussell/courses/cs384g-fall2013/lectures/mitchell/Mitchell.pdf).
|
147
149
|
* - `lanczos2`: Use a [Lanczos kernel](https://en.wikipedia.org/wiki/Lanczos_resampling#Lanczos_kernel) with `a=2`.
|
148
150
|
* - `lanczos3`: Use a Lanczos kernel with `a=3` (the default).
|
149
151
|
*
|
152
|
+
* When upsampling, these kernels map to `nearest`, `linear` and `cubic` interpolators.
|
153
|
+
* Downsampling kernels without a matching upsampling interpolator map to `cubic`.
|
154
|
+
*
|
150
155
|
* Only one resize can occur per pipeline.
|
151
156
|
* Previous calls to `resize` in the same pipeline will be ignored.
|
152
157
|
*
|
@@ -239,7 +244,7 @@ function isResizeExpected (options) {
|
|
239
244
|
* @param {String} [options.fit='cover'] - How the image should be resized/cropped to fit the target dimension(s), one of `cover`, `contain`, `fill`, `inside` or `outside`.
|
240
245
|
* @param {String} [options.position='centre'] - A position, gravity or strategy to use when `fit` is `cover` or `contain`.
|
241
246
|
* @param {String|Object} [options.background={r: 0, g: 0, b: 0, alpha: 1}] - background colour when `fit` is `contain`, parsed by the [color](https://www.npmjs.org/package/color) module, defaults to black without transparency.
|
242
|
-
* @param {String} [options.kernel='lanczos3'] - The kernel to use for image reduction. Use the `fastShrinkOnLoad` option to control kernel vs shrink-on-load.
|
247
|
+
* @param {String} [options.kernel='lanczos3'] - The kernel to use for image reduction and the inferred interpolator to use for upsampling. Use the `fastShrinkOnLoad` option to control kernel vs shrink-on-load.
|
243
248
|
* @param {Boolean} [options.withoutEnlargement=false] - Do not scale up if the width *or* height are already less than the target dimensions, equivalent to GraphicsMagick's `>` geometry option. This may result in output dimensions smaller than the target dimensions.
|
244
249
|
* @param {Boolean} [options.withoutReduction=false] - Do not scale down if the width *or* height are already greater than the target dimensions, equivalent to GraphicsMagick's `<` geometry option. This may still result in a crop to reach the target dimensions.
|
245
250
|
* @param {Boolean} [options.fastShrinkOnLoad=true] - Take greater advantage of the JPEG and WebP shrink-on-load feature, which can lead to a slight moiré pattern or round-down of an auto-scaled dimension.
|
package/lib/utility.js
CHANGED
@@ -153,6 +153,9 @@ function concurrency (concurrency) {
|
|
153
153
|
if (detectLibc.familySync() === detectLibc.GLIBC && !sharp._isUsingJemalloc()) {
|
154
154
|
// Reduce default concurrency to 1 when using glibc memory allocator
|
155
155
|
sharp.concurrency(1);
|
156
|
+
} else if (detectLibc.familySync() === detectLibc.MUSL && sharp.concurrency() === 1024) {
|
157
|
+
// Reduce default concurrency when musl thread over-subscription detected
|
158
|
+
sharp.concurrency(require('node:os').availableParallelism());
|
156
159
|
}
|
157
160
|
|
158
161
|
/**
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "@revizly/sharp",
|
3
3
|
"description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, GIF, AVIF and TIFF images",
|
4
|
-
"version": "0.33.
|
4
|
+
"version": "0.33.4-revizly2",
|
5
5
|
"author": "Lovell Fuller <npm@lovell.info>",
|
6
6
|
"homepage": "https://sharp.pixelplumbing.com",
|
7
7
|
"contributors": [
|
@@ -82,7 +82,7 @@
|
|
82
82
|
"Joris Dugué <zaruike10@gmail.com>",
|
83
83
|
"Chris Banks <christopher.bradley.banks@gmail.com>",
|
84
84
|
"Ompal Singh <ompal.hitm09@gmail.com>",
|
85
|
-
"Brodan <christopher.hranj@gmail.com",
|
85
|
+
"Brodan <christopher.hranj@gmail.com>",
|
86
86
|
"Ankur Parihar <ankur.github@gmail.com>",
|
87
87
|
"Brahim Ait elhaj <brahima@gmail.com>",
|
88
88
|
"Mart Jansink <m.jansink@gmail.com>",
|
@@ -141,30 +141,30 @@
|
|
141
141
|
"semver": "^7.6.0"
|
142
142
|
},
|
143
143
|
"optionalDependencies": {
|
144
|
-
"@revizly/sharp-libvips-linux-arm64": "1.0.
|
145
|
-
"@revizly/sharp-libvips-linux-x64": "1.0.
|
146
|
-
"@revizly/sharp-linux-arm64": "0.33.
|
147
|
-
"@revizly/sharp-linux-x64": "0.33.
|
144
|
+
"@revizly/sharp-libvips-linux-arm64": "1.0.5",
|
145
|
+
"@revizly/sharp-libvips-linux-x64": "1.0.5",
|
146
|
+
"@revizly/sharp-linux-arm64": "0.33.4-revizly1",
|
147
|
+
"@revizly/sharp-linux-x64": "0.33.4-revizly1"
|
148
148
|
},
|
149
149
|
"devDependencies": {
|
150
|
-
"@emnapi/runtime": "^1.1.
|
151
|
-
"@revizly/sharp-libvips-dev": "1.0.
|
150
|
+
"@emnapi/runtime": "^1.1.1",
|
151
|
+
"@revizly/sharp-libvips-dev": "1.0.5",
|
152
152
|
"@types/node": "*",
|
153
153
|
"async": "^3.2.5",
|
154
154
|
"cc": "^3.0.1",
|
155
|
-
"emnapi": "^1.1.
|
155
|
+
"emnapi": "^1.1.1",
|
156
156
|
"exif-reader": "^2.0.1",
|
157
157
|
"extract-zip": "^2.0.1",
|
158
158
|
"icc": "^3.0.0",
|
159
159
|
"jsdoc-to-markdown": "^8.0.1",
|
160
160
|
"license-checker": "^25.0.1",
|
161
|
-
"mocha": "^10.
|
161
|
+
"mocha": "^10.4.0",
|
162
162
|
"node-addon-api": "^8.0.0",
|
163
163
|
"nyc": "^15.1.0",
|
164
|
-
"prebuild": "^13.0.
|
164
|
+
"prebuild": "^13.0.1",
|
165
165
|
"semistandard": "^17.0.0",
|
166
|
-
"tar-fs": "^3.0.
|
167
|
-
"tsd": "^0.
|
166
|
+
"tar-fs": "^3.0.6",
|
167
|
+
"tsd": "^0.31.0"
|
168
168
|
},
|
169
169
|
"license": "Apache-2.0",
|
170
170
|
"engines": {
|
package/src/common.cc
CHANGED
@@ -75,7 +75,7 @@ namespace sharp {
|
|
75
75
|
Napi::Buffer<char> buffer = input.Get("buffer").As<Napi::Buffer<char>>();
|
76
76
|
descriptor->bufferLength = buffer.Length();
|
77
77
|
descriptor->buffer = buffer.Data();
|
78
|
-
descriptor->isBuffer =
|
78
|
+
descriptor->isBuffer = true;
|
79
79
|
}
|
80
80
|
descriptor->failOn = AttrAsEnum<VipsFailOn>(input, "failOn", VIPS_TYPE_FAIL_ON);
|
81
81
|
// Density for vector-based input
|
@@ -384,7 +384,7 @@ namespace sharp {
|
|
384
384
|
->set("access", descriptor->access)
|
385
385
|
->set("fail_on", descriptor->failOn);
|
386
386
|
if (descriptor->unlimited && ImageTypeSupportsUnlimited(imageType)) {
|
387
|
-
option->set("unlimited",
|
387
|
+
option->set("unlimited", true);
|
388
388
|
}
|
389
389
|
if (imageType == ImageType::SVG || imageType == ImageType::PDF) {
|
390
390
|
option->set("dpi", descriptor->density);
|
@@ -488,7 +488,7 @@ namespace sharp {
|
|
488
488
|
->set("access", descriptor->access)
|
489
489
|
->set("fail_on", descriptor->failOn);
|
490
490
|
if (descriptor->unlimited && ImageTypeSupportsUnlimited(imageType)) {
|
491
|
-
option->set("unlimited",
|
491
|
+
option->set("unlimited", true);
|
492
492
|
}
|
493
493
|
if (imageType == ImageType::SVG || imageType == ImageType::PDF) {
|
494
494
|
option->set("dpi", descriptor->density);
|
@@ -768,7 +768,7 @@ namespace sharp {
|
|
768
768
|
int *timeout = VIPS_NEW(im, int);
|
769
769
|
*timeout = seconds;
|
770
770
|
g_signal_connect(im, "eval", G_CALLBACK(VipsProgressCallBack), timeout);
|
771
|
-
vips_image_set_progress(im,
|
771
|
+
vips_image_set_progress(im, true);
|
772
772
|
}
|
773
773
|
}
|
774
774
|
}
|
@@ -778,7 +778,7 @@ namespace sharp {
|
|
778
778
|
*/
|
779
779
|
void VipsProgressCallBack(VipsImage *im, VipsProgress *progress, int *timeout) {
|
780
780
|
if (*timeout > 0 && progress->run >= *timeout) {
|
781
|
-
vips_image_set_kill(im,
|
781
|
+
vips_image_set_kill(im, true);
|
782
782
|
vips_error("timeout", "%d%% complete", progress->percent);
|
783
783
|
*timeout = 0;
|
784
784
|
}
|
@@ -1081,9 +1081,10 @@ namespace sharp {
|
|
1081
1081
|
/*
|
1082
1082
|
Ensure decoding remains sequential.
|
1083
1083
|
*/
|
1084
|
-
VImage StaySequential(VImage image,
|
1085
|
-
if (
|
1086
|
-
|
1084
|
+
VImage StaySequential(VImage image, bool condition) {
|
1085
|
+
if (vips_image_is_sequential(image.get_image()) && condition) {
|
1086
|
+
image = image.copy_memory().copy();
|
1087
|
+
image.remove(VIPS_META_SEQUENTIAL);
|
1087
1088
|
}
|
1088
1089
|
return image;
|
1089
1090
|
}
|
package/src/common.h
CHANGED
@@ -79,12 +79,12 @@ namespace sharp {
|
|
79
79
|
buffer(nullptr),
|
80
80
|
failOn(VIPS_FAIL_ON_WARNING),
|
81
81
|
limitInputPixels(0x3FFF * 0x3FFF),
|
82
|
-
unlimited(
|
82
|
+
unlimited(false),
|
83
83
|
access(VIPS_ACCESS_RANDOM),
|
84
84
|
bufferLength(0),
|
85
|
-
isBuffer(
|
85
|
+
isBuffer(false),
|
86
86
|
density(72.0),
|
87
|
-
ignoreIcc(
|
87
|
+
ignoreIcc(false),
|
88
88
|
rawDepth(VIPS_FORMAT_UCHAR),
|
89
89
|
rawChannels(0),
|
90
90
|
rawWidth(0),
|
@@ -103,9 +103,9 @@ namespace sharp {
|
|
103
103
|
textWidth(0),
|
104
104
|
textHeight(0),
|
105
105
|
textAlign(VIPS_ALIGN_LOW),
|
106
|
-
textJustify(
|
106
|
+
textJustify(false),
|
107
107
|
textDpi(72),
|
108
|
-
textRgba(
|
108
|
+
textRgba(false),
|
109
109
|
textSpacing(0),
|
110
110
|
textWrap(VIPS_TEXT_WRAP_WORD),
|
111
111
|
textAutofitDpi(0) {}
|
@@ -386,7 +386,7 @@ namespace sharp {
|
|
386
386
|
/*
|
387
387
|
Ensure decoding remains sequential.
|
388
388
|
*/
|
389
|
-
VImage StaySequential(VImage image,
|
389
|
+
VImage StaySequential(VImage image, bool condition = true);
|
390
390
|
|
391
391
|
} // namespace sharp
|
392
392
|
|
package/src/operations.cc
CHANGED
@@ -155,7 +155,7 @@ namespace sharp {
|
|
155
155
|
return image.conv(blur);
|
156
156
|
} else {
|
157
157
|
// Slower, accurate Gaussian blur
|
158
|
-
return StaySequential(image
|
158
|
+
return StaySequential(image).gaussblur(sigma);
|
159
159
|
}
|
160
160
|
}
|
161
161
|
|
@@ -386,7 +386,7 @@ namespace sharp {
|
|
386
386
|
pages.reserve(nPages);
|
387
387
|
|
388
388
|
// Split the image into cropped frames
|
389
|
-
image = StaySequential(image
|
389
|
+
image = StaySequential(image);
|
390
390
|
for (int i = 0; i < nPages; i++) {
|
391
391
|
pages.push_back(
|
392
392
|
image.extract_area(left, *pageHeight * i + top, width, height));
|
package/src/pipeline.cc
CHANGED
@@ -70,8 +70,8 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
70
70
|
// Calculate angle of rotation
|
71
71
|
VipsAngle rotation = VIPS_ANGLE_D0;
|
72
72
|
VipsAngle autoRotation = VIPS_ANGLE_D0;
|
73
|
-
bool autoFlip =
|
74
|
-
bool autoFlop =
|
73
|
+
bool autoFlip = false;
|
74
|
+
bool autoFlop = false;
|
75
75
|
|
76
76
|
if (baton->useExifOrientation) {
|
77
77
|
// Rotate and flip image according to Exif orientation
|
@@ -88,7 +88,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
88
88
|
baton->rotationAngle != 0.0);
|
89
89
|
|
90
90
|
if (shouldRotateBefore) {
|
91
|
-
image = sharp::StaySequential(image,
|
91
|
+
image = sharp::StaySequential(image,
|
92
92
|
rotation != VIPS_ANGLE_D0 ||
|
93
93
|
autoRotation != VIPS_ANGLE_D0 ||
|
94
94
|
autoFlip ||
|
@@ -104,17 +104,17 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
104
104
|
}
|
105
105
|
if (autoFlip) {
|
106
106
|
image = image.flip(VIPS_DIRECTION_VERTICAL);
|
107
|
-
autoFlip =
|
107
|
+
autoFlip = false;
|
108
108
|
} else if (baton->flip) {
|
109
109
|
image = image.flip(VIPS_DIRECTION_VERTICAL);
|
110
|
-
baton->flip =
|
110
|
+
baton->flip = false;
|
111
111
|
}
|
112
112
|
if (autoFlop) {
|
113
113
|
image = image.flip(VIPS_DIRECTION_HORIZONTAL);
|
114
|
-
autoFlop =
|
114
|
+
autoFlop = false;
|
115
115
|
} else if (baton->flop) {
|
116
116
|
image = image.flip(VIPS_DIRECTION_HORIZONTAL);
|
117
|
-
baton->flop =
|
117
|
+
baton->flop = false;
|
118
118
|
}
|
119
119
|
if (rotation != VIPS_ANGLE_D0) {
|
120
120
|
if (rotation != VIPS_ANGLE_D180) {
|
@@ -126,7 +126,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
126
126
|
if (baton->rotationAngle != 0.0) {
|
127
127
|
MultiPageUnsupported(nPages, "Rotate");
|
128
128
|
std::vector<double> background;
|
129
|
-
std::tie(image, background) = sharp::ApplyAlpha(image, baton->rotationBackground,
|
129
|
+
std::tie(image, background) = sharp::ApplyAlpha(image, baton->rotationBackground, false);
|
130
130
|
image = image.rotate(baton->rotationAngle, VImage::option()->set("background", background)).copy_memory();
|
131
131
|
}
|
132
132
|
}
|
@@ -134,7 +134,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
134
134
|
// Trim
|
135
135
|
if (baton->trimThreshold >= 0.0) {
|
136
136
|
MultiPageUnsupported(nPages, "Trim");
|
137
|
-
image = sharp::StaySequential(image
|
137
|
+
image = sharp::StaySequential(image);
|
138
138
|
image = sharp::Trim(image, baton->trimBackground, baton->trimThreshold, baton->trimLineArt);
|
139
139
|
baton->trimOffsetLeft = image.xoffset();
|
140
140
|
baton->trimOffsetTop = image.yoffset();
|
@@ -337,7 +337,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
337
337
|
// Convert to sRGB/P3 using embedded profile
|
338
338
|
try {
|
339
339
|
image = image.icc_transform(processingProfile, VImage::option()
|
340
|
-
->set("embedded",
|
340
|
+
->set("embedded", true)
|
341
341
|
->set("depth", sharp::Is16Bit(image.interpretation()) ? 16 : 8)
|
342
342
|
->set("intent", VIPS_INTENT_PERCEPTUAL));
|
343
343
|
} catch(...) {
|
@@ -357,11 +357,6 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
357
357
|
image = sharp::Flatten(image, baton->flattenBackground);
|
358
358
|
}
|
359
359
|
|
360
|
-
// Negate the colours in the image
|
361
|
-
if (baton->negate) {
|
362
|
-
image = sharp::Negate(image, baton->negateAlpha);
|
363
|
-
}
|
364
|
-
|
365
360
|
// Gamma encoding (darken)
|
366
361
|
if (baton->gamma >= 1 && baton->gamma <= 3) {
|
367
362
|
image = sharp::Gamma(image, 1.0 / baton->gamma);
|
@@ -397,7 +392,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
397
392
|
->set("kernel", baton->kernel));
|
398
393
|
}
|
399
394
|
|
400
|
-
image = sharp::StaySequential(image,
|
395
|
+
image = sharp::StaySequential(image,
|
401
396
|
autoRotation != VIPS_ANGLE_D0 ||
|
402
397
|
baton->flip ||
|
403
398
|
autoFlip ||
|
@@ -500,7 +495,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
500
495
|
|
501
496
|
// Attention-based or Entropy-based crop
|
502
497
|
MultiPageUnsupported(nPages, "Resize strategy");
|
503
|
-
image = sharp::StaySequential(image
|
498
|
+
image = sharp::StaySequential(image);
|
504
499
|
image = image.smartcrop(baton->width, baton->height, VImage::option()
|
505
500
|
->set("interesting", baton->position == 16 ? VIPS_INTERESTING_ENTROPY : VIPS_INTERESTING_ATTENTION)
|
506
501
|
->set("premultiplied", shouldPremultiplyAlpha)
|
@@ -519,7 +514,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
519
514
|
// Rotate post-extract non-90 angle
|
520
515
|
if (!baton->rotateBeforePreExtract && baton->rotationAngle != 0.0) {
|
521
516
|
MultiPageUnsupported(nPages, "Rotate");
|
522
|
-
image = sharp::StaySequential(image
|
517
|
+
image = sharp::StaySequential(image);
|
523
518
|
std::vector<double> background;
|
524
519
|
std::tie(image, background) = sharp::ApplyAlpha(image, baton->rotationBackground, shouldPremultiplyAlpha);
|
525
520
|
image = image.rotate(baton->rotationAngle, VImage::option()->set("background", background));
|
@@ -543,7 +538,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
543
538
|
// Affine transform
|
544
539
|
if (!baton->affineMatrix.empty()) {
|
545
540
|
MultiPageUnsupported(nPages, "Affine");
|
546
|
-
image = sharp::StaySequential(image
|
541
|
+
image = sharp::StaySequential(image);
|
547
542
|
std::vector<double> background;
|
548
543
|
std::tie(image, background) = sharp::ApplyAlpha(image, baton->affineBackground, shouldPremultiplyAlpha);
|
549
544
|
vips::VInterpolate interp = vips::VInterpolate::new_from_name(
|
@@ -566,6 +561,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
566
561
|
std::vector<double> background;
|
567
562
|
std::tie(image, background) = sharp::ApplyAlpha(image, baton->extendBackground, shouldPremultiplyAlpha);
|
568
563
|
|
564
|
+
image = sharp::StaySequential(image, nPages > 1);
|
569
565
|
image = nPages > 1
|
570
566
|
? sharp::EmbedMultiPage(image,
|
571
567
|
baton->extendLeft, baton->extendTop, baton->width, baton->height,
|
@@ -574,7 +570,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
574
570
|
VImage::option()->set("extend", baton->extendWith)->set("background", background));
|
575
571
|
} else {
|
576
572
|
std::vector<double> ignoredBackground(1);
|
577
|
-
image = sharp::StaySequential(image
|
573
|
+
image = sharp::StaySequential(image);
|
578
574
|
image = nPages > 1
|
579
575
|
? sharp::EmbedMultiPage(image,
|
580
576
|
baton->extendLeft, baton->extendTop, baton->width, baton->height,
|
@@ -670,7 +666,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
670
666
|
if (across != 0 || down != 0) {
|
671
667
|
int left;
|
672
668
|
int top;
|
673
|
-
compositeImage = sharp::StaySequential(compositeImage
|
669
|
+
compositeImage = sharp::StaySequential(compositeImage).replicate(across, down);
|
674
670
|
if (composite->hasOffset) {
|
675
671
|
std::tie(left, top) = sharp::CalculateCrop(
|
676
672
|
compositeImage.width(), compositeImage.height(), image.width(), image.height(),
|
@@ -728,13 +724,13 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
728
724
|
|
729
725
|
// Apply normalisation - stretch luminance to cover full dynamic range
|
730
726
|
if (baton->normalise) {
|
731
|
-
image = sharp::StaySequential(image
|
727
|
+
image = sharp::StaySequential(image);
|
732
728
|
image = sharp::Normalise(image, baton->normaliseLower, baton->normaliseUpper);
|
733
729
|
}
|
734
730
|
|
735
731
|
// Apply contrast limiting adaptive histogram equalization (CLAHE)
|
736
732
|
if (baton->claheWidth != 0 && baton->claheHeight != 0) {
|
737
|
-
image = sharp::StaySequential(image
|
733
|
+
image = sharp::StaySequential(image);
|
738
734
|
image = sharp::Clahe(image, baton->claheWidth, baton->claheHeight, baton->claheMaxSlope);
|
739
735
|
}
|
740
736
|
|
@@ -780,7 +776,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
780
776
|
if ((baton->keepMetadata & VIPS_FOREIGN_KEEP_ICC) && baton->colourspacePipeline != VIPS_INTERPRETATION_CMYK &&
|
781
777
|
baton->withIccProfile.empty() && sharp::HasProfile(image)) {
|
782
778
|
image = image.icc_transform(processingProfile, VImage::option()
|
783
|
-
->set("embedded",
|
779
|
+
->set("embedded", true)
|
784
780
|
->set("depth", sharp::Is16Bit(image.interpretation()) ? 16 : 8)
|
785
781
|
->set("intent", VIPS_INTENT_PERCEPTUAL));
|
786
782
|
}
|
@@ -811,7 +807,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
811
807
|
try {
|
812
808
|
image = image.icc_transform(const_cast<char*>(baton->withIccProfile.data()), VImage::option()
|
813
809
|
->set("input_profile", processingProfile)
|
814
|
-
->set("embedded",
|
810
|
+
->set("embedded", true)
|
815
811
|
->set("depth", sharp::Is16Bit(image.interpretation()) ? 16 : 8)
|
816
812
|
->set("intent", VIPS_INTENT_PERCEPTUAL));
|
817
813
|
} catch(...) {
|
@@ -820,6 +816,12 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
820
816
|
} else if (baton->keepMetadata & VIPS_FOREIGN_KEEP_ICC) {
|
821
817
|
image = sharp::SetProfile(image, inputProfile);
|
822
818
|
}
|
819
|
+
|
820
|
+
// Negate the colours in the image
|
821
|
+
if (baton->negate) {
|
822
|
+
image = sharp::Negate(image, baton->negateAlpha);
|
823
|
+
}
|
824
|
+
|
823
825
|
// Override EXIF Orientation tag
|
824
826
|
if (baton->withMetadataOrientation != -1) {
|
825
827
|
image = sharp::SetExifOrientation(image, baton->withMetadataOrientation);
|
@@ -1004,7 +1006,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
1004
1006
|
if (!sharp::HasAlpha(image)) {
|
1005
1007
|
baton->tileBackground.pop_back();
|
1006
1008
|
}
|
1007
|
-
image = sharp::StaySequential(image,
|
1009
|
+
image = sharp::StaySequential(image, baton->tileAngle != 0);
|
1008
1010
|
vips::VOption *options = BuildOptionsDZ(baton);
|
1009
1011
|
VipsArea *area = reinterpret_cast<VipsArea*>(image.dzsave_buffer(options));
|
1010
1012
|
baton->bufferOut = static_cast<char*>(area->data);
|
@@ -1206,7 +1208,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
1206
1208
|
if (!sharp::HasAlpha(image)) {
|
1207
1209
|
baton->tileBackground.pop_back();
|
1208
1210
|
}
|
1209
|
-
image = sharp::StaySequential(image,
|
1211
|
+
image = sharp::StaySequential(image, baton->tileAngle != 0);
|
1210
1212
|
vips::VOption *options = BuildOptionsDZ(baton);
|
1211
1213
|
image.dzsave(const_cast<char*>(baton->fileOut.data()), options);
|
1212
1214
|
baton->formatOut = "dz";
|
@@ -1338,16 +1340,16 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
1338
1340
|
std::tuple<VipsAngle, bool, bool>
|
1339
1341
|
CalculateExifRotationAndFlip(int const exifOrientation) {
|
1340
1342
|
VipsAngle rotate = VIPS_ANGLE_D0;
|
1341
|
-
bool flip =
|
1342
|
-
bool flop =
|
1343
|
+
bool flip = false;
|
1344
|
+
bool flop = false;
|
1343
1345
|
switch (exifOrientation) {
|
1344
1346
|
case 6: rotate = VIPS_ANGLE_D90; break;
|
1345
1347
|
case 3: rotate = VIPS_ANGLE_D180; break;
|
1346
1348
|
case 8: rotate = VIPS_ANGLE_D270; break;
|
1347
|
-
case 2: flop =
|
1348
|
-
case 7: flip =
|
1349
|
-
case 4: flop =
|
1350
|
-
case 5: flip =
|
1349
|
+
case 2: flop = true; break; // flop 1
|
1350
|
+
case 7: flip = true; rotate = VIPS_ANGLE_D90; break; // flip 6
|
1351
|
+
case 4: flop = true; rotate = VIPS_ANGLE_D180; break; // flop 3
|
1352
|
+
case 5: flip = true; rotate = VIPS_ANGLE_D270; break; // flip 8
|
1351
1353
|
}
|
1352
1354
|
return std::make_tuple(rotate, flip, flop);
|
1353
1355
|
}
|
@@ -1395,7 +1397,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
1395
1397
|
std::string suffix;
|
1396
1398
|
if (baton->tileFormat == "png") {
|
1397
1399
|
std::vector<std::pair<std::string, std::string>> options {
|
1398
|
-
{"interlace", baton->pngProgressive ? "
|
1400
|
+
{"interlace", baton->pngProgressive ? "true" : "false"},
|
1399
1401
|
{"compression", std::to_string(baton->pngCompressionLevel)},
|
1400
1402
|
{"filter", baton->pngAdaptiveFiltering ? "all" : "none"}
|
1401
1403
|
};
|
@@ -1404,25 +1406,25 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
1404
1406
|
std::vector<std::pair<std::string, std::string>> options {
|
1405
1407
|
{"Q", std::to_string(baton->webpQuality)},
|
1406
1408
|
{"alpha_q", std::to_string(baton->webpAlphaQuality)},
|
1407
|
-
{"lossless", baton->webpLossless ? "
|
1408
|
-
{"near_lossless", baton->webpNearLossless ? "
|
1409
|
-
{"smart_subsample", baton->webpSmartSubsample ? "
|
1409
|
+
{"lossless", baton->webpLossless ? "true" : "false"},
|
1410
|
+
{"near_lossless", baton->webpNearLossless ? "true" : "false"},
|
1411
|
+
{"smart_subsample", baton->webpSmartSubsample ? "true" : "false"},
|
1410
1412
|
{"preset", vips_enum_nick(VIPS_TYPE_FOREIGN_WEBP_PRESET, baton->webpPreset)},
|
1411
|
-
{"min_size", baton->webpMinSize ? "
|
1412
|
-
{"mixed", baton->webpMixed ? "
|
1413
|
+
{"min_size", baton->webpMinSize ? "true" : "false"},
|
1414
|
+
{"mixed", baton->webpMixed ? "true" : "false"},
|
1413
1415
|
{"effort", std::to_string(baton->webpEffort)}
|
1414
1416
|
};
|
1415
1417
|
suffix = AssembleSuffixString(".webp", options);
|
1416
1418
|
} else {
|
1417
1419
|
std::vector<std::pair<std::string, std::string>> options {
|
1418
1420
|
{"Q", std::to_string(baton->jpegQuality)},
|
1419
|
-
{"interlace", baton->jpegProgressive ? "
|
1421
|
+
{"interlace", baton->jpegProgressive ? "true" : "false"},
|
1420
1422
|
{"subsample_mode", baton->jpegChromaSubsampling == "4:4:4" ? "off" : "on"},
|
1421
|
-
{"trellis_quant", baton->jpegTrellisQuantisation ? "
|
1423
|
+
{"trellis_quant", baton->jpegTrellisQuantisation ? "true" : "false"},
|
1422
1424
|
{"quant_table", std::to_string(baton->jpegQuantisationTable)},
|
1423
|
-
{"overshoot_deringing", baton->jpegOvershootDeringing ? "
|
1424
|
-
{"optimize_scans", baton->jpegOptimiseScans ? "
|
1425
|
-
{"optimize_coding", baton->jpegOptimiseCoding ? "
|
1425
|
+
{"overshoot_deringing", baton->jpegOvershootDeringing ? "true": "false"},
|
1426
|
+
{"optimize_scans", baton->jpegOptimiseScans ? "true": "false"},
|
1427
|
+
{"optimize_coding", baton->jpegOptimiseCoding ? "true": "false"}
|
1426
1428
|
};
|
1427
1429
|
std::string extname = baton->tileLayout == VIPS_FOREIGN_DZ_LAYOUT_DZ ? ".jpeg" : ".jpg";
|
1428
1430
|
suffix = AssembleSuffixString(extname, options);
|