@revizly/sharp 0.33.2-revizly13

Sign up to get free protection for your applications and to get access to all the features.
@@ -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_