Finish converting natives

This commit is contained in:
Essem 2022-12-28 00:20:17 -06:00
parent e1a31d6ddc
commit 47b2d9fcff
No known key found for this signature in database
GPG Key ID: 7D497397CC3A2A8C
72 changed files with 746 additions and 876 deletions

View File

@ -7,14 +7,14 @@
using namespace std; using namespace std;
using namespace vips; using namespace vips;
char *Blur(string type, char *BufferData, size_t BufferLength, char *Blur(string *type, char *BufferData, size_t BufferLength,
ArgumentMap Arguments, size_t *DataSize) { ArgumentMap Arguments, size_t *DataSize) {
bool sharp = GetArgument<bool>(Arguments, "sharp"); bool sharp = GetArgument<bool>(Arguments, "sharp");
VOption *options = VImage::option()->set("access", "sequential"); VOption *options = VImage::option()->set("access", "sequential");
VImage in = VImage in =
VImage::new_from_buffer(BufferData, BufferLength, "", VImage::new_from_buffer(BufferData, BufferLength, "",
type == "gif" ? options->set("n", -1) : options) *type == "gif" ? options->set("n", -1) : options)
.colourspace(VIPS_INTERPRETATION_sRGB); .colourspace(VIPS_INTERPRETATION_sRGB);
if (!in.has_alpha()) if (!in.has_alpha())
@ -26,7 +26,7 @@ char *Blur(string type, char *BufferData, size_t BufferLength,
sharp ? in.sharpen(VImage::option()->set("sigma", 3)) : in.gaussblur(15); sharp ? in.sharpen(VImage::option()->set("sigma", 3)) : in.gaussblur(15);
void *buf; void *buf;
out.write_to_buffer(("." + type).c_str(), &buf, DataSize); out.write_to_buffer(("." + *type).c_str(), &buf, DataSize);
vips_error_clear(); vips_error_clear();
vips_thread_shutdown(); vips_thread_shutdown();

View File

@ -6,4 +6,4 @@
using std::map; using std::map;
using std::string; using std::string;
char* Blur(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize); char* Blur(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);

View File

@ -7,7 +7,7 @@
using namespace std; using namespace std;
using namespace vips; using namespace vips;
char *Caption(string type, char *BufferData, size_t BufferLength, char *Caption(string *type, char *BufferData, size_t BufferLength,
ArgumentMap Arguments, size_t *DataSize) { ArgumentMap Arguments, size_t *DataSize) {
string caption = GetArgument<string>(Arguments, "caption"); string caption = GetArgument<string>(Arguments, "caption");
@ -18,7 +18,7 @@ char *Caption(string type, char *BufferData, size_t BufferLength,
VImage in = VImage in =
VImage::new_from_buffer(BufferData, BufferLength, "", VImage::new_from_buffer(BufferData, BufferLength, "",
type == "gif" ? options->set("n", -1) : options) *type == "gif" ? options->set("n", -1) : options)
.colourspace(VIPS_INTERPRETATION_sRGB); .colourspace(VIPS_INTERPRETATION_sRGB);
if (!in.has_alpha()) if (!in.has_alpha())
@ -60,7 +60,7 @@ char *Caption(string type, char *BufferData, size_t BufferLength,
vector<VImage> img; vector<VImage> img;
for (int i = 0; i < nPages; i++) { for (int i = 0; i < nPages; i++) {
VImage img_frame = VImage img_frame =
type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in; *type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
VImage frame = captionImage.join( VImage frame = captionImage.join(
img_frame, VIPS_DIRECTION_VERTICAL, img_frame, VIPS_DIRECTION_VERTICAL,
VImage::option()->set("background", 0xffffff)->set("expand", true)); VImage::option()->set("background", 0xffffff)->set("expand", true));
@ -71,8 +71,8 @@ char *Caption(string type, char *BufferData, size_t BufferLength,
void *buf; void *buf;
final.write_to_buffer( final.write_to_buffer(
("." + type).c_str(), &buf, DataSize, ("." + *type).c_str(), &buf, DataSize,
type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1) *type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
: 0); : 0);
vips_error_clear(); vips_error_clear();

View File

@ -6,4 +6,4 @@
using std::map; using std::map;
using std::string; using std::string;
char* Caption(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize); char* Caption(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);

View File

@ -7,7 +7,7 @@
using namespace std; using namespace std;
using namespace vips; using namespace vips;
char *CaptionTwo(string type, char *BufferData, size_t BufferLength, char *CaptionTwo(string *type, char *BufferData, size_t BufferLength,
ArgumentMap Arguments, size_t *DataSize) { ArgumentMap Arguments, size_t *DataSize) {
bool top = GetArgument<bool>(Arguments, "top"); bool top = GetArgument<bool>(Arguments, "top");
@ -19,7 +19,7 @@ char *CaptionTwo(string type, char *BufferData, size_t BufferLength,
VImage in = VImage in =
VImage::new_from_buffer(BufferData, BufferLength, "", VImage::new_from_buffer(BufferData, BufferLength, "",
type == "gif" ? options->set("n", -1) : options) *type == "gif" ? options->set("n", -1) : options)
.colourspace(VIPS_INTERPRETATION_sRGB); .colourspace(VIPS_INTERPRETATION_sRGB);
if (!in.has_alpha()) if (!in.has_alpha())
@ -60,7 +60,7 @@ char *CaptionTwo(string type, char *BufferData, size_t BufferLength,
vector<VImage> img; vector<VImage> img;
for (int i = 0; i < nPages; i++) { for (int i = 0; i < nPages; i++) {
VImage img_frame = VImage img_frame =
type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in; *type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
VImage frame = VImage frame =
(top ? captionImage : img_frame) (top ? captionImage : img_frame)
.join(top ? img_frame : captionImage, VIPS_DIRECTION_VERTICAL, .join(top ? img_frame : captionImage, VIPS_DIRECTION_VERTICAL,
@ -74,8 +74,8 @@ char *CaptionTwo(string type, char *BufferData, size_t BufferLength,
void *buf; void *buf;
final.write_to_buffer( final.write_to_buffer(
("." + type).c_str(), &buf, DataSize, ("." + *type).c_str(), &buf, DataSize,
type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1) *type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
: 0); : 0);
vips_error_clear(); vips_error_clear();

View File

@ -6,4 +6,4 @@
using std::map; using std::map;
using std::string; using std::string;
char* CaptionTwo(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize); char* CaptionTwo(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);

View File

@ -10,7 +10,7 @@
using namespace std; using namespace std;
using namespace Magick; using namespace Magick;
char *Circle(string type, char *BufferData, size_t BufferLength, char *Circle(string *type, char *BufferData, size_t BufferLength,
ArgumentMap Arguments, size_t *DataSize) { ArgumentMap Arguments, size_t *DataSize) {
Blob blob; Blob blob;
@ -29,13 +29,13 @@ char *Circle(string type, char *BufferData, size_t BufferLength,
for (Image &image : coalesced) { for (Image &image : coalesced) {
image.rotationalBlur(10); image.rotationalBlur(10);
image.magick(type); image.magick(*type);
blurred.push_back(image); blurred.push_back(image);
} }
optimizeTransparency(blurred.begin(), blurred.end()); optimizeTransparency(blurred.begin(), blurred.end());
if (type == "gif") { if (*type == "gif") {
for (Image &image : blurred) { for (Image &image : blurred) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod); image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize(); image.quantize();

View File

@ -6,4 +6,4 @@
using std::map; using std::map;
using std::string; using std::string;
char* Circle(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize); char* Circle(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);

View File

@ -10,7 +10,7 @@ using namespace vips;
VImage sepia = VImage::new_matrixv(3, 3, 0.3588, 0.7044, 0.1368, 0.2990, 0.5870, 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); 0.1140, 0.2392, 0.4696, 0.0912);
char *Colors(string type, char *BufferData, size_t BufferLength, char *Colors(string *type, char *BufferData, size_t BufferLength,
ArgumentMap Arguments, size_t *DataSize) { ArgumentMap Arguments, size_t *DataSize) {
string color = GetArgument<string>(Arguments, "color"); string color = GetArgument<string>(Arguments, "color");
@ -19,7 +19,7 @@ char *Colors(string type, char *BufferData, size_t BufferLength,
VImage in = VImage in =
VImage::new_from_buffer(BufferData, BufferLength, "", VImage::new_from_buffer(BufferData, BufferLength, "",
type == "gif" ? options->set("n", -1) : options) *type == "gif" ? options->set("n", -1) : options)
.colourspace(VIPS_INTERPRETATION_sRGB); .colourspace(VIPS_INTERPRETATION_sRGB);
VImage out; VImage out;
@ -31,7 +31,7 @@ char *Colors(string type, char *BufferData, size_t BufferLength,
} }
void *buf; void *buf;
out.write_to_buffer(("." + type).c_str(), &buf, DataSize); out.write_to_buffer(("." + *type).c_str(), &buf, DataSize);
vips_error_clear(); vips_error_clear();
vips_thread_shutdown(); vips_thread_shutdown();

View File

@ -6,4 +6,4 @@
using std::map; using std::map;
using std::string; using std::string;
char* Colors(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize); char* Colors(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);

View File

@ -6,14 +6,14 @@
using namespace std; using namespace std;
using namespace vips; using namespace vips;
char *Crop(string type, char *BufferData, size_t BufferLength, char *Crop(string *type, char *BufferData, size_t BufferLength,
ArgumentMap Arguments, size_t *DataSize) { ArgumentMap Arguments, size_t *DataSize) {
VOption *options = VImage::option()->set("access", "sequential"); VOption *options = VImage::option()->set("access", "sequential");
VImage in = VImage in =
VImage::new_from_buffer(BufferData, BufferLength, "", VImage::new_from_buffer(BufferData, BufferLength, "",
type == "gif" ? options->set("n", -1) : options) *type == "gif" ? options->set("n", -1) : options)
.colourspace(VIPS_INTERPRETATION_sRGB); .colourspace(VIPS_INTERPRETATION_sRGB);
int width = in.width(); int width = in.width();
@ -24,7 +24,7 @@ char *Crop(string type, char *BufferData, size_t BufferLength,
int finalHeight = 0; int finalHeight = 0;
for (int i = 0; i < nPages; i++) { for (int i = 0; i < nPages; i++) {
VImage img_frame = VImage img_frame =
type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in; *type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
int frameWidth = img_frame.width(); int frameWidth = img_frame.width();
int frameHeight = img_frame.height(); int frameHeight = img_frame.height();
bool widthOrHeight = frameWidth / frameHeight >= 1; bool widthOrHeight = frameWidth / frameHeight >= 1;
@ -42,8 +42,8 @@ char *Crop(string type, char *BufferData, size_t BufferLength,
void *buf; void *buf;
final.write_to_buffer( final.write_to_buffer(
("." + type).c_str(), &buf, DataSize, ("." + *type).c_str(), &buf, DataSize,
type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1) *type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
: 0); : 0);
vips_error_clear(); vips_error_clear();

View File

@ -6,4 +6,4 @@
using std::map; using std::map;
using std::string; using std::string;
char* Crop(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize); char* Crop(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);

View File

@ -5,14 +5,14 @@
using namespace std; using namespace std;
using namespace vips; using namespace vips;
char *Deepfry(string type, char *BufferData, size_t BufferLength, char *Deepfry(string *type, char *BufferData, size_t BufferLength,
ArgumentMap Arguments, size_t *DataSize) { ArgumentMap Arguments, size_t *DataSize) {
VOption *options = VImage::option()->set("access", "sequential"); VOption *options = VImage::option()->set("access", "sequential");
VImage in = VImage in =
VImage::new_from_buffer(BufferData, BufferLength, "", VImage::new_from_buffer(BufferData, BufferLength, "",
type == "gif" ? options->set("n", -1) : options) *type == "gif" ? options->set("n", -1) : options)
.colourspace(VIPS_INTERPRETATION_sRGB); .colourspace(VIPS_INTERPRETATION_sRGB);
if (!in.has_alpha()) if (!in.has_alpha())
@ -26,7 +26,7 @@ char *Deepfry(string type, char *BufferData, size_t BufferLength,
VImage fried = (in * 1.3 - (255.0 * 1.3 - 255.0)) * 1.5; VImage fried = (in * 1.3 - (255.0 * 1.3 - 255.0)) * 1.5;
VImage final; VImage final;
if (totalHeight > 65500 && type == "gif") { if (totalHeight > 65500 && *type == "gif") {
vector<VImage> img; vector<VImage> img;
for (int i = 0; i < nPages; i++) { for (int i = 0; i < nPages; i++) {
VImage img_frame = in.crop(0, i * pageHeight, width, pageHeight); VImage img_frame = in.crop(0, i * pageHeight, width, pageHeight);
@ -49,13 +49,13 @@ char *Deepfry(string type, char *BufferData, size_t BufferLength,
VImage::option()->set("Q", 1)->set("strip", true)); VImage::option()->set("Q", 1)->set("strip", true));
final = VImage::new_from_buffer(jpgBuf, jpgLength, ""); final = VImage::new_from_buffer(jpgBuf, jpgLength, "");
final.set(VIPS_META_PAGE_HEIGHT, pageHeight); final.set(VIPS_META_PAGE_HEIGHT, pageHeight);
if (type == "gif") if (*type == "gif")
final.set("delay", fried.get_array_int("delay")); final.set("delay", fried.get_array_int("delay"));
} }
void *buf; void *buf;
final.write_to_buffer(("." + type).c_str(), &buf, DataSize, final.write_to_buffer(("." + *type).c_str(), &buf, DataSize,
type == "gif" ? VImage::option()->set("dither", 0) : 0); *type == "gif" ? VImage::option()->set("dither", 0) : 0);
vips_error_clear(); vips_error_clear();
vips_thread_shutdown(); vips_thread_shutdown();

View File

@ -6,4 +6,4 @@
using std::map; using std::map;
using std::string; using std::string;
char* Deepfry(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize); char* Deepfry(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);

View File

@ -11,7 +11,7 @@
using namespace std; using namespace std;
using namespace Magick; using namespace Magick;
char *Explode(string type, char *BufferData, size_t BufferLength, char *Explode(string *type, char *BufferData, size_t BufferLength,
ArgumentMap Arguments, size_t *DataSize) { ArgumentMap Arguments, size_t *DataSize) {
int amount = GetArgument<int>(Arguments, "amount"); int amount = GetArgument<int>(Arguments, "amount");
@ -33,13 +33,13 @@ char *Explode(string type, char *BufferData, size_t BufferLength,
for (Image &image : coalesced) { for (Image &image : coalesced) {
image.implode(amount); image.implode(amount);
image.magick(type); image.magick(*type);
blurred.push_back(image); blurred.push_back(image);
} }
optimizeTransparency(blurred.begin(), blurred.end()); optimizeTransparency(blurred.begin(), blurred.end());
if (type == "gif") { if (*type == "gif") {
for (Image &image : blurred) { for (Image &image : blurred) {
image.quantizeDither(false); image.quantizeDither(false);
image.quantize(); image.quantize();

View File

@ -6,4 +6,4 @@
using std::map; using std::map;
using std::string; using std::string;
char* Explode(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize); char* Explode(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);

View File

@ -7,7 +7,7 @@
using namespace std; using namespace std;
using namespace vips; using namespace vips;
char *Flag(string type, char *BufferData, size_t BufferLength, char *Flag(string *type, char *BufferData, size_t BufferLength,
ArgumentMap Arguments, size_t *DataSize) { ArgumentMap Arguments, size_t *DataSize) {
string overlay = GetArgument<string>(Arguments, "overlay"); string overlay = GetArgument<string>(Arguments, "overlay");
@ -17,7 +17,7 @@ char *Flag(string type, char *BufferData, size_t BufferLength,
VImage in = VImage in =
VImage::new_from_buffer(BufferData, BufferLength, "", VImage::new_from_buffer(BufferData, BufferLength, "",
type == "gif" ? options->set("n", -1) : options) *type == "gif" ? options->set("n", -1) : options)
.colourspace(VIPS_INTERPRETATION_sRGB); .colourspace(VIPS_INTERPRETATION_sRGB);
if (!in.has_alpha()) if (!in.has_alpha())
@ -43,7 +43,7 @@ char *Flag(string type, char *BufferData, size_t BufferLength,
vector<VImage> img; vector<VImage> img;
for (int i = 0; i < nPages; i++) { for (int i = 0; i < nPages; i++) {
VImage img_frame = VImage img_frame =
type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in; *type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
VImage composited = VImage composited =
img_frame.composite2(overlayImage, VIPS_BLEND_MODE_OVER); img_frame.composite2(overlayImage, VIPS_BLEND_MODE_OVER);
img.push_back(composited); img.push_back(composited);
@ -54,8 +54,8 @@ char *Flag(string type, char *BufferData, size_t BufferLength,
void *buf; void *buf;
final.write_to_buffer( final.write_to_buffer(
("." + type).c_str(), &buf, DataSize, ("." + *type).c_str(), &buf, DataSize,
type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1) *type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
: 0); : 0);
vips_error_clear(); vips_error_clear();

View File

@ -6,4 +6,4 @@
using std::map; using std::map;
using std::string; using std::string;
char* Flag(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize); char* Flag(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);

View File

@ -7,13 +7,13 @@
using namespace std; using namespace std;
using namespace vips; using namespace vips;
char *Flip(string type, char *BufferData, size_t BufferLength, char *Flip(string *type, char *BufferData, size_t BufferLength,
ArgumentMap Arguments, size_t *DataSize) { ArgumentMap Arguments, size_t *DataSize) {
bool flop = GetArgument<bool>(Arguments, "flop"); bool flop = GetArgument<bool>(Arguments, "flop");
VImage in = VImage::new_from_buffer(BufferData, BufferLength, "", VImage in = VImage::new_from_buffer(BufferData, BufferLength, "",
type == "gif" *type == "gif"
? VImage::option()->set("n", -1)->set( ? VImage::option()->set("n", -1)->set(
"access", "sequential") "access", "sequential")
: 0) : 0)
@ -24,7 +24,7 @@ char *Flip(string type, char *BufferData, size_t BufferLength,
VImage out; VImage out;
if (flop) { if (flop) {
out = in.flip(VIPS_DIRECTION_HORIZONTAL); out = in.flip(VIPS_DIRECTION_HORIZONTAL);
} else if (type == "gif") { } else if (*type == "gif") {
// libvips gif handling is both a blessing and a curse // libvips gif handling is both a blessing and a curse
vector<VImage> img; vector<VImage> img;
int pageHeight = vips_image_get_page_height(in.get_image()); int pageHeight = vips_image_get_page_height(in.get_image());
@ -42,8 +42,8 @@ char *Flip(string type, char *BufferData, size_t BufferLength,
void *buf; void *buf;
out.write_to_buffer( out.write_to_buffer(
("." + type).c_str(), &buf, DataSize, ("." + *type).c_str(), &buf, DataSize,
type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1) *type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
: 0); : 0);
vips_error_clear(); vips_error_clear();

View File

@ -6,4 +6,4 @@
using std::map; using std::map;
using std::string; using std::string;
char* Flip(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize); char* Flip(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);

View File

@ -8,7 +8,7 @@
using namespace std; using namespace std;
using namespace vips; using namespace vips;
char *Freeze(string type, char *BufferData, size_t BufferLength, char *Freeze(string *type, char *BufferData, size_t BufferLength,
ArgumentMap Arguments, size_t *DataSize) { ArgumentMap Arguments, size_t *DataSize) {
bool loop = GetArgumentWithFallback<bool>(Arguments, "loop", false); bool loop = GetArgumentWithFallback<bool>(Arguments, "loop", false);
@ -54,7 +54,7 @@ char *Freeze(string type, char *BufferData, size_t BufferLength,
VImage in = VImage in =
VImage::new_from_buffer(BufferData, BufferLength, "", VImage::new_from_buffer(BufferData, BufferLength, "",
type == "gif" ? options->set("n", -1) : options) *type == "gif" ? options->set("n", -1) : options)
.colourspace(VIPS_INTERPRETATION_sRGB); .colourspace(VIPS_INTERPRETATION_sRGB);
if (!in.has_alpha()) if (!in.has_alpha())
in = in.bandjoin(255); in = in.bandjoin(255);
@ -67,7 +67,7 @@ char *Freeze(string type, char *BufferData, size_t BufferLength,
out.set("loop", 1); out.set("loop", 1);
void *buf; void *buf;
out.write_to_buffer(("." + type).c_str(), &buf, DataSize); out.write_to_buffer(("." + *type).c_str(), &buf, DataSize);
vips_error_clear(); vips_error_clear();
vips_thread_shutdown(); vips_thread_shutdown();

View File

@ -4,4 +4,4 @@
using std::string; using std::string;
char* Freeze(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize); char* Freeze(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);

View File

@ -5,7 +5,7 @@
using namespace std; using namespace std;
using namespace vips; using namespace vips;
char *Gamexplain(string type, char *BufferData, size_t BufferLength, char *Gamexplain(string *type, char *BufferData, size_t BufferLength,
ArgumentMap Arguments, size_t *DataSize) { ArgumentMap Arguments, size_t *DataSize) {
string basePath = GetArgument<string>(Arguments, "basePath"); string basePath = GetArgument<string>(Arguments, "basePath");
@ -14,7 +14,7 @@ char *Gamexplain(string type, char *BufferData, size_t BufferLength,
VImage in = VImage in =
VImage::new_from_buffer(BufferData, BufferLength, "", VImage::new_from_buffer(BufferData, BufferLength, "",
type == "gif" ? options->set("n", -1) : options) *type == "gif" ? options->set("n", -1) : options)
.colourspace(VIPS_INTERPRETATION_sRGB); .colourspace(VIPS_INTERPRETATION_sRGB);
if (!in.has_alpha()) if (!in.has_alpha())
in = in.bandjoin(255); in = in.bandjoin(255);
@ -29,7 +29,7 @@ char *Gamexplain(string type, char *BufferData, size_t BufferLength,
vector<VImage> img; vector<VImage> img;
for (int i = 0; i < nPages; i++) { for (int i = 0; i < nPages; i++) {
VImage img_frame = VImage img_frame =
type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in; *type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
VImage resized = VImage resized =
img_frame img_frame
.resize(1181.0 / (double)width, .resize(1181.0 / (double)width,
@ -43,8 +43,8 @@ char *Gamexplain(string type, char *BufferData, size_t BufferLength,
void *buf; void *buf;
final.write_to_buffer( final.write_to_buffer(
("." + type).c_str(), &buf, DataSize, ("." + *type).c_str(), &buf, DataSize,
type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1) *type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
: 0); : 0);
vips_error_clear(); vips_error_clear();

View File

@ -4,4 +4,4 @@
using std::string; using std::string;
char* Gamexplain(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize); char* Gamexplain(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);

View File

@ -5,7 +5,7 @@
using namespace std; using namespace std;
using namespace vips; using namespace vips;
char *Globe(string type, char *BufferData, size_t BufferLength, char *Globe(string *type, char *BufferData, size_t BufferLength,
ArgumentMap Arguments, size_t *DataSize) { ArgumentMap Arguments, size_t *DataSize) {
string basePath = GetArgument<string>(Arguments, "basePath"); string basePath = GetArgument<string>(Arguments, "basePath");
@ -15,7 +15,7 @@ char *Globe(string type, char *BufferData, size_t BufferLength,
VImage in = VImage in =
VImage::new_from_buffer( VImage::new_from_buffer(
BufferData, BufferLength, "", BufferData, BufferLength, "",
type == "gif" ? options->set("n", -1)->set("access", "sequential") *type == "gif" ? options->set("n", -1)->set("access", "sequential")
: options) : options)
.colourspace(VIPS_INTERPRETATION_sRGB); .colourspace(VIPS_INTERPRETATION_sRGB);
if (!in.has_alpha()) if (!in.has_alpha())
@ -23,7 +23,7 @@ char *Globe(string type, char *BufferData, size_t BufferLength,
int width = in.width(); int width = in.width();
int pageHeight = vips_image_get_page_height(in.get_image()); int pageHeight = vips_image_get_page_height(in.get_image());
int nPages = type == "gif" ? vips_image_get_n_pages(in.get_image()) : 30; int nPages = *type == "gif" ? vips_image_get_n_pages(in.get_image()) : 30;
double size = min(width, pageHeight); double size = min(width, pageHeight);
@ -51,7 +51,7 @@ char *Globe(string type, char *BufferData, size_t BufferLength,
vector<VImage> img; vector<VImage> img;
for (int i = 0; i < nPages; i++) { for (int i = 0; i < nPages; i++) {
VImage img_frame = VImage img_frame =
type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in; *type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
VImage resized = img_frame.resize( VImage resized = img_frame.resize(
size / (double)width, size / (double)width,
VImage::option()->set("vscale", size / (double)pageHeight)); VImage::option()->set("vscale", size / (double)pageHeight));
@ -65,7 +65,7 @@ char *Globe(string type, char *BufferData, size_t BufferLength,
} }
VImage final = VImage::arrayjoin(img, VImage::option()->set("across", 1)); VImage final = VImage::arrayjoin(img, VImage::option()->set("across", 1));
final.set(VIPS_META_PAGE_HEIGHT, size); final.set(VIPS_META_PAGE_HEIGHT, size);
if (type != "gif") { if (*type != "gif") {
vector<int> delay(30, 50); vector<int> delay(30, 50);
final.set("delay", delay); final.set("delay", delay);
} }

View File

@ -4,4 +4,4 @@
using std::string; using std::string;
char* Globe(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize); char* Globe(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);

View File

@ -51,7 +51,7 @@
using namespace std; using namespace std;
std::map<std::string, char* (*)(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize)> FunctionMap = { std::map<std::string, char* (*)(string *type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize)> FunctionMap = {
{"blur", &Blur}, {"blur", &Blur},
{"caption", &Caption}, {"caption", &Caption},
{"captionTwo", &CaptionTwo}, {"captionTwo", &CaptionTwo},
@ -67,36 +67,33 @@ std::map<std::string, char* (*)(string type, char* BufferData, size_t BufferLeng
{"globe", Globe}, {"globe", Globe},
{"invert", Invert}, {"invert", Invert},
{"jpeg", Jpeg}, {"jpeg", Jpeg},
{"magik", Magik},
{"meme", Meme}, {"meme", Meme},
{"mirror", Mirror}, {"mirror", Mirror},
{"motivate", Motivate}, {"motivate", Motivate},
{"reddit", Reddit}, {"reddit", Reddit},
{"resize", Resize}, {"resize", Resize},
{"reverse", Reverse}, {"reverse", Reverse},
{"speed", &Speed},
{"uncaption", &Uncaption},
{"watermark", &Watermark}
};
std::map<std::string, char* (*)(string *type, ArgumentMap Arguments, size_t* DataSize)> NoInputFunctionMap = {
{"homebrew", Homebrew},
{"sonic", Sonic}
};
std::map<std::string, Napi::Value (*)(const Napi::CallbackInfo &info)> OldFunctionMap = {
{"magik", Magik},
{"scott", Scott}, {"scott", Scott},
{"snapchat", Snapchat}, {"snapchat", Snapchat},
{"speed", &Speed},
{"spin", Spin}, {"spin", Spin},
{"swirl", Swirl}, {"swirl", Swirl},
{"tile", Tile}, {"tile", Tile},
{"togif", ToGif}, {"togif", ToGif},
{"uncanny", Uncanny}, {"uncanny", Uncanny},
{"uncaption", &Uncaption},
{"wall", Wall}, {"wall", Wall},
{"watermark", &Watermark},
{"whisper", Whisper}, {"whisper", Whisper},
{"zamn", Zamn} {"zamn", Zamn}
}; };
std::map<std::string, char* (*)(string *type, ArgumentMap Arguments, size_t* DataSize)> NoInputFunctionMap = {
{"homebrew", Homebrew},
{"sonic", Sonic}
};
bool isNapiValueInt(Napi::Env& env, Napi::Value& num) { bool isNapiValueInt(Napi::Env& env, Napi::Value& num) {
return env.Global() return env.Global()
.Get("Number") .Get("Number")
@ -150,7 +147,7 @@ Napi::Value NewProcessImage(const Napi::CallbackInfo &info, bool input) {
char* buf; char* buf;
if (input) { if (input) {
Napi::Buffer<char> data = obj.Has("data") ? obj.Get("data").As<Napi::Buffer<char>>() : Napi::Buffer<char>::New(env, 0); Napi::Buffer<char> data = obj.Has("data") ? obj.Get("data").As<Napi::Buffer<char>>() : Napi::Buffer<char>::New(env, 0);
buf = FunctionMap.at(command)(type, data.Data(), data.Length(), Arguments, &length); buf = FunctionMap.at(command)(&type, data.Data(), data.Length(), Arguments, &length);
} else { } else {
buf = NoInputFunctionMap.at(command)(&type, Arguments, &length); buf = NoInputFunctionMap.at(command)(&type, Arguments, &length);
} }
@ -167,10 +164,6 @@ Napi::Value NewProcessImage(const Napi::CallbackInfo &info, bool input) {
return result; 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::Value ProcessImage(const Napi::CallbackInfo &info) { // janky solution for gradual adoption
Napi::Env env = info.Env(); Napi::Env env = info.Env();
@ -180,8 +173,6 @@ Napi::Value ProcessImage(const Napi::CallbackInfo &info) { // janky solution for
return NewProcessImage(info, true); return NewProcessImage(info, true);
} else if (MAP_HAS(NoInputFunctionMap, command)) { } else if (MAP_HAS(NoInputFunctionMap, command)) {
return NewProcessImage(info, false); return NewProcessImage(info, false);
} else if (MAP_HAS(OldFunctionMap, command)) {
return OldProcessImage(command, info);
} else { } else {
Napi::Error::New(env, "Invalid command").ThrowAsJavaScriptException(); Napi::Error::New(env, "Invalid command").ThrowAsJavaScriptException();
return env.Null(); return env.Null();
@ -208,11 +199,6 @@ Napi::Object Init(Napi::Env env, Napi::Object exports){
arr[i] = Napi::String::New(env, imap.first); arr[i] = Napi::String::New(env, imap.first);
i++; i++;
} }
for(auto const& imap: OldFunctionMap) {
Napi::HandleScope scope(env);
arr[i] = Napi::String::New(env, imap.first);
i++;
}
exports.Set(Napi::String::New(env, "funcs"), arr); exports.Set(Napi::String::New(env, "funcs"), arr);

View File

@ -5,14 +5,14 @@
using namespace std; using namespace std;
using namespace vips; using namespace vips;
char *Invert(string type, char *BufferData, size_t BufferLength, char *Invert(string *type, char *BufferData, size_t BufferLength,
ArgumentMap Arguments, size_t *DataSize) { ArgumentMap Arguments, size_t *DataSize) {
VOption *options = VImage::option()->set("access", "sequential"); VOption *options = VImage::option()->set("access", "sequential");
VImage in = VImage in =
VImage::new_from_buffer(BufferData, BufferLength, "", VImage::new_from_buffer(BufferData, BufferLength, "",
type == "gif" ? options->set("n", -1) : options) *type == "gif" ? options->set("n", -1) : options)
.colourspace(VIPS_INTERPRETATION_sRGB); .colourspace(VIPS_INTERPRETATION_sRGB);
if (!in.has_alpha()) if (!in.has_alpha())
in = in.bandjoin(255); in = in.bandjoin(255);
@ -23,7 +23,7 @@ char *Invert(string type, char *BufferData, size_t BufferLength,
VImage out = inverted.bandjoin(in.extract_band(3)); VImage out = inverted.bandjoin(in.extract_band(3));
void *buf; void *buf;
out.write_to_buffer(("." + type).c_str(), &buf, DataSize); out.write_to_buffer(("." + *type).c_str(), &buf, DataSize);
vips_error_clear(); vips_error_clear();
vips_thread_shutdown(); vips_thread_shutdown();

View File

@ -4,4 +4,4 @@
using std::string; using std::string;
char* Invert(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize); char* Invert(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);

View File

@ -5,13 +5,13 @@
using namespace std; using namespace std;
using namespace vips; using namespace vips;
char *Jpeg(string type, char *BufferData, size_t BufferLength, char *Jpeg(string *type, char *BufferData, size_t BufferLength,
ArgumentMap Arguments, size_t *DataSize) { ArgumentMap Arguments, size_t *DataSize) {
int quality = GetArgumentWithFallback<int>(Arguments, "quality", 0); int quality = GetArgumentWithFallback<int>(Arguments, "quality", 0);
void *buf; void *buf;
if (type == "gif") { if (*type == "gif") {
VImage in = VImage::new_from_buffer( VImage in = VImage::new_from_buffer(
BufferData, BufferLength, "", BufferData, BufferLength, "",
VImage::option()->set("access", "sequential")->set("n", -1)) VImage::option()->set("access", "sequential")->set("n", -1))
@ -53,15 +53,15 @@ char *Jpeg(string type, char *BufferData, size_t BufferLength,
final.set("delay", in.get_array_int("delay")); final.set("delay", in.get_array_int("delay"));
} }
final.write_to_buffer(("." + type).c_str(), &buf, DataSize, final.write_to_buffer(("." + *type).c_str(), &buf, DataSize,
type == "gif" ? VImage::option()->set("dither", 0) *type == "gif" ? VImage::option()->set("dither", 0)
: 0); : 0);
} else { } else {
VImage in = VImage::new_from_buffer(BufferData, BufferLength, ""); VImage in = VImage::new_from_buffer(BufferData, BufferLength, "");
in.write_to_buffer(".jpg", &buf, DataSize, in.write_to_buffer(".jpg", &buf, DataSize,
VImage::option()->set("Q", quality)->set("strip", true)); VImage::option()->set("Q", quality)->set("strip", true));
type = "jpg"; *type = "jpg";
} }
vips_error_clear(); vips_error_clear();

View File

@ -4,4 +4,4 @@
using std::string; using std::string;
char* Jpeg(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize); char* Jpeg(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);

View File

@ -1,62 +1,52 @@
#include "common.h"
#include <Magick++.h> #include <Magick++.h>
#include <napi.h>
#include <cstring>
#include <iostream> #include <iostream>
#include <list> #include <list>
using namespace std; using namespace std;
using namespace Magick; using namespace Magick;
Napi::Value Magik(const Napi::CallbackInfo &info) { char *Magik(string *type, char *BufferData, size_t BufferLength,
Napi::Env env = info.Env(); ArgumentMap Arguments, size_t *DataSize) {
Napi::Object result = Napi::Object::New(env);
Blob blob;
list<Image> frames;
list<Image> coalesced;
list<Image> blurred;
try { try {
Napi::Object obj = info[1].As<Napi::Object>(); readImages(&frames, Blob(BufferData, BufferLength));
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>(); } catch (Magick::WarningCoder &warning) {
string type = obj.Get("type").As<Napi::String>().Utf8Value(); cerr << "Coder Warning: " << warning.what() << endl;
} catch (Magick::Warning &warning) {
cerr << "Warning: " << warning.what() << endl;
}
coalesceImages(&coalesced, frames.begin(), frames.end());
Blob blob; for (Image &image : coalesced) {
image.scale(Geometry("350x350"));
list<Image> frames; image.liquidRescale(Geometry("175x175"));
list<Image> coalesced; image.liquidRescale(Geometry("350x350"));
list<Image> blurred; image.magick(*type);
try { blurred.push_back(image);
readImages(&frames, Blob(data.Data(), data.Length()));
} catch (Magick::WarningCoder &warning) {
cerr << "Coder Warning: " << warning.what() << endl;
} catch (Magick::Warning &warning) {
cerr << "Warning: " << warning.what() << endl;
}
coalesceImages(&coalesced, frames.begin(), frames.end());
for (Image &image : coalesced) {
image.scale(Geometry("350x350"));
image.liquidRescale(Geometry("175x175"));
image.liquidRescale(Geometry("350x350"));
image.magick(type);
blurred.push_back(image);
}
optimizeTransparency(blurred.begin(), blurred.end());
if (type == "gif") {
for (Image &image : blurred) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
}
}
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();
} }
return result; optimizeTransparency(blurred.begin(), blurred.end());
if (*type == "gif") {
for (Image &image : blurred) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
}
}
writeImages(blurred.begin(), blurred.end(), &blob);
*DataSize = blob.length();
char *data = (char *)malloc(*DataSize);
memcpy(data, blob.data(), *DataSize);
return data;
} }

View File

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

View File

@ -5,7 +5,7 @@
using namespace std; using namespace std;
using namespace vips; using namespace vips;
char *Meme(string type, char *BufferData, size_t BufferLength, char *Meme(string *type, char *BufferData, size_t BufferLength,
ArgumentMap Arguments, size_t *DataSize) { ArgumentMap Arguments, size_t *DataSize) {
string top = GetArgument<string>(Arguments, "top"); string top = GetArgument<string>(Arguments, "top");
string bottom = GetArgument<string>(Arguments, "bottom"); string bottom = GetArgument<string>(Arguments, "bottom");
@ -16,7 +16,7 @@ char *Meme(string type, char *BufferData, size_t BufferLength,
VImage in = VImage in =
VImage::new_from_buffer(BufferData, BufferLength, "", VImage::new_from_buffer(BufferData, BufferLength, "",
type == "gif" ? options->set("n", -1) : options) *type == "gif" ? options->set("n", -1) : options)
.colourspace(VIPS_INTERPRETATION_sRGB); .colourspace(VIPS_INTERPRETATION_sRGB);
if (!in.has_alpha()) if (!in.has_alpha())
in = in.bandjoin(255); in = in.bandjoin(255);
@ -112,7 +112,7 @@ char *Meme(string type, char *BufferData, size_t BufferLength,
vector<VImage> img; vector<VImage> img;
for (int i = 0; i < nPages; i++) { for (int i = 0; i < nPages; i++) {
VImage img_frame = VImage img_frame =
type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in; *type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
if (top != "") { if (top != "") {
img_frame = img_frame.composite2( img_frame = img_frame.composite2(
topText, VIPS_BLEND_MODE_OVER, topText, VIPS_BLEND_MODE_OVER,
@ -132,8 +132,8 @@ char *Meme(string type, char *BufferData, size_t BufferLength,
void *buf; void *buf;
final.write_to_buffer( final.write_to_buffer(
("." + type).c_str(), &buf, DataSize, ("." + *type).c_str(), &buf, DataSize,
type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1) *type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
: 0); : 0);
vips_error_clear(); vips_error_clear();

View File

@ -4,4 +4,4 @@
using std::string; using std::string;
char* Meme(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize); char* Meme(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);

View File

@ -5,7 +5,7 @@
using namespace std; using namespace std;
using namespace vips; using namespace vips;
char *Mirror(string type, char *BufferData, size_t BufferLength, char *Mirror(string *type, char *BufferData, size_t BufferLength,
ArgumentMap Arguments, size_t *DataSize) { ArgumentMap Arguments, size_t *DataSize) {
bool vertical = GetArgumentWithFallback<bool>(Arguments, "vertical", false); bool vertical = GetArgumentWithFallback<bool>(Arguments, "vertical", false);
bool first = GetArgumentWithFallback<bool>(Arguments, "first", false); bool first = GetArgumentWithFallback<bool>(Arguments, "first", false);
@ -14,7 +14,7 @@ char *Mirror(string type, char *BufferData, size_t BufferLength,
VImage in = VImage in =
VImage::new_from_buffer(BufferData, BufferLength, "", VImage::new_from_buffer(BufferData, BufferLength, "",
type == "gif" ? options->set("n", -1) : options) *type == "gif" ? options->set("n", -1) : options)
.colourspace(VIPS_INTERPRETATION_sRGB); .colourspace(VIPS_INTERPRETATION_sRGB);
if (!in.has_alpha()) if (!in.has_alpha())
in = in.bandjoin(255); in = in.bandjoin(255);
@ -22,7 +22,7 @@ char *Mirror(string type, char *BufferData, size_t BufferLength,
VImage out; VImage out;
if (vertical) { if (vertical) {
if (type == "gif") { if (*type == "gif") {
// once again, libvips gif handling is both a blessing and a curse // once again, libvips gif handling is both a blessing and a curse
vector<VImage> img; vector<VImage> img;
int pageHeight = vips_image_get_page_height(in.get_image()); int pageHeight = vips_image_get_page_height(in.get_image());
@ -59,7 +59,7 @@ char *Mirror(string type, char *BufferData, size_t BufferLength,
} }
void *buf; void *buf;
out.write_to_buffer(("." + type).c_str(), &buf, DataSize); out.write_to_buffer(("." + *type).c_str(), &buf, DataSize);
vips_error_clear(); vips_error_clear();
vips_thread_shutdown(); vips_thread_shutdown();

View File

@ -4,4 +4,4 @@
using std::string; using std::string;
char* Mirror(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize); char* Mirror(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);

View File

@ -5,7 +5,7 @@
using namespace std; using namespace std;
using namespace vips; using namespace vips;
char *Motivate(string type, char *BufferData, size_t BufferLength, char *Motivate(string *type, char *BufferData, size_t BufferLength,
ArgumentMap Arguments, size_t *DataSize) { ArgumentMap Arguments, size_t *DataSize) {
string top_text = GetArgument<string>(Arguments, "top"); string top_text = GetArgument<string>(Arguments, "top");
string bottom_text = GetArgument<string>(Arguments, "bottom"); string bottom_text = GetArgument<string>(Arguments, "bottom");
@ -16,7 +16,7 @@ char *Motivate(string type, char *BufferData, size_t BufferLength,
VImage in = VImage in =
VImage::new_from_buffer(BufferData, BufferLength, "", VImage::new_from_buffer(BufferData, BufferLength, "",
type == "gif" ? options->set("n", -1) : options) *type == "gif" ? options->set("n", -1) : options)
.colourspace(VIPS_INTERPRETATION_sRGB); .colourspace(VIPS_INTERPRETATION_sRGB);
if (!in.has_alpha()) if (!in.has_alpha())
in = in.bandjoin(255); in = in.bandjoin(255);
@ -70,7 +70,7 @@ char *Motivate(string type, char *BufferData, size_t BufferLength,
int height; int height;
for (int i = 0; i < nPages; i++) { for (int i = 0; i < nPages; i++) {
VImage img_frame = VImage img_frame =
type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in; *type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
int borderSize = max(2, width / 66); int borderSize = max(2, width / 66);
int borderSize2 = borderSize * 0.5; int borderSize2 = borderSize * 0.5;
@ -117,8 +117,8 @@ char *Motivate(string type, char *BufferData, size_t BufferLength,
final.set(VIPS_META_PAGE_HEIGHT, height); final.set(VIPS_META_PAGE_HEIGHT, height);
void *buf; void *buf;
final.write_to_buffer(("." + type).c_str(), &buf, DataSize, final.write_to_buffer(("." + *type).c_str(), &buf, DataSize,
type == "gif" ? VImage::option()->set("dither", 1) : 0); *type == "gif" ? VImage::option()->set("dither", 1) : 0);
vips_error_clear(); vips_error_clear();
vips_thread_shutdown(); vips_thread_shutdown();

View File

@ -4,4 +4,4 @@
using std::string; using std::string;
char* Motivate(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize); char* Motivate(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);

View File

@ -5,7 +5,7 @@
using namespace std; using namespace std;
using namespace vips; using namespace vips;
char *Reddit(string type, char *BufferData, size_t BufferLength, char *Reddit(string *type, char *BufferData, size_t BufferLength,
ArgumentMap Arguments, size_t *DataSize) { ArgumentMap Arguments, size_t *DataSize) {
string text = GetArgument<string>(Arguments, "text"); string text = GetArgument<string>(Arguments, "text");
@ -15,7 +15,7 @@ char *Reddit(string type, char *BufferData, size_t BufferLength,
VImage in = VImage in =
VImage::new_from_buffer(BufferData, BufferLength, "", VImage::new_from_buffer(BufferData, BufferLength, "",
type == "gif" ? options->set("n", -1) : options) *type == "gif" ? options->set("n", -1) : options)
.colourspace(VIPS_INTERPRETATION_sRGB); .colourspace(VIPS_INTERPRETATION_sRGB);
if (!in.has_alpha()) if (!in.has_alpha())
in = in.bandjoin(255); in = in.bandjoin(255);
@ -50,7 +50,7 @@ char *Reddit(string type, char *BufferData, size_t BufferLength,
vector<VImage> img; vector<VImage> img;
for (int i = 0; i < nPages; i++) { for (int i = 0; i < nPages; i++) {
VImage img_frame = VImage img_frame =
type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in; *type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
VImage frame = img_frame.join(watermark, VIPS_DIRECTION_VERTICAL, VImage frame = img_frame.join(watermark, VIPS_DIRECTION_VERTICAL,
VImage::option()->set("expand", true)); VImage::option()->set("expand", true));
img.push_back(frame); img.push_back(frame);
@ -60,8 +60,8 @@ char *Reddit(string type, char *BufferData, size_t BufferLength,
void *buf; void *buf;
final.write_to_buffer( final.write_to_buffer(
("." + type).c_str(), &buf, DataSize, ("." + *type).c_str(), &buf, DataSize,
type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1) *type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
: 0); : 0);
vips_error_clear(); vips_error_clear();

View File

@ -4,4 +4,4 @@
using std::string; using std::string;
char* Reddit(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize); char* Reddit(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);

View File

@ -5,7 +5,7 @@
using namespace std; using namespace std;
using namespace vips; using namespace vips;
char *Resize(string type, char *BufferData, size_t BufferLength, char *Resize(string *type, char *BufferData, size_t BufferLength,
ArgumentMap Arguments, size_t *DataSize) { ArgumentMap Arguments, size_t *DataSize) {
bool stretch = GetArgumentWithFallback<bool>(Arguments, "stretch", false); bool stretch = GetArgumentWithFallback<bool>(Arguments, "stretch", false);
bool wide = GetArgumentWithFallback<bool>(Arguments, "wide", false); bool wide = GetArgumentWithFallback<bool>(Arguments, "wide", false);
@ -14,7 +14,7 @@ char *Resize(string type, char *BufferData, size_t BufferLength,
VImage in = VImage in =
VImage::new_from_buffer(BufferData, BufferLength, "", VImage::new_from_buffer(BufferData, BufferLength, "",
type == "gif" ? options->set("n", -1) : options) *type == "gif" ? options->set("n", -1) : options)
.colourspace(VIPS_INTERPRETATION_sRGB); .colourspace(VIPS_INTERPRETATION_sRGB);
VImage out; VImage out;
@ -37,7 +37,7 @@ char *Resize(string type, char *BufferData, size_t BufferLength,
vector<VImage> img; vector<VImage> img;
for (int i = 0; i < nPages; i++) { for (int i = 0; i < nPages; i++) {
VImage img_frame = VImage img_frame =
type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in; *type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
VImage resized = img_frame.resize(0.1).resize( VImage resized = img_frame.resize(0.1).resize(
10, VImage::option()->set("kernel", VIPS_KERNEL_NEAREST)); 10, VImage::option()->set("kernel", VIPS_KERNEL_NEAREST));
img.push_back(resized); img.push_back(resized);
@ -48,7 +48,7 @@ char *Resize(string type, char *BufferData, size_t BufferLength,
out.set(VIPS_META_PAGE_HEIGHT, finalHeight); out.set(VIPS_META_PAGE_HEIGHT, finalHeight);
void *buf; void *buf;
out.write_to_buffer(("." + type).c_str(), &buf, DataSize); out.write_to_buffer(("." + *type).c_str(), &buf, DataSize);
vips_error_clear(); vips_error_clear();
vips_thread_shutdown(); vips_thread_shutdown();

View File

@ -4,4 +4,4 @@
using std::string; using std::string;
char* Resize(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize); char* Resize(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);

View File

@ -6,7 +6,7 @@
using namespace std; using namespace std;
using namespace vips; using namespace vips;
char *Reverse(string type, char *BufferData, size_t BufferLength, char *Reverse(string *type, char *BufferData, size_t BufferLength,
ArgumentMap Arguments, size_t *DataSize) { ArgumentMap Arguments, size_t *DataSize) {
bool soos = GetArgumentWithFallback<bool>(Arguments, "soos", false); bool soos = GetArgumentWithFallback<bool>(Arguments, "soos", false);
@ -53,7 +53,7 @@ char *Reverse(string type, char *BufferData, size_t BufferLength,
final.write_to_buffer(".gif", &buf, DataSize, final.write_to_buffer(".gif", &buf, DataSize,
VImage::option()->set("dither", 0)); VImage::option()->set("dither", 0));
type = "gif"; *type = "gif";
vips_error_clear(); vips_error_clear();
vips_thread_shutdown(); vips_thread_shutdown();

View File

@ -4,4 +4,4 @@
using std::string; using std::string;
char* Reverse(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize); char* Reverse(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);

View File

@ -1,73 +1,63 @@
#include "common.h"
#include <Magick++.h> #include <Magick++.h>
#include <napi.h>
#include <cstring>
#include <iostream> #include <iostream>
#include <list> #include <list>
using namespace std; using namespace std;
using namespace Magick; using namespace Magick;
Napi::Value Scott(const Napi::CallbackInfo &info) { char *Scott(string *type, char *BufferData, size_t BufferLength,
Napi::Env env = info.Env(); ArgumentMap Arguments, size_t *DataSize) {
Napi::Object result = Napi::Object::New(env); string basePath = GetArgument<string>(Arguments, "basePath");
Blob blob;
list<Image> frames;
list<Image> coalesced;
list<Image> mid;
Image watermark;
try { try {
Napi::Object obj = info[1].As<Napi::Object>(); readImages(&frames, Blob(BufferData, BufferLength));
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>(); } catch (Magick::WarningCoder &warning) {
string type = obj.Get("type").As<Napi::String>().Utf8Value(); cerr << "Coder Warning: " << warning.what() << endl;
string basePath = obj.Get("basePath").As<Napi::String>().Utf8Value(); } catch (Magick::Warning &warning) {
cerr << "Warning: " << warning.what() << endl;
}
watermark.read(basePath + "assets/images/scott.png");
coalesceImages(&coalesced, frames.begin(), frames.end());
Blob blob; for (Image &image : coalesced) {
Image watermark_new = watermark;
list<Image> frames; image.virtualPixelMethod(Magick::TransparentVirtualPixelMethod);
list<Image> coalesced; image.backgroundColor("none");
list<Image> mid; image.scale(Geometry("415x234!"));
Image watermark; double arguments[16] = {0, 0, 129, 187, 415, 0, 517, 182,
try { 415, 234, 517, 465, 0, 234, 132, 418};
readImages(&frames, Blob(data.Data(), data.Length())); image.distort(Magick::PerspectiveDistortion, 16, arguments, true);
} catch (Magick::WarningCoder &warning) { image.extent(Geometry("864x481"), Magick::CenterGravity);
cerr << "Coder Warning: " << warning.what() << endl; watermark_new.composite(image, Geometry("-110+83"),
} catch (Magick::Warning &warning) { Magick::OverCompositeOp);
cerr << "Warning: " << warning.what() << endl; watermark_new.magick(*type);
} watermark_new.animationDelay(image.animationDelay());
watermark.read(basePath + "assets/images/scott.png"); mid.push_back(watermark_new);
coalesceImages(&coalesced, frames.begin(), frames.end());
for (Image &image : coalesced) {
Image watermark_new = watermark;
image.virtualPixelMethod(Magick::TransparentVirtualPixelMethod);
image.backgroundColor("none");
image.scale(Geometry("415x234!"));
double arguments[16] = {0, 0, 129, 187, 415, 0, 517, 182,
415, 234, 517, 465, 0, 234, 132, 418};
image.distort(Magick::PerspectiveDistortion, 16, arguments, true);
image.extent(Geometry("864x481"), Magick::CenterGravity);
watermark_new.composite(image, Geometry("-110+83"),
Magick::OverCompositeOp);
watermark_new.magick(type);
watermark_new.animationDelay(image.animationDelay());
mid.push_back(watermark_new);
}
optimizeTransparency(mid.begin(), mid.end());
if (type == "gif") {
for (Image &image : mid) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
}
}
writeImages(mid.begin(), mid.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();
} }
return result; optimizeTransparency(mid.begin(), mid.end());
if (*type == "gif") {
for (Image &image : mid) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
}
}
writeImages(mid.begin(), mid.end(), &blob);
*DataSize = blob.length();
char *data = (char *)malloc(*DataSize);
memcpy(data, blob.data(), *DataSize);
return data;
} }

View File

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

View File

@ -1,92 +1,74 @@
#include <napi.h> #include "common.h"
#include <vips/vips8> #include <vips/vips8>
using namespace std; using namespace std;
using namespace vips; using namespace vips;
Napi::Value Snapchat(const Napi::CallbackInfo &info) { char *Snapchat(string *type, char *BufferData, size_t BufferLength,
Napi::Env env = info.Env(); ArgumentMap Arguments, size_t *DataSize) {
Napi::Object result = Napi::Object::New(env); string caption = GetArgument<string>(Arguments, "caption");
float pos = GetArgumentWithFallback<float>(Arguments, "pos", 0.5);
string basePath = GetArgument<string>(Arguments, "basePath");
try { VOption *options = VImage::option()->set("access", "sequential");
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 =
obj.Has("pos") ? obj.Get("pos").As<Napi::Number>().FloatValue() : 0.5;
string type = obj.Get("type").As<Napi::String>().Utf8Value();
string basePath = obj.Get("basePath").As<Napi::String>().Utf8Value();
VOption *options = VImage::option()->set("access", "sequential"); VImage in =
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);
VImage in = int width = in.width();
VImage::new_from_buffer(data.Data(), data.Length(), "", int pageHeight = vips_image_get_page_height(in.get_image());
type == "gif" ? options->set("n", -1) : options) int nPages = vips_image_get_n_pages(in.get_image());
.colourspace(VIPS_INTERPRETATION_sRGB); int size = width / 20;
if (!in.has_alpha()) int textWidth = width - ((width / 25) * 2);
in = in.bandjoin(255);
int width = in.width(); string font_string = "Helvetica Neue, Twemoji Color Font " + to_string(size);
int pageHeight = vips_image_get_page_height(in.get_image());
int nPages = vips_image_get_n_pages(in.get_image());
int size = width / 20;
int textWidth = width - ((width / 25) * 2);
string font_string = VImage textIn = VImage::text(
"Helvetica Neue, Twemoji Color Font " + to_string(size); ".", VImage::option()->set(
"fontfile", (basePath + "assets/fonts/caption2.ttf").c_str()));
textIn = VImage::text(
("<span foreground=\"white\" background=\"#000000B2\">" + caption +
"</span>")
.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));
int bgHeight = textIn.height() + (width / 25);
textIn = ((textIn == (vector<double>){0, 0, 0, 0}).bandand())
.ifthenelse({0, 0, 0, 178}, textIn)
.embed((width / 2) - (textIn.width() / 2),
(bgHeight / 2) - (textIn.height() / 2), width, bgHeight,
VImage::option()
->set("extend", "background")
->set("background", (vector<double>){0, 0, 0, 178}));
VImage textIn = VImage::text( vector<VImage> img;
".", VImage::option()->set( for (int i = 0; i < nPages; i++) {
"fontfile", (basePath + "assets/fonts/caption2.ttf").c_str())); VImage img_frame =
textIn = VImage::text( *type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
("<span foreground=\"white\" background=\"#000000B2\">" + caption + img_frame = img_frame.composite2(
"</span>") textIn, VIPS_BLEND_MODE_OVER,
.c_str(), VImage::option()->set("x", 0)->set("y", pageHeight * pos));
VImage::option() img.push_back(img_frame);
->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));
int bgHeight = textIn.height() + (width / 25);
textIn =
((textIn == (vector<double>){0, 0, 0, 0}).bandand())
.ifthenelse({0, 0, 0, 178}, textIn)
.embed((width / 2) - (textIn.width() / 2),
(bgHeight / 2) - (textIn.height() / 2), width, bgHeight,
VImage::option()
->set("extend", "background")
->set("background", (vector<double>){0, 0, 0, 178}));
vector<VImage> img;
for (int i = 0; i < nPages; i++) {
VImage img_frame =
type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
img_frame = img_frame.composite2(
textIn, VIPS_BLEND_MODE_OVER,
VImage::option()->set("x", 0)->set("y", pageHeight * pos));
img.push_back(img_frame);
}
VImage final = VImage::arrayjoin(img, VImage::option()->set("across", 1));
final.set(VIPS_META_PAGE_HEIGHT, pageHeight);
void *buf;
size_t length;
final.write_to_buffer(
("." + type).c_str(), &buf, &length,
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();
} }
VImage final = VImage::arrayjoin(img, VImage::option()->set("across", 1));
final.set(VIPS_META_PAGE_HEIGHT, pageHeight);
void *buf;
final.write_to_buffer(
("." + *type).c_str(), &buf, DataSize,
*type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
: 0);
vips_error_clear(); vips_error_clear();
vips_thread_shutdown(); vips_thread_shutdown();
return result; return (char *)buf;
} }

View File

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

View File

@ -42,7 +42,7 @@ char *vipsRemove(char *data, size_t length, size_t *DataSize, int speed) {
return (char *)buf; return (char *)buf;
} }
char *Speed(string type, char *BufferData, size_t BufferLength, char *Speed(string *type, char *BufferData, size_t BufferLength,
ArgumentMap Arguments, size_t *DataSize) { ArgumentMap Arguments, size_t *DataSize) {
bool slow = GetArgumentWithFallback<bool>(Arguments, "slow", false); bool slow = GetArgumentWithFallback<bool>(Arguments, "slow", false);

View File

@ -4,4 +4,4 @@
using std::string; using std::string;
char* Speed(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize); char* Speed(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);

View File

@ -1,80 +1,71 @@
#include "common.h"
#include <Magick++.h> #include <Magick++.h>
#include <napi.h>
#include <cstring>
#include <iostream> #include <iostream>
#include <list> #include <list>
using namespace std; using namespace std;
using namespace Magick; using namespace Magick;
Napi::Value Spin(const Napi::CallbackInfo &info) { char *Spin(string *type, char *BufferData, size_t BufferLength,
Napi::Env env = info.Env(); ArgumentMap Arguments, size_t *DataSize) {
int delay = GetArgumentWithFallback<int>(Arguments, "delay", 0);
Blob blob;
list<Image> frames;
list<Image> coalesced;
list<Image> mid;
try { try {
Napi::Object obj = info[1].As<Napi::Object>(); readImages(&frames, Blob(BufferData, BufferLength));
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>(); } catch (Magick::WarningCoder &warning) {
string type = obj.Get("type").As<Napi::String>().Utf8Value(); cerr << "Coder Warning: " << warning.what() << endl;
int delay = } catch (Magick::Warning &warning) {
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0; cerr << "Warning: " << warning.what() << endl;
Blob blob;
list<Image> frames;
list<Image> coalesced;
list<Image> mid;
try {
readImages(&frames, Blob(data.Data(), data.Length()));
} catch (Magick::WarningCoder &warning) {
cerr << "Coder Warning: " << warning.what() << endl;
} catch (Magick::Warning &warning) {
cerr << "Warning: " << warning.what() << endl;
}
coalesceImages(&coalesced, frames.begin(), frames.end());
if (type != "gif") {
list<Image>::iterator it = coalesced.begin();
for (int i = 0; i < 29; ++i) {
coalesced.push_back(*it);
}
}
int i = 0;
for (Image &image : coalesced) {
image.virtualPixelMethod(Magick::TransparentVirtualPixelMethod);
image.scale(Geometry("256x256"));
image.alphaChannel(Magick::SetAlphaChannel);
double rotation[1] = {(double)360 * i / coalesced.size()};
image.distort(Magick::ScaleRotateTranslateDistortion, 1, rotation);
image.magick("GIF");
mid.push_back(image);
i++;
}
for_each(mid.begin(), mid.end(),
gifDisposeMethodImage(Magick::BackgroundDispose));
optimizeTransparency(mid.begin(), mid.end());
if (delay != 0) {
for_each(mid.begin(), mid.end(), animationDelayImage(delay));
} else if (type != "gif") {
for_each(mid.begin(), mid.end(), animationDelayImage(5));
}
for (Image &image : mid) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
}
writeImages(mid.begin(), mid.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", "gif");
return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
} catch (...) {
throw Napi::Error::New(env, "Unknown error");
} }
coalesceImages(&coalesced, frames.begin(), frames.end());
if (*type != "gif") {
list<Image>::iterator it = coalesced.begin();
for (int i = 0; i < 29; ++i) {
coalesced.push_back(*it);
}
}
int i = 0;
for (Image &image : coalesced) {
image.virtualPixelMethod(Magick::TransparentVirtualPixelMethod);
image.scale(Geometry("256x256"));
image.alphaChannel(Magick::SetAlphaChannel);
double rotation[1] = {(double)360 * i / coalesced.size()};
image.distort(Magick::ScaleRotateTranslateDistortion, 1, rotation);
image.magick("GIF");
mid.push_back(image);
i++;
}
for_each(mid.begin(), mid.end(),
gifDisposeMethodImage(Magick::BackgroundDispose));
optimizeTransparency(mid.begin(), mid.end());
if (delay != 0) {
for_each(mid.begin(), mid.end(), animationDelayImage(delay));
} else if (*type != "gif") {
for_each(mid.begin(), mid.end(), animationDelayImage(5));
}
for (Image &image : mid) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
}
writeImages(mid.begin(), mid.end(), &blob);
*type = "gif";
*DataSize = blob.length();
char *data = (char *)malloc(*DataSize);
memcpy(data, blob.data(), *DataSize);
return data;
} }

View File

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

View File

@ -1,95 +1,80 @@
#include <napi.h> #include "common.h"
#include <vips/vips8> #include <vips/vips8>
using namespace std; using namespace std;
using namespace vips; using namespace vips;
Napi::Value Swirl(const Napi::CallbackInfo &info) { char *Swirl(string *type, char *BufferData, size_t BufferLength,
Napi::Env env = info.Env(); ArgumentMap Arguments, size_t *DataSize) {
Napi::Object result = Napi::Object::New(env);
try { VOption *options = VImage::option()->set("access", "sequential");
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();
VOption *options = VImage::option()->set("access", "sequential"); VImage in =
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);
VImage in = int pageHeight = vips_image_get_page_height(in.get_image());
VImage::new_from_buffer(data.Data(), data.Length(), "", int nPages = vips_image_get_n_pages(in.get_image());
type == "gif" ? options->set("n", -1) : options) int width = in.width();
.colourspace(VIPS_INTERPRETATION_sRGB); double newWidth = width * 3;
if (!in.has_alpha()) double newHeight = pageHeight * 3;
in = in.bandjoin(255); vector<double> divSize = {newWidth / 2, newHeight / 2};
int pageHeight = vips_image_get_page_height(in.get_image()); VImage index = VImage::xyz(newWidth, newHeight);
int nPages = vips_image_get_n_pages(in.get_image()); VImage center = index - divSize;
int width = in.width(); VImage polar = center
double newWidth = width * 3; .copy(VImage::option()
double newHeight = pageHeight * 3; ->set("format", VIPS_FORMAT_COMPLEX)
vector<double> divSize = {newWidth / 2, newHeight / 2}; ->set("bands", 1))
.polar()
.copy(VImage::option()
->set("format", VIPS_FORMAT_FLOAT)
->set("bands", 2));
VImage index = VImage::xyz(newWidth, newHeight); int size = min(width, pageHeight) / 2;
VImage center = index - divSize;
VImage polar = center
.copy(VImage::option()
->set("format", VIPS_FORMAT_COMPLEX)
->set("bands", 1))
.polar()
.copy(VImage::option()
->set("format", VIPS_FORMAT_FLOAT)
->set("bands", 2));
int size = min(width, pageHeight) / 2; VImage test = (1 - polar.extract_band(0) / size);
VImage degrees = test.cast(VIPS_FORMAT_FLOAT).pow(2);
VImage test = (1 - polar.extract_band(0) / size); VImage angle = polar.extract_band(1) + degrees * 180;
VImage degrees = test.cast(VIPS_FORMAT_FLOAT).pow(2);
VImage angle = polar.extract_band(1) + degrees * 180; VImage distortion = polar.extract_band(0)
.bandjoin(angle)
.copy(VImage::option()
->set("format", VIPS_FORMAT_COMPLEX)
->set("bands", 1))
.rect()
.copy(VImage::option()
->set("format", VIPS_FORMAT_FLOAT)
->set("bands", 2)) +
divSize;
VImage distortion = polar.extract_band(0) vector<VImage> img;
.bandjoin(angle) for (int i = 0; i < nPages; i++) {
.copy(VImage::option() VImage img_frame =
->set("format", VIPS_FORMAT_COMPLEX) *type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
->set("bands", 1))
.rect()
.copy(VImage::option()
->set("format", VIPS_FORMAT_FLOAT)
->set("bands", 2)) +
divSize;
vector<VImage> img; VImage distort =
for (int i = 0; i < nPages; i++) { img_frame
VImage img_frame = .gravity(VIPS_COMPASS_DIRECTION_CENTRE, newWidth, newHeight,
type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in; VImage::option()->set("extend", VIPS_EXTEND_COPY))
.mapim(distortion,
VImage distort = VImage::option()->set(
img_frame "interpolate", VInterpolate::new_from_name("bicubic")));
.gravity(VIPS_COMPASS_DIRECTION_CENTRE, newWidth, newHeight, VImage frame = distort.crop(width, pageHeight, width, pageHeight);
VImage::option()->set("extend", VIPS_EXTEND_COPY)) img.push_back(frame);
.mapim(distortion, VImage::option()->set(
"interpolate",
VInterpolate::new_from_name("bicubic")));
VImage frame = distort.crop(width, pageHeight, width, pageHeight);
img.push_back(frame);
}
VImage final = VImage::arrayjoin(img, VImage::option()->set("across", 1));
final.set(VIPS_META_PAGE_HEIGHT, pageHeight);
void *buf;
size_t length;
final.write_to_buffer(".gif", &buf, &length);
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();
} }
VImage final = VImage::arrayjoin(img, VImage::option()->set("across", 1));
final.set(VIPS_META_PAGE_HEIGHT, pageHeight);
void *buf;
final.write_to_buffer(".gif", &buf, DataSize);
vips_error_clear(); vips_error_clear();
vips_thread_shutdown(); vips_thread_shutdown();
return result; return (char *)buf;
} }

View File

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

View File

@ -1,75 +1,65 @@
#include "common.h"
#include <Magick++.h> #include <Magick++.h>
#include <napi.h>
#include <cstring>
#include <iostream> #include <iostream>
#include <list> #include <list>
using namespace std; using namespace std;
using namespace Magick; using namespace Magick;
Napi::Value Tile(const Napi::CallbackInfo &info) { char *Tile(string *type, char *BufferData, size_t BufferLength,
Napi::Env env = info.Env(); ArgumentMap Arguments, size_t *DataSize) {
Napi::Object result = Napi::Object::New(env);
Blob blob;
list<Image> frames;
list<Image> coalesced;
list<Image> mid;
try { try {
Napi::Object obj = info[1].As<Napi::Object>(); readImages(&frames, Blob(BufferData, BufferLength));
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>(); } catch (Magick::WarningCoder &warning) {
string type = obj.Get("type").As<Napi::String>().Utf8Value(); cerr << "Coder Warning: " << warning.what() << endl;
} catch (Magick::Warning &warning) {
cerr << "Warning: " << warning.what() << endl;
}
coalesceImages(&coalesced, frames.begin(), frames.end());
Blob blob; for (Image &image : coalesced) {
list<Image> duplicated;
list<Image> frames; Image appended;
list<Image> coalesced; list<Image> montage;
list<Image> mid; Image frame;
try { image.magick(*type);
readImages(&frames, Blob(data.Data(), data.Length())); for (int i = 0; i < 5; ++i) {
} catch (Magick::WarningCoder &warning) { duplicated.push_back(image);
cerr << "Coder Warning: " << warning.what() << endl;
} catch (Magick::Warning &warning) {
cerr << "Warning: " << warning.what() << endl;
} }
coalesceImages(&coalesced, frames.begin(), frames.end()); appendImages(&appended, duplicated.begin(), duplicated.end());
appended.repage();
for (Image &image : coalesced) { for (int i = 0; i < 5; ++i) {
list<Image> duplicated; montage.push_back(appended);
Image appended;
list<Image> montage;
Image frame;
image.magick(type);
for (int i = 0; i < 5; ++i) {
duplicated.push_back(image);
}
appendImages(&appended, duplicated.begin(), duplicated.end());
appended.repage();
for (int i = 0; i < 5; ++i) {
montage.push_back(appended);
}
appendImages(&frame, montage.begin(), montage.end(), true);
frame.repage();
frame.scale(Geometry("800x800>"));
frame.animationDelay(image.animationDelay());
mid.push_back(frame);
} }
appendImages(&frame, montage.begin(), montage.end(), true);
optimizeTransparency(mid.begin(), mid.end()); frame.repage();
frame.scale(Geometry("800x800>"));
if (type == "gif") { frame.animationDelay(image.animationDelay());
for (Image &image : mid) { mid.push_back(frame);
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
}
}
writeImages(mid.begin(), mid.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();
} }
return result; optimizeTransparency(mid.begin(), mid.end());
if (*type == "gif") {
for (Image &image : mid) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
}
}
writeImages(mid.begin(), mid.end(), &blob);
*DataSize = blob.length();
char *data = (char *)malloc(*DataSize);
memcpy(data, blob.data(), *DataSize);
return data;
} }

View File

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

View File

@ -1,43 +1,32 @@
#include <napi.h> #include "common.h"
#include <vips/vips8> #include <vips/vips8>
using namespace std; using namespace std;
using namespace vips; using namespace vips;
Napi::Value ToGif(const Napi::CallbackInfo &info) { char *ToGif(string *type, char *BufferData, size_t BufferLength,
Napi::Env env = info.Env(); ArgumentMap Arguments, size_t *DataSize) {
Napi::Object result = Napi::Object::New(env);
try { if (*type == "gif") {
Napi::Object obj = info[1].As<Napi::Object>(); vips_error_clear();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>(); vips_thread_shutdown();
string type = obj.Get("type").As<Napi::String>().Utf8Value(); *DataSize = BufferLength;
return BufferData;
} else {
VOption *options = VImage::option()->set("access", "sequential");
if (type == "gif") { VImage in = VImage::new_from_buffer(BufferData, BufferLength, "",
result.Set("data", data); *type == "webp" ? options->set("n", -1)
result.Set("type", "gif"); : options);
} else {
VOption *options = VImage::option()->set("access", "sequential");
VImage in = VImage::new_from_buffer(data.Data(), data.Length(), "", void *buf;
type == "webp" ? options->set("n", -1) in.write_to_buffer(".gif", &buf, DataSize);
: options);
void *buf; *type = "gif";
size_t length;
in.write_to_buffer(".gif", &buf, &length);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)buf, length)); vips_error_clear();
result.Set("type", "gif"); vips_thread_shutdown();
} return (char *)buf;
} 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;
} }

View File

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

View File

@ -1,120 +1,104 @@
#include "common.h" #include "common.h"
#include <napi.h>
#include <vips/vips8> #include <vips/vips8>
using namespace std; using namespace std;
using namespace vips; using namespace vips;
Napi::Value Uncanny(const Napi::CallbackInfo &info) { char *Uncanny(string *type, char *BufferData, size_t BufferLength,
Napi::Env env = info.Env(); ArgumentMap Arguments, size_t *DataSize) {
Napi::Object result = Napi::Object::New(env);
try { string caption = GetArgument<string>(Arguments, "caption");
Napi::Object obj = info[1].As<Napi::Object>(); string caption2 = GetArgument<string>(Arguments, "caption2");
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>(); string font = GetArgument<string>(Arguments, "font");
string caption = obj.Get("caption").As<Napi::String>().Utf8Value(); string path = GetArgument<string>(Arguments, "path");
string caption2 = obj.Get("caption2").As<Napi::String>().Utf8Value(); string basePath = GetArgument<string>(Arguments, "basePath");
string font = obj.Get("font").As<Napi::String>().Utf8Value();
string type = obj.Get("type").As<Napi::String>().Utf8Value();
string path = obj.Get("path").As<Napi::String>().Utf8Value();
string basePath = obj.Get("basePath").As<Napi::String>().Utf8Value();
VOption *options = VImage::option()->set("access", "sequential"); VOption *options = VImage::option()->set("access", "sequential");
VImage in = VImage in =
VImage::new_from_buffer(data.Data(), data.Length(), "", VImage::new_from_buffer(BufferData, BufferLength, "",
type == "gif" ? options->set("n", -1) : options) *type == "gif" ? options->set("n", -1) : options)
.colourspace(VIPS_INTERPRETATION_sRGB) .colourspace(VIPS_INTERPRETATION_sRGB)
.extract_band(0, VImage::option()->set("n", 3)); .extract_band(0, VImage::option()->set("n", 3));
VImage base = VImage::black(1280, 720, VImage::option()->set("bands", 3)); VImage base = VImage::black(1280, 720, VImage::option()->set("bands", 3));
string font_string = (font == "roboto" ? "Roboto Condensed" : font) + ", Twemoji Color Font " + string font_string = (font == "roboto" ? "Roboto Condensed" : font) +
(font != "impact" ? "bold" : "normal") + " 72"; ", Twemoji Color Font " +
(font != "impact" ? "bold" : "normal") + " 72";
string captionText = "<span background=\"black\" foreground=\"white\">" + string captionText =
caption + "</span>"; "<span background=\"black\" foreground=\"white\">" + caption + "</span>";
string caption2Text = string caption2Text =
"<span background=\"black\" foreground=\"red\">" + caption2 + "</span>"; "<span background=\"black\" foreground=\"red\">" + caption2 + "</span>";
auto findResult = fontPaths.find(font); auto findResult = fontPaths.find(font);
if (findResult != fontPaths.end()) { if (findResult != fontPaths.end()) {
VImage::text( VImage::text(".", VImage::option()->set(
".", VImage::option()->set("fontfile", "fontfile", (basePath + findResult->second).c_str()));
(basePath + findResult->second).c_str()));
}
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", 588)
->set("height", 90));
VImage captionImage =
text.extract_band(0, VImage::option()->set("n", 3))
.gravity(VIPS_COMPASS_DIRECTION_CENTRE, 640, text.height() + 40,
VImage::option()->set("extend", "black"));
VImage text2 = VImage::text(
caption2Text.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", 588)
->set("height", 90));
VImage caption2Image =
text2.extract_band(0, VImage::option()->set("n", 3))
.gravity(VIPS_COMPASS_DIRECTION_CENTRE, 640, text.height() + 40,
VImage::option()->set("extend", "black"));
base = base.insert(captionImage, 0, 0).insert(caption2Image, 640, 0);
int width = in.width();
int pageHeight = vips_image_get_page_height(in.get_image());
int nPages = vips_image_get_n_pages(in.get_image());
VImage uncanny = VImage::new_from_file((basePath + path).c_str());
base = base.insert(uncanny, 0, 130);
vector<VImage> img;
for (int i = 0; i < nPages; i++) {
VImage img_frame =
type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
VImage resized = img_frame.resize(690.0 / (double)width);
if (resized.height() > 590) {
double vscale = 590.0 / (double)resized.height();
resized =
resized.resize(vscale, VImage::option()->set("vscale", vscale));
}
VImage composited = base.insert(resized, 935 - (resized.width() / 2),
425 - (resized.height() / 2));
img.push_back(composited);
}
VImage final = VImage::arrayjoin(img, VImage::option()->set("across", 1));
final.set(VIPS_META_PAGE_HEIGHT, 720);
void *buf;
size_t length;
final.write_to_buffer(("." + type).c_str(), &buf, &length,
type == "gif" ? VImage::option()->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();
} }
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", 588)
->set("height", 90));
VImage captionImage =
text.extract_band(0, VImage::option()->set("n", 3))
.gravity(VIPS_COMPASS_DIRECTION_CENTRE, 640, text.height() + 40,
VImage::option()->set("extend", "black"));
VImage text2 = VImage::text(
caption2Text.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", 588)
->set("height", 90));
VImage caption2Image =
text2.extract_band(0, VImage::option()->set("n", 3))
.gravity(VIPS_COMPASS_DIRECTION_CENTRE, 640, text.height() + 40,
VImage::option()->set("extend", "black"));
base = base.insert(captionImage, 0, 0).insert(caption2Image, 640, 0);
int width = in.width();
int pageHeight = vips_image_get_page_height(in.get_image());
int nPages = vips_image_get_n_pages(in.get_image());
VImage uncanny = VImage::new_from_file((basePath + path).c_str());
base = base.insert(uncanny, 0, 130);
vector<VImage> img;
for (int i = 0; i < nPages; i++) {
VImage img_frame =
*type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
VImage resized = img_frame.resize(690.0 / (double)width);
if (resized.height() > 590) {
double vscale = 590.0 / (double)resized.height();
resized = resized.resize(vscale, VImage::option()->set("vscale", vscale));
}
VImage composited = base.insert(resized, 935 - (resized.width() / 2),
425 - (resized.height() / 2));
img.push_back(composited);
}
VImage final = VImage::arrayjoin(img, VImage::option()->set("across", 1));
final.set(VIPS_META_PAGE_HEIGHT, 720);
void *buf;
final.write_to_buffer(("." + *type).c_str(), &buf, DataSize,
*type == "gif" ? VImage::option()->set("reoptimise", 1)
: 0);
vips_error_clear(); vips_error_clear();
vips_thread_shutdown(); vips_thread_shutdown();
return result; return (char *)buf;
} }

View File

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

View File

@ -6,7 +6,7 @@
using namespace std; using namespace std;
using namespace vips; using namespace vips;
char *Uncaption(string type, char *BufferData, size_t BufferLength, char *Uncaption(string *type, char *BufferData, size_t BufferLength,
ArgumentMap Arguments, size_t *DataSize) { ArgumentMap Arguments, size_t *DataSize) {
float tolerance = GetArgumentWithFallback<float>(Arguments, "tolerance", 0.5); float tolerance = GetArgumentWithFallback<float>(Arguments, "tolerance", 0.5);
@ -16,7 +16,7 @@ char *Uncaption(string type, char *BufferData, size_t BufferLength,
VImage in = VImage in =
VImage::new_from_buffer( VImage::new_from_buffer(
BufferData, BufferLength, "", BufferData, BufferLength, "",
type == "gif" ? options->set("n", -1)->set("access", "sequential") *type == "gif" ? options->set("n", -1)->set("access", "sequential")
: options) : options)
.colourspace(VIPS_INTERPRETATION_sRGB); .colourspace(VIPS_INTERPRETATION_sRGB);
if (!in.has_alpha()) if (!in.has_alpha())
@ -47,8 +47,8 @@ char *Uncaption(string type, char *BufferData, size_t BufferLength,
void *buf; void *buf;
final.write_to_buffer( final.write_to_buffer(
("." + type).c_str(), &buf, DataSize, ("." + *type).c_str(), &buf, DataSize,
type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1) *type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
: 0); : 0);
vips_error_clear(); vips_error_clear();

View File

@ -6,4 +6,4 @@
using std::map; using std::map;
using std::string; using std::string;
char* Uncaption(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize); char* Uncaption(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);

View File

@ -1,68 +1,58 @@
#include "common.h"
#include <Magick++.h> #include <Magick++.h>
#include <napi.h>
#include <cstring>
#include <iostream> #include <iostream>
#include <list> #include <list>
using namespace std; using namespace std;
using namespace Magick; using namespace Magick;
Napi::Value Wall(const Napi::CallbackInfo &info) { char *Wall(string *type, char *BufferData, size_t BufferLength,
Napi::Env env = info.Env(); ArgumentMap Arguments, size_t *DataSize) {
Napi::Object result = Napi::Object::New(env);
Blob blob;
list<Image> frames;
list<Image> coalesced;
list<Image> mid;
try { try {
Napi::Object obj = info[1].As<Napi::Object>(); readImages(&frames, Blob(BufferData, BufferLength));
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>(); } catch (Magick::WarningCoder &warning) {
string type = obj.Get("type").As<Napi::String>().Utf8Value(); cerr << "Coder Warning: " << warning.what() << endl;
} catch (Magick::Warning &warning) {
cerr << "Warning: " << warning.what() << endl;
}
coalesceImages(&coalesced, frames.begin(), frames.end());
Blob blob; for (Image &image : coalesced) {
image.resize(Geometry("128x128"));
list<Image> frames; image.virtualPixelMethod(Magick::TileVirtualPixelMethod);
list<Image> coalesced; image.matteColor("none");
list<Image> mid; image.backgroundColor("none");
try { image.scale(Geometry("512x512"));
readImages(&frames, Blob(data.Data(), data.Length())); double arguments[16] = {0, 0, 57, 42, 0, 128, 63, 130,
} catch (Magick::WarningCoder &warning) { 128, 0, 140, 60, 128, 128, 140, 140};
cerr << "Coder Warning: " << warning.what() << endl; image.distort(Magick::PerspectiveDistortion, 16, arguments);
} catch (Magick::Warning &warning) { image.scale(Geometry("800x800>"));
cerr << "Warning: " << warning.what() << endl; image.magick(*type);
} mid.push_back(image);
coalesceImages(&coalesced, frames.begin(), frames.end());
for (Image &image : coalesced) {
image.resize(Geometry("128x128"));
image.virtualPixelMethod(Magick::TileVirtualPixelMethod);
image.matteColor("none");
image.backgroundColor("none");
image.scale(Geometry("512x512"));
double arguments[16] = {0, 0, 57, 42, 0, 128, 63, 130,
128, 0, 140, 60, 128, 128, 140, 140};
image.distort(Magick::PerspectiveDistortion, 16, arguments);
image.scale(Geometry("800x800>"));
image.magick(type);
mid.push_back(image);
}
optimizeTransparency(mid.begin(), mid.end());
if (type == "gif") {
for (Image &image : mid) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
}
}
writeImages(mid.begin(), mid.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();
} }
return result; optimizeTransparency(mid.begin(), mid.end());
if (*type == "gif") {
for (Image &image : mid) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
}
}
writeImages(mid.begin(), mid.end(), &blob);
*DataSize = blob.length();
char *data = (char *)malloc(*DataSize);
memcpy(data, blob.data(), *DataSize);
return data;
} }

View File

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

View File

@ -6,7 +6,7 @@
using namespace std; using namespace std;
using namespace vips; using namespace vips;
char *Watermark(string type, char *BufferData, size_t BufferLength, char *Watermark(string *type, char *BufferData, size_t BufferLength,
ArgumentMap Arguments, size_t *DataSize) { ArgumentMap Arguments, size_t *DataSize) {
string water = GetArgument<string>(Arguments, "water"); string water = GetArgument<string>(Arguments, "water");
@ -29,7 +29,7 @@ char *Watermark(string type, char *BufferData, size_t BufferLength,
VImage in = VImage in =
VImage::new_from_buffer(BufferData, BufferLength, "", VImage::new_from_buffer(BufferData, BufferLength, "",
type == "gif" ? options->set("n", -1) : options) *type == "gif" ? options->set("n", -1) : options)
.colourspace(VIPS_INTERPRETATION_sRGB); .colourspace(VIPS_INTERPRETATION_sRGB);
if (!in.has_alpha()) if (!in.has_alpha())
in = in.bandjoin(255); in = in.bandjoin(255);
@ -93,7 +93,7 @@ char *Watermark(string type, char *BufferData, size_t BufferLength,
VImage frame; VImage frame;
for (int i = 0; i < nPages; i++) { for (int i = 0; i < nPages; i++) {
VImage img_frame = VImage img_frame =
type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in; *type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
if (append) { if (append) {
VImage appended = img_frame.join(watermark, VIPS_DIRECTION_VERTICAL, VImage appended = img_frame.join(watermark, VIPS_DIRECTION_VERTICAL,
VImage::option()->set("expand", true)); VImage::option()->set("expand", true));
@ -123,8 +123,8 @@ char *Watermark(string type, char *BufferData, size_t BufferLength,
bg = frameAlpha.new_from_image({0, 0, 0}).copy(VImage::option()->set( bg = frameAlpha.new_from_image({0, 0, 0}).copy(VImage::option()->set(
"interpretation", VIPS_INTERPRETATION_sRGB)); "interpretation", VIPS_INTERPRETATION_sRGB));
frame = bg.bandjoin(frameAlpha); frame = bg.bandjoin(frameAlpha);
if (type == "jpg" || type == "jpeg") { if (*type == "jpg" || *type == "jpeg") {
type = "png"; *type = "png";
} }
} }
VImage content = VImage content =
@ -147,8 +147,8 @@ char *Watermark(string type, char *BufferData, size_t BufferLength,
void *buf; void *buf;
final.write_to_buffer( final.write_to_buffer(
("." + type).c_str(), &buf, DataSize, ("." + *type).c_str(), &buf, DataSize,
type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1) *type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
: 0); : 0);
vips_error_clear(); vips_error_clear();

View File

@ -6,4 +6,4 @@
using std::map; using std::map;
using std::string; using std::string;
char* Watermark(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize); char* Watermark(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);

View File

@ -1,105 +1,88 @@
#include <napi.h> #include "common.h"
#include <vips/vips8> #include <vips/vips8>
using namespace std; using namespace std;
using namespace vips; using namespace vips;
Napi::Value Whisper(const Napi::CallbackInfo &info) { char *Whisper(string *type, char *BufferData, size_t BufferLength,
Napi::Env env = info.Env(); ArgumentMap Arguments, size_t *DataSize) {
Napi::Object result = Napi::Object::New(env); string caption = GetArgument<string>(Arguments, "caption");
string basePath = GetArgument<string>(Arguments, "basePath");
try { VOption *options = VImage::option()->set("access", "sequential");
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();
string basePath = obj.Get("basePath").As<Napi::String>().Utf8Value();
VOption *options = VImage::option()->set("access", "sequential"); VImage in =
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);
VImage in = int width = in.width();
VImage::new_from_buffer(data.Data(), data.Length(), "", int pageHeight = vips_image_get_page_height(in.get_image());
type == "gif" ? options->set("n", -1) : options) int nPages = vips_image_get_n_pages(in.get_image());
.colourspace(VIPS_INTERPRETATION_sRGB); int size = width / 6;
if (!in.has_alpha()) int dividedWidth = width / 175;
in = in.bandjoin(255); int rad = 1;
int width = in.width(); string font_string = "Upright, Twemoji Color Font " + to_string(size);
int pageHeight = vips_image_get_page_height(in.get_image());
int nPages = vips_image_get_n_pages(in.get_image());
int size = width / 6;
int dividedWidth = width / 175;
int rad = 1;
string font_string = "Upright, Twemoji Color Font " + to_string(size); VImage mask;
if (dividedWidth >= 1) {
VImage mask; mask = VImage::black(dividedWidth * 2 + 1, dividedWidth * 2 + 1) + 128;
if (dividedWidth >= 1) { mask.draw_circle({255}, dividedWidth, dividedWidth, dividedWidth,
mask = VImage::black(dividedWidth * 2 + 1, dividedWidth * 2 + 1) + 128; VImage::option()->set("fill", true));
mask.draw_circle({255}, dividedWidth, dividedWidth, dividedWidth, } else {
VImage::option()->set("fill", true)); mask = VImage::black(rad * 2 + 1, rad * 2 + 1) + 128;
} else { mask.draw_circle({255}, rad, rad, rad, VImage::option()->set("fill", true));
mask = VImage::black(rad * 2 + 1, rad * 2 + 1) + 128;
mask.draw_circle({255}, rad, rad, rad,
VImage::option()->set("fill", true));
}
VImage textIn = VImage::text(
".", VImage::option()->set(
"fontfile", (basePath + "assets/fonts/whisper.otf").c_str()));
textIn = VImage::text(
("<span foreground=\"white\">" + caption + "</span>").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", width));
textIn = textIn.embed(rad + 10, rad + 10, (textIn.width() + 2 * rad) + 20,
(textIn.height() + 2 * rad) + 20);
VImage outline =
textIn.morph(mask, VIPS_OPERATION_MORPHOLOGY_DILATE)
.gaussblur(0.5, VImage::option()->set("min_ampl", 0.1));
outline = (outline == (vector<double>){0, 0, 0, 0});
VImage invert = outline.extract_band(3).invert();
outline =
outline.extract_band(0, VImage::option()->set("n", outline.bands() - 1))
.bandjoin(invert);
VImage textImg = outline.composite2(textIn, VIPS_BLEND_MODE_OVER);
vector<VImage> img;
for (int i = 0; i < nPages; i++) {
VImage img_frame =
type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
img_frame = img_frame.composite2(
textImg, VIPS_BLEND_MODE_OVER,
VImage::option()
->set("x", (width / 2) - (textImg.width() / 2))
->set("y", (pageHeight / 2) - (textImg.height() / 2)));
img.push_back(img_frame);
}
VImage final = VImage::arrayjoin(img, VImage::option()->set("across", 1));
final.set(VIPS_META_PAGE_HEIGHT, pageHeight);
void *buf;
size_t length;
final.write_to_buffer(
("." + type).c_str(), &buf, &length,
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();
} }
VImage textIn = VImage::text(
".", VImage::option()->set(
"fontfile", (basePath + "assets/fonts/whisper.otf").c_str()));
textIn = VImage::text(
("<span foreground=\"white\">" + caption + "</span>").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", width));
textIn = textIn.embed(rad + 10, rad + 10, (textIn.width() + 2 * rad) + 20,
(textIn.height() + 2 * rad) + 20);
VImage outline = textIn.morph(mask, VIPS_OPERATION_MORPHOLOGY_DILATE)
.gaussblur(0.5, VImage::option()->set("min_ampl", 0.1));
outline = (outline == (vector<double>){0, 0, 0, 0});
VImage invert = outline.extract_band(3).invert();
outline =
outline.extract_band(0, VImage::option()->set("n", outline.bands() - 1))
.bandjoin(invert);
VImage textImg = outline.composite2(textIn, VIPS_BLEND_MODE_OVER);
vector<VImage> img;
for (int i = 0; i < nPages; i++) {
VImage img_frame =
*type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
img_frame = img_frame.composite2(
textImg, VIPS_BLEND_MODE_OVER,
VImage::option()
->set("x", (width / 2) - (textImg.width() / 2))
->set("y", (pageHeight / 2) - (textImg.height() / 2)));
img.push_back(img_frame);
}
VImage final = VImage::arrayjoin(img, VImage::option()->set("across", 1));
final.set(VIPS_META_PAGE_HEIGHT, pageHeight);
void *buf;
final.write_to_buffer(
("." + *type).c_str(), &buf, DataSize,
*type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
: 0);
vips_error_clear(); vips_error_clear();
vips_thread_shutdown(); vips_thread_shutdown();
return result; return (char *)buf;
} }

View File

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

View File

@ -1,62 +1,50 @@
#include <napi.h> #include "common.h"
#include <vips/vips8> #include <vips/vips8>
using namespace std; using namespace std;
using namespace vips; using namespace vips;
Napi::Value Zamn(const Napi::CallbackInfo &info) { char *Zamn(string *type, char *BufferData, size_t BufferLength,
Napi::Env env = info.Env(); ArgumentMap Arguments, size_t *DataSize) {
Napi::Object result = Napi::Object::New(env); string basePath = GetArgument<string>(Arguments, "basePath");
try { VOption *options = VImage::option()->set("access", "sequential");
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();
VOption *options = VImage::option()->set("access", "sequential"); VImage in =
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);
VImage in = int width = in.width();
VImage::new_from_buffer(data.Data(), data.Length(), "", int pageHeight = vips_image_get_page_height(in.get_image());
type == "gif" ? options->set("n", -1) : options) int nPages = vips_image_get_n_pages(in.get_image());
.colourspace(VIPS_INTERPRETATION_sRGB);
if (!in.has_alpha()) in = in.bandjoin(255);
int width = in.width(); string assetPath = basePath + "assets/images/zamn.png";
int pageHeight = vips_image_get_page_height(in.get_image()); VImage tmpl = VImage::new_from_file(assetPath.c_str());
int nPages = vips_image_get_n_pages(in.get_image());
string assetPath = basePath + "assets/images/zamn.png"; vector<VImage> img;
VImage tmpl = VImage::new_from_file(assetPath.c_str()); for (int i = 0; i < nPages; i++) {
VImage img_frame =
vector<VImage> img; *type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
for (int i = 0; i < nPages; i++) { VImage composited =
VImage img_frame = tmpl.insert(img_frame.extract_band(0, VImage::option()->set("n", 3))
type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in; .bandjoin(255)
VImage composited = tmpl.insert( .resize(303.0 / (double)width,
img_frame.extract_band(0, VImage::option()->set("n", 3)).bandjoin(255).resize( VImage::option()->set(
303.0 / (double)width, "vscale", 438.0 / (double)pageHeight)),
VImage::option()->set("vscale", 438.0 / (double)pageHeight)), 310, 76);
310, 76); img.push_back(composited);
img.push_back(composited);
}
VImage final = VImage::arrayjoin(img, VImage::option()->set("across", 1));
final.set(VIPS_META_PAGE_HEIGHT, 516);
void *buf;
size_t length;
final.write_to_buffer(("." + type).c_str(), &buf, &length);
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();
} }
VImage final = VImage::arrayjoin(img, VImage::option()->set("across", 1));
final.set(VIPS_META_PAGE_HEIGHT, 516);
void *buf;
final.write_to_buffer(("." + *type).c_str(), &buf, DataSize);
vips_error_clear(); vips_error_clear();
vips_thread_shutdown(); vips_thread_shutdown();
return result; return (char *)buf;
} }

View File

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

View File

@ -6,7 +6,7 @@ let dirSizeCache;
export async function upload(client, result, context, interaction = false) { export async function upload(client, result, context, interaction = false) {
const filename = `${Math.random().toString(36).substring(2, 15)}.${result.name.split(".")[1]}`; const filename = `${Math.random().toString(36).substring(2, 15)}.${result.name.split(".")[1]}`;
await writeFile(`${process.env.TEMPDIR}/${filename}`, result.contents); await writeFile(`${process.env.TEMPDIR}/${filename}`, result.contents);
const imageURL = `${process.env.TMP_DOMAIN || "https://tmp.projectlounge.pw"}/${filename}`; const imageURL = `${process.env.TMP_DOMAIN || "https://tmp.esmbot.net"}/${filename}`;
const payload = { const payload = {
embeds: [{ embeds: [{
color: 16711680, color: 16711680,