canopycms-cdk 0.0.58 → 0.0.59

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 (144) hide show
  1. package/dist/constructs/asset-support.d.ts +10 -4
  2. package/dist/constructs/asset-support.d.ts.map +1 -1
  3. package/dist/constructs/asset-support.js +4 -1
  4. package/dist/constructs/asset-support.js.map +1 -1
  5. package/dist/constructs/cms-distribution.d.ts +2 -0
  6. package/dist/constructs/cms-distribution.d.ts.map +1 -1
  7. package/dist/constructs/cms-distribution.js +39 -11
  8. package/dist/constructs/cms-distribution.js.map +1 -1
  9. package/dist/constructs/cms-service.d.ts +27 -2
  10. package/dist/constructs/cms-service.d.ts.map +1 -1
  11. package/dist/constructs/cms-service.js +62 -11
  12. package/dist/constructs/cms-service.js.map +1 -1
  13. package/lambda/asset-transform/dist/handler.js +30452 -0
  14. package/lambda/asset-transform/dist/node_modules/.package-lock.json +129 -0
  15. package/lambda/asset-transform/dist/node_modules/@img/colour/LICENSE.md +82 -0
  16. package/lambda/asset-transform/dist/node_modules/@img/colour/README.md +15 -0
  17. package/lambda/asset-transform/dist/node_modules/@img/colour/color.cjs +1596 -0
  18. package/lambda/asset-transform/dist/node_modules/@img/colour/index.cjs +1 -0
  19. package/lambda/asset-transform/dist/node_modules/@img/colour/index.d.ts +929 -0
  20. package/lambda/asset-transform/dist/node_modules/@img/colour/package.json +58 -0
  21. package/lambda/asset-transform/dist/node_modules/@img/sharp-libvips-linux-arm64/README.md +46 -0
  22. package/lambda/asset-transform/dist/node_modules/@img/sharp-libvips-linux-arm64/lib/glib-2.0/include/glibconfig.h +218 -0
  23. package/lambda/asset-transform/dist/node_modules/@img/sharp-libvips-linux-arm64/lib/index.js +1 -0
  24. package/lambda/asset-transform/dist/node_modules/@img/sharp-libvips-linux-arm64/lib/libvips-cpp.so.8.18.3 +0 -0
  25. package/lambda/asset-transform/dist/node_modules/@img/sharp-libvips-linux-arm64/package.json +43 -0
  26. package/lambda/asset-transform/dist/node_modules/@img/sharp-libvips-linux-arm64/versions.json +30 -0
  27. package/lambda/asset-transform/dist/node_modules/@img/sharp-linux-arm64/LICENSE +191 -0
  28. package/lambda/asset-transform/dist/node_modules/@img/sharp-linux-arm64/README.md +18 -0
  29. package/lambda/asset-transform/dist/node_modules/@img/sharp-linux-arm64/index.cjs +2 -0
  30. package/lambda/asset-transform/dist/node_modules/@img/sharp-linux-arm64/lib/sharp-linux-arm64-0.35.3.node +0 -0
  31. package/lambda/asset-transform/dist/node_modules/@img/sharp-linux-arm64/package.json +47 -0
  32. package/lambda/asset-transform/dist/node_modules/detect-libc/LICENSE +201 -0
  33. package/lambda/asset-transform/dist/node_modules/detect-libc/README.md +163 -0
  34. package/lambda/asset-transform/dist/node_modules/detect-libc/index.d.ts +14 -0
  35. package/lambda/asset-transform/dist/node_modules/detect-libc/lib/detect-libc.js +313 -0
  36. package/lambda/asset-transform/dist/node_modules/detect-libc/lib/elf.js +39 -0
  37. package/lambda/asset-transform/dist/node_modules/detect-libc/lib/filesystem.js +51 -0
  38. package/lambda/asset-transform/dist/node_modules/detect-libc/lib/process.js +24 -0
  39. package/lambda/asset-transform/dist/node_modules/detect-libc/package.json +44 -0
  40. package/lambda/asset-transform/dist/node_modules/semver/LICENSE +15 -0
  41. package/lambda/asset-transform/dist/node_modules/semver/README.md +680 -0
  42. package/lambda/asset-transform/dist/node_modules/semver/bin/semver.js +195 -0
  43. package/lambda/asset-transform/dist/node_modules/semver/classes/comparator.js +143 -0
  44. package/lambda/asset-transform/dist/node_modules/semver/classes/index.js +7 -0
  45. package/lambda/asset-transform/dist/node_modules/semver/classes/range.js +577 -0
  46. package/lambda/asset-transform/dist/node_modules/semver/classes/semver.js +350 -0
  47. package/lambda/asset-transform/dist/node_modules/semver/functions/clean.js +8 -0
  48. package/lambda/asset-transform/dist/node_modules/semver/functions/cmp.js +54 -0
  49. package/lambda/asset-transform/dist/node_modules/semver/functions/coerce.js +62 -0
  50. package/lambda/asset-transform/dist/node_modules/semver/functions/compare-build.js +9 -0
  51. package/lambda/asset-transform/dist/node_modules/semver/functions/compare-loose.js +5 -0
  52. package/lambda/asset-transform/dist/node_modules/semver/functions/compare.js +7 -0
  53. package/lambda/asset-transform/dist/node_modules/semver/functions/diff.js +60 -0
  54. package/lambda/asset-transform/dist/node_modules/semver/functions/eq.js +5 -0
  55. package/lambda/asset-transform/dist/node_modules/semver/functions/gt.js +5 -0
  56. package/lambda/asset-transform/dist/node_modules/semver/functions/gte.js +5 -0
  57. package/lambda/asset-transform/dist/node_modules/semver/functions/inc.js +21 -0
  58. package/lambda/asset-transform/dist/node_modules/semver/functions/lt.js +5 -0
  59. package/lambda/asset-transform/dist/node_modules/semver/functions/lte.js +5 -0
  60. package/lambda/asset-transform/dist/node_modules/semver/functions/major.js +5 -0
  61. package/lambda/asset-transform/dist/node_modules/semver/functions/minor.js +5 -0
  62. package/lambda/asset-transform/dist/node_modules/semver/functions/neq.js +5 -0
  63. package/lambda/asset-transform/dist/node_modules/semver/functions/parse.js +18 -0
  64. package/lambda/asset-transform/dist/node_modules/semver/functions/patch.js +5 -0
  65. package/lambda/asset-transform/dist/node_modules/semver/functions/prerelease.js +8 -0
  66. package/lambda/asset-transform/dist/node_modules/semver/functions/rcompare.js +5 -0
  67. package/lambda/asset-transform/dist/node_modules/semver/functions/rsort.js +5 -0
  68. package/lambda/asset-transform/dist/node_modules/semver/functions/satisfies.js +12 -0
  69. package/lambda/asset-transform/dist/node_modules/semver/functions/sort.js +5 -0
  70. package/lambda/asset-transform/dist/node_modules/semver/functions/truncate.js +48 -0
  71. package/lambda/asset-transform/dist/node_modules/semver/functions/valid.js +8 -0
  72. package/lambda/asset-transform/dist/node_modules/semver/index.js +93 -0
  73. package/lambda/asset-transform/dist/node_modules/semver/internal/constants.js +37 -0
  74. package/lambda/asset-transform/dist/node_modules/semver/internal/debug.js +11 -0
  75. package/lambda/asset-transform/dist/node_modules/semver/internal/identifiers.js +29 -0
  76. package/lambda/asset-transform/dist/node_modules/semver/internal/lrucache.js +42 -0
  77. package/lambda/asset-transform/dist/node_modules/semver/internal/parse-options.js +17 -0
  78. package/lambda/asset-transform/dist/node_modules/semver/internal/re.js +223 -0
  79. package/lambda/asset-transform/dist/node_modules/semver/package.json +78 -0
  80. package/lambda/asset-transform/dist/node_modules/semver/preload.js +4 -0
  81. package/lambda/asset-transform/dist/node_modules/semver/range.bnf +17 -0
  82. package/lambda/asset-transform/dist/node_modules/semver/ranges/gtr.js +6 -0
  83. package/lambda/asset-transform/dist/node_modules/semver/ranges/intersects.js +9 -0
  84. package/lambda/asset-transform/dist/node_modules/semver/ranges/ltr.js +6 -0
  85. package/lambda/asset-transform/dist/node_modules/semver/ranges/max-satisfying.js +27 -0
  86. package/lambda/asset-transform/dist/node_modules/semver/ranges/min-satisfying.js +26 -0
  87. package/lambda/asset-transform/dist/node_modules/semver/ranges/min-version.js +63 -0
  88. package/lambda/asset-transform/dist/node_modules/semver/ranges/outside.js +82 -0
  89. package/lambda/asset-transform/dist/node_modules/semver/ranges/simplify.js +49 -0
  90. package/lambda/asset-transform/dist/node_modules/semver/ranges/subset.js +249 -0
  91. package/lambda/asset-transform/dist/node_modules/semver/ranges/to-comparators.js +10 -0
  92. package/lambda/asset-transform/dist/node_modules/semver/ranges/valid.js +13 -0
  93. package/lambda/asset-transform/dist/node_modules/sharp/LICENSE +191 -0
  94. package/lambda/asset-transform/dist/node_modules/sharp/README.md +112 -0
  95. package/lambda/asset-transform/dist/node_modules/sharp/dist/channel.cjs +177 -0
  96. package/lambda/asset-transform/dist/node_modules/sharp/dist/channel.mjs +177 -0
  97. package/lambda/asset-transform/dist/node_modules/sharp/dist/colour.cjs +199 -0
  98. package/lambda/asset-transform/dist/node_modules/sharp/dist/colour.mjs +199 -0
  99. package/lambda/asset-transform/dist/node_modules/sharp/dist/composite.cjs +213 -0
  100. package/lambda/asset-transform/dist/node_modules/sharp/dist/composite.mjs +213 -0
  101. package/lambda/asset-transform/dist/node_modules/sharp/dist/constructor.cjs +511 -0
  102. package/lambda/asset-transform/dist/node_modules/sharp/dist/constructor.mjs +511 -0
  103. package/lambda/asset-transform/dist/node_modules/sharp/dist/index.cjs +25 -0
  104. package/lambda/asset-transform/dist/node_modules/sharp/dist/index.d.cts +1999 -0
  105. package/lambda/asset-transform/dist/node_modules/sharp/dist/index.d.mts +2046 -0
  106. package/lambda/asset-transform/dist/node_modules/sharp/dist/index.mjs +25 -0
  107. package/lambda/asset-transform/dist/node_modules/sharp/dist/input.cjs +814 -0
  108. package/lambda/asset-transform/dist/node_modules/sharp/dist/input.mjs +814 -0
  109. package/lambda/asset-transform/dist/node_modules/sharp/dist/is.cjs +143 -0
  110. package/lambda/asset-transform/dist/node_modules/sharp/dist/is.mjs +143 -0
  111. package/lambda/asset-transform/dist/node_modules/sharp/dist/libvips.cjs +212 -0
  112. package/lambda/asset-transform/dist/node_modules/sharp/dist/libvips.mjs +212 -0
  113. package/lambda/asset-transform/dist/node_modules/sharp/dist/operation.cjs +998 -0
  114. package/lambda/asset-transform/dist/node_modules/sharp/dist/operation.mjs +998 -0
  115. package/lambda/asset-transform/dist/node_modules/sharp/dist/output.cjs +1788 -0
  116. package/lambda/asset-transform/dist/node_modules/sharp/dist/output.mjs +1788 -0
  117. package/lambda/asset-transform/dist/node_modules/sharp/dist/resize.cjs +617 -0
  118. package/lambda/asset-transform/dist/node_modules/sharp/dist/resize.mjs +617 -0
  119. package/lambda/asset-transform/dist/node_modules/sharp/dist/sharp.cjs +174 -0
  120. package/lambda/asset-transform/dist/node_modules/sharp/dist/sharp.mjs +174 -0
  121. package/lambda/asset-transform/dist/node_modules/sharp/dist/utility.cjs +301 -0
  122. package/lambda/asset-transform/dist/node_modules/sharp/dist/utility.mjs +301 -0
  123. package/lambda/asset-transform/dist/node_modules/sharp/install/build.js +38 -0
  124. package/lambda/asset-transform/dist/node_modules/sharp/lib/index.d.ts +1999 -0
  125. package/lambda/asset-transform/dist/node_modules/sharp/package.json +227 -0
  126. package/lambda/asset-transform/dist/node_modules/sharp/src/binding.gyp +303 -0
  127. package/lambda/asset-transform/dist/node_modules/sharp/src/common.cc +1183 -0
  128. package/lambda/asset-transform/dist/node_modules/sharp/src/common.h +421 -0
  129. package/lambda/asset-transform/dist/node_modules/sharp/src/metadata.cc +404 -0
  130. package/lambda/asset-transform/dist/node_modules/sharp/src/metadata.h +95 -0
  131. package/lambda/asset-transform/dist/node_modules/sharp/src/operations.cc +516 -0
  132. package/lambda/asset-transform/dist/node_modules/sharp/src/operations.h +137 -0
  133. package/lambda/asset-transform/dist/node_modules/sharp/src/pipeline.cc +1948 -0
  134. package/lambda/asset-transform/dist/node_modules/sharp/src/pipeline.h +422 -0
  135. package/lambda/asset-transform/dist/node_modules/sharp/src/sharp.cc +43 -0
  136. package/lambda/asset-transform/dist/node_modules/sharp/src/stats.cc +186 -0
  137. package/lambda/asset-transform/dist/node_modules/sharp/src/stats.h +62 -0
  138. package/lambda/asset-transform/dist/node_modules/sharp/src/utilities.cc +289 -0
  139. package/lambda/asset-transform/dist/node_modules/sharp/src/utilities.h +22 -0
  140. package/lambda/asset-transform/dist/package.json +5 -0
  141. package/package.json +5 -4
  142. package/worker/canopy-worker.service +16 -2
  143. package/worker/dist/index.js +50573 -0
  144. package/LICENSE +0 -21
@@ -0,0 +1,404 @@
1
+ /*!
2
+ Copyright 2013 Lovell Fuller and others.
3
+ SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ #include <cmath>
7
+ #include <numeric>
8
+ #include <string>
9
+ #include <utility>
10
+ #include <vector>
11
+
12
+ #include <napi.h>
13
+ #include <vips/vips8>
14
+
15
+ #include "./common.h"
16
+ #include "./metadata.h"
17
+
18
+ static void* readPNGComment(VipsImage *image, const char *field, GValue *value, void *p);
19
+
20
+ class MetadataWorker : public Napi::AsyncWorker {
21
+ public:
22
+ MetadataWorker(Napi::Function callback, MetadataBaton *baton, Napi::Function debuglog) :
23
+ Napi::AsyncWorker(callback), baton(baton), debuglog(Napi::Persistent(debuglog)) {}
24
+ ~MetadataWorker() {}
25
+
26
+ void Execute() {
27
+ // Decrement queued task counter
28
+ sharp::counterQueue--;
29
+
30
+ vips::VImage image;
31
+ sharp::ImageType imageType = sharp::ImageType::UNKNOWN;
32
+ try {
33
+ std::tie(image, imageType) = OpenInput(baton->input);
34
+ } catch (std::runtime_error const &err) {
35
+ (baton->err).append(err.what());
36
+ }
37
+ if (imageType != sharp::ImageType::UNKNOWN) {
38
+ // Image type
39
+ baton->format = sharp::ImageTypeId(imageType);
40
+ // VipsImage attributes
41
+ baton->width = image.width();
42
+ baton->height = image.height();
43
+ baton->space = vips_enum_nick(VIPS_TYPE_INTERPRETATION, image.interpretation());
44
+ baton->channels = image.bands();
45
+ baton->depth = vips_enum_nick(VIPS_TYPE_BAND_FORMAT, image.format());
46
+ if (sharp::HasDensity(image)) {
47
+ baton->density = sharp::GetDensity(image);
48
+ }
49
+ if (image.get_typeof("jpeg-chroma-subsample") == VIPS_TYPE_REF_STRING) {
50
+ baton->chromaSubsampling = image.get_string("jpeg-chroma-subsample");
51
+ }
52
+ if (image.get_typeof("interlaced") == G_TYPE_INT) {
53
+ baton->isProgressive = image.get_int("interlaced") == 1;
54
+ }
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);
60
+ }
61
+ if (image.get_typeof(VIPS_META_N_PAGES) == G_TYPE_INT) {
62
+ baton->pages = image.get_int(VIPS_META_N_PAGES);
63
+ }
64
+ if (image.get_typeof(VIPS_META_PAGE_HEIGHT) == G_TYPE_INT) {
65
+ baton->pageHeight = image.get_int(VIPS_META_PAGE_HEIGHT);
66
+ }
67
+ if (image.get_typeof("loop") == G_TYPE_INT) {
68
+ baton->loop = image.get_int("loop");
69
+ }
70
+ if (image.get_typeof("delay") == VIPS_TYPE_ARRAY_INT) {
71
+ baton->delay = image.get_array_int("delay");
72
+ }
73
+ if (image.get_typeof("heif-primary") == G_TYPE_INT) {
74
+ baton->pagePrimary = image.get_int("heif-primary");
75
+ }
76
+ if (image.get_typeof("heif-compression") == VIPS_TYPE_REF_STRING) {
77
+ baton->compression = image.get_string("heif-compression");
78
+ }
79
+ if (image.get_typeof(VIPS_META_RESOLUTION_UNIT) == VIPS_TYPE_REF_STRING) {
80
+ baton->resolutionUnit = image.get_string(VIPS_META_RESOLUTION_UNIT);
81
+ }
82
+ if (image.get_typeof("magick-format") == VIPS_TYPE_REF_STRING) {
83
+ baton->formatMagick = image.get_string("magick-format");
84
+ }
85
+ if (image.get_typeof("openslide.level-count") == VIPS_TYPE_REF_STRING) {
86
+ int const levels = std::stoi(image.get_string("openslide.level-count"));
87
+ for (int l = 0; l < levels; l++) {
88
+ std::string prefix = "openslide.level[" + std::to_string(l) + "].";
89
+ int const width = std::stoi(image.get_string((prefix + "width").data()));
90
+ int const height = std::stoi(image.get_string((prefix + "height").data()));
91
+ baton->levels.push_back(std::pair<int, int>(width, height));
92
+ }
93
+ }
94
+ if (image.get_typeof(VIPS_META_N_SUBIFDS) == G_TYPE_INT) {
95
+ baton->subifds = image.get_int(VIPS_META_N_SUBIFDS);
96
+ }
97
+ baton->hasProfile = sharp::HasProfile(image);
98
+ if (image.get_typeof("background") == VIPS_TYPE_ARRAY_DOUBLE) {
99
+ baton->background = image.get_array_double("background");
100
+ }
101
+ // Derived attributes
102
+ baton->hasAlpha = image.has_alpha();
103
+ baton->orientation = sharp::ExifOrientation(image);
104
+ // EXIF
105
+ if (image.get_typeof(VIPS_META_EXIF_NAME) == VIPS_TYPE_BLOB) {
106
+ size_t exifLength;
107
+ void const *exif = image.get_blob(VIPS_META_EXIF_NAME, &exifLength);
108
+ baton->exif = static_cast<char*>(g_malloc(exifLength));
109
+ memcpy(baton->exif, exif, exifLength);
110
+ baton->exifLength = exifLength;
111
+ }
112
+ // ICC profile
113
+ if (image.get_typeof(VIPS_META_ICC_NAME) == VIPS_TYPE_BLOB) {
114
+ size_t iccLength;
115
+ void const *icc = image.get_blob(VIPS_META_ICC_NAME, &iccLength);
116
+ baton->icc = static_cast<char*>(g_malloc(iccLength));
117
+ memcpy(baton->icc, icc, iccLength);
118
+ baton->iccLength = iccLength;
119
+ }
120
+ // IPTC
121
+ if (image.get_typeof(VIPS_META_IPTC_NAME) == VIPS_TYPE_BLOB) {
122
+ size_t iptcLength;
123
+ void const *iptc = image.get_blob(VIPS_META_IPTC_NAME, &iptcLength);
124
+ baton->iptc = static_cast<char *>(g_malloc(iptcLength));
125
+ memcpy(baton->iptc, iptc, iptcLength);
126
+ baton->iptcLength = iptcLength;
127
+ }
128
+ // XMP
129
+ if (image.get_typeof(VIPS_META_XMP_NAME) == VIPS_TYPE_BLOB) {
130
+ size_t xmpLength;
131
+ void const *xmp = image.get_blob(VIPS_META_XMP_NAME, &xmpLength);
132
+ baton->xmp = static_cast<char *>(g_malloc(xmpLength));
133
+ memcpy(baton->xmp, xmp, xmpLength);
134
+ baton->xmpLength = xmpLength;
135
+ }
136
+ // TIFFTAG_PHOTOSHOP
137
+ if (image.get_typeof(VIPS_META_PHOTOSHOP_NAME) == VIPS_TYPE_BLOB) {
138
+ size_t tifftagPhotoshopLength;
139
+ void const *tifftagPhotoshop = image.get_blob(VIPS_META_PHOTOSHOP_NAME, &tifftagPhotoshopLength);
140
+ baton->tifftagPhotoshop = static_cast<char *>(g_malloc(tifftagPhotoshopLength));
141
+ memcpy(baton->tifftagPhotoshop, tifftagPhotoshop, tifftagPhotoshopLength);
142
+ baton->tifftagPhotoshopLength = tifftagPhotoshopLength;
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
+ }
152
+ // PNG comments
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
+ }
198
+ }
199
+
200
+ // Clean up
201
+ vips_error_clear();
202
+ vips_thread_shutdown();
203
+ }
204
+
205
+ void OnOK() {
206
+ Napi::Env env = Env();
207
+ Napi::HandleScope scope(env);
208
+
209
+ // Handle warnings
210
+ std::string warning = sharp::VipsWarningPop();
211
+ while (!warning.empty()) {
212
+ debuglog.SHARP_CALLBACK_FN_NAME(Receiver().Value(), { Napi::String::New(env, warning) });
213
+ warning = sharp::VipsWarningPop();
214
+ }
215
+
216
+ if (baton->err.empty()) {
217
+ Napi::Object info = Napi::Object::New(env);
218
+ info.Set("format", baton->format);
219
+ if (!baton->mediaType.empty()) {
220
+ info.Set("mediaType", baton->mediaType);
221
+ }
222
+ if (baton->input->bufferLength > 0) {
223
+ info.Set("size", baton->input->bufferLength);
224
+ }
225
+ info.Set("width", baton->width);
226
+ info.Set("height", baton->height);
227
+ info.Set("space", baton->space);
228
+ info.Set("channels", baton->channels);
229
+ info.Set("depth", baton->depth);
230
+ if (baton->density > 0) {
231
+ info.Set("density", baton->density);
232
+ }
233
+ if (!baton->chromaSubsampling.empty()) {
234
+ info.Set("chromaSubsampling", baton->chromaSubsampling);
235
+ }
236
+ info.Set("isProgressive", baton->isProgressive);
237
+ info.Set("isPalette", baton->isPalette);
238
+ if (baton->bitsPerSample > 0) {
239
+ info.Set("bitsPerSample", baton->bitsPerSample);
240
+ }
241
+ if (baton->pages > 0) {
242
+ info.Set("pages", baton->pages);
243
+ }
244
+ if (baton->pageHeight > 0) {
245
+ info.Set("pageHeight", baton->pageHeight);
246
+ }
247
+ if (baton->loop >= 0) {
248
+ info.Set("loop", baton->loop);
249
+ }
250
+ if (!baton->delay.empty()) {
251
+ int i = 0;
252
+ Napi::Array delay = Napi::Array::New(env, static_cast<size_t>(baton->delay.size()));
253
+ for (int const d : baton->delay) {
254
+ delay.Set(i++, d);
255
+ }
256
+ info.Set("delay", delay);
257
+ }
258
+ if (baton->pagePrimary > -1) {
259
+ info.Set("pagePrimary", baton->pagePrimary);
260
+ }
261
+ if (!baton->compression.empty()) {
262
+ info.Set("compression", baton->compression);
263
+ }
264
+ if (!baton->resolutionUnit.empty()) {
265
+ info.Set("resolutionUnit", baton->resolutionUnit == "in" ? "inch" : baton->resolutionUnit);
266
+ }
267
+ if (!baton->formatMagick.empty()) {
268
+ info.Set("formatMagick", baton->formatMagick);
269
+ }
270
+ if (!baton->levels.empty()) {
271
+ int i = 0;
272
+ Napi::Array levels = Napi::Array::New(env, static_cast<size_t>(baton->levels.size()));
273
+ for (const auto& [width, height] : baton->levels) {
274
+ Napi::Object level = Napi::Object::New(env);
275
+ level.Set("width", width);
276
+ level.Set("height", height);
277
+ levels.Set(i++, level);
278
+ }
279
+ info.Set("levels", levels);
280
+ }
281
+ if (baton->subifds > 0) {
282
+ info.Set("subifds", baton->subifds);
283
+ }
284
+ if (!baton->background.empty()) {
285
+ Napi::Object background = Napi::Object::New(env);
286
+ if (baton->background.size() == 3) {
287
+ background.Set("r", baton->background[0]);
288
+ background.Set("g", baton->background[1]);
289
+ background.Set("b", baton->background[2]);
290
+ } else {
291
+ background.Set("gray", round(baton->background[0] * 100 / 255));
292
+ }
293
+ info.Set("background", background);
294
+ }
295
+ info.Set("hasProfile", baton->hasProfile);
296
+ info.Set("hasAlpha", baton->hasAlpha);
297
+ if (baton->orientation > 0) {
298
+ info.Set("orientation", baton->orientation);
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
+ }
309
+ if (baton->exifLength > 0) {
310
+ info.Set("exif", Napi::Buffer<char>::NewOrCopy(env, baton->exif, baton->exifLength, sharp::FreeCallback));
311
+ }
312
+ if (baton->iccLength > 0) {
313
+ info.Set("icc", Napi::Buffer<char>::NewOrCopy(env, baton->icc, baton->iccLength, sharp::FreeCallback));
314
+ }
315
+ if (baton->iptcLength > 0) {
316
+ info.Set("iptc", Napi::Buffer<char>::NewOrCopy(env, baton->iptc, baton->iptcLength, sharp::FreeCallback));
317
+ }
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
+ }
323
+ info.Set("xmp", Napi::Buffer<char>::NewOrCopy(env, baton->xmp, baton->xmpLength, sharp::FreeCallback));
324
+ }
325
+ if (baton->tifftagPhotoshopLength > 0) {
326
+ info.Set("tifftagPhotoshop",
327
+ Napi::Buffer<char>::NewOrCopy(env, baton->tifftagPhotoshop,
328
+ baton->tifftagPhotoshopLength, sharp::FreeCallback));
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
+ }
336
+ if (baton->comments.size() > 0) {
337
+ int i = 0;
338
+ Napi::Array comments = Napi::Array::New(env, baton->comments.size());
339
+ for (const auto& [keyword, text] : baton->comments) {
340
+ Napi::Object comment = Napi::Object::New(env);
341
+ comment.Set("keyword", keyword);
342
+ comment.Set("text", text);
343
+ comments.Set(i++, comment);
344
+ }
345
+ info.Set("comments", comments);
346
+ }
347
+ Callback().SHARP_CALLBACK_FN_NAME(Receiver().Value(), { env.Null(), info });
348
+ } else {
349
+ Callback().SHARP_CALLBACK_FN_NAME(Receiver().Value(),
350
+ { Napi::Error::New(env, sharp::TrimEnd(baton->err)).Value() });
351
+ }
352
+
353
+ delete baton->input;
354
+ delete baton;
355
+ }
356
+
357
+ private:
358
+ MetadataBaton* baton;
359
+ Napi::FunctionReference debuglog;
360
+ };
361
+
362
+ /*
363
+ metadata(options, callback)
364
+ */
365
+ Napi::Value metadata(const Napi::CallbackInfo& info) {
366
+ // V8 objects are converted to non-V8 types held in the baton struct
367
+ MetadataBaton *baton = new MetadataBaton;
368
+ Napi::Object options = info[size_t(0)].As<Napi::Object>();
369
+
370
+ // Input
371
+ baton->input = sharp::CreateInputDescriptor(options.Get("input").As<Napi::Object>());
372
+
373
+ // Function to notify of libvips warnings
374
+ Napi::Function debuglog = options.Get("debuglog").As<Napi::Function>();
375
+
376
+ // Join queue for worker thread
377
+ Napi::Function callback = info[size_t(1)].As<Napi::Function>();
378
+ MetadataWorker *worker = new MetadataWorker(callback, baton, debuglog);
379
+ worker->Receiver().Set("options", options);
380
+ worker->Queue();
381
+
382
+ // Increment queued task counter
383
+ sharp::counterQueue++;
384
+
385
+ return info.Env().Undefined();
386
+ }
387
+
388
+ const char *PNG_COMMENT_START = "png-comment-";
389
+ const int PNG_COMMENT_START_LEN = strlen(PNG_COMMENT_START);
390
+
391
+ static void* readPNGComment(VipsImage *image, const char *field, GValue *value, void *p) {
392
+ MetadataComments *comments = static_cast<MetadataComments *>(p);
393
+
394
+ if (vips_isprefix(PNG_COMMENT_START, field)) {
395
+ const char *keyword = strchr(field + PNG_COMMENT_START_LEN, '-');
396
+ const char *str;
397
+ if (keyword != NULL && !vips_image_get_string(image, field, &str)) {
398
+ keyword++; // Skip the hyphen
399
+ comments->push_back(std::make_pair(keyword, str));
400
+ }
401
+ }
402
+
403
+ return NULL;
404
+ }
@@ -0,0 +1,95 @@
1
+ /*!
2
+ Copyright 2013 Lovell Fuller and others.
3
+ SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ #ifndef SRC_METADATA_H_
7
+ #define SRC_METADATA_H_
8
+
9
+ #include <string>
10
+ #include <vector>
11
+ #include <napi.h>
12
+
13
+ #include "./common.h"
14
+
15
+ typedef std::vector<std::pair<std::string, std::string>> MetadataComments;
16
+
17
+ struct MetadataBaton {
18
+ // Input
19
+ sharp::InputDescriptor *input;
20
+ // Output
21
+ std::string format;
22
+ std::string mediaType;
23
+ int width;
24
+ int height;
25
+ std::string space;
26
+ int channels;
27
+ std::string depth;
28
+ int density;
29
+ std::string chromaSubsampling;
30
+ bool isProgressive;
31
+ bool isPalette;
32
+ int bitsPerSample;
33
+ int pages;
34
+ int pageHeight;
35
+ int loop;
36
+ std::vector<int> delay;
37
+ int pagePrimary;
38
+ std::string compression;
39
+ std::string resolutionUnit;
40
+ std::string formatMagick;
41
+ std::vector<std::pair<int, int>> levels;
42
+ int subifds;
43
+ std::vector<double> background;
44
+ bool hasProfile;
45
+ bool hasAlpha;
46
+ int orientation;
47
+ char *exif;
48
+ size_t exifLength;
49
+ char *icc;
50
+ size_t iccLength;
51
+ char *iptc;
52
+ size_t iptcLength;
53
+ char *xmp;
54
+ size_t xmpLength;
55
+ char *tifftagPhotoshop;
56
+ size_t tifftagPhotoshopLength;
57
+ char *gainMap;
58
+ size_t gainMapLength;
59
+ MetadataComments comments;
60
+ std::string err;
61
+
62
+ MetadataBaton():
63
+ input(nullptr),
64
+ width(0),
65
+ height(0),
66
+ channels(0),
67
+ density(0),
68
+ isProgressive(false),
69
+ isPalette(false),
70
+ bitsPerSample(0),
71
+ pages(0),
72
+ pageHeight(0),
73
+ loop(-1),
74
+ pagePrimary(-1),
75
+ subifds(0),
76
+ hasProfile(false),
77
+ hasAlpha(false),
78
+ orientation(0),
79
+ exif(nullptr),
80
+ exifLength(0),
81
+ icc(nullptr),
82
+ iccLength(0),
83
+ iptc(nullptr),
84
+ iptcLength(0),
85
+ xmp(nullptr),
86
+ xmpLength(0),
87
+ tifftagPhotoshop(nullptr),
88
+ tifftagPhotoshopLength(0),
89
+ gainMap(nullptr),
90
+ gainMapLength(0) {}
91
+ };
92
+
93
+ Napi::Value metadata(const Napi::CallbackInfo& info);
94
+
95
+ #endif // SRC_METADATA_H_