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.
Files changed (49) hide show
  1. package/README.md +12 -18
  2. package/dist/channel.cjs +177 -0
  3. package/{lib/channel.js → dist/channel.mjs} +11 -8
  4. package/dist/colour.cjs +199 -0
  5. package/{lib/colour.js → dist/colour.mjs} +42 -23
  6. package/dist/composite.cjs +213 -0
  7. package/{lib/composite.js → dist/composite.mjs} +14 -11
  8. package/{lib/constructor.js → dist/constructor.cjs} +102 -43
  9. package/dist/constructor.mjs +511 -0
  10. package/dist/index.cjs +25 -0
  11. package/dist/index.d.cts +1999 -0
  12. package/dist/index.d.mts +2046 -0
  13. package/dist/index.mjs +25 -0
  14. package/dist/input.cjs +814 -0
  15. package/{lib/input.js → dist/input.mjs} +232 -76
  16. package/{lib/is.js → dist/is.cjs} +19 -45
  17. package/dist/is.mjs +143 -0
  18. package/{lib/libvips.js → dist/libvips.cjs} +52 -43
  19. package/dist/libvips.mjs +212 -0
  20. package/dist/operation.cjs +998 -0
  21. package/{lib/operation.js → dist/operation.mjs} +131 -91
  22. package/{lib/output.js → dist/output.cjs} +262 -61
  23. package/dist/output.mjs +1788 -0
  24. package/dist/resize.cjs +617 -0
  25. package/{lib/resize.js → dist/resize.mjs} +65 -35
  26. package/dist/sharp.cjs +174 -0
  27. package/dist/sharp.mjs +174 -0
  28. package/{lib/utility.js → dist/utility.cjs} +30 -25
  29. package/dist/utility.mjs +301 -0
  30. package/install/build.js +38 -0
  31. package/lib/index.d.ts +387 -142
  32. package/package.json +90 -85
  33. package/src/binding.gyp +49 -26
  34. package/src/common.cc +203 -111
  35. package/src/common.h +68 -40
  36. package/src/metadata.cc +106 -22
  37. package/src/metadata.h +15 -5
  38. package/src/operations.cc +62 -21
  39. package/src/operations.h +15 -3
  40. package/src/pipeline.cc +391 -201
  41. package/src/pipeline.h +36 -7
  42. package/src/sharp.cc +11 -8
  43. package/src/stats.cc +16 -13
  44. package/src/stats.h +6 -3
  45. package/src/utilities.cc +35 -15
  46. package/src/utilities.h +5 -2
  47. package/install/check.js +0 -41
  48. package/lib/index.js +0 -16
  49. package/lib/sharp.js +0 -114
package/src/common.h CHANGED
@@ -1,13 +1,16 @@
1
- // Copyright 2013 Lovell Fuller and others.
2
- // SPDX-License-Identifier: Apache-2.0
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 < 15) || \
19
- (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION == 15 && VIPS_MICRO_VERSION < 3)
20
- #error "libvips version 8.15.3+ is required - please see https://sharp.pixelplumbing.com/install"
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 ((!defined(__clang__)) && defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6)))
24
- #error "GCC version 4.6+ is required for C++11 features - please see https://sharp.pixelplumbing.com/install"
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 { // NOLINT(runtime/indentation_namespace)
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(VIPS_ACCESS_RANDOM),
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(0),
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
- Does this image type support multiple pages?
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
- bool ImageTypeSupportsUnlimited(ImageType imageType);
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 channel, if any.
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
- // Copyright 2013 Lovell Fuller and others.
2
- // SPDX-License-Identifier: Apache-2.0
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 (vips::VError const &err) {
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("palette-bit-depth") == G_TYPE_INT) {
51
- baton->paletteBitDepth = image.get_int("palette-bit-depth");
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 = sharp::HasAlpha(image);
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.Call(Receiver().Value(), { Napi::String::New(env, warning) });
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
- if (baton->paletteBitDepth > 0) {
175
- info.Set("paletteBitDepth", baton->paletteBitDepth);
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 (std::pair<int, int> const &l : baton->levels) {
273
+ for (const auto& [width, height] : baton->levels) {
210
274
  Napi::Object level = Napi::Object::New(env);
211
- level.Set("width", l.first);
212
- level.Set("height", l.second);
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
- info.Set("background", baton->background[0]);
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 &c : baton->comments) {
339
+ for (const auto& [keyword, text] : baton->comments) {
257
340
  Napi::Object comment = Napi::Object::New(env);
258
- comment.Set("keyword", c.first);
259
- comment.Set("text", c.second);
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().Call(Receiver().Value(), { env.Null(), info });
347
+ Callback().SHARP_CALLBACK_FN_NAME(Receiver().Value(), { env.Null(), info });
265
348
  } else {
266
- Callback().Call(Receiver().Value(), { Napi::Error::New(env, sharp::TrimEnd(baton->err)).Value() });
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
- // Copyright 2013 Lovell Fuller and others.
2
- // SPDX-License-Identifier: Apache-2.0
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
- int paletteBitDepth;
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
- paletteBitDepth(0),
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);