@guru-ai-product/ai-product-kit 0.2.251113194913 → 0.2.251113205658

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 (129) hide show
  1. package/mcp/skills/aipk_init_project/template/AGENTS_TEMPLATE.md +1 -1
  2. package/mcp/src/server.js +1 -1
  3. package/package.json +1 -1
  4. package/skills/aipk_design/GURU_AI.md +119 -7
  5. package/skills/aipk_design/SKILL.md +8 -7
  6. package/skills/aipk_design/{auto_panel_splitter → update-requirements-from-design}/SKILL.md +18 -16
  7. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/.package-lock.json +113 -0
  8. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/@img/colour/LICENSE.md +82 -0
  9. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/@img/colour/README.md +15 -0
  10. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/@img/colour/color.cjs +1594 -0
  11. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/@img/colour/index.cjs +1 -0
  12. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/@img/colour/package.json +45 -0
  13. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/@img/sharp-darwin-arm64/LICENSE +191 -0
  14. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/@img/sharp-darwin-arm64/README.md +18 -0
  15. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/@img/sharp-darwin-arm64/lib/sharp-darwin-arm64.node +0 -0
  16. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/@img/sharp-darwin-arm64/package.json +40 -0
  17. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/@img/sharp-libvips-darwin-arm64/README.md +46 -0
  18. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/@img/sharp-libvips-darwin-arm64/lib/glib-2.0/include/glibconfig.h +220 -0
  19. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/@img/sharp-libvips-darwin-arm64/lib/index.js +1 -0
  20. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/@img/sharp-libvips-darwin-arm64/lib/libvips-cpp.8.17.3.dylib +0 -0
  21. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/@img/sharp-libvips-darwin-arm64/package.json +36 -0
  22. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/@img/sharp-libvips-darwin-arm64/versions.json +30 -0
  23. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/detect-libc/LICENSE +201 -0
  24. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/detect-libc/README.md +163 -0
  25. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/detect-libc/index.d.ts +14 -0
  26. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/detect-libc/lib/detect-libc.js +313 -0
  27. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/detect-libc/lib/elf.js +39 -0
  28. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/detect-libc/lib/filesystem.js +51 -0
  29. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/detect-libc/lib/process.js +24 -0
  30. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/detect-libc/package.json +44 -0
  31. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/LICENSE +15 -0
  32. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/README.md +664 -0
  33. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/bin/semver.js +191 -0
  34. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/classes/comparator.js +143 -0
  35. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/classes/index.js +7 -0
  36. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/classes/range.js +557 -0
  37. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/classes/semver.js +333 -0
  38. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/functions/clean.js +8 -0
  39. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/functions/cmp.js +54 -0
  40. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/functions/coerce.js +62 -0
  41. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/functions/compare-build.js +9 -0
  42. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/functions/compare-loose.js +5 -0
  43. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/functions/compare.js +7 -0
  44. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/functions/diff.js +60 -0
  45. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/functions/eq.js +5 -0
  46. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/functions/gt.js +5 -0
  47. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/functions/gte.js +5 -0
  48. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/functions/inc.js +21 -0
  49. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/functions/lt.js +5 -0
  50. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/functions/lte.js +5 -0
  51. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/functions/major.js +5 -0
  52. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/functions/minor.js +5 -0
  53. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/functions/neq.js +5 -0
  54. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/functions/parse.js +18 -0
  55. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/functions/patch.js +5 -0
  56. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/functions/prerelease.js +8 -0
  57. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/functions/rcompare.js +5 -0
  58. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/functions/rsort.js +5 -0
  59. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/functions/satisfies.js +12 -0
  60. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/functions/sort.js +5 -0
  61. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/functions/valid.js +8 -0
  62. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/index.js +91 -0
  63. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/internal/constants.js +37 -0
  64. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/internal/debug.js +11 -0
  65. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/internal/identifiers.js +29 -0
  66. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/internal/lrucache.js +42 -0
  67. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/internal/parse-options.js +17 -0
  68. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/internal/re.js +223 -0
  69. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/package.json +78 -0
  70. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/preload.js +4 -0
  71. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/range.bnf +16 -0
  72. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/ranges/gtr.js +6 -0
  73. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/ranges/intersects.js +9 -0
  74. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/ranges/ltr.js +6 -0
  75. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/ranges/max-satisfying.js +27 -0
  76. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/ranges/min-satisfying.js +26 -0
  77. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/ranges/min-version.js +63 -0
  78. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/ranges/outside.js +82 -0
  79. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/ranges/simplify.js +49 -0
  80. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/ranges/subset.js +249 -0
  81. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/ranges/to-comparators.js +10 -0
  82. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/semver/ranges/valid.js +13 -0
  83. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/sharp/LICENSE +191 -0
  84. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/sharp/README.md +118 -0
  85. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/sharp/install/build.js +38 -0
  86. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/sharp/install/check.js +14 -0
  87. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/sharp/lib/channel.js +177 -0
  88. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/sharp/lib/colour.js +195 -0
  89. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/sharp/lib/composite.js +212 -0
  90. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/sharp/lib/constructor.js +499 -0
  91. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/sharp/lib/index.d.ts +1971 -0
  92. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/sharp/lib/index.js +16 -0
  93. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/sharp/lib/input.js +809 -0
  94. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/sharp/lib/is.js +143 -0
  95. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/sharp/lib/libvips.js +207 -0
  96. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/sharp/lib/operation.js +1016 -0
  97. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/sharp/lib/output.js +1666 -0
  98. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/sharp/lib/resize.js +595 -0
  99. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/sharp/lib/sharp.js +121 -0
  100. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/sharp/lib/utility.js +291 -0
  101. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/sharp/package.json +202 -0
  102. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/sharp/src/binding.gyp +298 -0
  103. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/sharp/src/common.cc +1130 -0
  104. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/sharp/src/common.h +402 -0
  105. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/sharp/src/metadata.cc +346 -0
  106. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/sharp/src/metadata.h +90 -0
  107. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/sharp/src/operations.cc +499 -0
  108. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/sharp/src/operations.h +137 -0
  109. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/sharp/src/pipeline.cc +1814 -0
  110. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/sharp/src/pipeline.h +408 -0
  111. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/sharp/src/sharp.cc +43 -0
  112. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/sharp/src/stats.cc +186 -0
  113. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/sharp/src/stats.h +62 -0
  114. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/sharp/src/utilities.cc +288 -0
  115. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/node_modules/sharp/src/utilities.h +22 -0
  116. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/package-lock.json +529 -0
  117. package/skills/aipk_design/update-requirements-from-design/scripts/sharp-runtime/package.json +5 -0
  118. package/skills/aipk_design/{auto_panel_splitter/scripts/auto_panel_splitter_bundle.js → update-requirements-from-design/scripts/split-design-boards-bundle.js} +10 -1
  119. package/skills/aipk_design/{auto_panel_splitter/scripts/panel_asset_mapper_bundle.js → update-requirements-from-design/scripts/sync-design-to-requirements-bundle.js} +10 -1
  120. package/skills/aipk_development/GURU_AI.md +1 -1
  121. package/skills/aipk_init_project/GURU_AI.md +2 -2
  122. package/skills/aipk_init_project/template/AGENTS_TEMPLATE.md +1 -1
  123. package/skills/aipk_operations/GURU_AI.md +1 -1
  124. package/skills/aipk_requirements/GURU_AI.md +2 -2
  125. package/skills/aipk_requirements/documentation/SKILL.md +23 -1
  126. package/skills/aipk_skill_generate/GURU_AI.md +1 -1
  127. package/skills/aipk_tool_prompts/GURU_AI.md +1 -1
  128. /package/skills/aipk_design/{auto_panel_splitter → update-requirements-from-design}/scripts/auto_panel_splitter.js +0 -0
  129. /package/skills/aipk_design/{auto_panel_splitter → update-requirements-from-design}/scripts/panel_asset_mapper.js +0 -0
@@ -0,0 +1,346 @@
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 (vips::VError 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
+ // PNG comments
145
+ vips_image_map(image.get_image(), readPNGComment, &baton->comments);
146
+ }
147
+
148
+ // Clean up
149
+ vips_error_clear();
150
+ vips_thread_shutdown();
151
+ }
152
+
153
+ void OnOK() {
154
+ Napi::Env env = Env();
155
+ Napi::HandleScope scope(env);
156
+
157
+ // Handle warnings
158
+ std::string warning = sharp::VipsWarningPop();
159
+ while (!warning.empty()) {
160
+ debuglog.Call(Receiver().Value(), { Napi::String::New(env, warning) });
161
+ warning = sharp::VipsWarningPop();
162
+ }
163
+
164
+ if (baton->err.empty()) {
165
+ Napi::Object info = Napi::Object::New(env);
166
+ info.Set("format", baton->format);
167
+ if (baton->input->bufferLength > 0) {
168
+ info.Set("size", baton->input->bufferLength);
169
+ }
170
+ info.Set("width", baton->width);
171
+ info.Set("height", baton->height);
172
+ info.Set("space", baton->space);
173
+ info.Set("channels", baton->channels);
174
+ info.Set("depth", baton->depth);
175
+ if (baton->density > 0) {
176
+ info.Set("density", baton->density);
177
+ }
178
+ if (!baton->chromaSubsampling.empty()) {
179
+ info.Set("chromaSubsampling", baton->chromaSubsampling);
180
+ }
181
+ info.Set("isProgressive", baton->isProgressive);
182
+ info.Set("isPalette", baton->isPalette);
183
+ if (baton->bitsPerSample > 0) {
184
+ info.Set("bitsPerSample", baton->bitsPerSample);
185
+ if (baton->isPalette) {
186
+ // Deprecated, remove with libvips 8.17.0
187
+ info.Set("paletteBitDepth", baton->bitsPerSample);
188
+ }
189
+ }
190
+ if (baton->pages > 0) {
191
+ info.Set("pages", baton->pages);
192
+ }
193
+ if (baton->pageHeight > 0) {
194
+ info.Set("pageHeight", baton->pageHeight);
195
+ }
196
+ if (baton->loop >= 0) {
197
+ info.Set("loop", baton->loop);
198
+ }
199
+ if (!baton->delay.empty()) {
200
+ int i = 0;
201
+ Napi::Array delay = Napi::Array::New(env, static_cast<size_t>(baton->delay.size()));
202
+ for (int const d : baton->delay) {
203
+ delay.Set(i++, d);
204
+ }
205
+ info.Set("delay", delay);
206
+ }
207
+ if (baton->pagePrimary > -1) {
208
+ info.Set("pagePrimary", baton->pagePrimary);
209
+ }
210
+ if (!baton->compression.empty()) {
211
+ info.Set("compression", baton->compression);
212
+ }
213
+ if (!baton->resolutionUnit.empty()) {
214
+ info.Set("resolutionUnit", baton->resolutionUnit == "in" ? "inch" : baton->resolutionUnit);
215
+ }
216
+ if (!baton->formatMagick.empty()) {
217
+ info.Set("formatMagick", baton->formatMagick);
218
+ }
219
+ if (!baton->levels.empty()) {
220
+ int i = 0;
221
+ Napi::Array levels = Napi::Array::New(env, static_cast<size_t>(baton->levels.size()));
222
+ for (const auto& [width, height] : baton->levels) {
223
+ Napi::Object level = Napi::Object::New(env);
224
+ level.Set("width", width);
225
+ level.Set("height", height);
226
+ levels.Set(i++, level);
227
+ }
228
+ info.Set("levels", levels);
229
+ }
230
+ if (baton->subifds > 0) {
231
+ info.Set("subifds", baton->subifds);
232
+ }
233
+ if (!baton->background.empty()) {
234
+ Napi::Object background = Napi::Object::New(env);
235
+ if (baton->background.size() == 3) {
236
+ background.Set("r", baton->background[0]);
237
+ background.Set("g", baton->background[1]);
238
+ background.Set("b", baton->background[2]);
239
+ } else {
240
+ background.Set("gray", round(baton->background[0] * 100 / 255));
241
+ }
242
+ info.Set("background", background);
243
+ }
244
+ info.Set("hasProfile", baton->hasProfile);
245
+ info.Set("hasAlpha", baton->hasAlpha);
246
+ if (baton->orientation > 0) {
247
+ info.Set("orientation", baton->orientation);
248
+ }
249
+ Napi::Object autoOrient = Napi::Object::New(env);
250
+ info.Set("autoOrient", autoOrient);
251
+ if (baton->orientation >= 5) {
252
+ autoOrient.Set("width", baton->height);
253
+ autoOrient.Set("height", baton->width);
254
+ } else {
255
+ autoOrient.Set("width", baton->width);
256
+ autoOrient.Set("height", baton->height);
257
+ }
258
+ if (baton->exifLength > 0) {
259
+ info.Set("exif", Napi::Buffer<char>::NewOrCopy(env, baton->exif, baton->exifLength, sharp::FreeCallback));
260
+ }
261
+ if (baton->iccLength > 0) {
262
+ info.Set("icc", Napi::Buffer<char>::NewOrCopy(env, baton->icc, baton->iccLength, sharp::FreeCallback));
263
+ }
264
+ if (baton->iptcLength > 0) {
265
+ info.Set("iptc", Napi::Buffer<char>::NewOrCopy(env, baton->iptc, baton->iptcLength, sharp::FreeCallback));
266
+ }
267
+ if (baton->xmpLength > 0) {
268
+ if (g_utf8_validate(static_cast<char const *>(baton->xmp), baton->xmpLength, nullptr)) {
269
+ info.Set("xmpAsString",
270
+ Napi::String::New(env, static_cast<char const *>(baton->xmp), baton->xmpLength));
271
+ }
272
+ info.Set("xmp", Napi::Buffer<char>::NewOrCopy(env, baton->xmp, baton->xmpLength, sharp::FreeCallback));
273
+ }
274
+ if (baton->tifftagPhotoshopLength > 0) {
275
+ info.Set("tifftagPhotoshop",
276
+ Napi::Buffer<char>::NewOrCopy(env, baton->tifftagPhotoshop,
277
+ baton->tifftagPhotoshopLength, sharp::FreeCallback));
278
+ }
279
+ if (baton->comments.size() > 0) {
280
+ int i = 0;
281
+ Napi::Array comments = Napi::Array::New(env, baton->comments.size());
282
+ for (const auto& [keyword, text] : baton->comments) {
283
+ Napi::Object comment = Napi::Object::New(env);
284
+ comment.Set("keyword", keyword);
285
+ comment.Set("text", text);
286
+ comments.Set(i++, comment);
287
+ }
288
+ info.Set("comments", comments);
289
+ }
290
+ Callback().Call(Receiver().Value(), { env.Null(), info });
291
+ } else {
292
+ Callback().Call(Receiver().Value(), { Napi::Error::New(env, sharp::TrimEnd(baton->err)).Value() });
293
+ }
294
+
295
+ delete baton->input;
296
+ delete baton;
297
+ }
298
+
299
+ private:
300
+ MetadataBaton* baton;
301
+ Napi::FunctionReference debuglog;
302
+ };
303
+
304
+ /*
305
+ metadata(options, callback)
306
+ */
307
+ Napi::Value metadata(const Napi::CallbackInfo& info) {
308
+ // V8 objects are converted to non-V8 types held in the baton struct
309
+ MetadataBaton *baton = new MetadataBaton;
310
+ Napi::Object options = info[size_t(0)].As<Napi::Object>();
311
+
312
+ // Input
313
+ baton->input = sharp::CreateInputDescriptor(options.Get("input").As<Napi::Object>());
314
+
315
+ // Function to notify of libvips warnings
316
+ Napi::Function debuglog = options.Get("debuglog").As<Napi::Function>();
317
+
318
+ // Join queue for worker thread
319
+ Napi::Function callback = info[size_t(1)].As<Napi::Function>();
320
+ MetadataWorker *worker = new MetadataWorker(callback, baton, debuglog);
321
+ worker->Receiver().Set("options", options);
322
+ worker->Queue();
323
+
324
+ // Increment queued task counter
325
+ sharp::counterQueue++;
326
+
327
+ return info.Env().Undefined();
328
+ }
329
+
330
+ const char *PNG_COMMENT_START = "png-comment-";
331
+ const int PNG_COMMENT_START_LEN = strlen(PNG_COMMENT_START);
332
+
333
+ static void* readPNGComment(VipsImage *image, const char *field, GValue *value, void *p) {
334
+ MetadataComments *comments = static_cast<MetadataComments *>(p);
335
+
336
+ if (vips_isprefix(PNG_COMMENT_START, field)) {
337
+ const char *keyword = strchr(field + PNG_COMMENT_START_LEN, '-');
338
+ const char *str;
339
+ if (keyword != NULL && !vips_image_get_string(image, field, &str)) {
340
+ keyword++; // Skip the hyphen
341
+ comments->push_back(std::make_pair(keyword, str));
342
+ }
343
+ }
344
+
345
+ return NULL;
346
+ }
@@ -0,0 +1,90 @@
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
+ int width;
23
+ int height;
24
+ std::string space;
25
+ int channels;
26
+ std::string depth;
27
+ int density;
28
+ std::string chromaSubsampling;
29
+ bool isProgressive;
30
+ bool isPalette;
31
+ int bitsPerSample;
32
+ int pages;
33
+ int pageHeight;
34
+ int loop;
35
+ std::vector<int> delay;
36
+ int pagePrimary;
37
+ std::string compression;
38
+ std::string resolutionUnit;
39
+ std::string formatMagick;
40
+ std::vector<std::pair<int, int>> levels;
41
+ int subifds;
42
+ std::vector<double> background;
43
+ bool hasProfile;
44
+ bool hasAlpha;
45
+ int orientation;
46
+ char *exif;
47
+ size_t exifLength;
48
+ char *icc;
49
+ size_t iccLength;
50
+ char *iptc;
51
+ size_t iptcLength;
52
+ char *xmp;
53
+ size_t xmpLength;
54
+ char *tifftagPhotoshop;
55
+ size_t tifftagPhotoshopLength;
56
+ MetadataComments comments;
57
+ std::string err;
58
+
59
+ MetadataBaton():
60
+ input(nullptr),
61
+ width(0),
62
+ height(0),
63
+ channels(0),
64
+ density(0),
65
+ isProgressive(false),
66
+ isPalette(false),
67
+ bitsPerSample(0),
68
+ pages(0),
69
+ pageHeight(0),
70
+ loop(-1),
71
+ pagePrimary(-1),
72
+ subifds(0),
73
+ hasProfile(false),
74
+ hasAlpha(false),
75
+ orientation(0),
76
+ exif(nullptr),
77
+ exifLength(0),
78
+ icc(nullptr),
79
+ iccLength(0),
80
+ iptc(nullptr),
81
+ iptcLength(0),
82
+ xmp(nullptr),
83
+ xmpLength(0),
84
+ tifftagPhotoshop(nullptr),
85
+ tifftagPhotoshopLength(0) {}
86
+ };
87
+
88
+ Napi::Value metadata(const Napi::CallbackInfo& info);
89
+
90
+ #endif // SRC_METADATA_H_