sharp 0.24.0 → 0.25.2
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.
- package/README.md +5 -6
- package/binding.gyp +18 -3
- package/install/libvips.js +10 -8
- package/lib/channel.js +3 -2
- package/lib/composite.js +1 -2
- package/lib/constructor.js +8 -1
- package/lib/input.js +19 -37
- package/lib/libvips.js +10 -8
- package/lib/output.js +15 -4
- package/lib/resize.js +15 -3
- package/package.json +18 -12
- package/src/common.cc +46 -39
- package/src/common.h +15 -21
- package/src/metadata.cc +57 -94
- package/src/metadata.h +2 -2
- package/src/pipeline.cc +238 -294
- package/src/pipeline.h +4 -4
- package/src/sharp.cc +14 -24
- package/src/stats.cc +58 -85
- package/src/stats.h +4 -8
- package/src/utilities.cc +100 -145
- package/src/utilities.h +8 -8
package/src/common.h
CHANGED
|
@@ -19,14 +19,13 @@
|
|
|
19
19
|
#include <tuple>
|
|
20
20
|
#include <vector>
|
|
21
21
|
|
|
22
|
-
#include <
|
|
23
|
-
#include <nan.h>
|
|
22
|
+
#include <napi.h>
|
|
24
23
|
#include <vips/vips8>
|
|
25
24
|
|
|
26
25
|
// Verify platform and compiler compatibility
|
|
27
26
|
|
|
28
27
|
#if (VIPS_MAJOR_VERSION < 8 || (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION < 9))
|
|
29
|
-
#error "libvips version 8.9.
|
|
28
|
+
#error "libvips version 8.9.1+ is required - please see https://sharp.pixelplumbing.com/install"
|
|
30
29
|
#endif
|
|
31
30
|
|
|
32
31
|
#if ((!defined(__clang__)) && defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6)))
|
|
@@ -82,23 +81,18 @@ namespace sharp {
|
|
|
82
81
|
createBackground{ 0.0, 0.0, 0.0, 255.0 } {}
|
|
83
82
|
};
|
|
84
83
|
|
|
85
|
-
// Convenience methods to access the attributes of a
|
|
86
|
-
bool HasAttr(
|
|
87
|
-
std::string AttrAsStr(
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// Create an InputDescriptor instance from a v8::Object describing an input image
|
|
100
|
-
InputDescriptor* CreateInputDescriptor(
|
|
101
|
-
v8::Local<v8::Object> input, std::vector<v8::Local<v8::Object>> &buffersToPersist); // NOLINT(runtime/references)
|
|
84
|
+
// Convenience methods to access the attributes of a Napi::Object
|
|
85
|
+
bool HasAttr(Napi::Object obj, std::string attr);
|
|
86
|
+
std::string AttrAsStr(Napi::Object obj, std::string attr);
|
|
87
|
+
uint32_t AttrAsUint32(Napi::Object obj, std::string attr);
|
|
88
|
+
int32_t AttrAsInt32(Napi::Object obj, std::string attr);
|
|
89
|
+
double AttrAsDouble(Napi::Object obj, std::string attr);
|
|
90
|
+
double AttrAsDouble(Napi::Object obj, unsigned int const attr);
|
|
91
|
+
bool AttrAsBool(Napi::Object obj, std::string attr);
|
|
92
|
+
std::vector<double> AttrAsRgba(Napi::Object obj, std::string attr);
|
|
93
|
+
|
|
94
|
+
// Create an InputDescriptor instance from a Napi::Object describing an input image
|
|
95
|
+
InputDescriptor* CreateInputDescriptor(Napi::Object input);
|
|
102
96
|
|
|
103
97
|
enum class ImageType {
|
|
104
98
|
JPEG,
|
|
@@ -211,7 +205,7 @@ namespace sharp {
|
|
|
211
205
|
/*
|
|
212
206
|
Called when a Buffer undergoes GC, required to support mixed runtime libraries in Windows
|
|
213
207
|
*/
|
|
214
|
-
void
|
|
208
|
+
extern std::function<void(void*, char*)> FreeCallback;
|
|
215
209
|
|
|
216
210
|
/*
|
|
217
211
|
Called with warnings from the glib-registered "VIPS" domain
|
package/src/metadata.cc
CHANGED
|
@@ -15,28 +15,16 @@
|
|
|
15
15
|
#include <numeric>
|
|
16
16
|
#include <vector>
|
|
17
17
|
|
|
18
|
-
#include <
|
|
19
|
-
#include <nan.h>
|
|
18
|
+
#include <napi.h>
|
|
20
19
|
#include <vips/vips8>
|
|
21
20
|
|
|
22
21
|
#include "common.h"
|
|
23
22
|
#include "metadata.h"
|
|
24
23
|
|
|
25
|
-
class MetadataWorker : public
|
|
24
|
+
class MetadataWorker : public Napi::AsyncWorker {
|
|
26
25
|
public:
|
|
27
|
-
MetadataWorker(
|
|
28
|
-
|
|
29
|
-
std::vector<v8::Local<v8::Object>> const buffersToPersist) :
|
|
30
|
-
Nan::AsyncWorker(callback, "sharp:MetadataWorker"),
|
|
31
|
-
baton(baton), debuglog(debuglog),
|
|
32
|
-
buffersToPersist(buffersToPersist) {
|
|
33
|
-
// Protect Buffer objects from GC, keyed on index
|
|
34
|
-
std::accumulate(buffersToPersist.begin(), buffersToPersist.end(), 0,
|
|
35
|
-
[this](uint32_t index, v8::Local<v8::Object> const buffer) -> uint32_t {
|
|
36
|
-
SaveToPersistent(index, buffer);
|
|
37
|
-
return index + 1;
|
|
38
|
-
});
|
|
39
|
-
}
|
|
26
|
+
MetadataWorker(Napi::Function callback, MetadataBaton *baton, Napi::Function debuglog) :
|
|
27
|
+
Napi::AsyncWorker(callback), baton(baton), debuglog(Napi::Persistent(debuglog)) {}
|
|
40
28
|
~MetadataWorker() {}
|
|
41
29
|
|
|
42
30
|
void Execute() {
|
|
@@ -137,140 +125,115 @@ class MetadataWorker : public Nan::AsyncWorker {
|
|
|
137
125
|
vips_thread_shutdown();
|
|
138
126
|
}
|
|
139
127
|
|
|
140
|
-
void
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
Nan::HandleScope();
|
|
128
|
+
void OnOK() {
|
|
129
|
+
Napi::Env env = Env();
|
|
130
|
+
Napi::HandleScope scope(env);
|
|
144
131
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
132
|
+
// Handle warnings
|
|
133
|
+
std::string warning = sharp::VipsWarningPop();
|
|
134
|
+
while (!warning.empty()) {
|
|
135
|
+
debuglog.Call({ Napi::String::New(env, warning) });
|
|
136
|
+
warning = sharp::VipsWarningPop();
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (baton->err.empty()) {
|
|
140
|
+
Napi::Object info = Napi::Object::New(env);
|
|
141
|
+
info.Set("format", baton->format);
|
|
152
142
|
if (baton->input->bufferLength > 0) {
|
|
153
|
-
Set(
|
|
143
|
+
info.Set("size", baton->input->bufferLength);
|
|
154
144
|
}
|
|
155
|
-
Set(
|
|
156
|
-
Set(
|
|
157
|
-
Set(
|
|
158
|
-
Set(
|
|
159
|
-
Set(
|
|
145
|
+
info.Set("width", baton->width);
|
|
146
|
+
info.Set("height", baton->height);
|
|
147
|
+
info.Set("space", baton->space);
|
|
148
|
+
info.Set("channels", baton->channels);
|
|
149
|
+
info.Set("depth", baton->depth);
|
|
160
150
|
if (baton->density > 0) {
|
|
161
|
-
Set(
|
|
151
|
+
info.Set("density", baton->density);
|
|
162
152
|
}
|
|
163
153
|
if (!baton->chromaSubsampling.empty()) {
|
|
164
|
-
Set(
|
|
165
|
-
New("chromaSubsampling").ToLocalChecked(),
|
|
166
|
-
New<v8::String>(baton->chromaSubsampling).ToLocalChecked());
|
|
154
|
+
info.Set("chromaSubsampling", baton->chromaSubsampling);
|
|
167
155
|
}
|
|
168
|
-
Set(
|
|
156
|
+
info.Set("isProgressive", baton->isProgressive);
|
|
169
157
|
if (baton->paletteBitDepth > 0) {
|
|
170
|
-
Set(
|
|
158
|
+
info.Set("paletteBitDepth", baton->paletteBitDepth);
|
|
171
159
|
}
|
|
172
160
|
if (baton->pages > 0) {
|
|
173
|
-
Set(
|
|
161
|
+
info.Set("pages", baton->pages);
|
|
174
162
|
}
|
|
175
163
|
if (baton->pageHeight > 0) {
|
|
176
|
-
Set(
|
|
164
|
+
info.Set("pageHeight", baton->pageHeight);
|
|
177
165
|
}
|
|
178
166
|
if (baton->loop >= 0) {
|
|
179
|
-
Set(
|
|
167
|
+
info.Set("loop", baton->loop);
|
|
180
168
|
}
|
|
181
169
|
if (!baton->delay.empty()) {
|
|
182
170
|
int i = 0;
|
|
183
|
-
|
|
171
|
+
Napi::Array delay = Napi::Array::New(env, static_cast<size_t>(baton->delay.size()));
|
|
184
172
|
for (int const d : baton->delay) {
|
|
185
|
-
Set(
|
|
173
|
+
delay.Set(i++, d);
|
|
186
174
|
}
|
|
187
|
-
Set(
|
|
175
|
+
info.Set("delay", delay);
|
|
188
176
|
}
|
|
189
177
|
if (baton->pagePrimary > -1) {
|
|
190
|
-
Set(
|
|
178
|
+
info.Set("pagePrimary", baton->pagePrimary);
|
|
191
179
|
}
|
|
192
|
-
Set(
|
|
193
|
-
Set(
|
|
180
|
+
info.Set("hasProfile", baton->hasProfile);
|
|
181
|
+
info.Set("hasAlpha", baton->hasAlpha);
|
|
194
182
|
if (baton->orientation > 0) {
|
|
195
|
-
Set(
|
|
183
|
+
info.Set("orientation", baton->orientation);
|
|
196
184
|
}
|
|
197
185
|
if (baton->exifLength > 0) {
|
|
198
|
-
Set(
|
|
199
|
-
New("exif").ToLocalChecked(),
|
|
200
|
-
Nan::NewBuffer(baton->exif, baton->exifLength, sharp::FreeCallback, nullptr).ToLocalChecked());
|
|
186
|
+
info.Set("exif", Napi::Buffer<char>::New(env, baton->exif, baton->exifLength, sharp::FreeCallback));
|
|
201
187
|
}
|
|
202
188
|
if (baton->iccLength > 0) {
|
|
203
|
-
Set(
|
|
204
|
-
New("icc").ToLocalChecked(),
|
|
205
|
-
Nan::NewBuffer(baton->icc, baton->iccLength, sharp::FreeCallback, nullptr).ToLocalChecked());
|
|
189
|
+
info.Set("icc", Napi::Buffer<char>::New(env, baton->icc, baton->iccLength, sharp::FreeCallback));
|
|
206
190
|
}
|
|
207
191
|
if (baton->iptcLength > 0) {
|
|
208
|
-
Set(
|
|
209
|
-
New("iptc").ToLocalChecked(),
|
|
210
|
-
Nan::NewBuffer(baton->iptc, baton->iptcLength, sharp::FreeCallback, nullptr).ToLocalChecked());
|
|
192
|
+
info.Set("iptc", Napi::Buffer<char>::New(env, baton->iptc, baton->iptcLength, sharp::FreeCallback));
|
|
211
193
|
}
|
|
212
194
|
if (baton->xmpLength > 0) {
|
|
213
|
-
Set(
|
|
214
|
-
New("xmp").ToLocalChecked(),
|
|
215
|
-
Nan::NewBuffer(baton->xmp, baton->xmpLength, sharp::FreeCallback, nullptr).ToLocalChecked());
|
|
195
|
+
info.Set("xmp", Napi::Buffer<char>::New(env, baton->xmp, baton->xmpLength, sharp::FreeCallback));
|
|
216
196
|
}
|
|
217
197
|
if (baton->tifftagPhotoshopLength > 0) {
|
|
218
|
-
Set(
|
|
219
|
-
New(
|
|
220
|
-
Nan::NewBuffer(baton->tifftagPhotoshop, baton->tifftagPhotoshopLength, sharp::FreeCallback, nullptr)
|
|
221
|
-
.ToLocalChecked());
|
|
198
|
+
info.Set("tifftagPhotoshop",
|
|
199
|
+
Napi::Buffer<char>::New(env, baton->tifftagPhotoshop, baton->tifftagPhotoshopLength, sharp::FreeCallback));
|
|
222
200
|
}
|
|
223
|
-
|
|
201
|
+
Callback().MakeCallback(Receiver().Value(), { env.Null(), info });
|
|
202
|
+
} else {
|
|
203
|
+
Callback().MakeCallback(Receiver().Value(), { Napi::Error::New(env, baton->err).Value() });
|
|
224
204
|
}
|
|
225
205
|
|
|
226
|
-
// Dispose of Persistent wrapper around input Buffers so they can be garbage collected
|
|
227
|
-
std::accumulate(buffersToPersist.begin(), buffersToPersist.end(), 0,
|
|
228
|
-
[this](uint32_t index, v8::Local<v8::Object> const buffer) -> uint32_t {
|
|
229
|
-
GetFromPersistent(index);
|
|
230
|
-
return index + 1;
|
|
231
|
-
});
|
|
232
206
|
delete baton->input;
|
|
233
207
|
delete baton;
|
|
234
|
-
|
|
235
|
-
// Handle warnings
|
|
236
|
-
std::string warning = sharp::VipsWarningPop();
|
|
237
|
-
while (!warning.empty()) {
|
|
238
|
-
v8::Local<v8::Value> message[1] = { New(warning).ToLocalChecked() };
|
|
239
|
-
debuglog->Call(1, message, async_resource);
|
|
240
|
-
warning = sharp::VipsWarningPop();
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
// Return to JavaScript
|
|
244
|
-
callback->Call(2, argv, async_resource);
|
|
245
208
|
}
|
|
246
209
|
|
|
247
210
|
private:
|
|
248
211
|
MetadataBaton* baton;
|
|
249
|
-
|
|
250
|
-
std::vector<v8::Local<v8::Object>> buffersToPersist;
|
|
212
|
+
Napi::FunctionReference debuglog;
|
|
251
213
|
};
|
|
252
214
|
|
|
253
215
|
/*
|
|
254
216
|
metadata(options, callback)
|
|
255
217
|
*/
|
|
256
|
-
|
|
257
|
-
// Input Buffers must not undergo GC compaction during processing
|
|
258
|
-
std::vector<v8::Local<v8::Object>> buffersToPersist;
|
|
259
|
-
|
|
218
|
+
Napi::Value metadata(const Napi::CallbackInfo& info) {
|
|
260
219
|
// V8 objects are converted to non-V8 types held in the baton struct
|
|
261
220
|
MetadataBaton *baton = new MetadataBaton;
|
|
262
|
-
|
|
221
|
+
Napi::Object options = info[0].As<Napi::Object>();
|
|
263
222
|
|
|
264
223
|
// Input
|
|
265
|
-
baton->input = sharp::CreateInputDescriptor(
|
|
224
|
+
baton->input = sharp::CreateInputDescriptor(options.Get("input").As<Napi::Object>());
|
|
266
225
|
|
|
267
226
|
// Function to notify of libvips warnings
|
|
268
|
-
|
|
227
|
+
Napi::Function debuglog = options.Get("debuglog").As<Napi::Function>();
|
|
269
228
|
|
|
270
229
|
// Join queue for worker thread
|
|
271
|
-
|
|
272
|
-
|
|
230
|
+
Napi::Function callback = info[1].As<Napi::Function>();
|
|
231
|
+
MetadataWorker *worker = new MetadataWorker(callback, baton, debuglog);
|
|
232
|
+
worker->Receiver().Set("options", options);
|
|
233
|
+
worker->Queue();
|
|
273
234
|
|
|
274
235
|
// Increment queued task counter
|
|
275
236
|
g_atomic_int_inc(&sharp::counterQueue);
|
|
237
|
+
|
|
238
|
+
return info.Env().Undefined();
|
|
276
239
|
}
|
package/src/metadata.h
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
#define SRC_METADATA_H_
|
|
17
17
|
|
|
18
18
|
#include <string>
|
|
19
|
-
#include <
|
|
19
|
+
#include <napi.h>
|
|
20
20
|
|
|
21
21
|
#include "./common.h"
|
|
22
22
|
|
|
@@ -81,6 +81,6 @@ struct MetadataBaton {
|
|
|
81
81
|
tifftagPhotoshopLength(0) {}
|
|
82
82
|
};
|
|
83
83
|
|
|
84
|
-
|
|
84
|
+
Napi::Value metadata(const Napi::CallbackInfo& info);
|
|
85
85
|
|
|
86
86
|
#endif // SRC_METADATA_H_
|