sharp 0.33.5 → 0.35.3
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 +12 -18
- package/dist/channel.cjs +177 -0
- package/{lib/channel.js → dist/channel.mjs} +11 -8
- package/dist/colour.cjs +199 -0
- package/{lib/colour.js → dist/colour.mjs} +42 -23
- package/dist/composite.cjs +213 -0
- package/{lib/composite.js → dist/composite.mjs} +14 -11
- package/{lib/constructor.js → dist/constructor.cjs} +102 -43
- package/dist/constructor.mjs +511 -0
- package/dist/index.cjs +25 -0
- package/dist/index.d.cts +1999 -0
- package/dist/index.d.mts +2046 -0
- package/dist/index.mjs +25 -0
- package/dist/input.cjs +814 -0
- package/{lib/input.js → dist/input.mjs} +232 -76
- package/{lib/is.js → dist/is.cjs} +19 -45
- package/dist/is.mjs +143 -0
- package/{lib/libvips.js → dist/libvips.cjs} +52 -43
- package/dist/libvips.mjs +212 -0
- package/dist/operation.cjs +998 -0
- package/{lib/operation.js → dist/operation.mjs} +131 -91
- package/{lib/output.js → dist/output.cjs} +262 -61
- package/dist/output.mjs +1788 -0
- package/dist/resize.cjs +617 -0
- package/{lib/resize.js → dist/resize.mjs} +65 -35
- package/dist/sharp.cjs +174 -0
- package/dist/sharp.mjs +174 -0
- package/{lib/utility.js → dist/utility.cjs} +30 -25
- package/dist/utility.mjs +301 -0
- package/install/build.js +38 -0
- package/lib/index.d.ts +387 -142
- package/package.json +90 -85
- package/src/binding.gyp +49 -26
- package/src/common.cc +203 -111
- package/src/common.h +68 -40
- package/src/metadata.cc +106 -22
- package/src/metadata.h +15 -5
- package/src/operations.cc +62 -21
- package/src/operations.h +15 -3
- package/src/pipeline.cc +391 -201
- package/src/pipeline.h +36 -7
- package/src/sharp.cc +11 -8
- package/src/stats.cc +16 -13
- package/src/stats.h +6 -3
- package/src/utilities.cc +35 -15
- package/src/utilities.h +5 -2
- package/install/check.js +0 -41
- package/lib/index.js +0 -16
- package/lib/sharp.js +0 -114
package/src/common.h
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/*!
|
|
2
|
+
Copyright 2013 Lovell Fuller and others.
|
|
3
|
+
SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
3
5
|
|
|
4
6
|
#ifndef SRC_COMMON_H_
|
|
5
7
|
#define SRC_COMMON_H_
|
|
6
8
|
|
|
9
|
+
#include <atomic>
|
|
7
10
|
#include <string>
|
|
8
11
|
#include <tuple>
|
|
12
|
+
#include <utility>
|
|
9
13
|
#include <vector>
|
|
10
|
-
#include <atomic>
|
|
11
14
|
|
|
12
15
|
#include <napi.h>
|
|
13
16
|
#include <vips/vips8>
|
|
@@ -15,31 +18,35 @@
|
|
|
15
18
|
// Verify platform and compiler compatibility
|
|
16
19
|
|
|
17
20
|
#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.
|
|
21
|
+
(VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION < 18) || \
|
|
22
|
+
(VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION == 18 && VIPS_MICRO_VERSION < 3)
|
|
23
|
+
#error "libvips version 8.18.3+ is required - please see https://sharp.pixelplumbing.com/install"
|
|
21
24
|
#endif
|
|
22
25
|
|
|
23
|
-
#if
|
|
24
|
-
#
|
|
26
|
+
#if defined(__has_include)
|
|
27
|
+
#if !__has_include(<filesystem>)
|
|
28
|
+
#error "C++17 compiler required - please see https://sharp.pixelplumbing.com/install"
|
|
25
29
|
#endif
|
|
26
|
-
|
|
27
|
-
#if (defined(__clang__) && defined(__has_feature))
|
|
28
|
-
#if (!__has_feature(cxx_range_for))
|
|
29
|
-
#error "clang version 3.0+ is required for C++11 features - please see https://sharp.pixelplumbing.com/install"
|
|
30
30
|
#endif
|
|
31
|
+
|
|
32
|
+
#ifdef __EMSCRIPTEN__
|
|
33
|
+
#define SHARP_CALLBACK_FN_NAME Call
|
|
34
|
+
#else
|
|
35
|
+
#define SHARP_CALLBACK_FN_NAME MakeCallback
|
|
31
36
|
#endif
|
|
32
37
|
|
|
33
38
|
using vips::VImage;
|
|
34
39
|
|
|
35
40
|
namespace sharp {
|
|
36
41
|
|
|
37
|
-
struct InputDescriptor {
|
|
42
|
+
struct InputDescriptor {
|
|
38
43
|
std::string name;
|
|
39
44
|
std::string file;
|
|
45
|
+
bool autoOrient;
|
|
40
46
|
char *buffer;
|
|
41
47
|
VipsFailOn failOn;
|
|
42
48
|
uint64_t limitInputPixels;
|
|
49
|
+
uint64_t limitInputChannels;
|
|
43
50
|
bool unlimited;
|
|
44
51
|
VipsAccess access;
|
|
45
52
|
size_t bufferLength;
|
|
@@ -51,13 +58,13 @@ namespace sharp {
|
|
|
51
58
|
int rawWidth;
|
|
52
59
|
int rawHeight;
|
|
53
60
|
bool rawPremultiplied;
|
|
61
|
+
int rawPageHeight;
|
|
54
62
|
int pages;
|
|
55
63
|
int page;
|
|
56
|
-
int level;
|
|
57
|
-
int subifd;
|
|
58
64
|
int createChannels;
|
|
59
65
|
int createWidth;
|
|
60
66
|
int createHeight;
|
|
67
|
+
int createPageHeight;
|
|
61
68
|
std::vector<double> createBackground;
|
|
62
69
|
std::string createNoiseType;
|
|
63
70
|
double createNoiseMean;
|
|
@@ -74,13 +81,27 @@ namespace sharp {
|
|
|
74
81
|
int textSpacing;
|
|
75
82
|
VipsTextWrap textWrap;
|
|
76
83
|
int textAutofitDpi;
|
|
84
|
+
bool joinAnimated;
|
|
85
|
+
int joinAcross;
|
|
86
|
+
int joinShim;
|
|
87
|
+
std::vector<double> joinBackground;
|
|
88
|
+
VipsAlign joinHalign;
|
|
89
|
+
VipsAlign joinValign;
|
|
90
|
+
std::string svgStylesheet;
|
|
91
|
+
bool svgHighBitdepth;
|
|
92
|
+
int tiffSubifd;
|
|
93
|
+
int openSlideLevel;
|
|
94
|
+
std::vector<double> pdfBackground;
|
|
95
|
+
bool jp2Oneshot;
|
|
77
96
|
|
|
78
97
|
InputDescriptor():
|
|
98
|
+
autoOrient(false),
|
|
79
99
|
buffer(nullptr),
|
|
80
100
|
failOn(VIPS_FAIL_ON_WARNING),
|
|
81
101
|
limitInputPixels(0x3FFF * 0x3FFF),
|
|
102
|
+
limitInputChannels(5),
|
|
82
103
|
unlimited(false),
|
|
83
|
-
access(
|
|
104
|
+
access(VIPS_ACCESS_SEQUENTIAL),
|
|
84
105
|
bufferLength(0),
|
|
85
106
|
isBuffer(false),
|
|
86
107
|
density(72.0),
|
|
@@ -90,13 +111,13 @@ namespace sharp {
|
|
|
90
111
|
rawWidth(0),
|
|
91
112
|
rawHeight(0),
|
|
92
113
|
rawPremultiplied(false),
|
|
114
|
+
rawPageHeight(0),
|
|
93
115
|
pages(1),
|
|
94
|
-
page(
|
|
95
|
-
level(0),
|
|
96
|
-
subifd(-1),
|
|
116
|
+
page(-1),
|
|
97
117
|
createChannels(0),
|
|
98
118
|
createWidth(0),
|
|
99
119
|
createHeight(0),
|
|
120
|
+
createPageHeight(0),
|
|
100
121
|
createBackground{ 0.0, 0.0, 0.0, 255.0 },
|
|
101
122
|
createNoiseMean(0.0),
|
|
102
123
|
createNoiseSigma(0.0),
|
|
@@ -108,7 +129,18 @@ namespace sharp {
|
|
|
108
129
|
textRgba(false),
|
|
109
130
|
textSpacing(0),
|
|
110
131
|
textWrap(VIPS_TEXT_WRAP_WORD),
|
|
111
|
-
textAutofitDpi(0)
|
|
132
|
+
textAutofitDpi(0),
|
|
133
|
+
joinAnimated(false),
|
|
134
|
+
joinAcross(1),
|
|
135
|
+
joinShim(0),
|
|
136
|
+
joinBackground{ 0.0, 0.0, 0.0, 255.0 },
|
|
137
|
+
joinHalign(VIPS_ALIGN_LOW),
|
|
138
|
+
joinValign(VIPS_ALIGN_LOW),
|
|
139
|
+
svgHighBitdepth(false),
|
|
140
|
+
tiffSubifd(-1),
|
|
141
|
+
openSlideLevel(0),
|
|
142
|
+
pdfBackground{ 255.0, 255.0, 255.0, 255.0 },
|
|
143
|
+
jp2Oneshot(false) {}
|
|
112
144
|
};
|
|
113
145
|
|
|
114
146
|
// Convenience methods to access the attributes of a Napi::Object
|
|
@@ -147,6 +179,9 @@ namespace sharp {
|
|
|
147
179
|
FITS,
|
|
148
180
|
EXR,
|
|
149
181
|
JXL,
|
|
182
|
+
RAD,
|
|
183
|
+
DCRAW,
|
|
184
|
+
UHDR,
|
|
150
185
|
VIPS,
|
|
151
186
|
RAW,
|
|
152
187
|
UNKNOWN,
|
|
@@ -203,14 +238,9 @@ namespace sharp {
|
|
|
203
238
|
ImageType DetermineImageType(char const *file);
|
|
204
239
|
|
|
205
240
|
/*
|
|
206
|
-
|
|
207
|
-
*/
|
|
208
|
-
bool ImageTypeSupportsPage(ImageType imageType);
|
|
209
|
-
|
|
210
|
-
/*
|
|
211
|
-
Does this image type support removal of safety limits?
|
|
241
|
+
Format-specific options builder
|
|
212
242
|
*/
|
|
213
|
-
|
|
243
|
+
vips::VOption* GetOptionsForImageType(ImageType imageType, InputDescriptor *descriptor);
|
|
214
244
|
|
|
215
245
|
/*
|
|
216
246
|
Open an image from the given InputDescriptor (filesystem, compressed buffer, raw pixel data)
|
|
@@ -232,12 +262,6 @@ namespace sharp {
|
|
|
232
262
|
*/
|
|
233
263
|
VImage SetProfile(VImage image, std::pair<char*, size_t> icc);
|
|
234
264
|
|
|
235
|
-
/*
|
|
236
|
-
Does this image have an alpha channel?
|
|
237
|
-
Uses colour space interpretation with number of channels to guess this.
|
|
238
|
-
*/
|
|
239
|
-
bool HasAlpha(VImage image);
|
|
240
|
-
|
|
241
265
|
/*
|
|
242
266
|
Remove all EXIF-related image fields.
|
|
243
267
|
*/
|
|
@@ -350,12 +374,6 @@ namespace sharp {
|
|
|
350
374
|
*/
|
|
351
375
|
bool Is16Bit(VipsInterpretation const interpretation);
|
|
352
376
|
|
|
353
|
-
/*
|
|
354
|
-
Return the image alpha maximum. Useful for combining alpha bands. scRGB
|
|
355
|
-
images are 0 - 1 for image data, but the alpha is 0 - 255.
|
|
356
|
-
*/
|
|
357
|
-
double MaximumImageAlpha(VipsInterpretation const interpretation);
|
|
358
|
-
|
|
359
377
|
/*
|
|
360
378
|
Convert RGBA value to another colourspace
|
|
361
379
|
*/
|
|
@@ -368,7 +386,7 @@ namespace sharp {
|
|
|
368
386
|
std::tuple<VImage, std::vector<double>> ApplyAlpha(VImage image, std::vector<double> colour, bool premultiply);
|
|
369
387
|
|
|
370
388
|
/*
|
|
371
|
-
Removes alpha
|
|
389
|
+
Removes alpha channels, if any.
|
|
372
390
|
*/
|
|
373
391
|
VImage RemoveAlpha(VImage image);
|
|
374
392
|
|
|
@@ -388,6 +406,16 @@ namespace sharp {
|
|
|
388
406
|
*/
|
|
389
407
|
VImage StaySequential(VImage image, bool condition = true);
|
|
390
408
|
|
|
409
|
+
/*
|
|
410
|
+
Does this image have a gain map?
|
|
411
|
+
*/
|
|
412
|
+
bool HasGainMap(VImage image);
|
|
413
|
+
|
|
414
|
+
/*
|
|
415
|
+
Removes gain map, if any.
|
|
416
|
+
*/
|
|
417
|
+
VImage RemoveGainMap(VImage image);
|
|
418
|
+
|
|
391
419
|
} // namespace sharp
|
|
392
420
|
|
|
393
421
|
#endif // SRC_COMMON_H_
|
package/src/metadata.cc
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/*!
|
|
2
|
+
Copyright 2013 Lovell Fuller and others.
|
|
3
|
+
SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
3
5
|
|
|
6
|
+
#include <cmath>
|
|
4
7
|
#include <numeric>
|
|
8
|
+
#include <string>
|
|
9
|
+
#include <utility>
|
|
5
10
|
#include <vector>
|
|
6
11
|
|
|
7
12
|
#include <napi.h>
|
|
8
13
|
#include <vips/vips8>
|
|
9
14
|
|
|
10
|
-
#include "common.h"
|
|
11
|
-
#include "metadata.h"
|
|
15
|
+
#include "./common.h"
|
|
16
|
+
#include "./metadata.h"
|
|
12
17
|
|
|
13
18
|
static void* readPNGComment(VipsImage *image, const char *field, GValue *value, void *p);
|
|
14
19
|
|
|
@@ -26,7 +31,7 @@ class MetadataWorker : public Napi::AsyncWorker {
|
|
|
26
31
|
sharp::ImageType imageType = sharp::ImageType::UNKNOWN;
|
|
27
32
|
try {
|
|
28
33
|
std::tie(image, imageType) = OpenInput(baton->input);
|
|
29
|
-
} catch (
|
|
34
|
+
} catch (std::runtime_error const &err) {
|
|
30
35
|
(baton->err).append(err.what());
|
|
31
36
|
}
|
|
32
37
|
if (imageType != sharp::ImageType::UNKNOWN) {
|
|
@@ -47,8 +52,11 @@ class MetadataWorker : public Napi::AsyncWorker {
|
|
|
47
52
|
if (image.get_typeof("interlaced") == G_TYPE_INT) {
|
|
48
53
|
baton->isProgressive = image.get_int("interlaced") == 1;
|
|
49
54
|
}
|
|
50
|
-
if (image.get_typeof(
|
|
51
|
-
baton->
|
|
55
|
+
if (image.get_typeof(VIPS_META_PALETTE) == G_TYPE_INT) {
|
|
56
|
+
baton->isPalette = image.get_int(VIPS_META_PALETTE);
|
|
57
|
+
}
|
|
58
|
+
if (image.get_typeof(VIPS_META_BITS_PER_SAMPLE) == G_TYPE_INT) {
|
|
59
|
+
baton->bitsPerSample = image.get_int(VIPS_META_BITS_PER_SAMPLE);
|
|
52
60
|
}
|
|
53
61
|
if (image.get_typeof(VIPS_META_N_PAGES) == G_TYPE_INT) {
|
|
54
62
|
baton->pages = image.get_int(VIPS_META_N_PAGES);
|
|
@@ -91,7 +99,7 @@ class MetadataWorker : public Napi::AsyncWorker {
|
|
|
91
99
|
baton->background = image.get_array_double("background");
|
|
92
100
|
}
|
|
93
101
|
// Derived attributes
|
|
94
|
-
baton->hasAlpha =
|
|
102
|
+
baton->hasAlpha = image.has_alpha();
|
|
95
103
|
baton->orientation = sharp::ExifOrientation(image);
|
|
96
104
|
// EXIF
|
|
97
105
|
if (image.get_typeof(VIPS_META_EXIF_NAME) == VIPS_TYPE_BLOB) {
|
|
@@ -133,8 +141,60 @@ class MetadataWorker : public Napi::AsyncWorker {
|
|
|
133
141
|
memcpy(baton->tifftagPhotoshop, tifftagPhotoshop, tifftagPhotoshopLength);
|
|
134
142
|
baton->tifftagPhotoshopLength = tifftagPhotoshopLength;
|
|
135
143
|
}
|
|
144
|
+
// Gain Map
|
|
145
|
+
if (image.get_typeof("gainmap-data") == VIPS_TYPE_BLOB) {
|
|
146
|
+
size_t gainMapLength;
|
|
147
|
+
void const *gainMap = image.get_blob("gainmap-data", &gainMapLength);
|
|
148
|
+
baton->gainMap = static_cast<char *>(g_malloc(gainMapLength));
|
|
149
|
+
memcpy(baton->gainMap, gainMap, gainMapLength);
|
|
150
|
+
baton->gainMapLength = gainMapLength;
|
|
151
|
+
}
|
|
136
152
|
// PNG comments
|
|
137
153
|
vips_image_map(image.get_image(), readPNGComment, &baton->comments);
|
|
154
|
+
// Media type
|
|
155
|
+
std::string mediaType;
|
|
156
|
+
switch (imageType) {
|
|
157
|
+
case sharp::ImageType::JPEG:
|
|
158
|
+
case sharp::ImageType::PNG:
|
|
159
|
+
case sharp::ImageType::WEBP:
|
|
160
|
+
case sharp::ImageType::JP2:
|
|
161
|
+
case sharp::ImageType::TIFF:
|
|
162
|
+
case sharp::ImageType::GIF:
|
|
163
|
+
case sharp::ImageType::FITS:
|
|
164
|
+
case sharp::ImageType::JXL:
|
|
165
|
+
baton->mediaType = "image/" + baton->format;
|
|
166
|
+
break;
|
|
167
|
+
case sharp::ImageType::SVG:
|
|
168
|
+
baton->mediaType = "image/svg+xml";
|
|
169
|
+
break;
|
|
170
|
+
case sharp::ImageType::HEIF:
|
|
171
|
+
if (baton->compression == "av1") {
|
|
172
|
+
baton->mediaType = "image/avif";
|
|
173
|
+
} else if (baton->compression == "hevc") {
|
|
174
|
+
baton->mediaType = "image/heic";
|
|
175
|
+
}
|
|
176
|
+
break;
|
|
177
|
+
case sharp::ImageType::PDF:
|
|
178
|
+
baton->mediaType = "application/pdf";
|
|
179
|
+
break;
|
|
180
|
+
case sharp::ImageType::OPENSLIDE:
|
|
181
|
+
baton->mediaType = "image/tiff";
|
|
182
|
+
break;
|
|
183
|
+
case sharp::ImageType::PPM:
|
|
184
|
+
baton->mediaType = "image/x-portable-pixmap";
|
|
185
|
+
break;
|
|
186
|
+
case sharp::ImageType::EXR:
|
|
187
|
+
baton->mediaType = "image/x-exr";
|
|
188
|
+
break;
|
|
189
|
+
case sharp::ImageType::RAD:
|
|
190
|
+
baton->mediaType = "image/vnd.radiance";
|
|
191
|
+
break;
|
|
192
|
+
case sharp::ImageType::UHDR:
|
|
193
|
+
baton->mediaType = "image/jpeg";
|
|
194
|
+
break;
|
|
195
|
+
default:
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
138
198
|
}
|
|
139
199
|
|
|
140
200
|
// Clean up
|
|
@@ -149,13 +209,16 @@ class MetadataWorker : public Napi::AsyncWorker {
|
|
|
149
209
|
// Handle warnings
|
|
150
210
|
std::string warning = sharp::VipsWarningPop();
|
|
151
211
|
while (!warning.empty()) {
|
|
152
|
-
debuglog.
|
|
212
|
+
debuglog.SHARP_CALLBACK_FN_NAME(Receiver().Value(), { Napi::String::New(env, warning) });
|
|
153
213
|
warning = sharp::VipsWarningPop();
|
|
154
214
|
}
|
|
155
215
|
|
|
156
216
|
if (baton->err.empty()) {
|
|
157
217
|
Napi::Object info = Napi::Object::New(env);
|
|
158
218
|
info.Set("format", baton->format);
|
|
219
|
+
if (!baton->mediaType.empty()) {
|
|
220
|
+
info.Set("mediaType", baton->mediaType);
|
|
221
|
+
}
|
|
159
222
|
if (baton->input->bufferLength > 0) {
|
|
160
223
|
info.Set("size", baton->input->bufferLength);
|
|
161
224
|
}
|
|
@@ -171,8 +234,9 @@ class MetadataWorker : public Napi::AsyncWorker {
|
|
|
171
234
|
info.Set("chromaSubsampling", baton->chromaSubsampling);
|
|
172
235
|
}
|
|
173
236
|
info.Set("isProgressive", baton->isProgressive);
|
|
174
|
-
|
|
175
|
-
|
|
237
|
+
info.Set("isPalette", baton->isPalette);
|
|
238
|
+
if (baton->bitsPerSample > 0) {
|
|
239
|
+
info.Set("bitsPerSample", baton->bitsPerSample);
|
|
176
240
|
}
|
|
177
241
|
if (baton->pages > 0) {
|
|
178
242
|
info.Set("pages", baton->pages);
|
|
@@ -206,10 +270,10 @@ class MetadataWorker : public Napi::AsyncWorker {
|
|
|
206
270
|
if (!baton->levels.empty()) {
|
|
207
271
|
int i = 0;
|
|
208
272
|
Napi::Array levels = Napi::Array::New(env, static_cast<size_t>(baton->levels.size()));
|
|
209
|
-
for (
|
|
273
|
+
for (const auto& [width, height] : baton->levels) {
|
|
210
274
|
Napi::Object level = Napi::Object::New(env);
|
|
211
|
-
level.Set("width",
|
|
212
|
-
level.Set("height",
|
|
275
|
+
level.Set("width", width);
|
|
276
|
+
level.Set("height", height);
|
|
213
277
|
levels.Set(i++, level);
|
|
214
278
|
}
|
|
215
279
|
info.Set("levels", levels);
|
|
@@ -218,21 +282,30 @@ class MetadataWorker : public Napi::AsyncWorker {
|
|
|
218
282
|
info.Set("subifds", baton->subifds);
|
|
219
283
|
}
|
|
220
284
|
if (!baton->background.empty()) {
|
|
285
|
+
Napi::Object background = Napi::Object::New(env);
|
|
221
286
|
if (baton->background.size() == 3) {
|
|
222
|
-
Napi::Object background = Napi::Object::New(env);
|
|
223
287
|
background.Set("r", baton->background[0]);
|
|
224
288
|
background.Set("g", baton->background[1]);
|
|
225
289
|
background.Set("b", baton->background[2]);
|
|
226
|
-
info.Set("background", background);
|
|
227
290
|
} else {
|
|
228
|
-
|
|
291
|
+
background.Set("gray", round(baton->background[0] * 100 / 255));
|
|
229
292
|
}
|
|
293
|
+
info.Set("background", background);
|
|
230
294
|
}
|
|
231
295
|
info.Set("hasProfile", baton->hasProfile);
|
|
232
296
|
info.Set("hasAlpha", baton->hasAlpha);
|
|
233
297
|
if (baton->orientation > 0) {
|
|
234
298
|
info.Set("orientation", baton->orientation);
|
|
235
299
|
}
|
|
300
|
+
Napi::Object autoOrient = Napi::Object::New(env);
|
|
301
|
+
info.Set("autoOrient", autoOrient);
|
|
302
|
+
if (baton->orientation >= 5) {
|
|
303
|
+
autoOrient.Set("width", baton->height);
|
|
304
|
+
autoOrient.Set("height", baton->width);
|
|
305
|
+
} else {
|
|
306
|
+
autoOrient.Set("width", baton->width);
|
|
307
|
+
autoOrient.Set("height", baton->height);
|
|
308
|
+
}
|
|
236
309
|
if (baton->exifLength > 0) {
|
|
237
310
|
info.Set("exif", Napi::Buffer<char>::NewOrCopy(env, baton->exif, baton->exifLength, sharp::FreeCallback));
|
|
238
311
|
}
|
|
@@ -243,6 +316,10 @@ class MetadataWorker : public Napi::AsyncWorker {
|
|
|
243
316
|
info.Set("iptc", Napi::Buffer<char>::NewOrCopy(env, baton->iptc, baton->iptcLength, sharp::FreeCallback));
|
|
244
317
|
}
|
|
245
318
|
if (baton->xmpLength > 0) {
|
|
319
|
+
if (g_utf8_validate(static_cast<char const *>(baton->xmp), baton->xmpLength, nullptr)) {
|
|
320
|
+
info.Set("xmpAsString",
|
|
321
|
+
Napi::String::New(env, static_cast<char const *>(baton->xmp), baton->xmpLength));
|
|
322
|
+
}
|
|
246
323
|
info.Set("xmp", Napi::Buffer<char>::NewOrCopy(env, baton->xmp, baton->xmpLength, sharp::FreeCallback));
|
|
247
324
|
}
|
|
248
325
|
if (baton->tifftagPhotoshopLength > 0) {
|
|
@@ -250,20 +327,27 @@ class MetadataWorker : public Napi::AsyncWorker {
|
|
|
250
327
|
Napi::Buffer<char>::NewOrCopy(env, baton->tifftagPhotoshop,
|
|
251
328
|
baton->tifftagPhotoshopLength, sharp::FreeCallback));
|
|
252
329
|
}
|
|
330
|
+
if (baton->gainMapLength > 0) {
|
|
331
|
+
Napi::Object gainMap = Napi::Object::New(env);
|
|
332
|
+
info.Set("gainMap", gainMap);
|
|
333
|
+
gainMap.Set("image",
|
|
334
|
+
Napi::Buffer<char>::NewOrCopy(env, baton->gainMap, baton->gainMapLength, sharp::FreeCallback));
|
|
335
|
+
}
|
|
253
336
|
if (baton->comments.size() > 0) {
|
|
254
337
|
int i = 0;
|
|
255
338
|
Napi::Array comments = Napi::Array::New(env, baton->comments.size());
|
|
256
|
-
for (auto
|
|
339
|
+
for (const auto& [keyword, text] : baton->comments) {
|
|
257
340
|
Napi::Object comment = Napi::Object::New(env);
|
|
258
|
-
comment.Set("keyword",
|
|
259
|
-
comment.Set("text",
|
|
341
|
+
comment.Set("keyword", keyword);
|
|
342
|
+
comment.Set("text", text);
|
|
260
343
|
comments.Set(i++, comment);
|
|
261
344
|
}
|
|
262
345
|
info.Set("comments", comments);
|
|
263
346
|
}
|
|
264
|
-
Callback().
|
|
347
|
+
Callback().SHARP_CALLBACK_FN_NAME(Receiver().Value(), { env.Null(), info });
|
|
265
348
|
} else {
|
|
266
|
-
Callback().
|
|
349
|
+
Callback().SHARP_CALLBACK_FN_NAME(Receiver().Value(),
|
|
350
|
+
{ Napi::Error::New(env, sharp::TrimEnd(baton->err)).Value() });
|
|
267
351
|
}
|
|
268
352
|
|
|
269
353
|
delete baton->input;
|
package/src/metadata.h
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/*!
|
|
2
|
+
Copyright 2013 Lovell Fuller and others.
|
|
3
|
+
SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
3
5
|
|
|
4
6
|
#ifndef SRC_METADATA_H_
|
|
5
7
|
#define SRC_METADATA_H_
|
|
6
8
|
|
|
7
9
|
#include <string>
|
|
10
|
+
#include <vector>
|
|
8
11
|
#include <napi.h>
|
|
9
12
|
|
|
10
13
|
#include "./common.h"
|
|
@@ -16,6 +19,7 @@ struct MetadataBaton {
|
|
|
16
19
|
sharp::InputDescriptor *input;
|
|
17
20
|
// Output
|
|
18
21
|
std::string format;
|
|
22
|
+
std::string mediaType;
|
|
19
23
|
int width;
|
|
20
24
|
int height;
|
|
21
25
|
std::string space;
|
|
@@ -24,7 +28,8 @@ struct MetadataBaton {
|
|
|
24
28
|
int density;
|
|
25
29
|
std::string chromaSubsampling;
|
|
26
30
|
bool isProgressive;
|
|
27
|
-
|
|
31
|
+
bool isPalette;
|
|
32
|
+
int bitsPerSample;
|
|
28
33
|
int pages;
|
|
29
34
|
int pageHeight;
|
|
30
35
|
int loop;
|
|
@@ -49,6 +54,8 @@ struct MetadataBaton {
|
|
|
49
54
|
size_t xmpLength;
|
|
50
55
|
char *tifftagPhotoshop;
|
|
51
56
|
size_t tifftagPhotoshopLength;
|
|
57
|
+
char *gainMap;
|
|
58
|
+
size_t gainMapLength;
|
|
52
59
|
MetadataComments comments;
|
|
53
60
|
std::string err;
|
|
54
61
|
|
|
@@ -59,7 +66,8 @@ struct MetadataBaton {
|
|
|
59
66
|
channels(0),
|
|
60
67
|
density(0),
|
|
61
68
|
isProgressive(false),
|
|
62
|
-
|
|
69
|
+
isPalette(false),
|
|
70
|
+
bitsPerSample(0),
|
|
63
71
|
pages(0),
|
|
64
72
|
pageHeight(0),
|
|
65
73
|
loop(-1),
|
|
@@ -77,7 +85,9 @@ struct MetadataBaton {
|
|
|
77
85
|
xmp(nullptr),
|
|
78
86
|
xmpLength(0),
|
|
79
87
|
tifftagPhotoshop(nullptr),
|
|
80
|
-
tifftagPhotoshopLength(0)
|
|
88
|
+
tifftagPhotoshopLength(0),
|
|
89
|
+
gainMap(nullptr),
|
|
90
|
+
gainMapLength(0) {}
|
|
81
91
|
};
|
|
82
92
|
|
|
83
93
|
Napi::Value metadata(const Napi::CallbackInfo& info);
|