mirror of
https://github.com/lovell/sharp.git
synced 2025-07-09 18:40:16 +02:00
Expose libvips warnings via NODE_DEBUG env var
This commit is contained in:
parent
46aec7eabc
commit
301bfbd271
@ -1,5 +1,15 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
### v0.18 - "*ridge*"
|
||||||
|
|
||||||
|
Requires libvips v8.5.2.
|
||||||
|
|
||||||
|
#### v0.18.0 - TBD
|
||||||
|
|
||||||
|
* Expose warnings from libvips via NODE_DEBUG=sharp environment variable.
|
||||||
|
[#607](https://github.com/lovell/sharp/issues/607)
|
||||||
|
[@puzrin](https://github.com/puzrin)
|
||||||
|
|
||||||
### v0.17 - "*quill*"
|
### v0.17 - "*quill*"
|
||||||
|
|
||||||
Requires libvips v8.4.2.
|
Requires libvips v8.4.2.
|
||||||
|
@ -24,6 +24,9 @@ let versions = {
|
|||||||
} catch (err) {}
|
} catch (err) {}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
// Use NODE_DEBUG=sharp to enable libvips warnings
|
||||||
|
const debuglog = util.debuglog('sharp');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class Sharp
|
* @class Sharp
|
||||||
*
|
*
|
||||||
@ -174,6 +177,8 @@ const Sharp = function (input, options) {
|
|||||||
tiffSquash: false,
|
tiffSquash: false,
|
||||||
tileSize: 256,
|
tileSize: 256,
|
||||||
tileOverlap: 0,
|
tileOverlap: 0,
|
||||||
|
// Function to notify of libvips warnings
|
||||||
|
debuglog: debuglog,
|
||||||
// Function to notify of queue length changes
|
// Function to notify of queue length changes
|
||||||
queueListener: function (queueLength) {
|
queueListener: function (queueLength) {
|
||||||
queue.emit('change', queueLength);
|
queue.emit('change', queueLength);
|
||||||
|
@ -99,6 +99,7 @@
|
|||||||
"cc": {
|
"cc": {
|
||||||
"linelength": "120",
|
"linelength": "120",
|
||||||
"filter": [
|
"filter": [
|
||||||
|
"build/c++11",
|
||||||
"build/include",
|
"build/include",
|
||||||
"runtime/indentation_namespace"
|
"runtime/indentation_namespace"
|
||||||
]
|
]
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <queue>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
#include <node.h>
|
#include <node.h>
|
||||||
#include <node_buffer.h>
|
#include <node_buffer.h>
|
||||||
@ -354,6 +356,33 @@ namespace sharp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Temporary buffer of warnings
|
||||||
|
*/
|
||||||
|
std::queue<std::string> vipsWarnings;
|
||||||
|
std::mutex vipsWarningsMutex;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Called with warnings from the glib-registered "VIPS" domain
|
||||||
|
*/
|
||||||
|
void VipsWarningCallback(char const* log_domain, GLogLevelFlags log_level, char const* message, void* ignore) {
|
||||||
|
std::lock_guard<std::mutex> lock(vipsWarningsMutex);
|
||||||
|
vipsWarnings.emplace(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Pop the oldest warning message from the queue
|
||||||
|
*/
|
||||||
|
std::string VipsWarningPop() {
|
||||||
|
std::string warning;
|
||||||
|
std::lock_guard<std::mutex> lock(vipsWarningsMutex);
|
||||||
|
if (!vipsWarnings.empty()) {
|
||||||
|
warning = vipsWarnings.front();
|
||||||
|
vipsWarnings.pop();
|
||||||
|
}
|
||||||
|
return warning;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Calculate the (left, top) coordinates of the output image
|
Calculate the (left, top) coordinates of the output image
|
||||||
within the input image, applying the given gravity.
|
within the input image, applying the given gravity.
|
||||||
|
10
src/common.h
10
src/common.h
@ -189,6 +189,16 @@ namespace sharp {
|
|||||||
*/
|
*/
|
||||||
void FreeCallback(char* data, void* hint);
|
void FreeCallback(char* data, void* hint);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Called with warnings from the glib-registered "VIPS" domain
|
||||||
|
*/
|
||||||
|
void VipsWarningCallback(char const* log_domain, GLogLevelFlags log_level, char const* message, void* ignore);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Pop the oldest warning message from the queue
|
||||||
|
*/
|
||||||
|
std::string VipsWarningPop();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Calculate the (left, top) coordinates of the output image
|
Calculate the (left, top) coordinates of the output image
|
||||||
within the input image, applying the given gravity.
|
within the input image, applying the given gravity.
|
||||||
|
@ -25,9 +25,10 @@
|
|||||||
class MetadataWorker : public Nan::AsyncWorker {
|
class MetadataWorker : public Nan::AsyncWorker {
|
||||||
public:
|
public:
|
||||||
MetadataWorker(
|
MetadataWorker(
|
||||||
Nan::Callback *callback, MetadataBaton *baton,
|
Nan::Callback *callback, MetadataBaton *baton, Nan::Callback *debuglog,
|
||||||
std::vector<v8::Local<v8::Object>> const buffersToPersist)
|
std::vector<v8::Local<v8::Object>> const buffersToPersist) :
|
||||||
: Nan::AsyncWorker(callback), baton(baton), buffersToPersist(buffersToPersist) {
|
Nan::AsyncWorker(callback), baton(baton), debuglog(debuglog),
|
||||||
|
buffersToPersist(buffersToPersist) {
|
||||||
// Protect Buffer objects from GC, keyed on index
|
// Protect Buffer objects from GC, keyed on index
|
||||||
std::accumulate(buffersToPersist.begin(), buffersToPersist.end(), 0,
|
std::accumulate(buffersToPersist.begin(), buffersToPersist.end(), 0,
|
||||||
[this](uint32_t index, v8::Local<v8::Object> const buffer) -> uint32_t {
|
[this](uint32_t index, v8::Local<v8::Object> const buffer) -> uint32_t {
|
||||||
@ -132,12 +133,21 @@ class MetadataWorker : public Nan::AsyncWorker {
|
|||||||
delete baton->input;
|
delete baton->input;
|
||||||
delete baton;
|
delete baton;
|
||||||
|
|
||||||
|
// Handle warnings
|
||||||
|
std::string warning = sharp::VipsWarningPop();
|
||||||
|
while (!warning.empty()) {
|
||||||
|
v8::Local<v8::Value> message[1] = { New(warning).ToLocalChecked() };
|
||||||
|
debuglog->Call(1, message);
|
||||||
|
warning = sharp::VipsWarningPop();
|
||||||
|
}
|
||||||
|
|
||||||
// Return to JavaScript
|
// Return to JavaScript
|
||||||
callback->Call(2, argv);
|
callback->Call(2, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MetadataBaton* baton;
|
MetadataBaton* baton;
|
||||||
|
Nan::Callback *debuglog;
|
||||||
std::vector<v8::Local<v8::Object>> buffersToPersist;
|
std::vector<v8::Local<v8::Object>> buffersToPersist;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -155,9 +165,12 @@ NAN_METHOD(metadata) {
|
|||||||
// Input
|
// Input
|
||||||
baton->input = sharp::CreateInputDescriptor(sharp::AttrAs<v8::Object>(options, "input"), buffersToPersist);
|
baton->input = sharp::CreateInputDescriptor(sharp::AttrAs<v8::Object>(options, "input"), buffersToPersist);
|
||||||
|
|
||||||
|
// Function to notify of libvips warnings
|
||||||
|
Nan::Callback *debuglog = new Nan::Callback(sharp::AttrAs<v8::Function>(options, "debuglog"));
|
||||||
|
|
||||||
// Join queue for worker thread
|
// Join queue for worker thread
|
||||||
Nan::Callback *callback = new Nan::Callback(info[1].As<v8::Function>());
|
Nan::Callback *callback = new Nan::Callback(info[1].As<v8::Function>());
|
||||||
Nan::AsyncQueueWorker(new MetadataWorker(callback, baton, buffersToPersist));
|
Nan::AsyncQueueWorker(new MetadataWorker(callback, baton, debuglog, buffersToPersist));
|
||||||
|
|
||||||
// Increment queued task counter
|
// Increment queued task counter
|
||||||
g_atomic_int_inc(&sharp::counterQueue);
|
g_atomic_int_inc(&sharp::counterQueue);
|
||||||
|
@ -33,9 +33,10 @@
|
|||||||
class PipelineWorker : public Nan::AsyncWorker {
|
class PipelineWorker : public Nan::AsyncWorker {
|
||||||
public:
|
public:
|
||||||
PipelineWorker(
|
PipelineWorker(
|
||||||
Nan::Callback *callback, PipelineBaton *baton, Nan::Callback *queueListener,
|
Nan::Callback *callback, PipelineBaton *baton, Nan::Callback *debuglog, Nan::Callback *queueListener,
|
||||||
std::vector<v8::Local<v8::Object>> const buffersToPersist)
|
std::vector<v8::Local<v8::Object>> const buffersToPersist) :
|
||||||
: Nan::AsyncWorker(callback), baton(baton), queueListener(queueListener), buffersToPersist(buffersToPersist) {
|
Nan::AsyncWorker(callback), baton(baton), debuglog(debuglog), queueListener(queueListener),
|
||||||
|
buffersToPersist(buffersToPersist) {
|
||||||
// Protect Buffer objects from GC, keyed on index
|
// Protect Buffer objects from GC, keyed on index
|
||||||
std::accumulate(buffersToPersist.begin(), buffersToPersist.end(), 0,
|
std::accumulate(buffersToPersist.begin(), buffersToPersist.end(), 0,
|
||||||
[this](uint32_t index, v8::Local<v8::Object> const buffer) -> uint32_t {
|
[this](uint32_t index, v8::Local<v8::Object> const buffer) -> uint32_t {
|
||||||
@ -979,6 +980,14 @@ class PipelineWorker : public Nan::AsyncWorker {
|
|||||||
});
|
});
|
||||||
delete baton;
|
delete baton;
|
||||||
|
|
||||||
|
// Handle warnings
|
||||||
|
std::string warning = sharp::VipsWarningPop();
|
||||||
|
while (!warning.empty()) {
|
||||||
|
v8::Local<v8::Value> message[1] = { New(warning).ToLocalChecked() };
|
||||||
|
debuglog->Call(1, message);
|
||||||
|
warning = sharp::VipsWarningPop();
|
||||||
|
}
|
||||||
|
|
||||||
// Decrement processing task counter
|
// Decrement processing task counter
|
||||||
g_atomic_int_dec_and_test(&sharp::counterProcess);
|
g_atomic_int_dec_and_test(&sharp::counterProcess);
|
||||||
v8::Local<v8::Value> queueLength[1] = { New<v8::Uint32>(sharp::counterQueue) };
|
v8::Local<v8::Value> queueLength[1] = { New<v8::Uint32>(sharp::counterQueue) };
|
||||||
@ -991,6 +1000,7 @@ class PipelineWorker : public Nan::AsyncWorker {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
PipelineBaton *baton;
|
PipelineBaton *baton;
|
||||||
|
Nan::Callback *debuglog;
|
||||||
Nan::Callback *queueListener;
|
Nan::Callback *queueListener;
|
||||||
std::vector<v8::Local<v8::Object>> buffersToPersist;
|
std::vector<v8::Local<v8::Object>> buffersToPersist;
|
||||||
|
|
||||||
@ -1239,12 +1249,15 @@ NAN_METHOD(pipeline) {
|
|||||||
baton->accessMethod = VIPS_ACCESS_RANDOM;
|
baton->accessMethod = VIPS_ACCESS_RANDOM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Function to notify of libvips warnings
|
||||||
|
Nan::Callback *debuglog = new Nan::Callback(AttrAs<v8::Function>(options, "debuglog"));
|
||||||
|
|
||||||
// Function to notify of queue length changes
|
// Function to notify of queue length changes
|
||||||
Nan::Callback *queueListener = new Nan::Callback(AttrAs<v8::Function>(options, "queueListener"));
|
Nan::Callback *queueListener = new Nan::Callback(AttrAs<v8::Function>(options, "queueListener"));
|
||||||
|
|
||||||
// Join queue for worker thread
|
// Join queue for worker thread
|
||||||
Nan::Callback *callback = new Nan::Callback(info[1].As<v8::Function>());
|
Nan::Callback *callback = new Nan::Callback(info[1].As<v8::Function>());
|
||||||
Nan::AsyncQueueWorker(new PipelineWorker(callback, baton, queueListener, buffersToPersist));
|
Nan::AsyncQueueWorker(new PipelineWorker(callback, baton, debuglog, queueListener, buffersToPersist));
|
||||||
|
|
||||||
// Increment queued task counter
|
// Increment queued task counter
|
||||||
g_atomic_int_inc(&sharp::counterQueue);
|
g_atomic_int_inc(&sharp::counterQueue);
|
||||||
|
@ -24,6 +24,9 @@
|
|||||||
NAN_MODULE_INIT(init) {
|
NAN_MODULE_INIT(init) {
|
||||||
vips_init("sharp");
|
vips_init("sharp");
|
||||||
|
|
||||||
|
g_log_set_handler("VIPS", static_cast<GLogLevelFlags>(G_LOG_LEVEL_WARNING),
|
||||||
|
static_cast<GLogFunc>(sharp::VipsWarningCallback), nullptr);
|
||||||
|
|
||||||
// Methods available to JavaScript
|
// Methods available to JavaScript
|
||||||
Nan::Set(target, Nan::New("metadata").ToLocalChecked(),
|
Nan::Set(target, Nan::New("metadata").ToLocalChecked(),
|
||||||
Nan::GetFunction(Nan::New<v8::FunctionTemplate>(metadata)).ToLocalChecked());
|
Nan::GetFunction(Nan::New<v8::FunctionTemplate>(metadata)).ToLocalChecked());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user