Partial natives rework (#325)

* natve code reworking

* Whoops

* remove old code

* Make gc callback instead of do thing that causes segfault
This commit is contained in:
bjcscat 2022-11-27 13:03:07 -06:00 committed by GitHub
parent a6823e7724
commit 330dd67063
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
54 changed files with 357 additions and 397 deletions

View File

@ -1,26 +1,23 @@
#include <napi.h>
#include "common.h"
#include <vips/vips8>
#include <string>
#include <map>
using namespace std;
using namespace vips;
Napi::Value Blur(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();
Napi::Object result = Napi::Object::New(env);
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
bool sharp = obj.Get("sharp").As<Napi::Boolean>().Value();
string type = obj.Get("type").As<Napi::String>().Utf8Value();
char* Blur(string type, char* BufferData, size_t BufferLength, map<string, string> Arguments, size_t* DataSize) {
string caption = Arguments["caption"];
string font = MAP_GET(Arguments, "font");
bool sharp = MAP_GET(Arguments, "sharp") == "true";
VOption *options = VImage::option()->set("access", "sequential");
VImage in =
VImage::new_from_buffer(data.Data(), data.Length(), "",
type == "gif" ? options->set("n", -1) : options)
.colourspace(VIPS_INTERPRETATION_sRGB);
VImage::new_from_buffer(BufferData, BufferLength, "",
type == "gif" ? options->set("n", -1) : options)
.colourspace(VIPS_INTERPRETATION_sRGB);
if (!in.has_alpha()) in = in.bandjoin(255);
// TODO: find a better way to calculate the intensity for GIFs without
@ -29,18 +26,10 @@ Napi::Value Blur(const Napi::CallbackInfo &info) {
: in.gaussblur(15);
void *buf;
size_t length;
out.write_to_buffer(("." + type).c_str(), &buf, &length);
out.write_to_buffer(("." + type).c_str(), &buf, DataSize);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)buf, length));
result.Set("type", type);
} catch (std::exception const &err) {
Napi::Error::New(env, err.what()).ThrowAsJavaScriptException();
} catch (...) {
Napi::Error::New(env, "Unknown error").ThrowAsJavaScriptException();
}
vips_error_clear();
vips_thread_shutdown();
vips_error_clear();
vips_thread_shutdown();
return result;
return (char*) buf;
}

View File

@ -2,4 +2,7 @@
#include <napi.h>
Napi::Value Blur(const Napi::CallbackInfo& info);
using std::string;
using std::map;
char* Blur(string type, char* BufferData, size_t BufferLength, map<string, string> Arguments, size_t* DataSize);

View File

@ -1,29 +1,24 @@
#include "common.h"
#include <napi.h>
#include <map>
#include <vips/vips8>
using namespace std;
using namespace vips;
Napi::Value Caption(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();
Napi::Object result = Napi::Object::New(env);
char* Caption(string type, char* BufferData, size_t BufferLength, map<string, string> Arguments, size_t* DataSize) {
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
string caption = obj.Get("caption").As<Napi::String>().Utf8Value();
string font = obj.Get("font").As<Napi::String>().Utf8Value();
string type = obj.Get("type").As<Napi::String>().Utf8Value();
string basePath = obj.Get("basePath").As<Napi::String>().Utf8Value();
string caption = Arguments["caption"];
string font = MAP_GET(Arguments, "font");
VOption *options = VImage::option()->set("access", "sequential");
VImage in =
VImage::new_from_buffer(data.Data(), data.Length(), "",
type == "gif" ? options->set("n", -1) : options)
.colourspace(VIPS_INTERPRETATION_sRGB);
VImage::new_from_buffer(BufferData, BufferLength, "",
type == "gif" ? options->set("n", -1) : options)
.colourspace(VIPS_INTERPRETATION_sRGB);
if (!in.has_alpha())
in = in.bandjoin(255);
@ -33,26 +28,17 @@ Napi::Value Caption(const Napi::CallbackInfo &info) {
int nPages = vips_image_get_n_pages(in.get_image());
int textWidth = width - ((width / 25) * 2);
string font_string = (font == "roboto" ? "Roboto Condensed" : font) + ", Twemoji Color Emoji " +
(font != "impact" ? "bold" : "normal") +
" " + to_string(size);
string font_string = (font == "roboto" ? "Roboto Condensed" : font) + " " +
(font != "impact" ? "bold" : "normal") + " " +
to_string(size);
string captionText = "<span background=\"white\">" + caption + "</span>";
VImage text;
auto findResult = fontPaths.find(font);
if (findResult != fontPaths.end()) {
text = VImage::text(
".", VImage::option()->set("fontfile",
(basePath + findResult->second).c_str()));
}
text = VImage::text(
captionText.c_str(),
VImage::option()
VImage text =
VImage::text(captionText.c_str(), VImage::option()
->set("rgba", true)
->set("align", VIPS_ALIGN_CENTRE)
->set("font", font_string.c_str())
->set("fontfile", (basePath + "assets/fonts/twemoji.otf").c_str())
->set("width", textWidth));
VImage captionImage =
((text == (vector<double>){0, 0, 0, 0}).bandand())
@ -72,22 +58,14 @@ Napi::Value Caption(const Napi::CallbackInfo &info) {
VImage final = VImage::arrayjoin(img, VImage::option()->set("across", 1));
final.set(VIPS_META_PAGE_HEIGHT, pageHeight + captionImage.height());
void *buf;
size_t length;
void* buf;
final.write_to_buffer(
("." + type).c_str(), &buf, &length,
("." + type).c_str(), &buf, DataSize,
type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
: 0);
result.Set("data", Napi::Buffer<char>::New(env, (char *)buf, length));
result.Set("type", type);
} catch (std::exception const &err) {
Napi::Error::New(env, err.what()).ThrowAsJavaScriptException();
} catch (...) {
Napi::Error::New(env, "Unknown error").ThrowAsJavaScriptException();
}
vips_error_clear();
vips_thread_shutdown();
vips_error_clear();
vips_thread_shutdown();
return result;
return (char*) buf;
}

View File

@ -1,5 +1,7 @@
#pragma once
#include <map>
#include <string>
#include <napi.h>
Napi::Value Caption(const Napi::CallbackInfo& info);
char* Caption(std::string type, char* BufferData, size_t BufferLength, std::map<std::string, std::string> Arguments, size_t* DataSize);

View File

@ -1,30 +1,27 @@
#include "common.h"
#include <napi.h>
#include "common.h"
#include <string>
#include <map>
#include <vips/vips8>
using namespace std;
using namespace vips;
Napi::Value CaptionTwo(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();
Napi::Object result = Napi::Object::New(env);
char* CaptionTwo(string type, char* BufferData, size_t BufferLength, map<string, string> Arguments, size_t* DataSize) {
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
string caption = obj.Get("caption").As<Napi::String>().Utf8Value();
bool top = obj.Get("top").As<Napi::Boolean>().Value();
string font = obj.Get("font").As<Napi::String>().Utf8Value();
string type = obj.Get("type").As<Napi::String>().Utf8Value();
string basePath = obj.Get("basePath").As<Napi::String>().Utf8Value();
bool top = MAP_GET(Arguments, "top") == "true";
string caption = Arguments["caption"];
string font = MAP_GET(Arguments, "font");
string basePath = MAP_GET(Arguments, "basePath");
VOption *options = VImage::option()->set("access", "sequential");
VImage in =
VImage::new_from_buffer(data.Data(), data.Length(), "",
type == "gif" ? options->set("n", -1) : options)
.colourspace(VIPS_INTERPRETATION_sRGB);
VImage::new_from_buffer(BufferData, BufferLength, "",
type == "gif" ? options->set("n", -1) : options)
.colourspace(VIPS_INTERPRETATION_sRGB);
if (!in.has_alpha())
in = in.bandjoin(255);
@ -76,21 +73,13 @@ Napi::Value CaptionTwo(const Napi::CallbackInfo &info) {
final.set(VIPS_META_PAGE_HEIGHT, pageHeight + captionImage.height());
void *buf;
size_t length;
final.write_to_buffer(
("." + type).c_str(), &buf, &length,
("." + type).c_str(), &buf, DataSize,
type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
: 0);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)buf, length));
result.Set("type", type);
} catch (std::exception const &err) {
Napi::Error::New(env, err.what()).ThrowAsJavaScriptException();
} catch (...) {
Napi::Error::New(env, "Unknown error").ThrowAsJavaScriptException();
}
vips_error_clear();
vips_thread_shutdown();
return result;
vips_error_clear();
vips_thread_shutdown();
return (char*) buf;
}

View File

@ -1,5 +1,7 @@
#pragma once
#include <map>
#include <string>
#include <napi.h>
Napi::Value CaptionTwo(const Napi::CallbackInfo& info);
char* CaptionTwo(std::string type, char* BufferData, size_t BufferLength, std::map<std::string, std::string> Arguments, size_t* DataSize);

View File

@ -2,27 +2,22 @@
#include <napi.h>
#include <iostream>
#include <string>
#include <map>
#include <list>
using namespace std;
using namespace Magick;
Napi::Value Circle(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();
Napi::Object result = Napi::Object::New(env);
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
string type = obj.Get("type").As<Napi::String>().Utf8Value();
char* Circle(string type, char* BufferData, size_t BufferLength, map<string, string> Arguments, size_t* DataSize) {
Blob blob;
list<Image> frames;
list<Image> coalesced;
list<Image> blurred;
try {
readImages(&frames, Blob(data.Data(), data.Length()));
readImages(&frames, Blob(BufferData, BufferLength));
} catch (Magick::WarningCoder &warning) {
cerr << "Coder Warning: " << warning.what() << endl;
} catch (Magick::Warning &warning) {
@ -47,14 +42,7 @@ Napi::Value Circle(const Napi::CallbackInfo &info) {
writeImages(blurred.begin(), blurred.end(), &blob);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
blob.length()));
result.Set("type", type);
} catch (std::exception const &err) {
Napi::Error::New(env, err.what()).ThrowAsJavaScriptException();
} catch (...) {
Napi::Error::New(env, "Unknown error").ThrowAsJavaScriptException();
}
*DataSize = blob.length();
return result;
return (char*) blob.data();
}

View File

@ -1,5 +1,10 @@
#pragma once
#include <napi.h>
#include <string>
#include <map>
Napi::Value Circle(const Napi::CallbackInfo& info);
using std::string;
using std::map;
char* Circle(string type, char* BufferData, size_t BufferLength, map<string, string> Arguments, size_t* DataSize);

View File

@ -1,6 +1,8 @@
#include <napi.h>
#include <vips/vips8>
#include <map>
#include <string>
using namespace std;
using namespace vips;
@ -8,20 +10,14 @@ using namespace vips;
VImage sepia = VImage::new_matrixv(3, 3, 0.3588, 0.7044, 0.1368, 0.2990, 0.5870,
0.1140, 0.2392, 0.4696, 0.0912);
Napi::Value Colors(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();
Napi::Object result = Napi::Object::New(env);
char* Colors(string type, char* BufferData, size_t BufferLength, map<string, string> Arguments, size_t* DataSize) {
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
string color = obj.Get("color").As<Napi::String>().Utf8Value();
string type = obj.Get("type").As<Napi::String>().Utf8Value();
string color = Arguments["color"];
VOption *options = VImage::option()->set("access", "sequential");
VImage in =
VImage::new_from_buffer(data.Data(), data.Length(), "",
VImage::new_from_buffer(BufferData, BufferLength, "",
type == "gif" ? options->set("n", -1) : options)
.colourspace(VIPS_INTERPRETATION_sRGB);
@ -34,18 +30,10 @@ Napi::Value Colors(const Napi::CallbackInfo &info) {
}
void *buf;
size_t length;
out.write_to_buffer(("." + type).c_str(), &buf, &length);
out.write_to_buffer(("." + type).c_str(), &buf, DataSize);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)buf, length));
result.Set("type", type);
} catch (std::exception const &err) {
Napi::Error::New(env, err.what()).ThrowAsJavaScriptException();
} catch (...) {
Napi::Error::New(env, "Unknown error").ThrowAsJavaScriptException();
}
vips_error_clear();
vips_thread_shutdown();
vips_error_clear();
vips_thread_shutdown();
return result;
return (char*) buf;
}

View File

@ -1,5 +1,10 @@
#pragma once
#include <napi.h>
#include <map>
#include <string>
Napi::Value Colors(const Napi::CallbackInfo& info);
using std::map;
using std::string;
char* Colors(string type, char* BufferData, size_t BufferLength, map<string, string> Arguments, size_t* DataSize);

View File

@ -3,6 +3,9 @@
#include <string>
#include <unordered_map>
#define MAP_HAS(ARRAY, KEY) (ARRAY.count(KEY) > 0)
#define MAP_GET(ARRAY, KEY) (MAP_HAS(ARRAY, KEY) ? ARRAY.at(KEY) : NULL) // C++ has forced my hand
const std::unordered_map<std::string, std::string> fontPaths {
{"futura", "assets/fonts/caption.otf"},
{"helvetica", "assets/fonts/caption2.ttf"},

View File

@ -1,25 +1,19 @@
#include <napi.h>
#include <map>
#include <string>
#include <vips/vips8>
using namespace std;
using namespace vips;
Napi::Value Crop(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();
Napi::Object result = Napi::Object::New(env);
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
string type = obj.Get("type").As<Napi::String>().Utf8Value();
char* Crop(string type, char* BufferData, size_t BufferLength, map<string, string> Arguments, size_t* DataSize) {
VOption *options = VImage::option()->set("access", "sequential");
VImage in =
VImage::new_from_buffer(data.Data(), data.Length(), "",
type == "gif" ? options->set("n", -1) : options)
.colourspace(VIPS_INTERPRETATION_sRGB);
VImage::new_from_buffer(BufferData, BufferLength, "",
type == "gif" ? options->set("n", -1) : options)
.colourspace(VIPS_INTERPRETATION_sRGB);
int width = in.width();
int pageHeight = vips_image_get_page_height(in.get_image());
@ -46,21 +40,13 @@ Napi::Value Crop(const Napi::CallbackInfo &info) {
final.set(VIPS_META_PAGE_HEIGHT, finalHeight);
void *buf;
size_t length;
final.write_to_buffer(
("." + type).c_str(), &buf, &length,
("." + type).c_str(), &buf, DataSize,
type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
: 0);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)buf, length));
result.Set("type", type);
} catch (std::exception const &err) {
Napi::Error::New(env, err.what()).ThrowAsJavaScriptException();
} catch (...) {
Napi::Error::New(env, "Unknown error").ThrowAsJavaScriptException();
}
vips_error_clear();
vips_thread_shutdown();
vips_error_clear();
vips_thread_shutdown();
return result;
return (char*) buf;
}

View File

@ -1,5 +1,10 @@
#pragma once
#include <napi.h>
#include <map>
#include <string>
Napi::Value Crop(const Napi::CallbackInfo& info);
using std::map;
using std::string;
char* Crop(string type, char* BufferData, size_t BufferLength, map<string, string> Arguments, size_t* DataSize);

View File

@ -1,25 +1,18 @@
#include <napi.h>
#include <map>
#include <vips/vips8>
using namespace std;
using namespace vips;
Napi::Value Deepfry(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();
Napi::Object result = Napi::Object::New(env);
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
string type = obj.Get("type").As<Napi::String>().Utf8Value();
char* Deepfry(string type, char* BufferData, size_t BufferLength, map<string, string> Arguments, size_t* DataSize) {
VOption *options = VImage::option()->set("access", "sequential");
VImage in =
VImage::new_from_buffer(data.Data(), data.Length(), "",
type == "gif" ? options->set("n", -1) : options)
.colourspace(VIPS_INTERPRETATION_sRGB);
VImage::new_from_buffer(BufferData, BufferLength, "",
type == "gif" ? options->set("n", -1) : options)
.colourspace(VIPS_INTERPRETATION_sRGB);
if (!in.has_alpha())
in = in.bandjoin(255);
@ -59,20 +52,12 @@ Napi::Value Deepfry(const Napi::CallbackInfo &info) {
}
void *buf;
size_t length;
final.write_to_buffer(("." + type).c_str(), &buf, &length,
final.write_to_buffer(("." + type).c_str(), &buf, DataSize,
type == "gif" ? VImage::option()->set("dither", 0)
: 0);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)buf, length));
result.Set("type", type);
} catch (std::exception const &err) {
Napi::Error::New(env, err.what()).ThrowAsJavaScriptException();
} catch (...) {
Napi::Error::New(env, "Unknown error").ThrowAsJavaScriptException();
}
vips_error_clear();
vips_thread_shutdown();
vips_error_clear();
vips_thread_shutdown();
return result;
return (char*) buf;
}

View File

@ -1,5 +1,10 @@
#pragma once
#include <napi.h>
#include <map>
#include <string>
Napi::Value Deepfry(const Napi::CallbackInfo& info);
using std::map;
using std::string;
char* Deepfry(string type, char* BufferData, size_t BufferLength, map<string, string> Arguments, size_t* DataSize);

View File

@ -1,22 +1,19 @@
#include "common.h"
#include <Magick++.h>
#include <napi.h>
#include <iostream>
#include <string>
#include <map>
#include <list>
using namespace std;
using namespace Magick;
Napi::Value Explode(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();
char* Explode(string type, char* BufferData, size_t BufferLength, map<string, string> Arguments, size_t* DataSize) {
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
int amount = obj.Get("amount").As<Napi::Number>().Int32Value();
string type = obj.Get("type").As<Napi::String>().Utf8Value();
int delay =
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
int amount = stoi(Arguments.at("amount"));
int delay = MAP_HAS(Arguments, "delay") ? stoi(Arguments.at("delay")) : 0;
Blob blob;
@ -24,7 +21,7 @@ Napi::Value Explode(const Napi::CallbackInfo &info) {
list<Image> coalesced;
list<Image> blurred;
try {
readImages(&frames, Blob(data.Data(), data.Length()));
readImages(&frames, Blob(BufferData, BufferLength));
} catch (Magick::WarningCoder &warning) {
cerr << "Coder Warning: " << warning.what() << endl;
} catch (Magick::Warning &warning) {
@ -50,14 +47,7 @@ Napi::Value Explode(const Napi::CallbackInfo &info) {
writeImages(blurred.begin(), blurred.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
blob.length()));
result.Set("type", type);
return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
} catch (...) {
throw Napi::Error::New(env, "Unknown error");
}
*DataSize = blob.length();
return (char*) blob.data();
}

View File

@ -1,5 +1,10 @@
#pragma once
#include <napi.h>
#include <string>
#include <map>
Napi::Value Explode(const Napi::CallbackInfo& info);
using std::map;
using std::string;
char* Explode(string type, char* BufferData, size_t BufferLength, map<string, string> Arguments, size_t* DataSize);

View File

@ -1,27 +1,24 @@
#include <napi.h>
#include <vips/vips8>
#include <string>
#include <map>
using namespace std;
using namespace vips;
Napi::Value Flag(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();
Napi::Object result = Napi::Object::New(env);
char* Flag(string type, char* BufferData, size_t BufferLength, map<string, string> Arguments, size_t* DataSize) {
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
string overlay = obj.Get("overlay").As<Napi::String>().Utf8Value();
string type = obj.Get("type").As<Napi::String>().Utf8Value();
string basePath = obj.Get("basePath").As<Napi::String>().Utf8Value();
string overlay = Arguments["overlay"];
string basePath = Arguments["basePath"];
VOption *options = VImage::option()->set("access", "sequential");
VOption *options = VImage::option()->set("access", "sequential");
VImage in =
VImage::new_from_buffer(data.Data(), data.Length(), "",
type == "gif" ? options->set("n", -1) : options)
.colourspace(VIPS_INTERPRETATION_sRGB);
VImage::new_from_buffer(BufferData, BufferLength, "",
type == "gif" ? options->set("n", -1) : options)
.colourspace(VIPS_INTERPRETATION_sRGB);
if (!in.has_alpha()) in = in.bandjoin(255);
int width = in.width();
@ -54,20 +51,11 @@ Napi::Value Flag(const Napi::CallbackInfo &info) {
final.set(VIPS_META_PAGE_HEIGHT, pageHeight);
void *buf;
size_t length;
final.write_to_buffer(
("." + type).c_str(), &buf, &length,
("." + type).c_str(), &buf, DataSize,
type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1) : 0);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)buf, length));
result.Set("type", type);
} catch (std::exception const &err) {
Napi::Error::New(env, err.what()).ThrowAsJavaScriptException();
} catch (...) {
Napi::Error::New(env, "Unknown error").ThrowAsJavaScriptException();
}
vips_error_clear();
vips_thread_shutdown();
return result;
vips_error_clear();
vips_thread_shutdown();
return (char*) buf;
}

View File

@ -1,5 +1,10 @@
#pragma once
#include <napi.h>
#include <map>
#include <string>
Napi::Value Flag(const Napi::CallbackInfo& info);
using std::map;
using std::string;
char* Flag(string type, char* BufferData, size_t BufferLength, map<string, string> Arguments, size_t* DataSize);

View File

@ -1,23 +1,20 @@
#include <napi.h>
#include "common.h"
#include <map>
#include <vips/vips8>
using namespace std;
using namespace vips;
Napi::Value Flip(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();
Napi::Object result = Napi::Object::New(env);
char* Flip(string type, char* BufferData, size_t BufferLength, map<string, string> Arguments, size_t* DataSize) {
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
bool flop =
obj.Has("flop") ? obj.Get("flop").As<Napi::Boolean>().Value() : false;
string type = obj.Get("type").As<Napi::String>().Utf8Value();
bool flop = MAP_GET(Arguments, "flop") == "true";
VOption *options = VImage::option()->set("access", "sequential");
VImage in =
VImage::new_from_buffer(data.Data(), data.Length(), "",
VImage::new_from_buffer(BufferData, BufferLength, "",
type == "gif" ? VImage::option()->set("n", -1)->set("access", "sequential") : 0)
.colourspace(VIPS_INTERPRETATION_sRGB);
if (!in.has_alpha()) in = in.bandjoin(255);
@ -41,19 +38,13 @@ Napi::Value Flip(const Napi::CallbackInfo &info) {
out = in.flip(VIPS_DIRECTION_VERTICAL);
}
void *buf;
size_t length;
out.write_to_buffer(("." + type).c_str(), &buf, &length);
void* buf;
out.write_to_buffer(
("." + type).c_str(), &buf, DataSize,
type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
: 0);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)buf, length));
result.Set("type", type);
} catch (std::exception const &err) {
Napi::Error::New(env, err.what()).ThrowAsJavaScriptException();
} catch (...) {
Napi::Error::New(env, "Unknown error").ThrowAsJavaScriptException();
}
vips_error_clear();
vips_thread_shutdown();
return result;
vips_error_clear();
vips_thread_shutdown();
return (char*) buf;
}

View File

@ -1,5 +1,10 @@
#pragma once
#include <napi.h>
#include <map>
#include <string>
Napi::Value Flip(const Napi::CallbackInfo& info);
using std::map;
using std::string;
char* Flip(string type, char* BufferData, size_t BufferLength, map<string, string> Arguments, size_t* DataSize);

View File

@ -10,7 +10,7 @@ Napi::Value Freeze(const Napi::CallbackInfo &info) {
Napi::Object result = Napi::Object::New(env);
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Object obj = info[1].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
bool loop =
obj.Has("loop") ? obj.Get("loop").As<Napi::Boolean>().Value() : false;

View File

@ -10,7 +10,7 @@ Napi::Value Gamexplain(const Napi::CallbackInfo &info) {
Napi::Object result = Napi::Object::New(env);
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Object obj = info[1].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
string type = obj.Get("type").As<Napi::String>().Utf8Value();
string basePath = obj.Get("basePath").As<Napi::String>().Utf8Value();

View File

@ -10,7 +10,7 @@ Napi::Value Globe(const Napi::CallbackInfo &info) {
Napi::Object result = Napi::Object::New(env);
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Object obj = info[1].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
string type = obj.Get("type").As<Napi::String>().Utf8Value();
string basePath = obj.Get("basePath").As<Napi::String>().Utf8Value();

View File

@ -10,7 +10,7 @@ Napi::Value Homebrew(const Napi::CallbackInfo &info) {
Napi::Object result = Napi::Object::New(env);
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Object obj = info[1].As<Napi::Object>();
string caption = obj.Get("caption").As<Napi::String>().Utf8Value();
string basePath = obj.Get("basePath").As<Napi::String>().Utf8Value();

View File

@ -1,4 +1,9 @@
#include "common.h"
#include <napi.h>
#include <map>
#include <string>
#include "blur.h"
#include "colors.h"
#include "caption.h"
@ -37,58 +42,124 @@
#include "watermark.h"
#include "whisper.h"
#include "zamn.h"
#include <iostream>
#ifdef _WIN32
#include <Magick++.h>
#endif
#include <vips/vips8>
Napi::Object Init(Napi::Env env, Napi::Object exports)
{
using namespace std;
std::map<std::string, char* (*)(string type, char* BufferData, size_t BufferLength, map<string, string> Arguments, size_t* DataSize)> FunctionMap = {
{"caption", &Caption},
{"caption2", &CaptionTwo},
{"blur", &Blur},
{"circle", &Circle},
{"colors", &Colors},
{"crop", &Crop},
{"deepfry", &Deepfry},
{"explode", &Explode},
{"flag", &Flag},
{"flip", &Flip},
{"watermark", &Watermark},
{"uncaption", &Uncaption}
};
std::map<std::string, Napi::Value (*)(const Napi::CallbackInfo &info)> OldFunctionMap = {
{"speed", Speed},
{"freeze", Freeze},
{"gamexplain", Gamexplain},
{"globe", Globe},
{"homebrew", Homebrew},
{"invert", Invert},
{"jpeg", Jpeg},
{"magik", Magik},
{"meme", Meme},
{"mirror", Mirror},
{"motivate", Motivate},
{"reddit", Reddit},
{"resize", Resize},
{"reverse", Reverse},
{"scott", Scott},
{"snapchat", Snapchat},
{"sonic", Sonic},
{"spin", Spin},
{"swirl", Swirl},
{"tile", Tile},
{"togif", ToGif},
{"uncanny", Uncanny},
{"wall", Wall},
{"whisper", Whisper},
{"zamn", Zamn}
};
Napi::Value NewProcessImage(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();
Napi::Object result = Napi::Object::New(env);
try {
string command = info[0].As<Napi::String>().Utf8Value();
Napi::Object obj = info[1].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
string type = obj.Get("type").As<Napi::String>().Utf8Value();
Napi::Array properties = obj.GetPropertyNames();
std::map<string, string> Arguments;
for (unsigned int i = 0; i < properties.Length(); i++) {
string property = properties.Get(uint32_t(i)).As<Napi::String>().Utf8Value();
if (property == "data") {
continue;
}
Arguments[property] = obj.Get(property).ToString().As<Napi::String>().Utf8Value();
}
size_t length = 0;
char* buf = FunctionMap.at(command)(type, data.Data(), data.Length(), Arguments, &length);
result.Set("data", Napi::Buffer<char>::New(env, buf, length, [](Napi::Env env, void* data) {
free(data);
}));
result.Set("type", type);
} catch (std::exception const &err) {
Napi::Error::New(env, err.what()).ThrowAsJavaScriptException();
} catch (...) {
Napi::Error::New(env, "Unknown error").ThrowAsJavaScriptException();
}
return result;
}
Napi::Value OldProcessImage(std::string FunctionName, const Napi::CallbackInfo &info) {
return OldFunctionMap.at(FunctionName)(info);
}
Napi::Value ProcessImage(const Napi::CallbackInfo &info) { // janky solution for gradual adoption
Napi::Env env = info.Env();
string command = info[0].As<Napi::String>().Utf8Value();
if (MAP_HAS(FunctionMap, command)) {
return NewProcessImage(info);
} else if (MAP_HAS(OldFunctionMap, command)) {
return OldProcessImage(command, info);
} else {
Napi::Error::New(env, "Invalid command").ThrowAsJavaScriptException();
}
}
Napi::Object Init(Napi::Env env, Napi::Object exports){
#ifdef _WIN32
Magick::InitializeMagick("");
#endif
if (vips_init(""))
vips_error_exit(NULL);
exports.Set(Napi::String::New(env, "blur"), Napi::Function::New(env, Blur));
exports.Set(Napi::String::New(env, "colors"), Napi::Function::New(env, Colors));
exports.Set(Napi::String::New(env, "caption"), Napi::Function::New(env, Caption));
exports.Set(Napi::String::New(env, "captionTwo"), Napi::Function::New(env, CaptionTwo));
exports.Set(Napi::String::New(env, "circle"), Napi::Function::New(env, Circle));
exports.Set(Napi::String::New(env, "crop"), Napi::Function::New(env, Crop));
exports.Set(Napi::String::New(env, "deepfry"), Napi::Function::New(env, Deepfry));
exports.Set(Napi::String::New(env, "explode"), Napi::Function::New(env, Explode));
exports.Set(Napi::String::New(env, "flag"), Napi::Function::New(env, Flag));
exports.Set(Napi::String::New(env, "flip"), Napi::Function::New(env, Flip));
exports.Set(Napi::String::New(env, "freeze"), Napi::Function::New(env, Freeze));
exports.Set(Napi::String::New(env, "gamexplain"), Napi::Function::New(env, Gamexplain));
exports.Set(Napi::String::New(env, "globe"), Napi::Function::New(env, Globe));
exports.Set(Napi::String::New(env, "homebrew"), Napi::Function::New(env, Homebrew));
exports.Set(Napi::String::New(env, "invert"), Napi::Function::New(env, Invert));
exports.Set(Napi::String::New(env, "jpeg"), Napi::Function::New(env, Jpeg));
exports.Set(Napi::String::New(env, "magik"), Napi::Function::New(env, Magik));
exports.Set(Napi::String::New(env, "meme"), Napi::Function::New(env, Meme));
exports.Set(Napi::String::New(env, "mirror"), Napi::Function::New(env, Mirror));
exports.Set(Napi::String::New(env, "motivate"), Napi::Function::New(env, Motivate));
exports.Set(Napi::String::New(env, "reddit"), Napi::Function::New(env, Reddit));
exports.Set(Napi::String::New(env, "resize"), Napi::Function::New(env, Resize));
exports.Set(Napi::String::New(env, "reverse"), Napi::Function::New(env, Reverse));
exports.Set(Napi::String::New(env, "scott"), Napi::Function::New(env, Scott));
exports.Set(Napi::String::New(env, "snapchat"), Napi::Function::New(env, Snapchat));
exports.Set(Napi::String::New(env, "sonic"), Napi::Function::New(env, Sonic));
exports.Set(Napi::String::New(env, "speed"), Napi::Function::New(env, Speed));
exports.Set(Napi::String::New(env, "spin"), Napi::Function::New(env, Spin));
exports.Set(Napi::String::New(env, "squish"), Napi::Function::New(env, Squish));
exports.Set(Napi::String::New(env, "swirl"), Napi::Function::New(env, Swirl));
exports.Set(Napi::String::New(env, "tile"), Napi::Function::New(env, Tile));
exports.Set(Napi::String::New(env, "togif"), Napi::Function::New(env, ToGif));
exports.Set(Napi::String::New(env, "uncanny"), Napi::Function::New(env, Uncanny));
exports.Set(Napi::String::New(env, "uncaption"), Napi::Function::New(env, Uncaption));
exports.Set(Napi::String::New(env, "wall"), Napi::Function::New(env, Wall));
exports.Set(Napi::String::New(env, "watermark"), Napi::Function::New(env, Watermark));
exports.Set(Napi::String::New(env, "whisper"), Napi::Function::New(env, Whisper));
exports.Set(Napi::String::New(env, "zamn"), Napi::Function::New(env, Zamn));
return exports;
exports.Set(Napi::String::New(env, "image"), Napi::Function::New(env, ProcessImage)); // new function handler
return exports;
}
NODE_API_MODULE(addon, Init)

View File

@ -10,7 +10,7 @@ Napi::Value Invert(const Napi::CallbackInfo &info) {
Napi::Object result = Napi::Object::New(env);
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Object obj = info[1].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
string type = obj.Get("type").As<Napi::String>().Utf8Value();

View File

@ -10,7 +10,7 @@ Napi::Value Jpeg(const Napi::CallbackInfo &info) {
Napi::Object result = Napi::Object::New(env);
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Object obj = info[1].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
int quality = obj.Has("quality")
? obj.Get("quality").As<Napi::Number>().Int32Value()

View File

@ -12,7 +12,7 @@ Napi::Value Magik(const Napi::CallbackInfo &info) {
Napi::Object result = Napi::Object::New(env);
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Object obj = info[1].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
string type = obj.Get("type").As<Napi::String>().Utf8Value();

View File

@ -11,7 +11,7 @@ Napi::Value Meme(const Napi::CallbackInfo &info) {
Napi::Object result = Napi::Object::New(env);
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Object obj = info[1].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
string top = obj.Get("top").As<Napi::String>().Utf8Value();
string bottom = obj.Get("bottom").As<Napi::String>().Utf8Value();

View File

@ -10,7 +10,7 @@ Napi::Value Mirror(const Napi::CallbackInfo &info) {
Napi::Object result = Napi::Object::New(env);
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Object obj = info[1].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
bool vertical = obj.Has("vertical")
? obj.Get("vertical").As<Napi::Boolean>().Value()

View File

@ -11,7 +11,7 @@ Napi::Value Motivate(const Napi::CallbackInfo &info) {
Napi::Object result = Napi::Object::New(env);
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Object obj = info[1].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
string top_text = obj.Get("top").As<Napi::String>().Utf8Value();
string bottom_text = obj.Get("bottom").As<Napi::String>().Utf8Value();

View File

@ -10,7 +10,7 @@ Napi::Value Reddit(const Napi::CallbackInfo &info) {
Napi::Object result = Napi::Object::New(env);
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Object obj = info[1].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
string text = obj.Get("caption").As<Napi::String>().Utf8Value();
string type = obj.Get("type").As<Napi::String>().Utf8Value();

View File

@ -10,7 +10,7 @@ Napi::Value Resize(const Napi::CallbackInfo &info) {
Napi::Object result = Napi::Object::New(env);
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Object obj = info[1].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
bool stretch = obj.Has("stretch")
? obj.Get("stretch").As<Napi::Boolean>().Value()

View File

@ -10,7 +10,7 @@ Napi::Value Reverse(const Napi::CallbackInfo &info) {
Napi::Object result = Napi::Object::New(env);
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Object obj = info[1].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
bool soos =
obj.Has("soos") ? obj.Get("soos").As<Napi::Boolean>().Value() : false;

View File

@ -12,7 +12,7 @@ Napi::Value Scott(const Napi::CallbackInfo &info) {
Napi::Object result = Napi::Object::New(env);
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Object obj = info[1].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
string type = obj.Get("type").As<Napi::String>().Utf8Value();
string basePath = obj.Get("basePath").As<Napi::String>().Utf8Value();

View File

@ -10,7 +10,7 @@ Napi::Value Snapchat(const Napi::CallbackInfo &info) {
Napi::Object result = Napi::Object::New(env);
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Object obj = info[1].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
string caption = obj.Get("caption").As<Napi::String>().Utf8Value();
float pos =

View File

@ -10,7 +10,7 @@ Napi::Value Sonic(const Napi::CallbackInfo &info) {
Napi::Object result = Napi::Object::New(env);
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Object obj = info[1].As<Napi::Object>();
string text = obj.Get("text").As<Napi::String>().Utf8Value();
string basePath = obj.Get("basePath").As<Napi::String>().Utf8Value();

View File

@ -45,7 +45,7 @@ Napi::Value Speed(const Napi::CallbackInfo &info) {
Napi::Object result = Napi::Object::New(env);
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Object obj = info[1].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
bool slow =
obj.Has("slow") ? obj.Get("slow").As<Napi::Boolean>().Value() : false;
@ -92,7 +92,9 @@ Napi::Value Speed(const Napi::CallbackInfo &info) {
removeFrames = true;
break;
}
memset16(lastPos + 5, new_delay, 1);
lastPos = (char *)memchr(lastPos + 1, '\x00',
(data.Length() - (lastPos - fileData)) - 1);
++currentFrame;

View File

@ -2,4 +2,4 @@
#include <napi.h>
Napi::Value Speed(const Napi::CallbackInfo& info);
Napi::Value Speed(const Napi::CallbackInfo &info);

View File

@ -11,7 +11,7 @@ Napi::Value Spin(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Object obj = info[1].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
string type = obj.Get("type").As<Napi::String>().Utf8Value();
int delay =

View File

@ -11,7 +11,7 @@ Napi::Value Squish(const Napi::CallbackInfo &info) {
Napi::Object result = Napi::Object::New(env);
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Object obj = info[1].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
string type = obj.Get("type").As<Napi::String>().Utf8Value();

View File

@ -10,7 +10,7 @@ Napi::Value Swirl(const Napi::CallbackInfo &info) {
Napi::Object result = Napi::Object::New(env);
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Object obj = info[1].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
string type = obj.Get("type").As<Napi::String>().Utf8Value();

View File

@ -12,7 +12,7 @@ Napi::Value Tile(const Napi::CallbackInfo &info) {
Napi::Object result = Napi::Object::New(env);
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Object obj = info[1].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
string type = obj.Get("type").As<Napi::String>().Utf8Value();

View File

@ -10,7 +10,7 @@ Napi::Value ToGif(const Napi::CallbackInfo &info) {
Napi::Object result = Napi::Object::New(env);
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Object obj = info[1].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
string type = obj.Get("type").As<Napi::String>().Utf8Value();

View File

@ -11,7 +11,7 @@ Napi::Value Uncanny(const Napi::CallbackInfo &info) {
Napi::Object result = Napi::Object::New(env);
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Object obj = info[1].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
string caption = obj.Get("caption").As<Napi::String>().Utf8Value();
string caption2 = obj.Get("caption2").As<Napi::String>().Utf8Value();

View File

@ -1,26 +1,21 @@
#include <napi.h>
#include "common.h"
#include <vips/vips8>
#include <map>
using namespace std;
using namespace vips;
Napi::Value Uncaption(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();
Napi::Object result = Napi::Object::New(env);
char* Uncaption(string type, char* BufferData, size_t BufferLength, map<string, string> Arguments, size_t* DataSize) {
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
float tolerance = obj.Has("tolerance")
? obj.Get("tolerance").As<Napi::Number>().FloatValue()
float tolerance = MAP_HAS(Arguments, "tolerance")
? stof(Arguments["tolerance"])
: 0.5;
string type = obj.Get("type").As<Napi::String>().Utf8Value();
VOption *options = VImage::option();
VImage in =
VImage::new_from_buffer(data.Data(), data.Length(), "",
VImage::new_from_buffer(BufferData, BufferLength, "",
type == "gif" ? options->set("n", -1)->set("access", "sequential") : options)
.colourspace(VIPS_INTERPRETATION_sRGB);
if (!in.has_alpha()) in = in.bandjoin(255);
@ -50,20 +45,12 @@ Napi::Value Uncaption(const Napi::CallbackInfo &info) {
final.set(VIPS_META_PAGE_HEIGHT, newHeight);
void *buf;
size_t length;
final.write_to_buffer(
("." + type).c_str(), &buf, &length,
("." + type).c_str(), &buf, DataSize,
type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1) : 0);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)buf, length));
result.Set("type", type);
} catch (std::exception const &err) {
Napi::Error::New(env, err.what()).ThrowAsJavaScriptException();
} catch (...) {
Napi::Error::New(env, "Unknown error").ThrowAsJavaScriptException();
}
vips_error_clear();
vips_thread_shutdown();
return result;
return (char*) buf;
}

View File

@ -1,5 +1,5 @@
#pragma once
#include <napi.h>
#include <map>
Napi::Value Uncaption(const Napi::CallbackInfo& info);
char* Uncaption(string type, char* BufferData, size_t BufferLength, map<string, string> Arguments, size_t* DataSize);

View File

@ -12,7 +12,7 @@ Napi::Value Wall(const Napi::CallbackInfo &info) {
Napi::Object result = Napi::Object::New(env);
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Object obj = info[1].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
string type = obj.Get("type").As<Napi::String>().Utf8Value();

View File

@ -1,40 +1,32 @@
#include <napi.h>
#include "common.h"
#include <vips/vips8>
#include <map>
using namespace std;
using namespace vips;
Napi::Value Watermark(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();
Napi::Object result = Napi::Object::New(env);
char* Watermark(string type, char* BufferData, size_t BufferLength, map<string, string> Arguments, size_t* DataSize) {
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
string water = obj.Get("water").As<Napi::String>().Utf8Value();
int gravity = obj.Get("gravity").As<Napi::Number>().Int64Value();
bool resize = obj.Has("resize")
? obj.Get("resize").As<Napi::Boolean>().Value()
: false;
float yscale = obj.Has("yscale")
? obj.Get("yscale").As<Napi::Number>().FloatValue()
: false;
bool append = obj.Has("append")
? obj.Get("append").As<Napi::Boolean>().Value()
: false;
bool alpha =
obj.Has("alpha") ? obj.Get("alpha").As<Napi::Boolean>().Value() : false;
bool flip =
obj.Has("flip") ? obj.Get("flip").As<Napi::Boolean>().Value() : false;
bool mc = obj.Has("mc") ? obj.Get("mc").As<Napi::Boolean>().Value() : false;
string basePath = obj.Get("basePath").As<Napi::String>().Utf8Value();
string type = obj.Get("type").As<Napi::String>().Utf8Value();
string water = Arguments["water"];
int gravity = stoi(Arguments["gravity"]);
bool resize = MAP_HAS(Arguments, "resize") ? Arguments["resize"] == "true" : false;;
float yscale = MAP_HAS(Arguments, "yscale") ? stof(Arguments["yscale"]) : false;
bool append = MAP_HAS(Arguments, "append") ? Arguments["append"] == "true" : false;
bool alpha = MAP_HAS(Arguments, "alpha") ? Arguments["alpha"] == "true" : false;
bool flip = MAP_HAS(Arguments, "flip") ? Arguments["flip"] == "true" : false;
bool mc = MAP_HAS(Arguments, "mc");
string basePath = Arguments["basePath"];
VOption *options = VImage::option()->set("access", "sequential");
VImage in =
VImage::new_from_buffer(data.Data(), data.Length(), "",
VImage::new_from_buffer(BufferData, BufferLength, "",
type == "gif" ? options->set("n", -1) : options)
.colourspace(VIPS_INTERPRETATION_sRGB);
if (!in.has_alpha()) in = in.bandjoin(255);
@ -152,20 +144,11 @@ Napi::Value Watermark(const Napi::CallbackInfo &info) {
final.set(VIPS_META_PAGE_HEIGHT, pageHeight + addedHeight);
void *buf;
size_t length;
final.write_to_buffer(
("." + type).c_str(), &buf, &length,
("." + type).c_str(), &buf, DataSize,
type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1) : 0);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)buf, length));
result.Set("type", type);
} catch (std::exception const &err) {
Napi::Error::New(env, err.what()).ThrowAsJavaScriptException();
} catch (...) {
Napi::Error::New(env, "Unknown error").ThrowAsJavaScriptException();
}
vips_error_clear();
vips_thread_shutdown();
return result;
return (char*) buf;
}

View File

@ -2,4 +2,4 @@
#include <napi.h>
Napi::Value Watermark(const Napi::CallbackInfo& info);
char* Watermark(string type, char* BufferData, size_t BufferLength, map<string, string> Arguments, size_t* DataSize);

View File

@ -10,7 +10,7 @@ Napi::Value Whisper(const Napi::CallbackInfo &info) {
Napi::Object result = Napi::Object::New(env);
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Object obj = info[1].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
string caption = obj.Get("caption").As<Napi::String>().Utf8Value();
string type = obj.Get("type").As<Napi::String>().Utf8Value();

View File

@ -10,7 +10,7 @@ Napi::Value Zamn(const Napi::CallbackInfo &info) {
Napi::Object result = Napi::Object::New(env);
try {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Object obj = info[1].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
string type = obj.Get("type").As<Napi::String>().Utf8Value();
string basePath = obj.Get("basePath").As<Napi::String>().Utf8Value();

View File

@ -47,7 +47,7 @@ export default function run(object) {
}
objectWithFixedType.basePath = path.join(path.dirname(fileURLToPath(import.meta.url)), "../");
try {
const result = img[object.cmd](objectWithFixedType);
const result = img.image(object.cmd, objectWithFixedType);
const returnObject = {
buffer: result.data,
fileExtension: result.type