sharp 0.31.3 → 0.32.1
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/README.md +1 -3
- package/binding.gyp +1 -1
- package/install/can-compile.js +3 -0
- package/install/dll-copy.js +3 -0
- package/install/libvips.js +21 -15
- package/lib/agent.js +4 -1
- package/lib/channel.js +3 -0
- package/lib/colour.js +5 -1
- package/lib/composite.js +3 -0
- package/lib/constructor.js +20 -11
- package/lib/index.d.ts +1621 -0
- package/lib/index.js +3 -0
- package/lib/input.js +32 -6
- package/lib/is.js +12 -0
- package/lib/libvips.js +5 -2
- package/lib/operation.js +104 -37
- package/lib/output.js +31 -15
- package/lib/platform.js +3 -0
- package/lib/resize.js +52 -19
- package/lib/sharp.js +3 -0
- package/lib/utility.js +5 -1
- package/package.json +30 -23
- package/src/common.cc +26 -21
- package/src/common.h +19 -17
- package/src/libvips/cplusplus/vips-operators.cpp +7 -0
- package/src/metadata.cc +18 -22
- package/src/metadata.h +3 -13
- package/src/operations.cc +39 -44
- package/src/operations.h +9 -15
- package/src/pipeline.cc +88 -52
- package/src/pipeline.h +20 -15
- package/src/sharp.cc +2 -13
- package/src/stats.cc +6 -17
- package/src/stats.h +2 -13
- package/src/utilities.cc +16 -27
- package/src/utilities.h +2 -13
package/lib/utility.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// Copyright 2013 Lovell Fuller and others.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
1
4
|
'use strict';
|
|
2
5
|
|
|
3
6
|
const fs = require('fs');
|
|
@@ -43,7 +46,7 @@ const interpolators = {
|
|
|
43
46
|
};
|
|
44
47
|
|
|
45
48
|
/**
|
|
46
|
-
* An Object containing the version numbers of libvips and its dependencies.
|
|
49
|
+
* An Object containing the version numbers of sharp, libvips and its dependencies.
|
|
47
50
|
* @member
|
|
48
51
|
* @example
|
|
49
52
|
* console.log(sharp.versions);
|
|
@@ -54,6 +57,7 @@ let versions = {
|
|
|
54
57
|
try {
|
|
55
58
|
versions = require(`../vendor/${versions.vips}/${platformAndArch}/versions.json`);
|
|
56
59
|
} catch (_err) { /* ignore */ }
|
|
60
|
+
versions.sharp = require('../package.json').version;
|
|
57
61
|
|
|
58
62
|
/**
|
|
59
63
|
* An Object containing the platform and architecture
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "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.
|
|
4
|
+
"version": "0.32.1",
|
|
5
5
|
"author": "Lovell Fuller <npm@lovell.info>",
|
|
6
6
|
"homepage": "https://github.com/lovell/sharp",
|
|
7
7
|
"contributors": [
|
|
@@ -85,21 +85,24 @@
|
|
|
85
85
|
"Brodan <christopher.hranj@gmail.com",
|
|
86
86
|
"Ankur Parihar <ankur.github@gmail.com>",
|
|
87
87
|
"Brahim Ait elhaj <brahima@gmail.com>",
|
|
88
|
-
"Mart Jansink <m.jansink@gmail.com>"
|
|
88
|
+
"Mart Jansink <m.jansink@gmail.com>",
|
|
89
|
+
"Lachlan Newman <lachnewman007@gmail.com>"
|
|
89
90
|
],
|
|
90
91
|
"scripts": {
|
|
91
92
|
"install": "(node install/libvips && node install/dll-copy && prebuild-install) || (node install/can-compile && node-gyp rebuild && node install/dll-copy)",
|
|
92
93
|
"clean": "rm -rf node_modules/ build/ vendor/ .nyc_output/ coverage/ test/fixtures/output.*",
|
|
93
|
-
"test": "npm run test-lint && npm run test-unit && npm run test-licensing",
|
|
94
|
+
"test": "npm run test-lint && npm run test-unit && npm run test-licensing && npm run test-types",
|
|
94
95
|
"test-lint": "semistandard && cpplint",
|
|
95
96
|
"test-unit": "nyc --reporter=lcov --reporter=text --check-coverage --branches=100 mocha",
|
|
96
97
|
"test-licensing": "license-checker --production --summary --onlyAllow=\"Apache-2.0;BSD;ISC;MIT\"",
|
|
97
98
|
"test-leak": "./test/leak/leak.sh",
|
|
98
|
-
"
|
|
99
|
+
"test-types": "tsd",
|
|
100
|
+
"docs-build": "node docs/build && node docs/search-index/build",
|
|
99
101
|
"docs-serve": "cd docs && npx serve",
|
|
100
102
|
"docs-publish": "cd docs && npx firebase-tools deploy --project pixelplumbing --only hosting:pixelplumbing-sharp"
|
|
101
103
|
},
|
|
102
104
|
"main": "lib/index.js",
|
|
105
|
+
"types": "lib/index.d.ts",
|
|
103
106
|
"files": [
|
|
104
107
|
"binding.gyp",
|
|
105
108
|
"install/**",
|
|
@@ -131,43 +134,44 @@
|
|
|
131
134
|
"dependencies": {
|
|
132
135
|
"color": "^4.2.3",
|
|
133
136
|
"detect-libc": "^2.0.1",
|
|
134
|
-
"node-addon-api": "^
|
|
137
|
+
"node-addon-api": "^6.1.0",
|
|
135
138
|
"prebuild-install": "^7.1.1",
|
|
136
|
-
"semver": "^7.
|
|
139
|
+
"semver": "^7.5.0",
|
|
137
140
|
"simple-get": "^4.0.1",
|
|
138
141
|
"tar-fs": "^2.1.1",
|
|
139
142
|
"tunnel-agent": "^0.6.0"
|
|
140
143
|
},
|
|
141
144
|
"devDependencies": {
|
|
145
|
+
"@types/node": "*",
|
|
142
146
|
"async": "^3.2.4",
|
|
143
147
|
"cc": "^3.0.1",
|
|
144
|
-
"
|
|
145
|
-
"exif-reader": "^1.0.3",
|
|
148
|
+
"exif-reader": "^1.2.0",
|
|
146
149
|
"extract-zip": "^2.0.1",
|
|
147
|
-
"icc": "^
|
|
150
|
+
"icc": "^3.0.0",
|
|
151
|
+
"jsdoc-to-markdown": "^8.0.0",
|
|
148
152
|
"license-checker": "^25.0.1",
|
|
149
153
|
"mocha": "^10.2.0",
|
|
150
154
|
"mock-fs": "^5.2.0",
|
|
151
155
|
"nyc": "^15.1.0",
|
|
152
156
|
"prebuild": "^11.0.4",
|
|
153
|
-
"
|
|
154
|
-
"
|
|
157
|
+
"semistandard": "^16.0.1",
|
|
158
|
+
"tsd": "^0.28.1"
|
|
155
159
|
},
|
|
156
160
|
"license": "Apache-2.0",
|
|
157
161
|
"config": {
|
|
158
|
-
"libvips": "8.
|
|
162
|
+
"libvips": "8.14.2",
|
|
159
163
|
"integrity": {
|
|
160
|
-
"darwin-arm64v8": "sha512-
|
|
161
|
-
"darwin-x64": "sha512-
|
|
162
|
-
"linux-arm64v8": "sha512-
|
|
163
|
-
"linux-armv6": "sha512-
|
|
164
|
-
"linux-armv7": "sha512
|
|
165
|
-
"linux-x64": "sha512-
|
|
166
|
-
"linuxmusl-arm64v8": "sha512-
|
|
167
|
-
"linuxmusl-x64": "sha512-
|
|
168
|
-
"win32-arm64v8": "sha512-
|
|
169
|
-
"win32-ia32": "sha512-
|
|
170
|
-
"win32-x64": "sha512-
|
|
164
|
+
"darwin-arm64v8": "sha512-eUuxg6H0tXgX4z2lsaGtZ4cbPAm7yoFgkvPDd4csxoiVt+QUB25pEJwiXw7oB53VlBFIp3O8lbydSFS5zH8MQQ==",
|
|
165
|
+
"darwin-x64": "sha512-cMT4v76IgzSR0VoXqLk/yftRyzMEZ+SBVMLzXCgqP/lmnYisrpmHHNqrWnoZbUUBXbPXLn6KMultYOJHe/c9ZQ==",
|
|
166
|
+
"linux-arm64v8": "sha512-OcDJ/ly80pxwaKnw0W91sSvZczPtWsjmzrY/+6NMiQZT84LkmeaRuwErbHhorKDxnl7iZuNn9Uj5V25Xmj+LDQ==",
|
|
167
|
+
"linux-armv6": "sha512-hk2ohSOYTJEtVQxEQFyQ+tuayKpYqx6NiXa7AE+8MF+yscxt+g+mLJ7TjDqtmb4ttFGH4IVfsEfU2YXIqWqkpg==",
|
|
168
|
+
"linux-armv7": "sha512-/5Ci2Cd+yLZmTaEt9lVJ89elxX3RMJpps0ESjj43X40yrwka51QfXeg1QV38uNzZpCDIZkrbXZK0lyKldjpLuA==",
|
|
169
|
+
"linux-x64": "sha512-wjCKmWfBb0uz1UB7rPDLvO0s+VWuoAY/Vv/YGCRFEQUkdSLQUgHExrOMMbOM3FleuYfQqznDYCXXphkl7X44+w==",
|
|
170
|
+
"linuxmusl-arm64v8": "sha512-QtD2n90yi+rLE65C0gksFUU5uMUFPICI/pS3A0bgthpIcoCejAOYs3ZjVWpZbHQuV/lWahIUYO78MB9CzY860A==",
|
|
171
|
+
"linuxmusl-x64": "sha512-TokQ/ETCJAsPYuxIMOPYDp25rlcwtpmIMtRUR9PB75TmZEJe7abRfCEInIPYeD8F/HxxnJSLiEdlbn1z1Jfzng==",
|
|
172
|
+
"win32-arm64v8": "sha512-IIuj4EAgLqEVAoOuYH79C61a7TcJXlU/RBwk+5JsGWc2mr4J/Ar5J01e6XBvU4Lu3eqcU+3GPaACZEa1511buA==",
|
|
173
|
+
"win32-ia32": "sha512-CsZi7lrReX3B6tmYgOGJ0IiAfcN5APDC6l+3gdosxfTfwpLLO+jXaSmyNwIGeMqrdgckG/gwwc+IrUZmkmjJ/A==",
|
|
174
|
+
"win32-x64": "sha512-J7znmNKUK4ZKo6SnSnEtzT1xRAwvkGXxIx9/QihAadu1TFdS06yNhcENmwC4973+KZBlAdVpWbZ8sLrEoWkdCA=="
|
|
171
175
|
},
|
|
172
176
|
"runtime": "napi",
|
|
173
177
|
"target": 7
|
|
@@ -193,5 +197,8 @@
|
|
|
193
197
|
"filter": [
|
|
194
198
|
"build/include"
|
|
195
199
|
]
|
|
200
|
+
},
|
|
201
|
+
"tsd": {
|
|
202
|
+
"directory": "test/types/"
|
|
196
203
|
}
|
|
197
204
|
}
|
package/src/common.cc
CHANGED
|
@@ -1,16 +1,5 @@
|
|
|
1
|
-
// Copyright 2013
|
|
2
|
-
//
|
|
3
|
-
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
// you may not use this file except in compliance with the License.
|
|
5
|
-
// You may obtain a copy of the License at
|
|
6
|
-
//
|
|
7
|
-
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
//
|
|
9
|
-
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
// See the License for the specific language governing permissions and
|
|
13
|
-
// limitations under the License.
|
|
1
|
+
// Copyright 2013 Lovell Fuller and others.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
14
3
|
|
|
15
4
|
#include <cstdlib>
|
|
16
5
|
#include <string>
|
|
@@ -76,14 +65,6 @@ namespace sharp {
|
|
|
76
65
|
}
|
|
77
66
|
return vector;
|
|
78
67
|
}
|
|
79
|
-
Napi::Buffer<char> NewOrCopyBuffer(Napi::Env env, char* data, size_t len) {
|
|
80
|
-
try {
|
|
81
|
-
return Napi::Buffer<char>::New(env, data, len, FreeCallback);
|
|
82
|
-
} catch (Napi::Error const &err) {}
|
|
83
|
-
Napi::Buffer<char> buf = Napi::Buffer<char>::Copy(env, data, len);
|
|
84
|
-
FreeCallback(nullptr, data);
|
|
85
|
-
return buf;
|
|
86
|
-
}
|
|
87
68
|
|
|
88
69
|
// Create an InputDescriptor instance from a Napi::Object describing an input image
|
|
89
70
|
InputDescriptor* CreateInputDescriptor(Napi::Object input) {
|
|
@@ -101,6 +82,10 @@ namespace sharp {
|
|
|
101
82
|
if (HasAttr(input, "density")) {
|
|
102
83
|
descriptor->density = AttrAsDouble(input, "density");
|
|
103
84
|
}
|
|
85
|
+
// Should we ignore any embedded ICC profile
|
|
86
|
+
if (HasAttr(input, "ignoreIcc")) {
|
|
87
|
+
descriptor->ignoreIcc = AttrAsBool(input, "ignoreIcc");
|
|
88
|
+
}
|
|
104
89
|
// Raw pixel input
|
|
105
90
|
if (HasAttr(input, "rawChannels")) {
|
|
106
91
|
descriptor->rawDepth = AttrAsEnum<VipsBandFormat>(input, "rawDepth", VIPS_TYPE_BAND_FORMAT);
|
|
@@ -167,6 +152,9 @@ namespace sharp {
|
|
|
167
152
|
if (HasAttr(input, "textSpacing")) {
|
|
168
153
|
descriptor->textSpacing = AttrAsUint32(input, "textSpacing");
|
|
169
154
|
}
|
|
155
|
+
if (HasAttr(input, "textWrap")) {
|
|
156
|
+
descriptor->textWrap = AttrAsEnum<VipsTextWrap>(input, "textWrap", VIPS_TYPE_TEXT_WRAP);
|
|
157
|
+
}
|
|
170
158
|
}
|
|
171
159
|
// Limit input images to a given number of pixels, where pixels = width * height
|
|
172
160
|
descriptor->limitInputPixels = static_cast<uint64_t>(AttrAsInt64(input, "limitInputPixels"));
|
|
@@ -228,6 +216,13 @@ namespace sharp {
|
|
|
228
216
|
return EndsWith(str, ".v") || EndsWith(str, ".V") || EndsWith(str, ".vips") || EndsWith(str, ".VIPS");
|
|
229
217
|
}
|
|
230
218
|
|
|
219
|
+
/*
|
|
220
|
+
Trim space from end of string.
|
|
221
|
+
*/
|
|
222
|
+
std::string TrimEnd(std::string const &str) {
|
|
223
|
+
return str.substr(0, str.find_last_not_of(" \n\r\f") + 1);
|
|
224
|
+
}
|
|
225
|
+
|
|
231
226
|
/*
|
|
232
227
|
Provide a string identifier for the given image type.
|
|
233
228
|
*/
|
|
@@ -454,6 +449,7 @@ namespace sharp {
|
|
|
454
449
|
->set("justify", descriptor->textJustify)
|
|
455
450
|
->set("rgba", descriptor->textRgba)
|
|
456
451
|
->set("spacing", descriptor->textSpacing)
|
|
452
|
+
->set("wrap", descriptor->textWrap)
|
|
457
453
|
->set("autofit_dpi", &descriptor->textAutofitDpi);
|
|
458
454
|
if (descriptor->textWidth > 0) {
|
|
459
455
|
textOptions->set("width", descriptor->textWidth);
|
|
@@ -612,6 +608,15 @@ namespace sharp {
|
|
|
612
608
|
return copy;
|
|
613
609
|
}
|
|
614
610
|
|
|
611
|
+
/*
|
|
612
|
+
Remove GIF palette from image.
|
|
613
|
+
*/
|
|
614
|
+
VImage RemoveGifPalette(VImage image) {
|
|
615
|
+
VImage copy = image.copy();
|
|
616
|
+
copy.remove("gif-palette");
|
|
617
|
+
return copy;
|
|
618
|
+
}
|
|
619
|
+
|
|
615
620
|
/*
|
|
616
621
|
Does this image have a non-default density?
|
|
617
622
|
*/
|
package/src/common.h
CHANGED
|
@@ -1,16 +1,5 @@
|
|
|
1
|
-
// Copyright 2013
|
|
2
|
-
//
|
|
3
|
-
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
// you may not use this file except in compliance with the License.
|
|
5
|
-
// You may obtain a copy of the License at
|
|
6
|
-
//
|
|
7
|
-
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
//
|
|
9
|
-
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
// See the License for the specific language governing permissions and
|
|
13
|
-
// limitations under the License.
|
|
1
|
+
// Copyright 2013 Lovell Fuller and others.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
14
3
|
|
|
15
4
|
#ifndef SRC_COMMON_H_
|
|
16
5
|
#define SRC_COMMON_H_
|
|
@@ -25,9 +14,9 @@
|
|
|
25
14
|
// Verify platform and compiler compatibility
|
|
26
15
|
|
|
27
16
|
#if (VIPS_MAJOR_VERSION < 8) || \
|
|
28
|
-
(VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION <
|
|
29
|
-
(VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION ==
|
|
30
|
-
#error "libvips version 8.
|
|
17
|
+
(VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION < 14) || \
|
|
18
|
+
(VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION == 14 && VIPS_MICRO_VERSION < 2)
|
|
19
|
+
#error "libvips version 8.14.2+ is required - please see https://sharp.pixelplumbing.com/install"
|
|
31
20
|
#endif
|
|
32
21
|
|
|
33
22
|
#if ((!defined(__clang__)) && defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6)))
|
|
@@ -55,6 +44,7 @@ namespace sharp {
|
|
|
55
44
|
size_t bufferLength;
|
|
56
45
|
bool isBuffer;
|
|
57
46
|
double density;
|
|
47
|
+
bool ignoreIcc;
|
|
58
48
|
VipsBandFormat rawDepth;
|
|
59
49
|
int rawChannels;
|
|
60
50
|
int rawWidth;
|
|
@@ -81,6 +71,7 @@ namespace sharp {
|
|
|
81
71
|
int textDpi;
|
|
82
72
|
bool textRgba;
|
|
83
73
|
int textSpacing;
|
|
74
|
+
VipsTextWrap textWrap;
|
|
84
75
|
int textAutofitDpi;
|
|
85
76
|
|
|
86
77
|
InputDescriptor():
|
|
@@ -92,6 +83,7 @@ namespace sharp {
|
|
|
92
83
|
bufferLength(0),
|
|
93
84
|
isBuffer(FALSE),
|
|
94
85
|
density(72.0),
|
|
86
|
+
ignoreIcc(FALSE),
|
|
95
87
|
rawDepth(VIPS_FORMAT_UCHAR),
|
|
96
88
|
rawChannels(0),
|
|
97
89
|
rawWidth(0),
|
|
@@ -114,6 +106,7 @@ namespace sharp {
|
|
|
114
106
|
textDpi(72),
|
|
115
107
|
textRgba(FALSE),
|
|
116
108
|
textSpacing(0),
|
|
109
|
+
textWrap(VIPS_TEXT_WRAP_WORD),
|
|
117
110
|
textAutofitDpi(0) {}
|
|
118
111
|
};
|
|
119
112
|
|
|
@@ -133,7 +126,6 @@ namespace sharp {
|
|
|
133
126
|
return static_cast<T>(
|
|
134
127
|
vips_enum_from_nick(nullptr, type, AttrAsStr(obj, attr).data()));
|
|
135
128
|
}
|
|
136
|
-
Napi::Buffer<char> NewOrCopyBuffer(Napi::Env env, char* data, size_t len);
|
|
137
129
|
|
|
138
130
|
// Create an InputDescriptor instance from a Napi::Object describing an input image
|
|
139
131
|
InputDescriptor* CreateInputDescriptor(Napi::Object input);
|
|
@@ -189,6 +181,11 @@ namespace sharp {
|
|
|
189
181
|
bool IsDzZip(std::string const &str);
|
|
190
182
|
bool IsV(std::string const &str);
|
|
191
183
|
|
|
184
|
+
/*
|
|
185
|
+
Trim space from end of string.
|
|
186
|
+
*/
|
|
187
|
+
std::string TrimEnd(std::string const &str);
|
|
188
|
+
|
|
192
189
|
/*
|
|
193
190
|
Provide a string identifier for the given image type.
|
|
194
191
|
*/
|
|
@@ -255,6 +252,11 @@ namespace sharp {
|
|
|
255
252
|
*/
|
|
256
253
|
VImage RemoveAnimationProperties(VImage image);
|
|
257
254
|
|
|
255
|
+
/*
|
|
256
|
+
Remove GIF palette from image.
|
|
257
|
+
*/
|
|
258
|
+
VImage RemoveGifPalette(VImage image);
|
|
259
|
+
|
|
258
260
|
/*
|
|
259
261
|
Does this image have a non-default density?
|
|
260
262
|
*/
|
|
@@ -3679,6 +3679,13 @@ VipsBlob *VImage::webpsave_buffer( VOption *options ) const
|
|
|
3679
3679
|
return( buffer );
|
|
3680
3680
|
}
|
|
3681
3681
|
|
|
3682
|
+
void VImage::webpsave_mime( VOption *options ) const
|
|
3683
|
+
{
|
|
3684
|
+
call( "webpsave_mime",
|
|
3685
|
+
(options ? options : VImage::option())->
|
|
3686
|
+
set( "in", *this ) );
|
|
3687
|
+
}
|
|
3688
|
+
|
|
3682
3689
|
void VImage::webpsave_target( VTarget target, VOption *options ) const
|
|
3683
3690
|
{
|
|
3684
3691
|
call( "webpsave_target",
|
package/src/metadata.cc
CHANGED
|
@@ -1,16 +1,5 @@
|
|
|
1
|
-
// Copyright 2013
|
|
2
|
-
//
|
|
3
|
-
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
// you may not use this file except in compliance with the License.
|
|
5
|
-
// You may obtain a copy of the License at
|
|
6
|
-
//
|
|
7
|
-
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
//
|
|
9
|
-
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
// See the License for the specific language governing permissions and
|
|
13
|
-
// limitations under the License.
|
|
1
|
+
// Copyright 2013 Lovell Fuller and others.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
14
3
|
|
|
15
4
|
#include <numeric>
|
|
16
5
|
#include <vector>
|
|
@@ -80,6 +69,9 @@ class MetadataWorker : public Napi::AsyncWorker {
|
|
|
80
69
|
if (image.get_typeof(VIPS_META_RESOLUTION_UNIT) == VIPS_TYPE_REF_STRING) {
|
|
81
70
|
baton->resolutionUnit = image.get_string(VIPS_META_RESOLUTION_UNIT);
|
|
82
71
|
}
|
|
72
|
+
if (image.get_typeof("magick-format") == VIPS_TYPE_REF_STRING) {
|
|
73
|
+
baton->formatMagick = image.get_string("magick-format");
|
|
74
|
+
}
|
|
83
75
|
if (image.get_typeof("openslide.level-count") == VIPS_TYPE_REF_STRING) {
|
|
84
76
|
int const levels = std::stoi(image.get_string("openslide.level-count"));
|
|
85
77
|
for (int l = 0; l < levels; l++) {
|
|
@@ -153,7 +145,7 @@ class MetadataWorker : public Napi::AsyncWorker {
|
|
|
153
145
|
// Handle warnings
|
|
154
146
|
std::string warning = sharp::VipsWarningPop();
|
|
155
147
|
while (!warning.empty()) {
|
|
156
|
-
debuglog.
|
|
148
|
+
debuglog.MakeCallback(Receiver().Value(), { Napi::String::New(env, warning) });
|
|
157
149
|
warning = sharp::VipsWarningPop();
|
|
158
150
|
}
|
|
159
151
|
|
|
@@ -204,6 +196,9 @@ class MetadataWorker : public Napi::AsyncWorker {
|
|
|
204
196
|
if (!baton->resolutionUnit.empty()) {
|
|
205
197
|
info.Set("resolutionUnit", baton->resolutionUnit == "in" ? "inch" : baton->resolutionUnit);
|
|
206
198
|
}
|
|
199
|
+
if (!baton->formatMagick.empty()) {
|
|
200
|
+
info.Set("formatMagick", baton->formatMagick);
|
|
201
|
+
}
|
|
207
202
|
if (!baton->levels.empty()) {
|
|
208
203
|
int i = 0;
|
|
209
204
|
Napi::Array levels = Napi::Array::New(env, static_cast<size_t>(baton->levels.size()));
|
|
@@ -235,24 +230,25 @@ class MetadataWorker : public Napi::AsyncWorker {
|
|
|
235
230
|
info.Set("orientation", baton->orientation);
|
|
236
231
|
}
|
|
237
232
|
if (baton->exifLength > 0) {
|
|
238
|
-
info.Set("exif",
|
|
233
|
+
info.Set("exif", Napi::Buffer<char>::NewOrCopy(env, baton->exif, baton->exifLength, sharp::FreeCallback));
|
|
239
234
|
}
|
|
240
235
|
if (baton->iccLength > 0) {
|
|
241
|
-
info.Set("icc",
|
|
236
|
+
info.Set("icc", Napi::Buffer<char>::NewOrCopy(env, baton->icc, baton->iccLength, sharp::FreeCallback));
|
|
242
237
|
}
|
|
243
238
|
if (baton->iptcLength > 0) {
|
|
244
|
-
info.Set("iptc",
|
|
239
|
+
info.Set("iptc", Napi::Buffer<char>::NewOrCopy(env, baton->iptc, baton->iptcLength, sharp::FreeCallback));
|
|
245
240
|
}
|
|
246
241
|
if (baton->xmpLength > 0) {
|
|
247
|
-
info.Set("xmp",
|
|
242
|
+
info.Set("xmp", Napi::Buffer<char>::NewOrCopy(env, baton->xmp, baton->xmpLength, sharp::FreeCallback));
|
|
248
243
|
}
|
|
249
244
|
if (baton->tifftagPhotoshopLength > 0) {
|
|
250
245
|
info.Set("tifftagPhotoshop",
|
|
251
|
-
|
|
246
|
+
Napi::Buffer<char>::NewOrCopy(env, baton->tifftagPhotoshop,
|
|
247
|
+
baton->tifftagPhotoshopLength, sharp::FreeCallback));
|
|
252
248
|
}
|
|
253
249
|
Callback().MakeCallback(Receiver().Value(), { env.Null(), info });
|
|
254
250
|
} else {
|
|
255
|
-
Callback().MakeCallback(Receiver().Value(), { Napi::Error::New(env, baton->err).Value() });
|
|
251
|
+
Callback().MakeCallback(Receiver().Value(), { Napi::Error::New(env, sharp::TrimEnd(baton->err)).Value() });
|
|
256
252
|
}
|
|
257
253
|
|
|
258
254
|
delete baton->input;
|
|
@@ -270,7 +266,7 @@ class MetadataWorker : public Napi::AsyncWorker {
|
|
|
270
266
|
Napi::Value metadata(const Napi::CallbackInfo& info) {
|
|
271
267
|
// V8 objects are converted to non-V8 types held in the baton struct
|
|
272
268
|
MetadataBaton *baton = new MetadataBaton;
|
|
273
|
-
Napi::Object options = info[0].As<Napi::Object>();
|
|
269
|
+
Napi::Object options = info[size_t(0)].As<Napi::Object>();
|
|
274
270
|
|
|
275
271
|
// Input
|
|
276
272
|
baton->input = sharp::CreateInputDescriptor(options.Get("input").As<Napi::Object>());
|
|
@@ -279,7 +275,7 @@ Napi::Value metadata(const Napi::CallbackInfo& info) {
|
|
|
279
275
|
Napi::Function debuglog = options.Get("debuglog").As<Napi::Function>();
|
|
280
276
|
|
|
281
277
|
// Join queue for worker thread
|
|
282
|
-
Napi::Function callback = info[1].As<Napi::Function>();
|
|
278
|
+
Napi::Function callback = info[size_t(1)].As<Napi::Function>();
|
|
283
279
|
MetadataWorker *worker = new MetadataWorker(callback, baton, debuglog);
|
|
284
280
|
worker->Receiver().Set("options", options);
|
|
285
281
|
worker->Queue();
|
package/src/metadata.h
CHANGED
|
@@ -1,16 +1,5 @@
|
|
|
1
|
-
// Copyright 2013
|
|
2
|
-
//
|
|
3
|
-
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
// you may not use this file except in compliance with the License.
|
|
5
|
-
// You may obtain a copy of the License at
|
|
6
|
-
//
|
|
7
|
-
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
//
|
|
9
|
-
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
// See the License for the specific language governing permissions and
|
|
13
|
-
// limitations under the License.
|
|
1
|
+
// Copyright 2013 Lovell Fuller and others.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
14
3
|
|
|
15
4
|
#ifndef SRC_METADATA_H_
|
|
16
5
|
#define SRC_METADATA_H_
|
|
@@ -41,6 +30,7 @@ struct MetadataBaton {
|
|
|
41
30
|
int pagePrimary;
|
|
42
31
|
std::string compression;
|
|
43
32
|
std::string resolutionUnit;
|
|
33
|
+
std::string formatMagick;
|
|
44
34
|
std::vector<std::pair<int, int>> levels;
|
|
45
35
|
int subifds;
|
|
46
36
|
std::vector<double> background;
|
package/src/operations.cc
CHANGED
|
@@ -1,23 +1,11 @@
|
|
|
1
|
-
// Copyright 2013
|
|
2
|
-
//
|
|
3
|
-
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
// you may not use this file except in compliance with the License.
|
|
5
|
-
// You may obtain a copy of the License at
|
|
6
|
-
//
|
|
7
|
-
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
//
|
|
9
|
-
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
// See the License for the specific language governing permissions and
|
|
13
|
-
// limitations under the License.
|
|
1
|
+
// Copyright 2013 Lovell Fuller and others.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
14
3
|
|
|
15
4
|
#include <algorithm>
|
|
16
5
|
#include <functional>
|
|
17
6
|
#include <memory>
|
|
18
7
|
#include <tuple>
|
|
19
8
|
#include <vector>
|
|
20
|
-
|
|
21
9
|
#include <vips/vips8>
|
|
22
10
|
|
|
23
11
|
#include "common.h"
|
|
@@ -57,7 +45,7 @@ namespace sharp {
|
|
|
57
45
|
/*
|
|
58
46
|
* Stretch luminance to cover full dynamic range.
|
|
59
47
|
*/
|
|
60
|
-
VImage Normalise(VImage image) {
|
|
48
|
+
VImage Normalise(VImage image, int const lower, int const upper) {
|
|
61
49
|
// Get original colourspace
|
|
62
50
|
VipsInterpretation typeBeforeNormalize = image.interpretation();
|
|
63
51
|
if (typeBeforeNormalize == VIPS_INTERPRETATION_RGB) {
|
|
@@ -67,9 +55,11 @@ namespace sharp {
|
|
|
67
55
|
VImage lab = image.colourspace(VIPS_INTERPRETATION_LAB);
|
|
68
56
|
// Extract luminance
|
|
69
57
|
VImage luminance = lab[0];
|
|
58
|
+
|
|
70
59
|
// Find luminance range
|
|
71
|
-
int const min = luminance.percent(
|
|
72
|
-
int const max = luminance.percent(
|
|
60
|
+
int const min = lower == 0 ? luminance.min() : luminance.percent(lower);
|
|
61
|
+
int const max = upper == 100 ? luminance.max() : luminance.percent(upper);
|
|
62
|
+
|
|
73
63
|
if (std::abs(max - min) > 1) {
|
|
74
64
|
// Extract chroma
|
|
75
65
|
VImage chroma = lab.extract_band(1, VImage::option()->set("n", 2));
|
|
@@ -196,6 +186,7 @@ namespace sharp {
|
|
|
196
186
|
|
|
197
187
|
VImage Modulate(VImage image, double const brightness, double const saturation,
|
|
198
188
|
int const hue, double const lightness) {
|
|
189
|
+
VipsInterpretation colourspaceBeforeModulate = image.interpretation();
|
|
199
190
|
if (HasAlpha(image)) {
|
|
200
191
|
// Separate alpha channel
|
|
201
192
|
VImage alpha = image[image.bands() - 1];
|
|
@@ -205,7 +196,7 @@ namespace sharp {
|
|
|
205
196
|
{ brightness, saturation, 1},
|
|
206
197
|
{ lightness, 0.0, static_cast<double>(hue) }
|
|
207
198
|
)
|
|
208
|
-
.colourspace(
|
|
199
|
+
.colourspace(colourspaceBeforeModulate)
|
|
209
200
|
.bandjoin(alpha);
|
|
210
201
|
} else {
|
|
211
202
|
return image
|
|
@@ -214,7 +205,7 @@ namespace sharp {
|
|
|
214
205
|
{ brightness, saturation, 1 },
|
|
215
206
|
{ lightness, 0.0, static_cast<double>(hue) }
|
|
216
207
|
)
|
|
217
|
-
.colourspace(
|
|
208
|
+
.colourspace(colourspaceBeforeModulate);
|
|
218
209
|
}
|
|
219
210
|
}
|
|
220
211
|
|
|
@@ -278,30 +269,20 @@ namespace sharp {
|
|
|
278
269
|
if (image.width() < 3 && image.height() < 3) {
|
|
279
270
|
throw VError("Image to trim must be at least 3x3 pixels");
|
|
280
271
|
}
|
|
281
|
-
|
|
282
|
-
// Scale up 8-bit values to match 16-bit input image
|
|
283
|
-
double multiplier = sharp::Is16Bit(image.interpretation()) ? 256.0 : 1.0;
|
|
284
|
-
threshold *= multiplier;
|
|
285
|
-
|
|
286
|
-
std::vector<double> backgroundAlpha(1);
|
|
287
272
|
if (background.size() == 0) {
|
|
288
273
|
// Top-left pixel provides the default background colour if none is given
|
|
289
274
|
background = image.extract_area(0, 0, 1, 1)(0, 0);
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
backgroundAlpha[0] = background[3] * multiplier;
|
|
275
|
+
} else if (sharp::Is16Bit(image.interpretation())) {
|
|
276
|
+
for (size_t i = 0; i < background.size(); i++) {
|
|
277
|
+
background[i] *= 256.0;
|
|
278
|
+
}
|
|
279
|
+
threshold *= 256.0;
|
|
296
280
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
background[1] * multiplier,
|
|
301
|
-
background[2] * multiplier
|
|
302
|
-
};
|
|
281
|
+
std::vector<double> backgroundAlpha({ background.back() });
|
|
282
|
+
if (HasAlpha(image)) {
|
|
283
|
+
background.pop_back();
|
|
303
284
|
} else {
|
|
304
|
-
background
|
|
285
|
+
background.resize(image.bands());
|
|
305
286
|
}
|
|
306
287
|
int left, top, width, height;
|
|
307
288
|
left = image.find_trim(&top, &width, &height, VImage::option()
|
|
@@ -342,12 +323,26 @@ namespace sharp {
|
|
|
342
323
|
if (a.size() > bands) {
|
|
343
324
|
throw VError("Band expansion using linear is unsupported");
|
|
344
325
|
}
|
|
326
|
+
bool const uchar = !Is16Bit(image.interpretation());
|
|
345
327
|
if (HasAlpha(image) && a.size() != bands && (a.size() == 1 || a.size() == bands - 1 || bands - 1 == 1)) {
|
|
346
328
|
// Separate alpha channel
|
|
347
329
|
VImage alpha = image[bands - 1];
|
|
348
|
-
return RemoveAlpha(image).linear(a, b, VImage::option()->set("uchar",
|
|
330
|
+
return RemoveAlpha(image).linear(a, b, VImage::option()->set("uchar", uchar)).bandjoin(alpha);
|
|
331
|
+
} else {
|
|
332
|
+
return image.linear(a, b, VImage::option()->set("uchar", uchar));
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/*
|
|
337
|
+
* Unflatten
|
|
338
|
+
*/
|
|
339
|
+
VImage Unflatten(VImage image) {
|
|
340
|
+
if (HasAlpha(image)) {
|
|
341
|
+
VImage alpha = image[image.bands() - 1];
|
|
342
|
+
VImage noAlpha = RemoveAlpha(image);
|
|
343
|
+
return noAlpha.bandjoin(alpha & (noAlpha.colourspace(VIPS_INTERPRETATION_B_W) < 255));
|
|
349
344
|
} else {
|
|
350
|
-
return image.
|
|
345
|
+
return image.bandjoin(image.colourspace(VIPS_INTERPRETATION_B_W) < 255);
|
|
351
346
|
}
|
|
352
347
|
}
|
|
353
348
|
|
|
@@ -395,11 +390,11 @@ namespace sharp {
|
|
|
395
390
|
* Split into frames, embed each frame, reassemble, and update pageHeight.
|
|
396
391
|
*/
|
|
397
392
|
VImage EmbedMultiPage(VImage image, int left, int top, int width, int height,
|
|
398
|
-
std::vector<double> background, int nPages, int *pageHeight) {
|
|
393
|
+
VipsExtend extendWith, std::vector<double> background, int nPages, int *pageHeight) {
|
|
399
394
|
if (top == 0 && height == *pageHeight) {
|
|
400
395
|
// Fast path; no need to adjust the height of the multi-page image
|
|
401
396
|
return image.embed(left, 0, width, image.height(), VImage::option()
|
|
402
|
-
->set("extend",
|
|
397
|
+
->set("extend", extendWith)
|
|
403
398
|
->set("background", background));
|
|
404
399
|
} else if (left == 0 && width == image.width()) {
|
|
405
400
|
// Fast path; no need to adjust the width of the multi-page image
|
|
@@ -411,7 +406,7 @@ namespace sharp {
|
|
|
411
406
|
|
|
412
407
|
// Do the embed on the wide image
|
|
413
408
|
image = image.embed(0, top, image.width(), height, VImage::option()
|
|
414
|
-
->set("extend",
|
|
409
|
+
->set("extend", extendWith)
|
|
415
410
|
->set("background", background));
|
|
416
411
|
|
|
417
412
|
// Split the wide image into frames
|
|
@@ -441,7 +436,7 @@ namespace sharp {
|
|
|
441
436
|
// Embed each frame in the target size
|
|
442
437
|
for (int i = 0; i < nPages; i++) {
|
|
443
438
|
pages[i] = pages[i].embed(left, top, width, height, VImage::option()
|
|
444
|
-
->set("extend",
|
|
439
|
+
->set("extend", extendWith)
|
|
445
440
|
->set("background", background));
|
|
446
441
|
}
|
|
447
442
|
|