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/pipeline.h
CHANGED
|
@@ -19,12 +19,12 @@
|
|
|
19
19
|
#include <string>
|
|
20
20
|
#include <vector>
|
|
21
21
|
|
|
22
|
-
#include <
|
|
22
|
+
#include <napi.h>
|
|
23
23
|
#include <vips/vips8>
|
|
24
24
|
|
|
25
25
|
#include "./common.h"
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
Napi::Value pipeline(const Napi::CallbackInfo& info);
|
|
28
28
|
|
|
29
29
|
enum class Canvas {
|
|
30
30
|
CROP,
|
|
@@ -150,7 +150,7 @@ struct PipelineBaton {
|
|
|
150
150
|
double tiffXres;
|
|
151
151
|
double tiffYres;
|
|
152
152
|
int heifQuality;
|
|
153
|
-
|
|
153
|
+
VipsForeignHeifCompression heifCompression;
|
|
154
154
|
bool heifLossless;
|
|
155
155
|
std::string err;
|
|
156
156
|
bool withMetadata;
|
|
@@ -258,7 +258,7 @@ struct PipelineBaton {
|
|
|
258
258
|
tiffXres(1.0),
|
|
259
259
|
tiffYres(1.0),
|
|
260
260
|
heifQuality(80),
|
|
261
|
-
heifCompression(
|
|
261
|
+
heifCompression(VIPS_FOREIGN_HEIF_COMPRESSION_HEVC),
|
|
262
262
|
heifLossless(false),
|
|
263
263
|
withMetadata(false),
|
|
264
264
|
withMetadataOrientation(-1),
|
package/src/sharp.cc
CHANGED
|
@@ -12,8 +12,7 @@
|
|
|
12
12
|
// See the License for the specific language governing permissions and
|
|
13
13
|
// limitations under the License.
|
|
14
14
|
|
|
15
|
-
#include <
|
|
16
|
-
#include <nan.h>
|
|
15
|
+
#include <napi.h>
|
|
17
16
|
#include <vips/vips8>
|
|
18
17
|
|
|
19
18
|
#include "common.h"
|
|
@@ -22,33 +21,24 @@
|
|
|
22
21
|
#include "utilities.h"
|
|
23
22
|
#include "stats.h"
|
|
24
23
|
|
|
25
|
-
|
|
24
|
+
Napi::Object init(Napi::Env env, Napi::Object exports) {
|
|
26
25
|
vips_init("sharp");
|
|
27
26
|
|
|
28
27
|
g_log_set_handler("VIPS", static_cast<GLogLevelFlags>(G_LOG_LEVEL_WARNING),
|
|
29
28
|
static_cast<GLogFunc>(sharp::VipsWarningCallback), nullptr);
|
|
30
29
|
|
|
31
30
|
// Methods available to JavaScript
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
Nan::GetFunction(Nan::New<v8::FunctionTemplate>(simd)).ToLocalChecked());
|
|
44
|
-
Nan::Set(target, Nan::New("libvipsVersion").ToLocalChecked(),
|
|
45
|
-
Nan::GetFunction(Nan::New<v8::FunctionTemplate>(libvipsVersion)).ToLocalChecked());
|
|
46
|
-
Nan::Set(target, Nan::New("format").ToLocalChecked(),
|
|
47
|
-
Nan::GetFunction(Nan::New<v8::FunctionTemplate>(format)).ToLocalChecked());
|
|
48
|
-
Nan::Set(target, Nan::New("_maxColourDistance").ToLocalChecked(),
|
|
49
|
-
Nan::GetFunction(Nan::New<v8::FunctionTemplate>(_maxColourDistance)).ToLocalChecked());
|
|
50
|
-
Nan::Set(target, Nan::New("stats").ToLocalChecked(),
|
|
51
|
-
Nan::GetFunction(Nan::New<v8::FunctionTemplate>(stats)).ToLocalChecked());
|
|
31
|
+
exports.Set("metadata", Napi::Function::New(env, metadata));
|
|
32
|
+
exports.Set("pipeline", Napi::Function::New(env, pipeline));
|
|
33
|
+
exports.Set("cache", Napi::Function::New(env, cache));
|
|
34
|
+
exports.Set("concurrency", Napi::Function::New(env, concurrency));
|
|
35
|
+
exports.Set("counters", Napi::Function::New(env, counters));
|
|
36
|
+
exports.Set("simd", Napi::Function::New(env, simd));
|
|
37
|
+
exports.Set("libvipsVersion", Napi::Function::New(env, libvipsVersion));
|
|
38
|
+
exports.Set("format", Napi::Function::New(env, format));
|
|
39
|
+
exports.Set("_maxColourDistance", Napi::Function::New(env, _maxColourDistance));
|
|
40
|
+
exports.Set("stats", Napi::Function::New(env, stats));
|
|
41
|
+
return exports;
|
|
52
42
|
}
|
|
53
43
|
|
|
54
|
-
|
|
44
|
+
NODE_API_MODULE(sharp, init)
|
package/src/stats.cc
CHANGED
|
@@ -16,28 +16,16 @@
|
|
|
16
16
|
#include <vector>
|
|
17
17
|
#include <iostream>
|
|
18
18
|
|
|
19
|
-
#include <
|
|
20
|
-
#include <nan.h>
|
|
19
|
+
#include <napi.h>
|
|
21
20
|
#include <vips/vips8>
|
|
22
21
|
|
|
23
22
|
#include "common.h"
|
|
24
23
|
#include "stats.h"
|
|
25
24
|
|
|
26
|
-
class StatsWorker : public
|
|
25
|
+
class StatsWorker : public Napi::AsyncWorker {
|
|
27
26
|
public:
|
|
28
|
-
StatsWorker(
|
|
29
|
-
|
|
30
|
-
std::vector<v8::Local<v8::Object>> const buffersToPersist) :
|
|
31
|
-
Nan::AsyncWorker(callback, "sharp:StatsWorker"),
|
|
32
|
-
baton(baton), debuglog(debuglog),
|
|
33
|
-
buffersToPersist(buffersToPersist) {
|
|
34
|
-
// Protect Buffer objects from GC, keyed on index
|
|
35
|
-
std::accumulate(buffersToPersist.begin(), buffersToPersist.end(), 0,
|
|
36
|
-
[this](uint32_t index, v8::Local<v8::Object> const buffer) -> uint32_t {
|
|
37
|
-
SaveToPersistent(index, buffer);
|
|
38
|
-
return index + 1;
|
|
39
|
-
});
|
|
40
|
-
}
|
|
27
|
+
StatsWorker(Napi::Function callback, StatsBaton *baton, Napi::Function debuglog) :
|
|
28
|
+
Napi::AsyncWorker(callback), baton(baton), debuglog(Napi::Persistent(debuglog)) {}
|
|
41
29
|
~StatsWorker() {}
|
|
42
30
|
|
|
43
31
|
const int STAT_MIN_INDEX = 0;
|
|
@@ -54,13 +42,9 @@ class StatsWorker : public Nan::AsyncWorker {
|
|
|
54
42
|
void Execute() {
|
|
55
43
|
// Decrement queued task counter
|
|
56
44
|
g_atomic_int_dec_and_test(&sharp::counterQueue);
|
|
57
|
-
using Nan::New;
|
|
58
|
-
using Nan::Set;
|
|
59
|
-
using sharp::MaximumImageAlpha;
|
|
60
45
|
|
|
61
46
|
vips::VImage image;
|
|
62
47
|
sharp::ImageType imageType = sharp::ImageType::UNKNOWN;
|
|
63
|
-
|
|
64
48
|
try {
|
|
65
49
|
std::tie(image, imageType) = OpenInput(baton->input);
|
|
66
50
|
} catch (vips::VError const &err) {
|
|
@@ -71,20 +55,23 @@ class StatsWorker : public Nan::AsyncWorker {
|
|
|
71
55
|
vips::VImage stats = image.stats();
|
|
72
56
|
int const bands = image.bands();
|
|
73
57
|
for (int b = 1; b <= bands; b++) {
|
|
74
|
-
ChannelStats cStats(
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
58
|
+
ChannelStats cStats(
|
|
59
|
+
static_cast<int>(stats.getpoint(STAT_MIN_INDEX, b).front()),
|
|
60
|
+
static_cast<int>(stats.getpoint(STAT_MAX_INDEX, b).front()),
|
|
61
|
+
stats.getpoint(STAT_SUM_INDEX, b).front(),
|
|
62
|
+
stats.getpoint(STAT_SQ_SUM_INDEX, b).front(),
|
|
63
|
+
stats.getpoint(STAT_MEAN_INDEX, b).front(),
|
|
64
|
+
stats.getpoint(STAT_STDEV_INDEX, b).front(),
|
|
65
|
+
static_cast<int>(stats.getpoint(STAT_MINX_INDEX, b).front()),
|
|
66
|
+
static_cast<int>(stats.getpoint(STAT_MINY_INDEX, b).front()),
|
|
67
|
+
static_cast<int>(stats.getpoint(STAT_MAXX_INDEX, b).front()),
|
|
68
|
+
static_cast<int>(stats.getpoint(STAT_MAXY_INDEX, b).front()));
|
|
82
69
|
baton->channelStats.push_back(cStats);
|
|
83
70
|
}
|
|
84
71
|
// Image is not opaque when alpha layer is present and contains a non-mamixa value
|
|
85
72
|
if (sharp::HasAlpha(image)) {
|
|
86
73
|
double const minAlpha = static_cast<double>(stats.getpoint(STAT_MIN_INDEX, bands).front());
|
|
87
|
-
if (minAlpha != MaximumImageAlpha(image.interpretation())) {
|
|
74
|
+
if (minAlpha != sharp::MaximumImageAlpha(image.interpretation())) {
|
|
88
75
|
baton->isOpaque = false;
|
|
89
76
|
}
|
|
90
77
|
}
|
|
@@ -100,92 +87,78 @@ class StatsWorker : public Nan::AsyncWorker {
|
|
|
100
87
|
vips_thread_shutdown();
|
|
101
88
|
}
|
|
102
89
|
|
|
103
|
-
void
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
Nan::HandleScope();
|
|
90
|
+
void OnOK() {
|
|
91
|
+
Napi::Env env = Env();
|
|
92
|
+
Napi::HandleScope scope(env);
|
|
107
93
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
94
|
+
// Handle warnings
|
|
95
|
+
std::string warning = sharp::VipsWarningPop();
|
|
96
|
+
while (!warning.empty()) {
|
|
97
|
+
debuglog.Call({ Napi::String::New(env, warning) });
|
|
98
|
+
warning = sharp::VipsWarningPop();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (baton->err.empty()) {
|
|
112
102
|
// Stats Object
|
|
113
|
-
|
|
114
|
-
|
|
103
|
+
Napi::Object info = Napi::Object::New(env);
|
|
104
|
+
Napi::Array channels = Napi::Array::New(env);
|
|
115
105
|
|
|
116
106
|
std::vector<ChannelStats>::iterator it;
|
|
117
107
|
int i = 0;
|
|
118
108
|
for (it = baton->channelStats.begin(); it < baton->channelStats.end(); it++, i++) {
|
|
119
|
-
|
|
120
|
-
Set(
|
|
121
|
-
Set(
|
|
122
|
-
Set(
|
|
123
|
-
Set(
|
|
124
|
-
Set(
|
|
125
|
-
Set(
|
|
126
|
-
Set(
|
|
127
|
-
Set(
|
|
128
|
-
Set(
|
|
129
|
-
Set(
|
|
130
|
-
Set(
|
|
109
|
+
Napi::Object channelStat = Napi::Object::New(env);
|
|
110
|
+
channelStat.Set("min", it->min);
|
|
111
|
+
channelStat.Set("max", it->max);
|
|
112
|
+
channelStat.Set("sum", it->sum);
|
|
113
|
+
channelStat.Set("squaresSum", it->squaresSum);
|
|
114
|
+
channelStat.Set("mean", it->mean);
|
|
115
|
+
channelStat.Set("stdev", it->stdev);
|
|
116
|
+
channelStat.Set("minX", it->minX);
|
|
117
|
+
channelStat.Set("minY", it->minY);
|
|
118
|
+
channelStat.Set("maxX", it->maxX);
|
|
119
|
+
channelStat.Set("maxY", it->maxY);
|
|
120
|
+
channels.Set(i, channelStat);
|
|
131
121
|
}
|
|
132
122
|
|
|
133
|
-
Set(
|
|
134
|
-
Set(
|
|
135
|
-
Set(
|
|
136
|
-
|
|
123
|
+
info.Set("channels", channels);
|
|
124
|
+
info.Set("isOpaque", baton->isOpaque);
|
|
125
|
+
info.Set("entropy", baton->entropy);
|
|
126
|
+
Callback().MakeCallback(Receiver().Value(), { env.Null(), info });
|
|
127
|
+
} else {
|
|
128
|
+
Callback().MakeCallback(Receiver().Value(), { Napi::Error::New(env, baton->err).Value() });
|
|
137
129
|
}
|
|
138
130
|
|
|
139
|
-
// Dispose of Persistent wrapper around input Buffers so they can be garbage collected
|
|
140
|
-
std::accumulate(buffersToPersist.begin(), buffersToPersist.end(), 0,
|
|
141
|
-
[this](uint32_t index, v8::Local<v8::Object> const buffer) -> uint32_t {
|
|
142
|
-
GetFromPersistent(index);
|
|
143
|
-
return index + 1;
|
|
144
|
-
});
|
|
145
131
|
delete baton->input;
|
|
146
132
|
delete baton;
|
|
147
|
-
|
|
148
|
-
// Handle warnings
|
|
149
|
-
std::string warning = sharp::VipsWarningPop();
|
|
150
|
-
while (!warning.empty()) {
|
|
151
|
-
v8::Local<v8::Value> message[1] = { New(warning).ToLocalChecked() };
|
|
152
|
-
debuglog->Call(1, message, async_resource);
|
|
153
|
-
warning = sharp::VipsWarningPop();
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// Return to JavaScript
|
|
157
|
-
callback->Call(2, argv, async_resource);
|
|
158
133
|
}
|
|
159
134
|
|
|
160
135
|
private:
|
|
161
136
|
StatsBaton* baton;
|
|
162
|
-
|
|
163
|
-
std::vector<v8::Local<v8::Object>> buffersToPersist;
|
|
137
|
+
Napi::FunctionReference debuglog;
|
|
164
138
|
};
|
|
165
139
|
|
|
166
140
|
/*
|
|
167
141
|
stats(options, callback)
|
|
168
142
|
*/
|
|
169
|
-
|
|
170
|
-
using sharp::AttrTo;
|
|
171
|
-
|
|
172
|
-
// Input Buffers must not undergo GC compaction during processing
|
|
173
|
-
std::vector<v8::Local<v8::Object>> buffersToPersist;
|
|
174
|
-
|
|
143
|
+
Napi::Value stats(const Napi::CallbackInfo& info) {
|
|
175
144
|
// V8 objects are converted to non-V8 types held in the baton struct
|
|
176
145
|
StatsBaton *baton = new StatsBaton;
|
|
177
|
-
|
|
146
|
+
Napi::Object options = info[0].As<Napi::Object>();
|
|
178
147
|
|
|
179
148
|
// Input
|
|
180
|
-
baton->input = sharp::CreateInputDescriptor(
|
|
149
|
+
baton->input = sharp::CreateInputDescriptor(options.Get("input").As<Napi::Object>());
|
|
181
150
|
|
|
182
151
|
// Function to notify of libvips warnings
|
|
183
|
-
|
|
152
|
+
Napi::Function debuglog = options.Get("debuglog").As<Napi::Function>();
|
|
184
153
|
|
|
185
154
|
// Join queue for worker thread
|
|
186
|
-
|
|
187
|
-
|
|
155
|
+
Napi::Function callback = info[1].As<Napi::Function>();
|
|
156
|
+
StatsWorker *worker = new StatsWorker(callback, baton, debuglog);
|
|
157
|
+
worker->Receiver().Set("options", options);
|
|
158
|
+
worker->Queue();
|
|
188
159
|
|
|
189
160
|
// Increment queued task counter
|
|
190
161
|
g_atomic_int_inc(&sharp::counterQueue);
|
|
162
|
+
|
|
163
|
+
return info.Env().Undefined();
|
|
191
164
|
}
|
package/src/stats.h
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
#define SRC_STATS_H_
|
|
17
17
|
|
|
18
18
|
#include <string>
|
|
19
|
-
#include <
|
|
19
|
+
#include <napi.h>
|
|
20
20
|
|
|
21
21
|
#include "./common.h"
|
|
22
22
|
|
|
@@ -33,12 +33,8 @@ struct ChannelStats {
|
|
|
33
33
|
int maxX;
|
|
34
34
|
int maxY;
|
|
35
35
|
|
|
36
|
-
ChannelStats(
|
|
37
|
-
|
|
38
|
-
, minX(0), minY(0), maxX(0), maxY(0) {}
|
|
39
|
-
|
|
40
|
-
ChannelStats(int minVal, int maxVal, double sumVal, double squaresSumVal,
|
|
41
|
-
double meanVal, double stdevVal, int minXVal, int minYVal, int maxXVal, int maxYVal):
|
|
36
|
+
ChannelStats(int minVal, int maxVal, double sumVal, double squaresSumVal,
|
|
37
|
+
double meanVal, double stdevVal, int minXVal, int minYVal, int maxXVal, int maxYVal):
|
|
42
38
|
min(minVal), max(maxVal), sum(sumVal), squaresSum(squaresSumVal),
|
|
43
39
|
mean(meanVal), stdev(stdevVal), minX(minXVal), minY(minYVal), maxX(maxXVal), maxY(maxYVal) {}
|
|
44
40
|
};
|
|
@@ -61,6 +57,6 @@ struct StatsBaton {
|
|
|
61
57
|
{}
|
|
62
58
|
};
|
|
63
59
|
|
|
64
|
-
|
|
60
|
+
Napi::Value stats(const Napi::CallbackInfo& info);
|
|
65
61
|
|
|
66
62
|
#endif // SRC_STATS_H_
|