sharp 0.33.0-alpha.8 → 0.33.0-rc.2
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 +6 -2
- package/lib/colour.js +4 -6
- package/lib/constructor.js +9 -7
- package/lib/index.d.ts +79 -16
- package/lib/input.js +34 -8
- package/lib/is.js +15 -1
- package/lib/libvips.js +26 -8
- package/lib/output.js +210 -59
- package/lib/resize.js +42 -45
- package/lib/sharp.js +70 -53
- package/lib/utility.js +10 -4
- package/package.json +36 -23
- package/src/binding.gyp +37 -27
- package/src/common.cc +48 -1
- package/src/common.h +18 -3
- package/src/metadata.cc +3 -3
- package/src/operations.cc +35 -18
- package/src/operations.h +3 -3
- package/src/pipeline.cc +64 -54
- package/src/pipeline.h +13 -9
- package/src/stats.cc +3 -3
- package/src/utilities.cc +5 -0
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.33.0-
|
|
4
|
+
"version": "0.33.0-rc.2",
|
|
5
5
|
"author": "Lovell Fuller <npm@lovell.info>",
|
|
6
6
|
"homepage": "https://github.com/lovell/sharp",
|
|
7
7
|
"contributors": [
|
|
@@ -86,7 +86,9 @@
|
|
|
86
86
|
"Ankur Parihar <ankur.github@gmail.com>",
|
|
87
87
|
"Brahim Ait elhaj <brahima@gmail.com>",
|
|
88
88
|
"Mart Jansink <m.jansink@gmail.com>",
|
|
89
|
-
"Lachlan Newman <lachnewman007@gmail.com>"
|
|
89
|
+
"Lachlan Newman <lachnewman007@gmail.com>",
|
|
90
|
+
"Dennis Beatty <dennis@dcbeatty.com>",
|
|
91
|
+
"Ingvar Stepanyan <me@rreverser.com>"
|
|
90
92
|
],
|
|
91
93
|
"scripts": {
|
|
92
94
|
"install": "node install/check",
|
|
@@ -139,30 +141,36 @@
|
|
|
139
141
|
"semver": "^7.5.4"
|
|
140
142
|
},
|
|
141
143
|
"optionalDependencies": {
|
|
142
|
-
"@
|
|
143
|
-
"@
|
|
144
|
-
"@
|
|
145
|
-
"@
|
|
146
|
-
"@
|
|
147
|
-
"@
|
|
148
|
-
"@
|
|
149
|
-
"@
|
|
150
|
-
"@
|
|
151
|
-
"@
|
|
152
|
-
"@
|
|
153
|
-
"@
|
|
154
|
-
"@
|
|
155
|
-
"@
|
|
156
|
-
"@
|
|
157
|
-
"@
|
|
144
|
+
"@img/sharp-darwin-arm64": "0.33.0-rc.2",
|
|
145
|
+
"@img/sharp-darwin-x64": "0.33.0-rc.2",
|
|
146
|
+
"@img/sharp-libvips-darwin-arm64": "1.0.0",
|
|
147
|
+
"@img/sharp-libvips-darwin-x64": "1.0.0",
|
|
148
|
+
"@img/sharp-libvips-linux-arm": "1.0.0",
|
|
149
|
+
"@img/sharp-libvips-linux-arm64": "1.0.0",
|
|
150
|
+
"@img/sharp-libvips-linux-s390x": "1.0.0",
|
|
151
|
+
"@img/sharp-libvips-linux-x64": "1.0.0",
|
|
152
|
+
"@img/sharp-libvips-linuxmusl-arm64": "1.0.0",
|
|
153
|
+
"@img/sharp-libvips-linuxmusl-x64": "1.0.0",
|
|
154
|
+
"@img/sharp-linux-arm": "0.33.0-rc.2",
|
|
155
|
+
"@img/sharp-linux-arm64": "0.33.0-rc.2",
|
|
156
|
+
"@img/sharp-linux-s390x": "0.33.0-rc.2",
|
|
157
|
+
"@img/sharp-linux-x64": "0.33.0-rc.2",
|
|
158
|
+
"@img/sharp-linuxmusl-arm64": "0.33.0-rc.2",
|
|
159
|
+
"@img/sharp-linuxmusl-x64": "0.33.0-rc.2",
|
|
160
|
+
"@img/sharp-wasm32": "0.33.0-rc.2",
|
|
161
|
+
"@img/sharp-win32-ia32": "0.33.0-rc.2",
|
|
162
|
+
"@img/sharp-win32-x64": "0.33.0-rc.2"
|
|
158
163
|
},
|
|
159
164
|
"devDependencies": {
|
|
160
|
-
"@
|
|
161
|
-
"@
|
|
162
|
-
"@
|
|
165
|
+
"@emnapi/runtime": "^0.44.0",
|
|
166
|
+
"@img/sharp-libvips-dev": "1.0.0",
|
|
167
|
+
"@img/sharp-libvips-dev-wasm32": "1.0.0",
|
|
168
|
+
"@img/sharp-libvips-win32-ia32": "1.0.0",
|
|
169
|
+
"@img/sharp-libvips-win32-x64": "1.0.0",
|
|
163
170
|
"@types/node": "*",
|
|
164
|
-
"async": "^3.2.
|
|
171
|
+
"async": "^3.2.5",
|
|
165
172
|
"cc": "^3.0.1",
|
|
173
|
+
"emnapi": "^0.44.0",
|
|
166
174
|
"exif-reader": "^2.0.0",
|
|
167
175
|
"extract-zip": "^2.0.1",
|
|
168
176
|
"icc": "^3.0.0",
|
|
@@ -179,7 +187,7 @@
|
|
|
179
187
|
"license": "Apache-2.0",
|
|
180
188
|
"engines": {
|
|
181
189
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
|
182
|
-
"libvips": ">=8.
|
|
190
|
+
"libvips": ">=8.15.0"
|
|
183
191
|
},
|
|
184
192
|
"funding": {
|
|
185
193
|
"url": "https://opencollective.com/libvips"
|
|
@@ -200,6 +208,11 @@
|
|
|
200
208
|
"build/include"
|
|
201
209
|
]
|
|
202
210
|
},
|
|
211
|
+
"nyc": {
|
|
212
|
+
"include": [
|
|
213
|
+
"lib"
|
|
214
|
+
]
|
|
215
|
+
},
|
|
203
216
|
"tsd": {
|
|
204
217
|
"directory": "test/types/"
|
|
205
218
|
}
|
package/src/binding.gyp
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
'variables': {
|
|
6
6
|
'vips_version': '<!(node -p "require(\'../lib/libvips\').minimumLibvipsVersion")',
|
|
7
7
|
'platform_and_arch': '<!(node -p "require(\'../lib/libvips\').buildPlatformArch()")',
|
|
8
|
+
'sharp_libvips_version': '<!(node -p "require(\'../package.json\').optionalDependencies[\'@img/sharp-libvips-<(platform_and_arch)\']")',
|
|
8
9
|
'sharp_libvips_include_dir': '<!(node -p "require(\'../lib/libvips\').buildSharpLibvipsIncludeDir()")',
|
|
9
10
|
'sharp_libvips_cplusplus_dir': '<!(node -p "require(\'../lib/libvips\').buildSharpLibvipsCPlusPlusDir()")',
|
|
10
11
|
'sharp_libvips_lib_dir': '<!(node -p "require(\'../lib/libvips\').buildSharpLibvipsLibDir()")'
|
|
@@ -32,11 +33,11 @@
|
|
|
32
33
|
'<(sharp_libvips_lib_dir)/glib-2.0/include'
|
|
33
34
|
],
|
|
34
35
|
'link_settings': {
|
|
35
|
-
'library_dirs': [
|
|
36
|
+
'library_dirs': [
|
|
37
|
+
'<(sharp_libvips_lib_dir)'
|
|
38
|
+
],
|
|
36
39
|
'libraries': [
|
|
37
|
-
'libvips.lib'
|
|
38
|
-
'libglib-2.0.lib',
|
|
39
|
-
'libgobject-2.0.lib'
|
|
40
|
+
'libvips.lib'
|
|
40
41
|
],
|
|
41
42
|
},
|
|
42
43
|
'configurations': {
|
|
@@ -129,6 +130,9 @@
|
|
|
129
130
|
'<(sharp_libvips_include_dir)/glib-2.0',
|
|
130
131
|
'<(sharp_libvips_lib_dir)/glib-2.0/include'
|
|
131
132
|
],
|
|
133
|
+
'library_dirs': [
|
|
134
|
+
'<(sharp_libvips_lib_dir)'
|
|
135
|
+
],
|
|
132
136
|
'conditions': [
|
|
133
137
|
['OS == "win"', {
|
|
134
138
|
'defines': [
|
|
@@ -136,19 +140,13 @@
|
|
|
136
140
|
'_FILE_OFFSET_BITS=64'
|
|
137
141
|
],
|
|
138
142
|
'link_settings': {
|
|
139
|
-
'library_dirs': ['<(sharp_libvips_lib_dir)'],
|
|
140
143
|
'libraries': [
|
|
141
|
-
'libvips.lib'
|
|
142
|
-
'libglib-2.0.lib',
|
|
143
|
-
'libgobject-2.0.lib'
|
|
144
|
+
'libvips.lib'
|
|
144
145
|
]
|
|
145
146
|
}
|
|
146
147
|
}],
|
|
147
148
|
['OS == "mac"', {
|
|
148
149
|
'link_settings': {
|
|
149
|
-
'library_dirs': [
|
|
150
|
-
'<(sharp_libvips_lib_dir)'
|
|
151
|
-
],
|
|
152
150
|
'libraries': [
|
|
153
151
|
'libvips-cpp.42.dylib'
|
|
154
152
|
]
|
|
@@ -157,8 +155,9 @@
|
|
|
157
155
|
'OTHER_LDFLAGS': [
|
|
158
156
|
# Ensure runtime linking is relative to sharp.node
|
|
159
157
|
'-Wl,-rpath,\'@loader_path/../../sharp-libvips-<(platform_and_arch)/lib\'',
|
|
160
|
-
'-Wl,-rpath,\'@loader_path
|
|
161
|
-
'-Wl,-rpath,\'@loader_path
|
|
158
|
+
'-Wl,-rpath,\'@loader_path/../../../sharp-libvips-<(platform_and_arch)/<(sharp_libvips_version)/lib\'',
|
|
159
|
+
'-Wl,-rpath,\'@loader_path/../../node_modules/@img/sharp-libvips-<(platform_and_arch)/lib\'',
|
|
160
|
+
'-Wl,-rpath,\'@loader_path/../../../node_modules/@img/sharp-libvips-<(platform_and_arch)/lib\''
|
|
162
161
|
]
|
|
163
162
|
}
|
|
164
163
|
}],
|
|
@@ -167,21 +166,39 @@
|
|
|
167
166
|
'_GLIBCXX_USE_CXX11_ABI=1'
|
|
168
167
|
],
|
|
169
168
|
'link_settings': {
|
|
170
|
-
'library_dirs': [
|
|
171
|
-
'<(sharp_libvips_lib_dir)'
|
|
172
|
-
],
|
|
173
169
|
'libraries': [
|
|
174
170
|
'-l:libvips-cpp.so.42'
|
|
175
171
|
],
|
|
176
172
|
'ldflags': [
|
|
177
|
-
# Ensure runtime linking is relative to sharp.node
|
|
178
173
|
'-Wl,-s',
|
|
179
174
|
'-Wl,--disable-new-dtags',
|
|
175
|
+
'-Wl,-z,nodelete',
|
|
180
176
|
'-Wl,-rpath=\'$$ORIGIN/../../sharp-libvips-<(platform_and_arch)/lib\'',
|
|
181
|
-
'-Wl,-rpath=\'$$ORIGIN
|
|
182
|
-
'-Wl,-rpath=\'$$ORIGIN
|
|
177
|
+
'-Wl,-rpath=\'$$ORIGIN/../../../sharp-libvips-<(platform_and_arch)/<(sharp_libvips_version)/lib\'',
|
|
178
|
+
'-Wl,-rpath=\'$$ORIGIN/../../node_modules/@img/sharp-libvips-<(platform_and_arch)/lib\'',
|
|
179
|
+
'-Wl,-rpath=\'$$ORIGIN/../../../node_modules/@img/sharp-libvips-<(platform_and_arch)/lib\''
|
|
183
180
|
]
|
|
184
181
|
}
|
|
182
|
+
}],
|
|
183
|
+
['OS == "emscripten"', {
|
|
184
|
+
'product_extension': 'node.js',
|
|
185
|
+
'link_settings': {
|
|
186
|
+
'ldflags': [
|
|
187
|
+
'-fexceptions',
|
|
188
|
+
'--pre-js=<!(node -p "require.resolve(\'./emscripten/pre.js\')")',
|
|
189
|
+
'-Oz',
|
|
190
|
+
'-sALLOW_MEMORY_GROWTH',
|
|
191
|
+
'-sENVIRONMENT=node',
|
|
192
|
+
'-sEXPORTED_FUNCTIONS=["_vips_shutdown", "_uv_library_shutdown"]',
|
|
193
|
+
'-sNODERAWFS',
|
|
194
|
+
'-sTEXTDECODER=0',
|
|
195
|
+
'-sWASM_ASYNC_COMPILATION=0',
|
|
196
|
+
'-sWASM_BIGINT'
|
|
197
|
+
],
|
|
198
|
+
'libraries': [
|
|
199
|
+
'<!@(PKG_CONFIG_PATH="<!(node -p "require(\'@img/sharp-libvips-dev-wasm32/lib\')")/pkgconfig" pkg-config --static --libs vips-cpp)'
|
|
200
|
+
],
|
|
201
|
+
}
|
|
185
202
|
}]
|
|
186
203
|
]
|
|
187
204
|
}]
|
|
@@ -206,11 +223,6 @@
|
|
|
206
223
|
'configurations': {
|
|
207
224
|
'Release': {
|
|
208
225
|
'conditions': [
|
|
209
|
-
['OS == "linux"', {
|
|
210
|
-
'cflags_cc': [
|
|
211
|
-
'-Wno-cast-function-type'
|
|
212
|
-
]
|
|
213
|
-
}],
|
|
214
226
|
['target_arch == "arm"', {
|
|
215
227
|
'cflags_cc': [
|
|
216
228
|
'-Wno-psabi'
|
|
@@ -256,9 +268,7 @@
|
|
|
256
268
|
'copies': [{
|
|
257
269
|
'destination': 'build/Release',
|
|
258
270
|
'files': [
|
|
259
|
-
'<(sharp_libvips_lib_dir)/libvips-42.dll'
|
|
260
|
-
'<(sharp_libvips_lib_dir)/libglib-2.0-0.dll',
|
|
261
|
-
'<(sharp_libvips_lib_dir)/libgobject-2.0-0.dll'
|
|
271
|
+
'<(sharp_libvips_lib_dir)/libvips-42.dll'
|
|
262
272
|
]
|
|
263
273
|
}]
|
|
264
274
|
}]
|
package/src/common.cc
CHANGED
|
@@ -531,7 +531,33 @@ namespace sharp {
|
|
|
531
531
|
Does this image have an embedded profile?
|
|
532
532
|
*/
|
|
533
533
|
bool HasProfile(VImage image) {
|
|
534
|
-
return
|
|
534
|
+
return image.get_typeof(VIPS_META_ICC_NAME) == VIPS_TYPE_BLOB;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
/*
|
|
538
|
+
Get copy of embedded profile.
|
|
539
|
+
*/
|
|
540
|
+
std::pair<char*, size_t> GetProfile(VImage image) {
|
|
541
|
+
std::pair<char*, size_t> icc(nullptr, 0);
|
|
542
|
+
if (HasProfile(image)) {
|
|
543
|
+
size_t length;
|
|
544
|
+
const void *data = image.get_blob(VIPS_META_ICC_NAME, &length);
|
|
545
|
+
icc.first = static_cast<char*>(g_malloc(length));
|
|
546
|
+
icc.second = length;
|
|
547
|
+
memcpy(icc.first, data, length);
|
|
548
|
+
}
|
|
549
|
+
return icc;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
/*
|
|
553
|
+
Set embedded profile.
|
|
554
|
+
*/
|
|
555
|
+
VImage SetProfile(VImage image, std::pair<char*, size_t> icc) {
|
|
556
|
+
if (icc.first != nullptr) {
|
|
557
|
+
image = image.copy();
|
|
558
|
+
image.set(VIPS_META_ICC_NAME, reinterpret_cast<VipsCallbackFn>(vips_area_free_cb), icc.first, icc.second);
|
|
559
|
+
}
|
|
560
|
+
return image;
|
|
535
561
|
}
|
|
536
562
|
|
|
537
563
|
/*
|
|
@@ -542,6 +568,27 @@ namespace sharp {
|
|
|
542
568
|
return image.has_alpha();
|
|
543
569
|
}
|
|
544
570
|
|
|
571
|
+
static void* RemoveExifCallback(VipsImage *image, char const *field, GValue *value, void *data) {
|
|
572
|
+
std::vector<std::string> *fieldNames = static_cast<std::vector<std::string> *>(data);
|
|
573
|
+
std::string fieldName(field);
|
|
574
|
+
if (fieldName.substr(0, 8) == ("exif-ifd")) {
|
|
575
|
+
fieldNames->push_back(fieldName);
|
|
576
|
+
}
|
|
577
|
+
return nullptr;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/*
|
|
581
|
+
Remove all EXIF-related image fields.
|
|
582
|
+
*/
|
|
583
|
+
VImage RemoveExif(VImage image) {
|
|
584
|
+
std::vector<std::string> fieldNames;
|
|
585
|
+
vips_image_map(image.get_image(), static_cast<VipsImageMapFn>(RemoveExifCallback), &fieldNames);
|
|
586
|
+
for (const auto& f : fieldNames) {
|
|
587
|
+
image.remove(f.data());
|
|
588
|
+
}
|
|
589
|
+
return image;
|
|
590
|
+
}
|
|
591
|
+
|
|
545
592
|
/*
|
|
546
593
|
Get EXIF Orientation of image, if any.
|
|
547
594
|
*/
|
package/src/common.h
CHANGED
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
// Verify platform and compiler compatibility
|
|
16
16
|
|
|
17
17
|
#if (VIPS_MAJOR_VERSION < 8) || \
|
|
18
|
-
(VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION <
|
|
19
|
-
(VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION ==
|
|
20
|
-
#error "libvips version 8.
|
|
18
|
+
(VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION < 15) || \
|
|
19
|
+
(VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION == 15 && VIPS_MICRO_VERSION < 0)
|
|
20
|
+
#error "libvips version 8.15.0+ is required - please see https://sharp.pixelplumbing.com/install"
|
|
21
21
|
#endif
|
|
22
22
|
|
|
23
23
|
#if ((!defined(__clang__)) && defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6)))
|
|
@@ -222,12 +222,27 @@ namespace sharp {
|
|
|
222
222
|
*/
|
|
223
223
|
bool HasProfile(VImage image);
|
|
224
224
|
|
|
225
|
+
/*
|
|
226
|
+
Get copy of embedded profile.
|
|
227
|
+
*/
|
|
228
|
+
std::pair<char*, size_t> GetProfile(VImage image);
|
|
229
|
+
|
|
230
|
+
/*
|
|
231
|
+
Set embedded profile.
|
|
232
|
+
*/
|
|
233
|
+
VImage SetProfile(VImage image, std::pair<char*, size_t> icc);
|
|
234
|
+
|
|
225
235
|
/*
|
|
226
236
|
Does this image have an alpha channel?
|
|
227
237
|
Uses colour space interpretation with number of channels to guess this.
|
|
228
238
|
*/
|
|
229
239
|
bool HasAlpha(VImage image);
|
|
230
240
|
|
|
241
|
+
/*
|
|
242
|
+
Remove all EXIF-related image fields.
|
|
243
|
+
*/
|
|
244
|
+
VImage RemoveExif(VImage image);
|
|
245
|
+
|
|
231
246
|
/*
|
|
232
247
|
Get EXIF Orientation of image, if any.
|
|
233
248
|
*/
|
package/src/metadata.cc
CHANGED
|
@@ -145,7 +145,7 @@ class MetadataWorker : public Napi::AsyncWorker {
|
|
|
145
145
|
// Handle warnings
|
|
146
146
|
std::string warning = sharp::VipsWarningPop();
|
|
147
147
|
while (!warning.empty()) {
|
|
148
|
-
debuglog.
|
|
148
|
+
debuglog.Call(Receiver().Value(), { Napi::String::New(env, warning) });
|
|
149
149
|
warning = sharp::VipsWarningPop();
|
|
150
150
|
}
|
|
151
151
|
|
|
@@ -246,9 +246,9 @@ class MetadataWorker : public Napi::AsyncWorker {
|
|
|
246
246
|
Napi::Buffer<char>::NewOrCopy(env, baton->tifftagPhotoshop,
|
|
247
247
|
baton->tifftagPhotoshopLength, sharp::FreeCallback));
|
|
248
248
|
}
|
|
249
|
-
Callback().
|
|
249
|
+
Callback().Call(Receiver().Value(), { env.Null(), info });
|
|
250
250
|
} else {
|
|
251
|
-
Callback().
|
|
251
|
+
Callback().Call(Receiver().Value(), { Napi::Error::New(env, sharp::TrimEnd(baton->err)).Value() });
|
|
252
252
|
}
|
|
253
253
|
|
|
254
254
|
delete baton->input;
|
package/src/operations.cc
CHANGED
|
@@ -16,30 +16,44 @@ using vips::VError;
|
|
|
16
16
|
|
|
17
17
|
namespace sharp {
|
|
18
18
|
/*
|
|
19
|
-
* Tint an image using the
|
|
19
|
+
* Tint an image using the provided RGB.
|
|
20
20
|
*/
|
|
21
|
-
VImage Tint(VImage image, double const
|
|
22
|
-
|
|
21
|
+
VImage Tint(VImage image, std::vector<double> const tint) {
|
|
22
|
+
std::vector<double> const tintLab = (VImage::black(1, 1) + tint)
|
|
23
|
+
.colourspace(VIPS_INTERPRETATION_LAB, VImage::option()->set("source_space", VIPS_INTERPRETATION_sRGB))
|
|
24
|
+
.getpoint(0, 0);
|
|
25
|
+
// LAB identity function
|
|
26
|
+
VImage identityLab = VImage::identity(VImage::option()->set("bands", 3))
|
|
27
|
+
.colourspace(VIPS_INTERPRETATION_LAB, VImage::option()->set("source_space", VIPS_INTERPRETATION_sRGB));
|
|
28
|
+
// Scale luminance range, 0.0 to 1.0
|
|
29
|
+
VImage l = identityLab[0] / 100;
|
|
30
|
+
// Weighting functions
|
|
31
|
+
VImage weightL = 1.0 - 4.0 * ((l - 0.5) * (l - 0.5));
|
|
32
|
+
VImage weightAB = (weightL * tintLab).extract_band(1, VImage::option()->set("n", 2));
|
|
33
|
+
identityLab = identityLab[0].bandjoin(weightAB);
|
|
34
|
+
// Convert lookup table to sRGB
|
|
35
|
+
VImage lut = identityLab.colourspace(VIPS_INTERPRETATION_sRGB,
|
|
36
|
+
VImage::option()->set("source_space", VIPS_INTERPRETATION_LAB));
|
|
37
|
+
// Original colourspace
|
|
23
38
|
VipsInterpretation typeBeforeTint = image.interpretation();
|
|
24
39
|
if (typeBeforeTint == VIPS_INTERPRETATION_RGB) {
|
|
25
40
|
typeBeforeTint = VIPS_INTERPRETATION_sRGB;
|
|
26
41
|
}
|
|
27
|
-
//
|
|
28
|
-
VImage luminance = image.colourspace(VIPS_INTERPRETATION_LAB)[0];
|
|
29
|
-
// Create the tinted version by combining the L from the original and the chroma from the tint
|
|
30
|
-
std::vector<double> chroma {a, b};
|
|
31
|
-
VImage tinted = luminance
|
|
32
|
-
.bandjoin(chroma)
|
|
33
|
-
.copy(VImage::option()->set("interpretation", VIPS_INTERPRETATION_LAB))
|
|
34
|
-
.colourspace(typeBeforeTint);
|
|
35
|
-
// Attach original alpha channel, if any
|
|
42
|
+
// Apply lookup table
|
|
36
43
|
if (HasAlpha(image)) {
|
|
37
|
-
// Extract original alpha channel
|
|
38
44
|
VImage alpha = image[image.bands() - 1];
|
|
39
|
-
|
|
40
|
-
|
|
45
|
+
image = RemoveAlpha(image)
|
|
46
|
+
.colourspace(VIPS_INTERPRETATION_B_W)
|
|
47
|
+
.maplut(lut)
|
|
48
|
+
.colourspace(typeBeforeTint)
|
|
49
|
+
.bandjoin(alpha);
|
|
50
|
+
} else {
|
|
51
|
+
image = image
|
|
52
|
+
.colourspace(VIPS_INTERPRETATION_B_W)
|
|
53
|
+
.maplut(lut)
|
|
54
|
+
.colourspace(typeBeforeTint);
|
|
41
55
|
}
|
|
42
|
-
return
|
|
56
|
+
return image;
|
|
43
57
|
}
|
|
44
58
|
|
|
45
59
|
/*
|
|
@@ -141,7 +155,7 @@ namespace sharp {
|
|
|
141
155
|
return image.conv(blur);
|
|
142
156
|
} else {
|
|
143
157
|
// Slower, accurate Gaussian blur
|
|
144
|
-
return image.gaussblur(sigma);
|
|
158
|
+
return StaySequential(image, VIPS_ACCESS_SEQUENTIAL).gaussblur(sigma);
|
|
145
159
|
}
|
|
146
160
|
}
|
|
147
161
|
|
|
@@ -265,7 +279,7 @@ namespace sharp {
|
|
|
265
279
|
/*
|
|
266
280
|
Trim an image
|
|
267
281
|
*/
|
|
268
|
-
VImage Trim(VImage image, std::vector<double> background, double threshold) {
|
|
282
|
+
VImage Trim(VImage image, std::vector<double> background, double threshold, bool const lineArt) {
|
|
269
283
|
if (image.width() < 3 && image.height() < 3) {
|
|
270
284
|
throw VError("Image to trim must be at least 3x3 pixels");
|
|
271
285
|
}
|
|
@@ -287,6 +301,7 @@ namespace sharp {
|
|
|
287
301
|
int left, top, width, height;
|
|
288
302
|
left = image.find_trim(&top, &width, &height, VImage::option()
|
|
289
303
|
->set("background", background)
|
|
304
|
+
->set("line_art", lineArt)
|
|
290
305
|
->set("threshold", threshold));
|
|
291
306
|
if (HasAlpha(image)) {
|
|
292
307
|
// Search alpha channel (A)
|
|
@@ -294,6 +309,7 @@ namespace sharp {
|
|
|
294
309
|
VImage alpha = image[image.bands() - 1];
|
|
295
310
|
leftA = alpha.find_trim(&topA, &widthA, &heightA, VImage::option()
|
|
296
311
|
->set("background", backgroundAlpha)
|
|
312
|
+
->set("line_art", lineArt)
|
|
297
313
|
->set("threshold", threshold));
|
|
298
314
|
if (widthA > 0 && heightA > 0) {
|
|
299
315
|
if (width > 0 && height > 0) {
|
|
@@ -370,6 +386,7 @@ namespace sharp {
|
|
|
370
386
|
pages.reserve(nPages);
|
|
371
387
|
|
|
372
388
|
// Split the image into cropped frames
|
|
389
|
+
image = StaySequential(image, VIPS_ACCESS_SEQUENTIAL);
|
|
373
390
|
for (int i = 0; i < nPages; i++) {
|
|
374
391
|
pages.push_back(
|
|
375
392
|
image.extract_area(left, *pageHeight * i + top, width, height));
|
package/src/operations.h
CHANGED
|
@@ -15,9 +15,9 @@ using vips::VImage;
|
|
|
15
15
|
namespace sharp {
|
|
16
16
|
|
|
17
17
|
/*
|
|
18
|
-
* Tint an image using the
|
|
18
|
+
* Tint an image using the provided RGB.
|
|
19
19
|
*/
|
|
20
|
-
VImage Tint(VImage image, double const
|
|
20
|
+
VImage Tint(VImage image, std::vector<double> const tint);
|
|
21
21
|
|
|
22
22
|
/*
|
|
23
23
|
* Stretch luminance to cover full dynamic range.
|
|
@@ -79,7 +79,7 @@ namespace sharp {
|
|
|
79
79
|
/*
|
|
80
80
|
Trim an image
|
|
81
81
|
*/
|
|
82
|
-
VImage Trim(VImage image, std::vector<double> background, double const
|
|
82
|
+
VImage Trim(VImage image, std::vector<double> background, double threshold, bool const lineArt);
|
|
83
83
|
|
|
84
84
|
/*
|
|
85
85
|
* Linear adjustment (a * in + b)
|