@revizly/sharp 0.33.2-revizly3

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.
@@ -0,0 +1,269 @@
1
+ // Copyright 2013 Lovell Fuller and others.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ #include <cmath>
5
+ #include <string>
6
+ #include <cstdio>
7
+
8
+ #include <napi.h>
9
+ #include <vips/vips8>
10
+ #include <vips/vector.h>
11
+
12
+ #include "common.h"
13
+ #include "operations.h"
14
+ #include "utilities.h"
15
+
16
+ /*
17
+ Get and set cache limits
18
+ */
19
+ Napi::Value cache(const Napi::CallbackInfo& info) {
20
+ Napi::Env env = info.Env();
21
+
22
+ // Set memory limit
23
+ if (info[size_t(0)].IsNumber()) {
24
+ vips_cache_set_max_mem(info[size_t(0)].As<Napi::Number>().Int32Value() * 1048576);
25
+ }
26
+ // Set file limit
27
+ if (info[size_t(1)].IsNumber()) {
28
+ vips_cache_set_max_files(info[size_t(1)].As<Napi::Number>().Int32Value());
29
+ }
30
+ // Set items limit
31
+ if (info[size_t(2)].IsNumber()) {
32
+ vips_cache_set_max(info[size_t(2)].As<Napi::Number>().Int32Value());
33
+ }
34
+
35
+ // Get memory stats
36
+ Napi::Object memory = Napi::Object::New(env);
37
+ memory.Set("current", round(vips_tracked_get_mem() / 1048576));
38
+ memory.Set("high", round(vips_tracked_get_mem_highwater() / 1048576));
39
+ memory.Set("max", round(vips_cache_get_max_mem() / 1048576));
40
+ // Get file stats
41
+ Napi::Object files = Napi::Object::New(env);
42
+ files.Set("current", vips_tracked_get_files());
43
+ files.Set("max", vips_cache_get_max_files());
44
+
45
+ // Get item stats
46
+ Napi::Object items = Napi::Object::New(env);
47
+ items.Set("current", vips_cache_get_size());
48
+ items.Set("max", vips_cache_get_max());
49
+
50
+ Napi::Object cache = Napi::Object::New(env);
51
+ cache.Set("memory", memory);
52
+ cache.Set("files", files);
53
+ cache.Set("items", items);
54
+ return cache;
55
+ }
56
+
57
+ /*
58
+ Get and set size of thread pool
59
+ */
60
+ Napi::Value concurrency(const Napi::CallbackInfo& info) {
61
+ // Set concurrency
62
+ if (info[size_t(0)].IsNumber()) {
63
+ vips_concurrency_set(info[size_t(0)].As<Napi::Number>().Int32Value());
64
+ }
65
+ // Get concurrency
66
+ return Napi::Number::New(info.Env(), vips_concurrency_get());
67
+ }
68
+
69
+ /*
70
+ Get internal counters (queued tasks, processing tasks)
71
+ */
72
+ Napi::Value counters(const Napi::CallbackInfo& info) {
73
+ Napi::Object counters = Napi::Object::New(info.Env());
74
+ counters.Set("queue", static_cast<int>(sharp::counterQueue));
75
+ counters.Set("process", static_cast<int>(sharp::counterProcess));
76
+ return counters;
77
+ }
78
+
79
+ /*
80
+ Get and set use of SIMD vector unit instructions
81
+ */
82
+ Napi::Value simd(const Napi::CallbackInfo& info) {
83
+ // Set state
84
+ if (info[size_t(0)].IsBoolean()) {
85
+ vips_vector_set_enabled(info[size_t(0)].As<Napi::Boolean>().Value());
86
+ }
87
+ // Get state
88
+ return Napi::Boolean::New(info.Env(), vips_vector_isenabled());
89
+ }
90
+
91
+ /*
92
+ Get libvips version
93
+ */
94
+ Napi::Value libvipsVersion(const Napi::CallbackInfo& info) {
95
+ Napi::Env env = info.Env();
96
+ Napi::Object version = Napi::Object::New(env);
97
+
98
+ char semver[9];
99
+ std::snprintf(semver, sizeof(semver), "%d.%d.%d", vips_version(0), vips_version(1), vips_version(2));
100
+ version.Set("semver", Napi::String::New(env, semver));
101
+ #ifdef SHARP_USE_GLOBAL_LIBVIPS
102
+ version.Set("isGlobal", Napi::Boolean::New(env, true));
103
+ #else
104
+ version.Set("isGlobal", Napi::Boolean::New(env, false));
105
+ #endif
106
+ #ifdef __EMSCRIPTEN__
107
+ version.Set("isWasm", Napi::Boolean::New(env, true));
108
+ #else
109
+ version.Set("isWasm", Napi::Boolean::New(env, false));
110
+ #endif
111
+ return version;
112
+ }
113
+
114
+ /*
115
+ Get available input/output file/buffer/stream formats
116
+ */
117
+ Napi::Value format(const Napi::CallbackInfo& info) {
118
+ Napi::Env env = info.Env();
119
+ Napi::Object format = Napi::Object::New(env);
120
+ for (std::string const f : {
121
+ "jpeg", "png", "webp", "tiff", "magick", "openslide", "dz",
122
+ "ppm", "fits", "gif", "svg", "heif", "pdf", "vips", "jp2k", "jxl"
123
+ }) {
124
+ // Input
125
+ const VipsObjectClass *oc = vips_class_find("VipsOperation", (f + "load").c_str());
126
+ Napi::Boolean hasInputFile = Napi::Boolean::New(env, oc);
127
+ Napi::Boolean hasInputBuffer =
128
+ Napi::Boolean::New(env, vips_type_find("VipsOperation", (f + "load_buffer").c_str()));
129
+ Napi::Object input = Napi::Object::New(env);
130
+ input.Set("file", hasInputFile);
131
+ input.Set("buffer", hasInputBuffer);
132
+ input.Set("stream", hasInputBuffer);
133
+ if (hasInputFile) {
134
+ const VipsForeignClass *fc = VIPS_FOREIGN_CLASS(oc);
135
+ if (fc->suffs) {
136
+ Napi::Array fileSuffix = Napi::Array::New(env);
137
+ const char **suffix = fc->suffs;
138
+ for (int i = 0; *suffix; i++, suffix++) {
139
+ fileSuffix.Set(i, Napi::String::New(env, *suffix));
140
+ }
141
+ input.Set("fileSuffix", fileSuffix);
142
+ }
143
+ }
144
+ // Output
145
+ Napi::Boolean hasOutputFile =
146
+ Napi::Boolean::New(env, vips_type_find("VipsOperation", (f + "save").c_str()));
147
+ Napi::Boolean hasOutputBuffer =
148
+ Napi::Boolean::New(env, vips_type_find("VipsOperation", (f + "save_buffer").c_str()));
149
+ Napi::Object output = Napi::Object::New(env);
150
+ output.Set("file", hasOutputFile);
151
+ output.Set("buffer", hasOutputBuffer);
152
+ output.Set("stream", hasOutputBuffer);
153
+ // Other attributes
154
+ Napi::Object container = Napi::Object::New(env);
155
+ container.Set("id", f);
156
+ container.Set("input", input);
157
+ container.Set("output", output);
158
+ // Add to set of formats
159
+ format.Set(f, container);
160
+ }
161
+
162
+ // Raw, uncompressed data
163
+ Napi::Boolean supported = Napi::Boolean::New(env, true);
164
+ Napi::Boolean unsupported = Napi::Boolean::New(env, false);
165
+ Napi::Object rawInput = Napi::Object::New(env);
166
+ rawInput.Set("file", unsupported);
167
+ rawInput.Set("buffer", supported);
168
+ rawInput.Set("stream", supported);
169
+ Napi::Object rawOutput = Napi::Object::New(env);
170
+ rawOutput.Set("file", unsupported);
171
+ rawOutput.Set("buffer", supported);
172
+ rawOutput.Set("stream", supported);
173
+ Napi::Object raw = Napi::Object::New(env);
174
+ raw.Set("id", "raw");
175
+ raw.Set("input", rawInput);
176
+ raw.Set("output", rawOutput);
177
+ format.Set("raw", raw);
178
+
179
+ return format;
180
+ }
181
+
182
+ /*
183
+ (Un)block libvips operations at runtime.
184
+ */
185
+ void block(const Napi::CallbackInfo& info) {
186
+ Napi::Array ops = info[size_t(0)].As<Napi::Array>();
187
+ bool const state = info[size_t(1)].As<Napi::Boolean>().Value();
188
+ for (unsigned int i = 0; i < ops.Length(); i++) {
189
+ vips_operation_block_set(ops.Get(i).As<Napi::String>().Utf8Value().c_str(), state);
190
+ }
191
+ }
192
+
193
+ /*
194
+ Synchronous, internal-only method used by some of the functional tests.
195
+ Calculates the maximum colour distance using the DE2000 algorithm
196
+ between two images of the same dimensions and number of channels.
197
+ */
198
+ Napi::Value _maxColourDistance(const Napi::CallbackInfo& info) {
199
+ Napi::Env env = info.Env();
200
+
201
+ // Open input files
202
+ VImage image1;
203
+ sharp::ImageType imageType1 = sharp::DetermineImageType(info[size_t(0)].As<Napi::String>().Utf8Value().data());
204
+ if (imageType1 != sharp::ImageType::UNKNOWN) {
205
+ try {
206
+ image1 = VImage::new_from_file(info[size_t(0)].As<Napi::String>().Utf8Value().c_str());
207
+ } catch (...) {
208
+ throw Napi::Error::New(env, "Input file 1 has corrupt header");
209
+ }
210
+ } else {
211
+ throw Napi::Error::New(env, "Input file 1 is of an unsupported image format");
212
+ }
213
+ VImage image2;
214
+ sharp::ImageType imageType2 = sharp::DetermineImageType(info[size_t(1)].As<Napi::String>().Utf8Value().data());
215
+ if (imageType2 != sharp::ImageType::UNKNOWN) {
216
+ try {
217
+ image2 = VImage::new_from_file(info[size_t(1)].As<Napi::String>().Utf8Value().c_str());
218
+ } catch (...) {
219
+ throw Napi::Error::New(env, "Input file 2 has corrupt header");
220
+ }
221
+ } else {
222
+ throw Napi::Error::New(env, "Input file 2 is of an unsupported image format");
223
+ }
224
+ // Ensure same number of channels
225
+ if (image1.bands() != image2.bands()) {
226
+ throw Napi::Error::New(env, "mismatchedBands");
227
+ }
228
+ // Ensure same dimensions
229
+ if (image1.width() != image2.width() || image1.height() != image2.height()) {
230
+ throw Napi::Error::New(env, "mismatchedDimensions");
231
+ }
232
+
233
+ double maxColourDistance;
234
+ try {
235
+ // Premultiply and remove alpha
236
+ if (sharp::HasAlpha(image1)) {
237
+ image1 = image1.premultiply().extract_band(1, VImage::option()->set("n", image1.bands() - 1));
238
+ }
239
+ if (sharp::HasAlpha(image2)) {
240
+ image2 = image2.premultiply().extract_band(1, VImage::option()->set("n", image2.bands() - 1));
241
+ }
242
+ // Calculate colour distance
243
+ maxColourDistance = image1.dE00(image2).max();
244
+ } catch (vips::VError const &err) {
245
+ throw Napi::Error::New(env, err.what());
246
+ }
247
+
248
+ // Clean up libvips' per-request data and threads
249
+ vips_error_clear();
250
+ vips_thread_shutdown();
251
+
252
+ return Napi::Number::New(env, maxColourDistance);
253
+ }
254
+
255
+ #if defined(__GNUC__)
256
+ // mallctl will be resolved by the runtime linker when jemalloc is being used
257
+ extern "C" {
258
+ int mallctl(const char *name, void *oldp, size_t *oldlenp, void *newp, size_t newlen) __attribute__((weak));
259
+ }
260
+ Napi::Value _isUsingJemalloc(const Napi::CallbackInfo& info) {
261
+ Napi::Env env = info.Env();
262
+ return Napi::Boolean::New(env, mallctl != nullptr);
263
+ }
264
+ #else
265
+ Napi::Value _isUsingJemalloc(const Napi::CallbackInfo& info) {
266
+ Napi::Env env = info.Env();
267
+ return Napi::Boolean::New(env, false);
268
+ }
269
+ #endif
@@ -0,0 +1,19 @@
1
+ // Copyright 2013 Lovell Fuller and others.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ #ifndef SRC_UTILITIES_H_
5
+ #define SRC_UTILITIES_H_
6
+
7
+ #include <napi.h>
8
+
9
+ Napi::Value cache(const Napi::CallbackInfo& info);
10
+ Napi::Value concurrency(const Napi::CallbackInfo& info);
11
+ Napi::Value counters(const Napi::CallbackInfo& info);
12
+ Napi::Value simd(const Napi::CallbackInfo& info);
13
+ Napi::Value libvipsVersion(const Napi::CallbackInfo& info);
14
+ Napi::Value format(const Napi::CallbackInfo& info);
15
+ void block(const Napi::CallbackInfo& info);
16
+ Napi::Value _maxColourDistance(const Napi::CallbackInfo& info);
17
+ Napi::Value _isUsingJemalloc(const Napi::CallbackInfo& info);
18
+
19
+ #endif // SRC_UTILITIES_H_