Compare commits
10 commits
5ba0336837
...
3272429cf6
Author | SHA1 | Date | |
---|---|---|---|
3272429cf6 | |||
d236179639 | |||
a77dc5acf9 | |||
d36ff74326 | |||
10b80f2fd0 | |||
cc7ea2762c | |||
de308ca795 | |||
2bd00d7845 | |||
21e0914268 | |||
c6dd21addd |
97 changed files with 895 additions and 787 deletions
|
@ -2,12 +2,20 @@ cmake_minimum_required(VERSION 3.15)
|
||||||
cmake_policy(SET CMP0091 NEW)
|
cmake_policy(SET CMP0091 NEW)
|
||||||
cmake_policy(SET CMP0042 NEW)
|
cmake_policy(SET CMP0042 NEW)
|
||||||
project(image)
|
project(image)
|
||||||
include_directories(${CMAKE_JS_INC})
|
|
||||||
file(GLOB SOURCE_FILES "natives/*.cc" "natives/*.h")
|
file(GLOB SOURCE_FILES "natives/*.cc" "natives/*.h")
|
||||||
add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${CMAKE_JS_SRC})
|
|
||||||
|
if (CMAKE_JS_VERSION)
|
||||||
|
include_directories(${CMAKE_JS_INC})
|
||||||
|
add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${CMAKE_JS_SRC} natives/node/image.cc)
|
||||||
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" SUFFIX ".node")
|
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" SUFFIX ".node")
|
||||||
target_link_libraries(${PROJECT_NAME} ${CMAKE_JS_LIB})
|
target_link_libraries(${PROJECT_NAME} ${CMAKE_JS_LIB})
|
||||||
|
else()
|
||||||
|
add_executable(${PROJECT_NAME} ${SOURCE_FILES} natives/cli/image.cc)
|
||||||
|
endif()
|
||||||
|
|
||||||
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_17)
|
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_17)
|
||||||
|
|
||||||
if(MSVC) # todo: change flags for more parity with GCC/clang, I don't know much about MSVC so pull requests are open
|
if(MSVC) # todo: change flags for more parity with GCC/clang, I don't know much about MSVC so pull requests are open
|
||||||
set(CMAKE_CXX_FLAGS "/Wall /EHsc /GS")
|
set(CMAKE_CXX_FLAGS "/Wall /EHsc /GS")
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "/Zi")
|
set(CMAKE_CXX_FLAGS_DEBUG "/Zi")
|
||||||
|
@ -17,9 +25,11 @@ set(BUILD_SHARED_LIBS TRUE)
|
||||||
else()
|
else()
|
||||||
set(CMAKE_CXX_FLAGS "-Wall -Wextra -Werror=format-security -Wno-cast-function-type -fexceptions -D_GLIBCXX_ASSERTIONS -fstack-clash-protection -pedantic -D_GLIBCXX_USE_CXX11_ABI=1")
|
set(CMAKE_CXX_FLAGS "-Wall -Wextra -Werror=format-security -Wno-cast-function-type -fexceptions -D_GLIBCXX_ASSERTIONS -fstack-clash-protection -pedantic -D_GLIBCXX_USE_CXX11_ABI=1")
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "-g")
|
set(CMAKE_CXX_FLAGS_DEBUG "-g")
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
|
set(CMAKE_CXX_FLAGS_RELEASE "-O2")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
|
||||||
find_package(ImageMagick REQUIRED COMPONENTS Magick++ MagickCore)
|
find_package(ImageMagick REQUIRED COMPONENTS Magick++ MagickCore)
|
||||||
add_definitions(-DMAGICKCORE_QUANTUM_DEPTH=16)
|
add_definitions(-DMAGICKCORE_QUANTUM_DEPTH=16)
|
||||||
add_definitions(-DMAGICKCORE_HDRI_ENABLE=0)
|
add_definitions(-DMAGICKCORE_HDRI_ENABLE=0)
|
||||||
|
@ -31,7 +41,7 @@ include_directories(${VIPS_INCLUDE_DIRS})
|
||||||
link_directories(${VIPS_LIBRARY_DIRS})
|
link_directories(${VIPS_LIBRARY_DIRS})
|
||||||
target_link_libraries(${PROJECT_NAME} ${VIPS_LDFLAGS})
|
target_link_libraries(${PROJECT_NAME} ${VIPS_LDFLAGS})
|
||||||
|
|
||||||
if(MSVC AND CMAKE_JS_NODELIB_DEF AND CMAKE_JS_NODELIB_TARGET)
|
if(MSVC AND CMAKE_JS_NODELIB_DEF AND CMAKE_JS_NODELIB_TARGET AND CMAKE_JS_VERSION)
|
||||||
# Generate node.lib
|
# Generate node.lib
|
||||||
execute_process(COMMAND ${CMAKE_AR} /def:${CMAKE_JS_NODELIB_DEF} /out:${CMAKE_JS_NODELIB_TARGET} ${CMAKE_STATIC_LINKER_FLAGS})
|
execute_process(COMMAND ${CMAKE_AR} /def:${CMAKE_JS_NODELIB_DEF} /out:${CMAKE_JS_NODELIB_TARGET} ${CMAKE_STATIC_LINKER_FLAGS})
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -28,7 +28,7 @@ lavalink:
|
||||||
plugins:
|
plugins:
|
||||||
- dependency: "com.github.esmBot:lava-xm-plugin:v0.2.1"
|
- dependency: "com.github.esmBot:lava-xm-plugin:v0.2.1"
|
||||||
repository: "https://jitpack.io"
|
repository: "https://jitpack.io"
|
||||||
- dependency: "com.github.TopiSenpai.LavaSrc:lavasrc-plugin:3.1.7"
|
- dependency: "com.github.TopiSenpai.LavaSrc:lavasrc-plugin:3.2.0"
|
||||||
repository: "https://jitpack.io"
|
repository: "https://jitpack.io"
|
||||||
|
|
||||||
plugins:
|
plugins:
|
||||||
|
|
BIN
assets/images/scottmap.png
Normal file
BIN
assets/images/scottmap.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 133 KiB |
|
@ -25,7 +25,9 @@ class ImageCommand extends Command {
|
||||||
|
|
||||||
const imageParams = {
|
const imageParams = {
|
||||||
cmd: this.constructor.command,
|
cmd: this.constructor.command,
|
||||||
params: {},
|
params: {
|
||||||
|
togif: !!this.options.togif
|
||||||
|
},
|
||||||
id: (this.interaction ?? this.message).id
|
id: (this.interaction ?? this.message).id
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -129,6 +131,11 @@ class ImageCommand extends Command {
|
||||||
description: "An image/GIF URL"
|
description: "An image/GIF URL"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
this.flags.push({
|
||||||
|
name: "togif",
|
||||||
|
type: 5,
|
||||||
|
description: "Force GIF output"
|
||||||
|
});
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,11 @@ class EvalCommand extends Command {
|
||||||
const sendString = `\`\`\`js\n${cleaned}\n\`\`\``;
|
const sendString = `\`\`\`js\n${cleaned}\n\`\`\``;
|
||||||
if (sendString.length >= 2000) {
|
if (sendString.length >= 2000) {
|
||||||
return {
|
return {
|
||||||
text: "The result was too large, so here it is as a file:",
|
content: "The result was too large, so here it is as a file:",
|
||||||
file: cleaned,
|
files: [{
|
||||||
|
contents: cleaned,
|
||||||
name: "result.txt"
|
name: "result.txt"
|
||||||
|
}]
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return sendString;
|
return sendString;
|
||||||
|
|
|
@ -7,7 +7,7 @@ class RestartCommand extends Command {
|
||||||
this.success = false;
|
this.success = false;
|
||||||
return "Only the bot owner can restart me!";
|
return "Only the bot owner can restart me!";
|
||||||
}
|
}
|
||||||
await this.message.channel.createMessage(Object.assign({
|
await this.channel.createMessage(Object.assign({
|
||||||
content: "esmBot is restarting."
|
content: "esmBot is restarting."
|
||||||
}, this.reference));
|
}, this.reference));
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
import ImageCommand from "../../classes/imageCommand.js";
|
import ImageCommand from "../../classes/imageCommand.js";
|
||||||
|
|
||||||
class ExplodeCommand extends ImageCommand {
|
class ExplodeCommand extends ImageCommand {
|
||||||
params = {
|
|
||||||
amount: -1
|
|
||||||
};
|
|
||||||
|
|
||||||
static description = "Explodes an image";
|
static description = "Explodes an image";
|
||||||
static aliases = ["exp"];
|
static aliases = ["exp"];
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import ImageCommand from "../../classes/imageCommand.js";
|
||||||
|
|
||||||
class ImplodeCommand extends ImageCommand {
|
class ImplodeCommand extends ImageCommand {
|
||||||
params = {
|
params = {
|
||||||
amount: 1
|
implode: true
|
||||||
};
|
};
|
||||||
|
|
||||||
static description = "Implodes an image";
|
static description = "Implodes an image";
|
||||||
|
|
|
@ -128,7 +128,6 @@
|
||||||
"$19 Fortnite Card",
|
"$19 Fortnite Card",
|
||||||
"Wild Woody",
|
"Wild Woody",
|
||||||
"RDI Halcyon",
|
"RDI Halcyon",
|
||||||
"cry about it",
|
|
||||||
"KFC",
|
"KFC",
|
||||||
"Cave Story",
|
"Cave Story",
|
||||||
"YouTube ads",
|
"YouTube ads",
|
||||||
|
@ -159,7 +158,6 @@
|
||||||
"Item Asylum",
|
"Item Asylum",
|
||||||
"TIC-80",
|
"TIC-80",
|
||||||
"Ghetto Smosh",
|
"Ghetto Smosh",
|
||||||
"brought to you by the DFS project",
|
|
||||||
"Splatoon 3",
|
"Splatoon 3",
|
||||||
"changed",
|
"changed",
|
||||||
"Chutes and Ladders",
|
"Chutes and Ladders",
|
||||||
|
@ -196,6 +194,9 @@
|
||||||
"ANTONBLAST",
|
"ANTONBLAST",
|
||||||
"[object Object]",
|
"[object Object]",
|
||||||
"Xonotic",
|
"Xonotic",
|
||||||
|
"Lario",
|
||||||
|
"Hi-Fi Rush",
|
||||||
|
"Calckey",
|
||||||
"The clock is ticking."
|
"The clock is ticking."
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ As you can see, each command is grouped into categories, which are represented b
|
||||||
!!! tip
|
!!! tip
|
||||||
The `message` category is special; commands in here act as right-click context menu message commands instead of "classic" or slash commands.
|
The `message` category is special; commands in here act as right-click context menu message commands instead of "classic" or slash commands.
|
||||||
|
|
||||||
## Commnand Structure
|
## Command Structure
|
||||||
It's recommended to use the `Command` class located in `classes/command.js` to create a new command in most cases. This class provides various parameters and fields that will likely be useful when creating a command. Here is a simple example of a working command file:
|
It's recommended to use the `Command` class located in `classes/command.js` to create a new command in most cases. This class provides various parameters and fields that will likely be useful when creating a command. Here is a simple example of a working command file:
|
||||||
```js
|
```js
|
||||||
import Command from "../../classes/command.js";
|
import Command from "../../classes/command.js";
|
||||||
|
|
6
events/guildCreate.js
Normal file
6
events/guildCreate.js
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import { log } from "../utils/logger.js";
|
||||||
|
|
||||||
|
// run when the bot is added to a guild
|
||||||
|
export default async (client, guild) => {
|
||||||
|
log(`[GUILD JOIN] ${guild.name} (${guild.id}) added the bot.`);
|
||||||
|
};
|
|
@ -1,6 +1,7 @@
|
||||||
import { players, queues, skipVotes } from "../utils/soundplayer.js";
|
import { players, queues, skipVotes } from "../utils/soundplayer.js";
|
||||||
import AwaitRejoin from "../utils/awaitrejoin.js";
|
import AwaitRejoin from "../utils/awaitrejoin.js";
|
||||||
import { random } from "../utils/misc.js";
|
import { random } from "../utils/misc.js";
|
||||||
|
import { logger } from "../utils/logger.js";
|
||||||
|
|
||||||
const isWaiting = new Map();
|
const isWaiting = new Map();
|
||||||
|
|
||||||
|
@ -16,9 +17,10 @@ export default async (client, member, oldChannel) => {
|
||||||
content: "🔊 Waiting 10 seconds for someone to return..."
|
content: "🔊 Waiting 10 seconds for someone to return..."
|
||||||
});
|
});
|
||||||
const awaitRejoin = new AwaitRejoin(oldChannel, true, member.id);
|
const awaitRejoin = new AwaitRejoin(oldChannel, true, member.id);
|
||||||
awaitRejoin.on("end", async (rejoined, newMember) => {
|
awaitRejoin.once("end", async (rejoined, newMember, cancel) => {
|
||||||
isWaiting.delete(oldChannel.id);
|
isWaiting.delete(oldChannel.id);
|
||||||
if (rejoined) {
|
if (rejoined) {
|
||||||
|
if (cancel) return;
|
||||||
connection.player.setPaused(false);
|
connection.player.setPaused(false);
|
||||||
if (member.id !== newMember.id) {
|
if (member.id !== newMember.id) {
|
||||||
players.set(connection.voiceChannel.guildID, { player: connection.player, type: connection.type, host: newMember.id, voiceChannel: connection.voiceChannel, originalChannel: connection.originalChannel, loop: connection.loop, shuffle: connection.shuffle, playMessage: connection.playMessage });
|
players.set(connection.voiceChannel.guildID, { player: connection.player, type: connection.type, host: newMember.id, voiceChannel: connection.voiceChannel, originalChannel: connection.originalChannel, loop: connection.loop, shuffle: connection.shuffle, playMessage: connection.playMessage });
|
||||||
|
@ -29,19 +31,20 @@ export default async (client, member, oldChannel) => {
|
||||||
try {
|
try {
|
||||||
await waitMessage.delete();
|
await waitMessage.delete();
|
||||||
} catch {
|
} catch {
|
||||||
// no-op
|
logger.warn(`Failed to delete wait message ${waitMessage.id}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
if (waitMessage.channel.messages.has(waitMessage.id)) await waitMessage.delete();
|
if (waitMessage.channel.messages.has(waitMessage.id)) await waitMessage.delete();
|
||||||
} catch {
|
} catch {
|
||||||
// no-op
|
logger.warn(`Failed to delete wait message ${waitMessage.id}`);
|
||||||
}
|
}
|
||||||
|
if (cancel) return;
|
||||||
try {
|
try {
|
||||||
connection.player.node.leaveChannel(connection.originalChannel.guildID);
|
connection.player.node.leaveChannel(connection.originalChannel.guildID);
|
||||||
} catch {
|
} catch {
|
||||||
// no-op
|
logger.warn(`Failed to leave voice channel ${connection.originalChannel.guildID}`);
|
||||||
}
|
}
|
||||||
players.delete(connection.originalChannel.guildID);
|
players.delete(connection.originalChannel.guildID);
|
||||||
queues.delete(connection.originalChannel.guildID);
|
queues.delete(connection.originalChannel.guildID);
|
||||||
|
@ -58,13 +61,13 @@ export default async (client, member, oldChannel) => {
|
||||||
content: "🔊 Waiting 10 seconds for the host to return..."
|
content: "🔊 Waiting 10 seconds for the host to return..."
|
||||||
});
|
});
|
||||||
const awaitRejoin = new AwaitRejoin(oldChannel, false, member.id);
|
const awaitRejoin = new AwaitRejoin(oldChannel, false, member.id);
|
||||||
awaitRejoin.on("end", async (rejoined) => {
|
awaitRejoin.once("end", async (rejoined) => {
|
||||||
isWaiting.delete(oldChannel.id);
|
isWaiting.delete(oldChannel.id);
|
||||||
if (rejoined) {
|
if (rejoined) {
|
||||||
try {
|
try {
|
||||||
if (waitMessage.channel.messages.has(waitMessage.id)) await waitMessage.delete();
|
if (waitMessage.channel.messages.has(waitMessage.id)) await waitMessage.delete();
|
||||||
} catch {
|
} catch {
|
||||||
// no-op
|
logger.warn(`Failed to delete wait message ${waitMessage.id}`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const members = oldChannel.voiceMembers.filter((i) => i.id !== client.user.id && !i.bot);
|
const members = oldChannel.voiceMembers.filter((i) => i.id !== client.user.id && !i.bot);
|
||||||
|
@ -72,12 +75,12 @@ export default async (client, member, oldChannel) => {
|
||||||
try {
|
try {
|
||||||
if (waitMessage.channel.messages.has(waitMessage.id)) await waitMessage.delete();
|
if (waitMessage.channel.messages.has(waitMessage.id)) await waitMessage.delete();
|
||||||
} catch {
|
} catch {
|
||||||
// no-op
|
logger.warn(`Failed to delete wait message ${waitMessage.id}`);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
connection.player.node.leaveChannel(connection.originalChannel.guildID);
|
connection.player.node.leaveChannel(connection.originalChannel.guildID);
|
||||||
} catch {
|
} catch {
|
||||||
// no-op
|
logger.warn(`Failed to leave voice channel ${connection.originalChannel.guildID}`);
|
||||||
}
|
}
|
||||||
players.delete(connection.originalChannel.guildID);
|
players.delete(connection.originalChannel.guildID);
|
||||||
queues.delete(connection.originalChannel.guildID);
|
queues.delete(connection.originalChannel.guildID);
|
||||||
|
@ -99,7 +102,7 @@ export default async (client, member, oldChannel) => {
|
||||||
try {
|
try {
|
||||||
connection.player.node.leaveChannel(connection.originalChannel.guildID);
|
connection.player.node.leaveChannel(connection.originalChannel.guildID);
|
||||||
} catch {
|
} catch {
|
||||||
// no-op
|
logger.warn(`Failed to leave voice channel ${connection.originalChannel.guildID}`);
|
||||||
}
|
}
|
||||||
players.delete(connection.originalChannel.guildID);
|
players.delete(connection.originalChannel.guildID);
|
||||||
queues.delete(connection.originalChannel.guildID);
|
queues.delete(connection.originalChannel.guildID);
|
||||||
|
|
|
@ -2,7 +2,7 @@ site_name: esmBot
|
||||||
docs_dir: docs/
|
docs_dir: docs/
|
||||||
repo_name: 'esmBot/esmBot'
|
repo_name: 'esmBot/esmBot'
|
||||||
repo_url: 'https://github.com/esmBot/esmBot'
|
repo_url: 'https://github.com/esmBot/esmBot'
|
||||||
copyright: Copyright © 2018 - 2022 <a href="https://essem.space">Essem</a>
|
copyright: Copyright © 2018 - 2023 <a href="https://essem.space">Essem</a>
|
||||||
nav:
|
nav:
|
||||||
- Home: index.md
|
- Home: index.md
|
||||||
- setup.md
|
- setup.md
|
||||||
|
|
|
@ -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, string *outType, 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()) in = in.bandjoin(255);
|
if (!in.has_alpha()) in = in.bandjoin(255);
|
||||||
|
@ -25,7 +25,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(("." + *outType).c_str(), &buf, DataSize);
|
||||||
|
|
||||||
return (char *)buf;
|
return (char *)buf;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Blur(string* type, char* BufferData, size_t BufferLength,
|
char* Blur(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -7,28 +7,29 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace vips;
|
using namespace vips;
|
||||||
|
|
||||||
char *Bounce(string *type, char *BufferData, size_t BufferLength,
|
char *Bounce(string type, string *outType, char *BufferData,
|
||||||
ArgumentMap Arguments, size_t *DataSize) {
|
size_t BufferLength, [[maybe_unused]] ArgumentMap Arguments,
|
||||||
|
size_t *DataSize) {
|
||||||
VOption *options = VImage::option();
|
VOption *options = VImage::option();
|
||||||
|
|
||||||
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()) in = in.bandjoin(255);
|
if (!in.has_alpha()) in = in.bandjoin(255);
|
||||||
|
|
||||||
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()) : 15;
|
int nPages = type == "gif" ? vips_image_get_n_pages(in.get_image()) : 15;
|
||||||
double mult = M_PI / nPages;
|
double mult = M_PI / nPages;
|
||||||
int halfHeight = pageHeight / 2;
|
int halfHeight = pageHeight / 2;
|
||||||
|
|
||||||
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;
|
||||||
double height = halfHeight * ((abs(sin(i * mult)) * -1) + 1);
|
double height = halfHeight * ((abs(sin(i * mult)) * -1) + 1);
|
||||||
VImage embedded =
|
VImage embedded =
|
||||||
img_frame.embed(0, height, width, pageHeight + halfHeight);
|
img_frame.embed(0, height, width, pageHeight + halfHeight);
|
||||||
|
@ -36,7 +37,7 @@ char *Bounce(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, pageHeight + halfHeight);
|
final.set(VIPS_META_PAGE_HEIGHT, pageHeight + halfHeight);
|
||||||
if (*type != "gif") {
|
if (type != "gif") {
|
||||||
vector<int> delay(30, 50);
|
vector<int> delay(30, 50);
|
||||||
final.set("delay", delay);
|
final.set("delay", delay);
|
||||||
}
|
}
|
||||||
|
@ -44,7 +45,7 @@ char *Bounce(string *type, char *BufferData, size_t BufferLength,
|
||||||
void *buf;
|
void *buf;
|
||||||
final.write_to_buffer(".gif", &buf, DataSize);
|
final.write_to_buffer(".gif", &buf, DataSize);
|
||||||
|
|
||||||
*type = "gif";
|
*outType = "gif";
|
||||||
|
|
||||||
return (char *)buf;
|
return (char *)buf;
|
||||||
}
|
}
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Bounce(string* type, char* BufferData, size_t BufferLength,
|
char* Bounce(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -6,8 +6,8 @@
|
||||||
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, string *outType, char *BufferData,
|
||||||
ArgumentMap Arguments, size_t *DataSize) {
|
size_t BufferLength, ArgumentMap Arguments, size_t *DataSize) {
|
||||||
string caption = GetArgument<string>(Arguments, "caption");
|
string caption = GetArgument<string>(Arguments, "caption");
|
||||||
string font = GetArgument<string>(Arguments, "font");
|
string font = GetArgument<string>(Arguments, "font");
|
||||||
string basePath = GetArgument<string>(Arguments, "basePath");
|
string basePath = GetArgument<string>(Arguments, "basePath");
|
||||||
|
@ -16,7 +16,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()) in = in.bandjoin(255);
|
if (!in.has_alpha()) in = in.bandjoin(255);
|
||||||
|
@ -57,7 +57,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));
|
||||||
|
@ -68,8 +68,9 @@ 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,
|
("." + *outType).c_str(), &buf, DataSize,
|
||||||
*type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
*outType == "gif"
|
||||||
|
? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||||
: 0);
|
: 0);
|
||||||
|
|
||||||
return (char *)buf;
|
return (char *)buf;
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Caption(string* type, char* BufferData, size_t BufferLength,
|
char* Caption(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -7,8 +7,8 @@
|
||||||
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, string *outType, char *BufferData,
|
||||||
ArgumentMap Arguments, size_t *DataSize) {
|
size_t BufferLength, ArgumentMap Arguments, size_t *DataSize) {
|
||||||
bool top = GetArgument<bool>(Arguments, "top");
|
bool top = GetArgument<bool>(Arguments, "top");
|
||||||
string caption = GetArgument<string>(Arguments, "caption");
|
string caption = GetArgument<string>(Arguments, "caption");
|
||||||
string font = GetArgument<string>(Arguments, "font");
|
string font = GetArgument<string>(Arguments, "font");
|
||||||
|
@ -18,7 +18,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()) in = in.bandjoin(255);
|
if (!in.has_alpha()) in = in.bandjoin(255);
|
||||||
|
@ -58,7 +58,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,
|
||||||
|
@ -72,8 +72,9 @@ 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,
|
("." + *outType).c_str(), &buf, DataSize,
|
||||||
*type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
*outType == "gif"
|
||||||
|
? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||||
: 0);
|
: 0);
|
||||||
|
|
||||||
return (char *)buf;
|
return (char *)buf;
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* CaptionTwo(string* type, char* BufferData, size_t BufferLength,
|
char* CaptionTwo(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -11,8 +11,9 @@
|
||||||
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, string *outType, char *BufferData,
|
||||||
ArgumentMap Arguments, size_t *DataSize) {
|
size_t BufferLength, [[maybe_unused]] ArgumentMap Arguments,
|
||||||
|
size_t *DataSize) {
|
||||||
Blob blob;
|
Blob blob;
|
||||||
|
|
||||||
list<Image> frames;
|
list<Image> frames;
|
||||||
|
@ -29,13 +30,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(*outType);
|
||||||
blurred.push_back(image);
|
blurred.push_back(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
optimizeTransparency(blurred.begin(), blurred.end());
|
optimizeTransparency(blurred.begin(), blurred.end());
|
||||||
|
|
||||||
if (*type == "gif") {
|
if (*outType == "gif") {
|
||||||
for (Image &image : blurred) {
|
for (Image &image : blurred) {
|
||||||
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
|
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
|
||||||
image.quantize();
|
image.quantize();
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Circle(string* type, char* BufferData, size_t BufferLength,
|
char* Circle(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
26
natives/cli/image.cc
Normal file
26
natives/cli/image.cc
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#include <cstring>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "../common.h"
|
||||||
|
|
||||||
|
void showUsage(char *path) {
|
||||||
|
std::cout << "Usage: " << path << " operation [--arg=\"param\"] [...]" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
if (argc < 1 ||
|
||||||
|
(argc == 1 && !strcmp(argv[1], "-h"))) {
|
||||||
|
showUsage(argv[0]);
|
||||||
|
#ifdef _WIN32
|
||||||
|
system("PAUSE");
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *op = argv[1];
|
||||||
|
|
||||||
|
//handleArguments(argc, argv);
|
||||||
|
|
||||||
|
std::cout << "This does nothing yet, but it might in the future!" << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -10,15 +10,15 @@ 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, string *outType, char *BufferData,
|
||||||
ArgumentMap Arguments, size_t *DataSize) {
|
size_t BufferLength, ArgumentMap Arguments, size_t *DataSize) {
|
||||||
string color = GetArgument<string>(Arguments, "color");
|
string color = GetArgument<string>(Arguments, "color");
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
VImage out;
|
VImage out;
|
||||||
|
@ -30,7 +30,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(("." + *outType).c_str(), &buf, DataSize);
|
||||||
|
|
||||||
return (char *)buf;
|
return (char *)buf;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Colors(string* type, char* BufferData, size_t BufferLength,
|
char* Colors(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -12,6 +12,46 @@ using std::variant;
|
||||||
typedef variant<string, float, bool, int> ArgumentVariant;
|
typedef variant<string, float, bool, int> ArgumentVariant;
|
||||||
typedef map<string, ArgumentVariant> ArgumentMap;
|
typedef map<string, ArgumentVariant> ArgumentMap;
|
||||||
|
|
||||||
|
#include "blur.h"
|
||||||
|
#include "bounce.h"
|
||||||
|
#include "caption.h"
|
||||||
|
#include "caption2.h"
|
||||||
|
#include "circle.h"
|
||||||
|
#include "colors.h"
|
||||||
|
#include "crop.h"
|
||||||
|
#include "deepfry.h"
|
||||||
|
#include "explode.h"
|
||||||
|
#include "flag.h"
|
||||||
|
#include "flip.h"
|
||||||
|
#include "freeze.h"
|
||||||
|
#include "gamexplain.h"
|
||||||
|
#include "globe.h"
|
||||||
|
#include "homebrew.h"
|
||||||
|
#include "invert.h"
|
||||||
|
#include "jpeg.h"
|
||||||
|
#include "magik.h"
|
||||||
|
#include "meme.h"
|
||||||
|
#include "mirror.h"
|
||||||
|
#include "motivate.h"
|
||||||
|
#include "reddit.h"
|
||||||
|
#include "resize.h"
|
||||||
|
#include "reverse.h"
|
||||||
|
#include "scott.h"
|
||||||
|
#include "snapchat.h"
|
||||||
|
#include "sonic.h"
|
||||||
|
#include "speed.h"
|
||||||
|
#include "spin.h"
|
||||||
|
#include "squish.h"
|
||||||
|
#include "swirl.h"
|
||||||
|
#include "tile.h"
|
||||||
|
#include "togif.h"
|
||||||
|
#include "uncanny.h"
|
||||||
|
#include "uncaption.h"
|
||||||
|
#include "wall.h"
|
||||||
|
#include "watermark.h"
|
||||||
|
#include "whisper.h"
|
||||||
|
#include "zamn.h"
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T GetArgument(ArgumentMap map, string key) {
|
T GetArgument(ArgumentMap map, string key) {
|
||||||
try {
|
try {
|
||||||
|
@ -43,3 +83,48 @@ const std::unordered_map<std::string, std::string> fontPaths{
|
||||||
{"futura", "assets/fonts/caption.otf"},
|
{"futura", "assets/fonts/caption.otf"},
|
||||||
{"helvetica", "assets/fonts/caption2.ttf"},
|
{"helvetica", "assets/fonts/caption2.ttf"},
|
||||||
{"roboto", "assets/fonts/reddit.ttf"}};
|
{"roboto", "assets/fonts/reddit.ttf"}};
|
||||||
|
|
||||||
|
const std::map<std::string,
|
||||||
|
char* (*)(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
|
ArgumentMap Arguments, size_t* DataSize)>
|
||||||
|
FunctionMap = {{"blur", &Blur},
|
||||||
|
{"bounce", &Bounce},
|
||||||
|
{"caption", &Caption},
|
||||||
|
{"captionTwo", &CaptionTwo},
|
||||||
|
{"circle", &Circle},
|
||||||
|
{"colors", &Colors},
|
||||||
|
{"crop", &Crop},
|
||||||
|
{"deepfry", &Deepfry},
|
||||||
|
{"explode", &Explode},
|
||||||
|
{"flag", &Flag},
|
||||||
|
{"flip", &Flip},
|
||||||
|
{"freeze", &Freeze},
|
||||||
|
{"gamexplain", Gamexplain},
|
||||||
|
{"globe", Globe},
|
||||||
|
{"invert", Invert},
|
||||||
|
{"jpeg", Jpeg},
|
||||||
|
{"magik", Magik},
|
||||||
|
{"meme", Meme},
|
||||||
|
{"mirror", Mirror},
|
||||||
|
{"motivate", Motivate},
|
||||||
|
{"reddit", Reddit},
|
||||||
|
{"resize", Resize},
|
||||||
|
{"reverse", Reverse},
|
||||||
|
{"scott", Scott},
|
||||||
|
{"snapchat", Snapchat},
|
||||||
|
{"speed", &Speed},
|
||||||
|
{"spin", Spin},
|
||||||
|
{"squish", Squish},
|
||||||
|
{"swirl", Swirl},
|
||||||
|
{"tile", Tile},
|
||||||
|
{"togif", ToGif},
|
||||||
|
{"uncanny", Uncanny},
|
||||||
|
{"uncaption", &Uncaption},
|
||||||
|
{"wall", Wall},
|
||||||
|
{"watermark", &Watermark},
|
||||||
|
{"whisper", Whisper},
|
||||||
|
{"zamn", Zamn}};
|
||||||
|
|
||||||
|
const std::map<std::string,
|
||||||
|
char* (*)(string type, string* outType, ArgumentMap Arguments, size_t* DataSize)>
|
||||||
|
NoInputFunctionMap = {{"homebrew", Homebrew}, {"sonic", Sonic}};
|
|
@ -7,13 +7,13 @@
|
||||||
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, string *outType, char *BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t *DataSize) {
|
[[maybe_unused]] 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,9 @@ 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,
|
("." + *outType).c_str(), &buf, DataSize,
|
||||||
*type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
*outType == "gif"
|
||||||
|
? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||||
: 0);
|
: 0);
|
||||||
|
|
||||||
return (char *)buf;
|
return (char *)buf;
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Crop(string* type, char* BufferData, size_t BufferLength,
|
char* Crop(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -6,13 +6,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, string *outType, char *BufferData,
|
||||||
ArgumentMap Arguments, size_t *DataSize) {
|
size_t BufferLength, [[maybe_unused]] 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()) in = in.bandjoin(255);
|
if (!in.has_alpha()) in = in.bandjoin(255);
|
||||||
|
@ -25,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);
|
||||||
|
@ -48,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") final.set("delay", fried.get_array_int("delay"));
|
if (type == "gif") final.set("delay", fried.get_array_int("delay"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void *buf;
|
void *buf;
|
||||||
final.write_to_buffer(
|
final.write_to_buffer(
|
||||||
("." + *type).c_str(), &buf, DataSize,
|
("." + *outType).c_str(), &buf, DataSize,
|
||||||
*type == "gif" ? VImage::option()->set("dither", 0) : 0);
|
*outType == "gif" ? VImage::option()->set("dither", 0) : 0);
|
||||||
|
|
||||||
return (char *)buf;
|
return (char *)buf;
|
||||||
}
|
}
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Deepfry(string* type, char* BufferData, size_t BufferLength,
|
char* Deepfry(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -1,58 +1,52 @@
|
||||||
|
#include <vips/vips8>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#include <Magick++.h>
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include <iostream>
|
|
||||||
#include <list>
|
|
||||||
#include <map>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace Magick;
|
using namespace vips;
|
||||||
|
|
||||||
char *Explode(string *type, char *BufferData, size_t BufferLength,
|
char *Explode(string type, string *outType, char *BufferData,
|
||||||
ArgumentMap Arguments, size_t *DataSize) {
|
size_t BufferLength, ArgumentMap Arguments, size_t *DataSize) {
|
||||||
|
bool implode = GetArgument<bool>(Arguments, "implode");
|
||||||
|
string basePath = GetArgument<string>(Arguments, "basePath");
|
||||||
|
|
||||||
int amount = GetArgument<int>(Arguments, "amount");
|
VOption *options = VImage::option();
|
||||||
int delay = GetArgumentWithFallback<int>(Arguments, "delay", 0);
|
|
||||||
|
|
||||||
Blob blob;
|
VImage in =
|
||||||
|
VImage::new_from_buffer(
|
||||||
|
BufferData, BufferLength, "",
|
||||||
|
type == "gif" ? options->set("n", -1)->set("access", "sequential")
|
||||||
|
: options)
|
||||||
|
.colourspace(VIPS_INTERPRETATION_sRGB);
|
||||||
|
if (!in.has_alpha()) in = in.bandjoin(255);
|
||||||
|
|
||||||
list<Image> frames;
|
int width = in.width();
|
||||||
list<Image> coalesced;
|
int pageHeight = vips_image_get_page_height(in.get_image());
|
||||||
list<Image> blurred;
|
int nPages = vips_image_get_n_pages(in.get_image());
|
||||||
try {
|
|
||||||
readImages(&frames, Blob(BufferData, BufferLength));
|
string distortPath = basePath + "assets/images/" +
|
||||||
} catch (Magick::WarningCoder &warning) {
|
(implode ? "linearimplode.png" : "linearexplode.png");
|
||||||
cerr << "Coder Warning: " << warning.what() << endl;
|
VImage distort =
|
||||||
} catch (Magick::Warning &warning) {
|
(VImage::new_from_file(distortPath.c_str())
|
||||||
cerr << "Warning: " << warning.what() << endl;
|
.resize(width / 500.0, VImage::option()
|
||||||
|
->set("vscale", pageHeight / 500.0)
|
||||||
|
->set("kernel", VIPS_KERNEL_CUBIC)) /
|
||||||
|
65535);
|
||||||
|
|
||||||
|
VImage distortImage = (distort[0] * width).bandjoin(distort[1] * pageHeight);
|
||||||
|
|
||||||
|
vector<VImage> img;
|
||||||
|
for (int i = 0; i < nPages; i++) {
|
||||||
|
VImage img_frame =
|
||||||
|
type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
|
||||||
|
VImage mapped = img_frame.mapim(distortImage);
|
||||||
|
img.push_back(mapped);
|
||||||
}
|
}
|
||||||
coalesceImages(&coalesced, frames.begin(), frames.end());
|
VImage final = VImage::arrayjoin(img, VImage::option()->set("across", 1));
|
||||||
|
final.set(VIPS_META_PAGE_HEIGHT, pageHeight);
|
||||||
|
|
||||||
for (Image &image : coalesced) {
|
void *buf;
|
||||||
image.implode(amount);
|
final.write_to_buffer(("." + *outType).c_str(), &buf, DataSize);
|
||||||
image.magick(*type);
|
|
||||||
blurred.push_back(image);
|
return (char *)buf;
|
||||||
}
|
|
||||||
|
|
||||||
optimizeTransparency(blurred.begin(), blurred.end());
|
|
||||||
|
|
||||||
if (*type == "gif") {
|
|
||||||
for (Image &image : blurred) {
|
|
||||||
image.quantizeDither(false);
|
|
||||||
image.quantize();
|
|
||||||
if (delay != 0) image.animationDelay(delay);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
writeImages(blurred.begin(), blurred.end(), &blob);
|
|
||||||
|
|
||||||
*DataSize = blob.length();
|
|
||||||
|
|
||||||
// workaround because the data is tied to the blob
|
|
||||||
char *data = (char *)malloc(*DataSize);
|
|
||||||
memcpy(data, blob.data(), *DataSize);
|
|
||||||
return data;
|
|
||||||
}
|
}
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Explode(string* type, char* BufferData, size_t BufferLength,
|
char* Explode(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -5,7 +5,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, string *outType, 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");
|
||||||
string basePath = GetArgument<string>(Arguments, "basePath");
|
string basePath = GetArgument<string>(Arguments, "basePath");
|
||||||
|
@ -14,7 +14,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()) in = in.bandjoin(255);
|
if (!in.has_alpha()) in = in.bandjoin(255);
|
||||||
|
@ -40,8 +40,9 @@ 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,
|
("." + *outType).c_str(), &buf, DataSize,
|
||||||
*type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
*outType == "gif"
|
||||||
|
? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||||
: 0);
|
: 0);
|
||||||
|
|
||||||
return (char *)buf;
|
return (char *)buf;
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Flag(string* type, char* BufferData, size_t BufferLength,
|
char* Flag(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -6,12 +6,12 @@
|
||||||
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, string *outType, 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)
|
||||||
|
@ -21,7 +21,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());
|
||||||
|
@ -39,8 +39,9 @@ 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,
|
("." + *outType).c_str(), &buf, DataSize,
|
||||||
*type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
*outType == "gif"
|
||||||
|
? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||||
: 0);
|
: 0);
|
||||||
|
|
||||||
return (char *)buf;
|
return (char *)buf;
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Flip(string* type, char* BufferData, size_t BufferLength,
|
char* Flip(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -7,8 +7,8 @@
|
||||||
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, string *outType, char *BufferData,
|
||||||
ArgumentMap Arguments, size_t *DataSize) {
|
size_t BufferLength, ArgumentMap Arguments, size_t *DataSize) {
|
||||||
bool loop = GetArgumentWithFallback<bool>(Arguments, "loop", false);
|
bool loop = GetArgumentWithFallback<bool>(Arguments, "loop", false);
|
||||||
int frame = GetArgumentWithFallback<int>(Arguments, "frame", -1);
|
int frame = GetArgumentWithFallback<int>(Arguments, "frame", -1);
|
||||||
|
|
||||||
|
@ -46,9 +46,9 @@ char *Freeze(string *type, char *BufferData, size_t BufferLength,
|
||||||
} else if (frame >= 0 && !loop) {
|
} else if (frame >= 0 && !loop) {
|
||||||
VOption *options = VImage::option()->set("access", "sequential");
|
VOption *options = VImage::option()->set("access", "sequential");
|
||||||
|
|
||||||
VImage in = VImage::new_from_buffer(
|
VImage in =
|
||||||
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()) in = in.bandjoin(255);
|
if (!in.has_alpha()) in = in.bandjoin(255);
|
||||||
|
|
||||||
|
@ -60,7 +60,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(("." + *outType).c_str(), &buf, DataSize);
|
||||||
|
|
||||||
return (char *)buf;
|
return (char *)buf;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Freeze(string* type, char* BufferData, size_t BufferLength,
|
char* Freeze(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -5,15 +5,15 @@
|
||||||
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, string *outType, char *BufferData,
|
||||||
ArgumentMap Arguments, size_t *DataSize) {
|
size_t BufferLength, ArgumentMap Arguments, size_t *DataSize) {
|
||||||
string basePath = GetArgument<string>(Arguments, "basePath");
|
string basePath = GetArgument<string>(Arguments, "basePath");
|
||||||
|
|
||||||
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()) in = in.bandjoin(255);
|
if (!in.has_alpha()) in = in.bandjoin(255);
|
||||||
|
|
||||||
|
@ -27,7 +27,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,
|
||||||
|
@ -41,8 +41,9 @@ 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,
|
("." + *outType).c_str(), &buf, DataSize,
|
||||||
*type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
*outType == "gif"
|
||||||
|
? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||||
: 0);
|
: 0);
|
||||||
|
|
||||||
return (char *)buf;
|
return (char *)buf;
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Gamexplain(string* type, char* BufferData, size_t BufferLength,
|
char* Gamexplain(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -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, string *outType, 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,14 +14,14 @@ 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()) in = in.bandjoin(255);
|
if (!in.has_alpha()) in = in.bandjoin(255);
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
@ -47,7 +47,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));
|
||||||
|
@ -61,7 +61,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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Globe(string* type, char* BufferData, size_t BufferLength,
|
char* Globe(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -5,7 +5,8 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace vips;
|
using namespace vips;
|
||||||
|
|
||||||
char *Homebrew(string *type, ArgumentMap Arguments, size_t *DataSize) {
|
char *Homebrew(string type, string *outType, ArgumentMap Arguments,
|
||||||
|
size_t *DataSize) {
|
||||||
string caption = GetArgument<string>(Arguments, "caption");
|
string caption = GetArgument<string>(Arguments, "caption");
|
||||||
string basePath = GetArgument<string>(Arguments, "basePath");
|
string basePath = GetArgument<string>(Arguments, "basePath");
|
||||||
|
|
||||||
|
@ -30,9 +31,7 @@ char *Homebrew(string *type, ArgumentMap Arguments, size_t *DataSize) {
|
||||||
->set("y", 300 - (text.height() / 2) - 8));
|
->set("y", 300 - (text.height() / 2) - 8));
|
||||||
|
|
||||||
void *buf;
|
void *buf;
|
||||||
out.write_to_buffer(".png", &buf, DataSize);
|
out.write_to_buffer(("." + *outType).c_str(), &buf, DataSize);
|
||||||
|
|
||||||
*type = "png";
|
|
||||||
|
|
||||||
return (char *)buf;
|
return (char *)buf;
|
||||||
}
|
}
|
|
@ -4,4 +4,4 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char *Homebrew(string *type, ArgumentMap Arguments, size_t *DataSize);
|
char *Homebrew(string type, string *outType, ArgumentMap Arguments, size_t *DataSize);
|
|
@ -5,13 +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, string *outType, char *BufferData,
|
||||||
ArgumentMap Arguments, size_t *DataSize) {
|
size_t BufferLength, [[maybe_unused]] 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()) in = in.bandjoin(255);
|
if (!in.has_alpha()) in = in.bandjoin(255);
|
||||||
|
|
||||||
|
@ -21,7 +22,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(("." + *outType).c_str(), &buf, DataSize);
|
||||||
|
|
||||||
return (char *)buf;
|
return (char *)buf;
|
||||||
}
|
}
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Invert(string* type, char* BufferData, size_t BufferLength,
|
char* Invert(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -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, string *outType, 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,13 +53,22 @@ char *Jpeg(string *type, char *BufferData, size_t BufferLength,
|
||||||
}
|
}
|
||||||
|
|
||||||
final.write_to_buffer(
|
final.write_to_buffer(
|
||||||
("." + *type).c_str(), &buf, DataSize,
|
("." + *outType).c_str(), &buf, DataSize,
|
||||||
*type == "gif" ? VImage::option()->set("dither", 0) : 0);
|
*outType == "gif" ? VImage::option()->set("dither", 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,
|
void *jpgBuf;
|
||||||
|
in.write_to_buffer(".jpg", &jpgBuf, DataSize,
|
||||||
VImage::option()->set("Q", quality)->set("strip", true));
|
VImage::option()->set("Q", quality)->set("strip", true));
|
||||||
*type = "jpg";
|
if (*outType == "gif") {
|
||||||
|
VImage gifIn = VImage::new_from_buffer((char *)jpgBuf, *DataSize, "");
|
||||||
|
gifIn.write_to_buffer(
|
||||||
|
".gif", &buf, DataSize,
|
||||||
|
VImage::option()->set("Q", quality)->set("strip", true));
|
||||||
|
} else {
|
||||||
|
*outType = "jpg";
|
||||||
|
buf = jpgBuf;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (char *)buf;
|
return (char *)buf;
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Jpeg(string* type, char* BufferData, size_t BufferLength,
|
char* Jpeg(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -9,8 +9,8 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace Magick;
|
using namespace Magick;
|
||||||
|
|
||||||
char *Magik(string *type, char *BufferData, size_t BufferLength,
|
char *Magik(string type, string *outType, char *BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t *DataSize) {
|
[[maybe_unused]] ArgumentMap Arguments, size_t *DataSize) {
|
||||||
Blob blob;
|
Blob blob;
|
||||||
|
|
||||||
list<Image> frames;
|
list<Image> frames;
|
||||||
|
@ -29,13 +29,13 @@ char *Magik(string *type, char *BufferData, size_t BufferLength,
|
||||||
image.scale(Geometry("350x350"));
|
image.scale(Geometry("350x350"));
|
||||||
image.liquidRescale(Geometry("175x175"));
|
image.liquidRescale(Geometry("175x175"));
|
||||||
image.liquidRescale(Geometry("350x350"));
|
image.liquidRescale(Geometry("350x350"));
|
||||||
image.magick(*type);
|
image.magick(*outType);
|
||||||
blurred.push_back(image);
|
blurred.push_back(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
optimizeTransparency(blurred.begin(), blurred.end());
|
optimizeTransparency(blurred.begin(), blurred.end());
|
||||||
|
|
||||||
if (*type == "gif") {
|
if (*outType == "gif") {
|
||||||
for (Image &image : blurred) {
|
for (Image &image : blurred) {
|
||||||
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
|
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
|
||||||
image.quantize();
|
image.quantize();
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Magik(string* type, char* BufferData, size_t BufferLength,
|
char* Magik(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -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, string *outType, 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()) in = in.bandjoin(255);
|
if (!in.has_alpha()) in = in.bandjoin(255);
|
||||||
|
|
||||||
|
@ -110,7 +110,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,
|
||||||
|
@ -130,8 +130,9 @@ 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,
|
("." + *outType).c_str(), &buf, DataSize,
|
||||||
*type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
*outType == "gif"
|
||||||
|
? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||||
: 0);
|
: 0);
|
||||||
|
|
||||||
return (char *)buf;
|
return (char *)buf;
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Meme(string* type, char* BufferData, size_t BufferLength,
|
char* Meme(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -5,8 +5,8 @@
|
||||||
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, string *outType, char *BufferData,
|
||||||
ArgumentMap Arguments, size_t *DataSize) {
|
size_t BufferLength, 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,14 +14,14 @@ 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()) in = in.bandjoin(255);
|
if (!in.has_alpha()) in = in.bandjoin(255);
|
||||||
|
|
||||||
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());
|
||||||
|
@ -58,7 +58,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(("." + *outType).c_str(), &buf, DataSize);
|
||||||
|
|
||||||
return (char *)buf;
|
return (char *)buf;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Mirror(string* type, char* BufferData, size_t BufferLength,
|
char* Mirror(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -5,8 +5,8 @@
|
||||||
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, string *outType, char *BufferData,
|
||||||
ArgumentMap Arguments, size_t *DataSize) {
|
size_t BufferLength, 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");
|
||||||
string font = GetArgument<string>(Arguments, "font");
|
string font = GetArgument<string>(Arguments, "font");
|
||||||
|
@ -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()) in = in.bandjoin(255);
|
if (!in.has_alpha()) in = in.bandjoin(255);
|
||||||
|
|
||||||
|
@ -69,7 +69,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;
|
||||||
|
@ -116,8 +116,8 @@ char *Motivate(string *type, char *BufferData, size_t BufferLength,
|
||||||
|
|
||||||
void *buf;
|
void *buf;
|
||||||
final.write_to_buffer(
|
final.write_to_buffer(
|
||||||
("." + *type).c_str(), &buf, DataSize,
|
("." + *outType).c_str(), &buf, DataSize,
|
||||||
*type == "gif" ? VImage::option()->set("dither", 1) : 0);
|
*outType == "gif" ? VImage::option()->set("dither", 1) : 0);
|
||||||
|
|
||||||
return (char *)buf;
|
return (char *)buf;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Motivate(string* type, char* BufferData, size_t BufferLength,
|
char* Motivate(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -4,46 +4,7 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "blur.h"
|
#include "../common.h"
|
||||||
#include "bounce.h"
|
|
||||||
#include "caption.h"
|
|
||||||
#include "caption2.h"
|
|
||||||
#include "circle.h"
|
|
||||||
#include "colors.h"
|
|
||||||
#include "common.h"
|
|
||||||
#include "crop.h"
|
|
||||||
#include "deepfry.h"
|
|
||||||
#include "explode.h"
|
|
||||||
#include "flag.h"
|
|
||||||
#include "flip.h"
|
|
||||||
#include "freeze.h"
|
|
||||||
#include "gamexplain.h"
|
|
||||||
#include "globe.h"
|
|
||||||
#include "homebrew.h"
|
|
||||||
#include "invert.h"
|
|
||||||
#include "jpeg.h"
|
|
||||||
#include "magik.h"
|
|
||||||
#include "meme.h"
|
|
||||||
#include "mirror.h"
|
|
||||||
#include "motivate.h"
|
|
||||||
#include "reddit.h"
|
|
||||||
#include "resize.h"
|
|
||||||
#include "reverse.h"
|
|
||||||
#include "scott.h"
|
|
||||||
#include "snapchat.h"
|
|
||||||
#include "sonic.h"
|
|
||||||
#include "speed.h"
|
|
||||||
#include "spin.h"
|
|
||||||
#include "squish.h"
|
|
||||||
#include "swirl.h"
|
|
||||||
#include "tile.h"
|
|
||||||
#include "togif.h"
|
|
||||||
#include "uncanny.h"
|
|
||||||
#include "uncaption.h"
|
|
||||||
#include "wall.h"
|
|
||||||
#include "watermark.h"
|
|
||||||
#include "whisper.h"
|
|
||||||
#include "zamn.h"
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <Magick++.h>
|
#include <Magick++.h>
|
||||||
|
@ -52,51 +13,6 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
std::map<std::string,
|
|
||||||
char* (*)(string* type, char* BufferData, size_t BufferLength,
|
|
||||||
ArgumentMap Arguments, size_t* DataSize)>
|
|
||||||
FunctionMap = {{"blur", &Blur},
|
|
||||||
{"bounce", &Bounce},
|
|
||||||
{"caption", &Caption},
|
|
||||||
{"captionTwo", &CaptionTwo},
|
|
||||||
{"circle", &Circle},
|
|
||||||
{"colors", &Colors},
|
|
||||||
{"crop", &Crop},
|
|
||||||
{"deepfry", &Deepfry},
|
|
||||||
{"explode", &Explode},
|
|
||||||
{"flag", &Flag},
|
|
||||||
{"flip", &Flip},
|
|
||||||
{"freeze", &Freeze},
|
|
||||||
{"gamexplain", Gamexplain},
|
|
||||||
{"globe", Globe},
|
|
||||||
{"invert", Invert},
|
|
||||||
{"jpeg", Jpeg},
|
|
||||||
{"magik", Magik},
|
|
||||||
{"meme", Meme},
|
|
||||||
{"mirror", Mirror},
|
|
||||||
{"motivate", Motivate},
|
|
||||||
{"reddit", Reddit},
|
|
||||||
{"resize", Resize},
|
|
||||||
{"reverse", Reverse},
|
|
||||||
{"scott", Scott},
|
|
||||||
{"snapchat", Snapchat},
|
|
||||||
{"speed", &Speed},
|
|
||||||
{"spin", Spin},
|
|
||||||
{"squish", Squish},
|
|
||||||
{"swirl", Swirl},
|
|
||||||
{"tile", Tile},
|
|
||||||
{"togif", ToGif},
|
|
||||||
{"uncanny", Uncanny},
|
|
||||||
{"uncaption", &Uncaption},
|
|
||||||
{"wall", Wall},
|
|
||||||
{"watermark", &Watermark},
|
|
||||||
{"whisper", Whisper},
|
|
||||||
{"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")
|
||||||
|
@ -116,7 +32,7 @@ Napi::Value ProcessImage(const Napi::CallbackInfo& info) {
|
||||||
string command = info[0].As<Napi::String>().Utf8Value();
|
string command = info[0].As<Napi::String>().Utf8Value();
|
||||||
Napi::Object obj = info[1].As<Napi::Object>();
|
Napi::Object obj = info[1].As<Napi::Object>();
|
||||||
string type =
|
string type =
|
||||||
obj.Has("type") ? obj.Get("type").As<Napi::String>().Utf8Value() : NULL;
|
obj.Has("type") ? obj.Get("type").As<Napi::String>().Utf8Value() : "png";
|
||||||
|
|
||||||
Napi::Array properties = obj.GetPropertyNames();
|
Napi::Array properties = obj.GetPropertyNames();
|
||||||
|
|
||||||
|
@ -148,25 +64,28 @@ Napi::Value ProcessImage(const Napi::CallbackInfo& info) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string outType = GetArgument<bool>(Arguments, "togif") ? "gif" : type;
|
||||||
|
|
||||||
size_t length = 0;
|
size_t length = 0;
|
||||||
char* buf;
|
char* buf;
|
||||||
if (obj.Has("data")) {
|
if (obj.Has("data")) {
|
||||||
Napi::Buffer<char> data = obj.Has("data")
|
Napi::Buffer<char> data = obj.Has("data")
|
||||||
? obj.Get("data").As<Napi::Buffer<char>>()
|
? obj.Get("data").As<Napi::Buffer<char>>()
|
||||||
: Napi::Buffer<char>::New(env, 0);
|
: Napi::Buffer<char>::New(env, 0);
|
||||||
buf = FunctionMap.at(command)(&type, data.Data(), data.Length(),
|
buf = FunctionMap.at(command)(type, &outType, data.Data(), data.Length(),
|
||||||
Arguments, &length);
|
Arguments, &length);
|
||||||
} else {
|
} else {
|
||||||
buf = NoInputFunctionMap.at(command)(&type, Arguments, &length);
|
buf = NoInputFunctionMap.at(command)(type, &outType, Arguments, &length);
|
||||||
}
|
}
|
||||||
|
|
||||||
vips_error_clear();
|
vips_error_clear();
|
||||||
vips_thread_shutdown();
|
vips_thread_shutdown();
|
||||||
|
|
||||||
result.Set("data", Napi::Buffer<char>::New(
|
result.Set("data",
|
||||||
env, buf, length,
|
Napi::Buffer<char>::New(env, buf, length,
|
||||||
[](Napi::Env env, void* data) { free(data); }));
|
[]([[maybe_unused]] Napi::Env env,
|
||||||
result.Set("type", type);
|
void* data) { free(data); }));
|
||||||
|
result.Set("type", outType);
|
||||||
} catch (std::exception const& err) {
|
} catch (std::exception const& err) {
|
||||||
Napi::Error::New(env, err.what()).ThrowAsJavaScriptException();
|
Napi::Error::New(env, err.what()).ThrowAsJavaScriptException();
|
||||||
} catch (...) {
|
} catch (...) {
|
|
@ -5,8 +5,8 @@
|
||||||
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, string *outType, char *BufferData,
|
||||||
ArgumentMap Arguments, size_t *DataSize) {
|
size_t BufferLength, ArgumentMap Arguments, size_t *DataSize) {
|
||||||
string text = GetArgument<string>(Arguments, "text");
|
string text = GetArgument<string>(Arguments, "text");
|
||||||
string basePath = GetArgument<string>(Arguments, "basePath");
|
string basePath = GetArgument<string>(Arguments, "basePath");
|
||||||
|
|
||||||
|
@ -14,7 +14,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()) in = in.bandjoin(255);
|
if (!in.has_alpha()) in = in.bandjoin(255);
|
||||||
|
|
||||||
|
@ -48,7 +48,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);
|
||||||
|
@ -58,8 +58,9 @@ 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,
|
("." + *outType).c_str(), &buf, DataSize,
|
||||||
*type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
*outType == "gif"
|
||||||
|
? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||||
: 0);
|
: 0);
|
||||||
|
|
||||||
return (char *)buf;
|
return (char *)buf;
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Reddit(string* type, char* BufferData, size_t BufferLength,
|
char* Reddit(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -5,8 +5,8 @@
|
||||||
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, string *outType, char *BufferData,
|
||||||
ArgumentMap Arguments, size_t *DataSize) {
|
size_t BufferLength, 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(("." + *outType).c_str(), &buf, DataSize);
|
||||||
|
|
||||||
return (char *)buf;
|
return (char *)buf;
|
||||||
}
|
}
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Resize(string* type, char* BufferData, size_t BufferLength,
|
char* Resize(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -6,8 +6,8 @@
|
||||||
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, string *outType, char *BufferData,
|
||||||
ArgumentMap Arguments, size_t *DataSize) {
|
size_t BufferLength, ArgumentMap Arguments, size_t *DataSize) {
|
||||||
bool soos = GetArgumentWithFallback<bool>(Arguments, "soos", false);
|
bool soos = GetArgumentWithFallback<bool>(Arguments, "soos", false);
|
||||||
|
|
||||||
VOption *options =
|
VOption *options =
|
||||||
|
@ -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";
|
*outType = "gif";
|
||||||
|
|
||||||
return (char *)buf;
|
return (char *)buf;
|
||||||
}
|
}
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Reverse(string* type, char* BufferData, size_t BufferLength,
|
char* Reverse(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -1,64 +1,55 @@
|
||||||
#include <Magick++.h>
|
#include <vips/vips8>
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include <iostream>
|
|
||||||
#include <list>
|
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace Magick;
|
using namespace vips;
|
||||||
|
|
||||||
char *Scott(string *type, char *BufferData, size_t BufferLength,
|
char *Scott(string type, string *outType, 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");
|
||||||
|
|
||||||
Blob blob;
|
VOption *options = VImage::option()->set("access", "sequential");
|
||||||
|
|
||||||
list<Image> frames;
|
VImage in =
|
||||||
list<Image> coalesced;
|
VImage::new_from_buffer(BufferData, BufferLength, "",
|
||||||
list<Image> mid;
|
type == "gif" ? options->set("n", -1) : options)
|
||||||
Image watermark;
|
.colourspace(VIPS_INTERPRETATION_sRGB);
|
||||||
try {
|
if (!in.has_alpha()) in = in.bandjoin(255);
|
||||||
readImages(&frames, Blob(BufferData, BufferLength));
|
|
||||||
} catch (Magick::WarningCoder &warning) {
|
int width = in.width();
|
||||||
cerr << "Coder Warning: " << warning.what() << endl;
|
int pageHeight = vips_image_get_page_height(in.get_image());
|
||||||
} catch (Magick::Warning &warning) {
|
int nPages = vips_image_get_n_pages(in.get_image());
|
||||||
cerr << "Warning: " << warning.what() << endl;
|
|
||||||
|
string assetPath = basePath + "assets/images/scott.png";
|
||||||
|
VImage bg = VImage::new_from_file(assetPath.c_str());
|
||||||
|
|
||||||
|
string distortPath = basePath + "assets/images/scottmap.png";
|
||||||
|
VImage distort = VImage::new_from_file(distortPath.c_str());
|
||||||
|
|
||||||
|
VImage distortImage =
|
||||||
|
((distort[1] / 255) * 414).bandjoin((distort[0] / 255) * 233);
|
||||||
|
|
||||||
|
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(
|
||||||
|
415 / (double)width,
|
||||||
|
VImage::option()->set("vscale", 234 / (double)pageHeight));
|
||||||
|
VImage mapped = resized.mapim(distortImage)
|
||||||
|
.extract_band(0, VImage::option()->set("n", 3))
|
||||||
|
.bandjoin(distort[2]);
|
||||||
|
VImage offset = mapped.embed(127, 181, 864, 481);
|
||||||
|
VImage composited = bg.composite2(offset, VIPS_BLEND_MODE_OVER);
|
||||||
|
img.push_back(composited);
|
||||||
}
|
}
|
||||||
watermark.read(basePath + "assets/images/scott.png");
|
VImage final = VImage::arrayjoin(img, VImage::option()->set("across", 1));
|
||||||
coalesceImages(&coalesced, frames.begin(), frames.end());
|
final.set(VIPS_META_PAGE_HEIGHT, 481);
|
||||||
|
|
||||||
for (Image &image : coalesced) {
|
void *buf;
|
||||||
Image watermark_new = watermark;
|
final.write_to_buffer(
|
||||||
image.virtualPixelMethod(Magick::TransparentVirtualPixelMethod);
|
("." + *outType).c_str(), &buf, DataSize,
|
||||||
image.backgroundColor("none");
|
*outType == "gif" ? VImage::option()->set("dither", 1) : 0);
|
||||||
image.scale(Geometry("415x234!"));
|
return (char *)buf;
|
||||||
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);
|
|
||||||
|
|
||||||
*DataSize = blob.length();
|
|
||||||
|
|
||||||
char *data = (char *)malloc(*DataSize);
|
|
||||||
memcpy(data, blob.data(), *DataSize);
|
|
||||||
return data;
|
|
||||||
}
|
}
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Scott(string* type, char* BufferData, size_t BufferLength,
|
char* Scott(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -5,8 +5,8 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace vips;
|
using namespace vips;
|
||||||
|
|
||||||
char *Snapchat(string *type, char *BufferData, size_t BufferLength,
|
char *Snapchat(string type, string *outType, char *BufferData,
|
||||||
ArgumentMap Arguments, size_t *DataSize) {
|
size_t BufferLength, ArgumentMap Arguments, size_t *DataSize) {
|
||||||
string caption = GetArgument<string>(Arguments, "caption");
|
string caption = GetArgument<string>(Arguments, "caption");
|
||||||
float pos = GetArgumentWithFallback<float>(Arguments, "pos", 0.5);
|
float pos = GetArgumentWithFallback<float>(Arguments, "pos", 0.5);
|
||||||
string basePath = GetArgument<string>(Arguments, "basePath");
|
string basePath = GetArgument<string>(Arguments, "basePath");
|
||||||
|
@ -15,7 +15,7 @@ char *Snapchat(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()) in = in.bandjoin(255);
|
if (!in.has_alpha()) in = in.bandjoin(255);
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ char *Snapchat(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;
|
||||||
img_frame = img_frame.composite2(
|
img_frame = img_frame.composite2(
|
||||||
textIn, VIPS_BLEND_MODE_OVER,
|
textIn, VIPS_BLEND_MODE_OVER,
|
||||||
VImage::option()->set("x", 0)->set("y", pageHeight * pos));
|
VImage::option()->set("x", 0)->set("y", pageHeight * pos));
|
||||||
|
@ -63,8 +63,9 @@ char *Snapchat(string *type, char *BufferData, size_t BufferLength,
|
||||||
|
|
||||||
void *buf;
|
void *buf;
|
||||||
final.write_to_buffer(
|
final.write_to_buffer(
|
||||||
("." + *type).c_str(), &buf, DataSize,
|
("." + *outType).c_str(), &buf, DataSize,
|
||||||
*type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
*outType == "gif"
|
||||||
|
? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||||
: 0);
|
: 0);
|
||||||
|
|
||||||
return (char *)buf;
|
return (char *)buf;
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Snapchat(string* type, char* BufferData, size_t BufferLength,
|
char* Snapchat(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -5,7 +5,8 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace vips;
|
using namespace vips;
|
||||||
|
|
||||||
char *Sonic(string *type, ArgumentMap Arguments, size_t *DataSize) {
|
char *Sonic(string type, string *outType, ArgumentMap Arguments,
|
||||||
|
size_t *DataSize) {
|
||||||
string text = GetArgument<string>(Arguments, "text");
|
string text = GetArgument<string>(Arguments, "text");
|
||||||
string basePath = GetArgument<string>(Arguments, "basePath");
|
string basePath = GetArgument<string>(Arguments, "basePath");
|
||||||
|
|
||||||
|
@ -28,9 +29,7 @@ char *Sonic(string *type, ArgumentMap Arguments, size_t *DataSize) {
|
||||||
VImage::option()->set("x", 391)->set("y", 84));
|
VImage::option()->set("x", 391)->set("y", 84));
|
||||||
|
|
||||||
void *buf;
|
void *buf;
|
||||||
out.write_to_buffer(".png", &buf, DataSize);
|
out.write_to_buffer(("." + *outType).c_str(), &buf, DataSize);
|
||||||
|
|
||||||
*type = "png";
|
|
||||||
|
|
||||||
return (char *)buf;
|
return (char *)buf;
|
||||||
}
|
}
|
|
@ -4,4 +4,4 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char *Sonic(string *type, ArgumentMap Arguments, size_t *DataSize);
|
char *Sonic(string type, string *outType, ArgumentMap Arguments, size_t *DataSize);
|
|
@ -39,8 +39,8 @@ 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([[maybe_unused]] string type, string *outType, char *BufferData,
|
||||||
ArgumentMap Arguments, size_t *DataSize) {
|
size_t BufferLength, ArgumentMap Arguments, size_t *DataSize) {
|
||||||
bool slow = GetArgumentWithFallback<bool>(Arguments, "slow", false);
|
bool slow = GetArgumentWithFallback<bool>(Arguments, "slow", false);
|
||||||
int speed = GetArgumentWithFallback<int>(Arguments, "speed", 2);
|
int speed = GetArgumentWithFallback<int>(Arguments, "speed", 2);
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ char *Speed(string *type, char *BufferData, size_t BufferLength,
|
||||||
bool removeFrames = false;
|
bool removeFrames = false;
|
||||||
char *lastPos;
|
char *lastPos;
|
||||||
|
|
||||||
int amount = 0;
|
// int amount = 0;
|
||||||
|
|
||||||
lastPos = (char *)memchr(fileData, '\x00', BufferLength);
|
lastPos = (char *)memchr(fileData, '\x00', BufferLength);
|
||||||
while (lastPos != NULL) {
|
while (lastPos != NULL) {
|
||||||
|
@ -62,7 +62,7 @@ char *Speed(string *type, char *BufferData, size_t BufferLength,
|
||||||
(BufferLength - (lastPos - fileData)) - 1);
|
(BufferLength - (lastPos - fileData)) - 1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
++amount;
|
//++amount;
|
||||||
uint16_t old_delay;
|
uint16_t old_delay;
|
||||||
memcpy(&old_delay, lastPos + 5, 2);
|
memcpy(&old_delay, lastPos + 5, 2);
|
||||||
old_delays.push_back(old_delay);
|
old_delays.push_back(old_delay);
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Speed(string* type, char* BufferData, size_t BufferLength,
|
char* Speed(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -1,15 +1,16 @@
|
||||||
#include "common.h"
|
|
||||||
#include <Magick++.h>
|
#include <Magick++.h>
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace Magick;
|
using namespace Magick;
|
||||||
|
|
||||||
char *Spin(string *type, char *BufferData, size_t BufferLength,
|
char *Spin(string type, string *outType, char *BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t *DataSize) {
|
[[maybe_unused]] ArgumentMap Arguments, size_t *DataSize) {
|
||||||
int delay = GetArgumentWithFallback<int>(Arguments, "delay", 0);
|
int delay = GetArgumentWithFallback<int>(Arguments, "delay", 0);
|
||||||
|
|
||||||
Blob blob;
|
Blob blob;
|
||||||
|
@ -26,7 +27,7 @@ char *Spin(string *type, char *BufferData, size_t BufferLength,
|
||||||
}
|
}
|
||||||
coalesceImages(&coalesced, frames.begin(), frames.end());
|
coalesceImages(&coalesced, frames.begin(), frames.end());
|
||||||
|
|
||||||
if (*type != "gif") {
|
if (type != "gif") {
|
||||||
list<Image>::iterator it = coalesced.begin();
|
list<Image>::iterator it = coalesced.begin();
|
||||||
for (int i = 0; i < 29; ++i) {
|
for (int i = 0; i < 29; ++i) {
|
||||||
coalesced.push_back(*it);
|
coalesced.push_back(*it);
|
||||||
|
@ -51,7 +52,7 @@ char *Spin(string *type, char *BufferData, size_t BufferLength,
|
||||||
optimizeTransparency(mid.begin(), mid.end());
|
optimizeTransparency(mid.begin(), mid.end());
|
||||||
if (delay != 0) {
|
if (delay != 0) {
|
||||||
for_each(mid.begin(), mid.end(), animationDelayImage(delay));
|
for_each(mid.begin(), mid.end(), animationDelayImage(delay));
|
||||||
} else if (*type != "gif") {
|
} else if (type != "gif") {
|
||||||
for_each(mid.begin(), mid.end(), animationDelayImage(5));
|
for_each(mid.begin(), mid.end(), animationDelayImage(5));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +63,7 @@ char *Spin(string *type, char *BufferData, size_t BufferLength,
|
||||||
|
|
||||||
writeImages(mid.begin(), mid.end(), &blob);
|
writeImages(mid.begin(), mid.end(), &blob);
|
||||||
|
|
||||||
*type = "gif";
|
*outType = "gif";
|
||||||
*DataSize = blob.length();
|
*DataSize = blob.length();
|
||||||
|
|
||||||
char *data = (char *)malloc(*DataSize);
|
char *data = (char *)malloc(*DataSize);
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Spin(string* type, char* BufferData, size_t BufferLength,
|
char* Spin(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -7,27 +7,28 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace vips;
|
using namespace vips;
|
||||||
|
|
||||||
char *Squish(string *type, char *BufferData, size_t BufferLength,
|
char *Squish(string type, string *outType, char *BufferData,
|
||||||
ArgumentMap Arguments, size_t *DataSize) {
|
size_t BufferLength, [[maybe_unused]] ArgumentMap Arguments,
|
||||||
|
size_t *DataSize) {
|
||||||
VOption *options = VImage::option();
|
VOption *options = VImage::option();
|
||||||
|
|
||||||
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()) in = in.bandjoin(255);
|
if (!in.has_alpha()) in = in.bandjoin(255);
|
||||||
|
|
||||||
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 mult = (2 * M_PI) / nPages;
|
double mult = (2 * M_PI) / nPages;
|
||||||
|
|
||||||
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;
|
||||||
double newWidth = (sin(i * mult) / 4) + 0.75;
|
double newWidth = (sin(i * mult) / 4) + 0.75;
|
||||||
double newHeight = (cos(i * mult) / 4) + 0.75;
|
double newHeight = (cos(i * mult) / 4) + 0.75;
|
||||||
VImage resized =
|
VImage resized =
|
||||||
|
@ -37,7 +38,7 @@ char *Squish(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, pageHeight);
|
final.set(VIPS_META_PAGE_HEIGHT, pageHeight);
|
||||||
if (*type != "gif") {
|
if (type != "gif") {
|
||||||
vector<int> delay(30, 50);
|
vector<int> delay(30, 50);
|
||||||
final.set("delay", delay);
|
final.set("delay", delay);
|
||||||
}
|
}
|
||||||
|
@ -45,7 +46,7 @@ char *Squish(string *type, char *BufferData, size_t BufferLength,
|
||||||
void *buf;
|
void *buf;
|
||||||
final.write_to_buffer(".gif", &buf, DataSize);
|
final.write_to_buffer(".gif", &buf, DataSize);
|
||||||
|
|
||||||
*type = "gif";
|
*outType = "gif";
|
||||||
|
|
||||||
return (char *)buf;
|
return (char *)buf;
|
||||||
}
|
}
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Squish(string* type, char* BufferData, size_t BufferLength,
|
char* Squish(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -5,13 +5,13 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace vips;
|
using namespace vips;
|
||||||
|
|
||||||
char *Swirl(string *type, char *BufferData, size_t BufferLength,
|
char *Swirl(string type, string *outType, char *BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t *DataSize) {
|
[[maybe_unused]] 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()) in = in.bandjoin(255);
|
if (!in.has_alpha()) in = in.bandjoin(255);
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ char *Swirl(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 distort =
|
VImage distort =
|
||||||
img_frame
|
img_frame
|
||||||
|
@ -70,7 +70,7 @@ char *Swirl(string *type, char *BufferData, size_t BufferLength,
|
||||||
final.set(VIPS_META_PAGE_HEIGHT, pageHeight);
|
final.set(VIPS_META_PAGE_HEIGHT, pageHeight);
|
||||||
|
|
||||||
void *buf;
|
void *buf;
|
||||||
final.write_to_buffer(".gif", &buf, DataSize);
|
final.write_to_buffer(("." + *outType).c_str(), &buf, DataSize);
|
||||||
|
|
||||||
return (char *)buf;
|
return (char *)buf;
|
||||||
}
|
}
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Swirl(string* type, char* BufferData, size_t BufferLength,
|
char* Swirl(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -9,8 +9,8 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace Magick;
|
using namespace Magick;
|
||||||
|
|
||||||
char *Tile(string *type, char *BufferData, size_t BufferLength,
|
char *Tile(string type, string *outType, char *BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t *DataSize) {
|
[[maybe_unused]] ArgumentMap Arguments, size_t *DataSize) {
|
||||||
Blob blob;
|
Blob blob;
|
||||||
|
|
||||||
list<Image> frames;
|
list<Image> frames;
|
||||||
|
@ -30,7 +30,7 @@ char *Tile(string *type, char *BufferData, size_t BufferLength,
|
||||||
Image appended;
|
Image appended;
|
||||||
list<Image> montage;
|
list<Image> montage;
|
||||||
Image frame;
|
Image frame;
|
||||||
image.magick(*type);
|
image.magick(*outType);
|
||||||
for (int i = 0; i < 5; ++i) {
|
for (int i = 0; i < 5; ++i) {
|
||||||
duplicated.push_back(image);
|
duplicated.push_back(image);
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ char *Tile(string *type, char *BufferData, size_t BufferLength,
|
||||||
|
|
||||||
optimizeTransparency(mid.begin(), mid.end());
|
optimizeTransparency(mid.begin(), mid.end());
|
||||||
|
|
||||||
if (*type == "gif") {
|
if (*outType == "gif") {
|
||||||
for (Image &image : mid) {
|
for (Image &image : mid) {
|
||||||
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
|
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
|
||||||
image.quantize();
|
image.quantize();
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Tile(string* type, char* BufferData, size_t BufferLength,
|
char* Tile(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -5,9 +5,9 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace vips;
|
using namespace vips;
|
||||||
|
|
||||||
char *ToGif(string *type, char *BufferData, size_t BufferLength,
|
char *ToGif(string type, string *outType, char *BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t *DataSize) {
|
[[maybe_unused]] ArgumentMap Arguments, size_t *DataSize) {
|
||||||
if (*type == "gif") {
|
if (type == "gif") {
|
||||||
*DataSize = BufferLength;
|
*DataSize = BufferLength;
|
||||||
char *data = (char *)malloc(BufferLength);
|
char *data = (char *)malloc(BufferLength);
|
||||||
memcpy(data, BufferData, BufferLength);
|
memcpy(data, BufferData, BufferLength);
|
||||||
|
@ -17,11 +17,11 @@ char *ToGif(string *type, char *BufferData, size_t BufferLength,
|
||||||
|
|
||||||
VImage in = VImage::new_from_buffer(
|
VImage in = VImage::new_from_buffer(
|
||||||
BufferData, BufferLength, "",
|
BufferData, BufferLength, "",
|
||||||
*type == "webp" ? options->set("n", -1) : options);
|
type == "webp" ? options->set("n", -1) : options);
|
||||||
|
|
||||||
void *buf;
|
void *buf;
|
||||||
in.write_to_buffer(".gif", &buf, DataSize);
|
in.write_to_buffer(".gif", &buf, DataSize);
|
||||||
*type = "gif";
|
*outType = "gif";
|
||||||
|
|
||||||
return (char *)buf;
|
return (char *)buf;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* ToGif(string* type, char* BufferData, size_t BufferLength,
|
char* ToGif(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -5,8 +5,8 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace vips;
|
using namespace vips;
|
||||||
|
|
||||||
char *Uncanny(string *type, char *BufferData, size_t BufferLength,
|
char *Uncanny(string type, string *outType, char *BufferData,
|
||||||
ArgumentMap Arguments, size_t *DataSize) {
|
size_t BufferLength, ArgumentMap Arguments, size_t *DataSize) {
|
||||||
string caption = GetArgument<string>(Arguments, "caption");
|
string caption = GetArgument<string>(Arguments, "caption");
|
||||||
string caption2 = GetArgument<string>(Arguments, "caption2");
|
string caption2 = GetArgument<string>(Arguments, "caption2");
|
||||||
string font = GetArgument<string>(Arguments, "font");
|
string font = GetArgument<string>(Arguments, "font");
|
||||||
|
@ -17,7 +17,7 @@ char *Uncanny(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)
|
||||||
.extract_band(0, VImage::option()->set("n", 3));
|
.extract_band(0, VImage::option()->set("n", 3));
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ char *Uncanny(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(690.0 / (double)width);
|
VImage resized = img_frame.resize(690.0 / (double)width);
|
||||||
if (resized.height() > 590) {
|
if (resized.height() > 590) {
|
||||||
double vscale = 590.0 / (double)resized.height();
|
double vscale = 590.0 / (double)resized.height();
|
||||||
|
@ -94,8 +94,8 @@ char *Uncanny(string *type, char *BufferData, size_t BufferLength,
|
||||||
|
|
||||||
void *buf;
|
void *buf;
|
||||||
final.write_to_buffer(
|
final.write_to_buffer(
|
||||||
("." + *type).c_str(), &buf, DataSize,
|
("." + *outType).c_str(), &buf, DataSize,
|
||||||
*type == "gif" ? VImage::option()->set("reoptimise", 1) : 0);
|
*outType == "gif" ? VImage::option()->set("reoptimise", 1) : 0);
|
||||||
|
|
||||||
return (char *)buf;
|
return (char *)buf;
|
||||||
}
|
}
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Uncanny(string* type, char* BufferData, size_t BufferLength,
|
char* Uncanny(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -6,8 +6,8 @@
|
||||||
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, string *outType, char *BufferData,
|
||||||
ArgumentMap Arguments, size_t *DataSize) {
|
size_t BufferLength, ArgumentMap Arguments, size_t *DataSize) {
|
||||||
float tolerance = GetArgumentWithFallback<float>(Arguments, "tolerance", 0.5);
|
float tolerance = GetArgumentWithFallback<float>(Arguments, "tolerance", 0.5);
|
||||||
|
|
||||||
VOption *options = VImage::option();
|
VOption *options = VImage::option();
|
||||||
|
@ -15,7 +15,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()) in = in.bandjoin(255);
|
if (!in.has_alpha()) in = in.bandjoin(255);
|
||||||
|
@ -45,8 +45,9 @@ 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,
|
("." + *outType).c_str(), &buf, DataSize,
|
||||||
*type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
*outType == "gif"
|
||||||
|
? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||||
: 0);
|
: 0);
|
||||||
|
|
||||||
return (char *)buf;
|
return (char *)buf;
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Uncaption(string* type, char* BufferData, size_t BufferLength,
|
char* Uncaption(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -9,8 +9,8 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace Magick;
|
using namespace Magick;
|
||||||
|
|
||||||
char *Wall(string *type, char *BufferData, size_t BufferLength,
|
char *Wall(string type, string *outType, char *BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t *DataSize) {
|
[[maybe_unused]] ArgumentMap Arguments, size_t *DataSize) {
|
||||||
Blob blob;
|
Blob blob;
|
||||||
|
|
||||||
list<Image> frames;
|
list<Image> frames;
|
||||||
|
@ -35,13 +35,13 @@ char *Wall(string *type, char *BufferData, size_t BufferLength,
|
||||||
128, 0, 140, 60, 128, 128, 140, 140};
|
128, 0, 140, 60, 128, 128, 140, 140};
|
||||||
image.distort(Magick::PerspectiveDistortion, 16, arguments);
|
image.distort(Magick::PerspectiveDistortion, 16, arguments);
|
||||||
image.scale(Geometry("800x800>"));
|
image.scale(Geometry("800x800>"));
|
||||||
image.magick(*type);
|
image.magick(*outType);
|
||||||
mid.push_back(image);
|
mid.push_back(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
optimizeTransparency(mid.begin(), mid.end());
|
optimizeTransparency(mid.begin(), mid.end());
|
||||||
|
|
||||||
if (*type == "gif") {
|
if (*outType == "gif") {
|
||||||
for (Image &image : mid) {
|
for (Image &image : mid) {
|
||||||
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
|
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
|
||||||
image.quantize();
|
image.quantize();
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Wall(string* type, char* BufferData, size_t BufferLength,
|
char* Wall(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -6,8 +6,8 @@
|
||||||
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, string *outType, char *BufferData,
|
||||||
ArgumentMap Arguments, size_t *DataSize) {
|
size_t BufferLength, ArgumentMap Arguments, size_t *DataSize) {
|
||||||
string water = GetArgument<string>(Arguments, "water");
|
string water = GetArgument<string>(Arguments, "water");
|
||||||
int gravity = GetArgument<int>(Arguments, "gravity");
|
int gravity = GetArgument<int>(Arguments, "gravity");
|
||||||
|
|
||||||
|
@ -28,7 +28,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()) in = in.bandjoin(255);
|
if (!in.has_alpha()) in = in.bandjoin(255);
|
||||||
|
|
||||||
|
@ -91,7 +91,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));
|
||||||
|
@ -121,8 +121,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 (*outType == "jpg" || *outType == "jpeg") {
|
||||||
*type = "png";
|
*outType = "png";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
VImage content =
|
VImage content =
|
||||||
|
@ -145,8 +145,9 @@ 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,
|
("." + *outType).c_str(), &buf, DataSize,
|
||||||
*type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
*outType == "gif"
|
||||||
|
? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||||
: 0);
|
: 0);
|
||||||
|
|
||||||
return (char *)buf;
|
return (char *)buf;
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Watermark(string* type, char* BufferData, size_t BufferLength,
|
char* Watermark(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -5,8 +5,8 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace vips;
|
using namespace vips;
|
||||||
|
|
||||||
char *Whisper(string *type, char *BufferData, size_t BufferLength,
|
char *Whisper(string type, string *outType, char *BufferData,
|
||||||
ArgumentMap Arguments, size_t *DataSize) {
|
size_t BufferLength, ArgumentMap Arguments, size_t *DataSize) {
|
||||||
string caption = GetArgument<string>(Arguments, "caption");
|
string caption = GetArgument<string>(Arguments, "caption");
|
||||||
string basePath = GetArgument<string>(Arguments, "basePath");
|
string basePath = GetArgument<string>(Arguments, "basePath");
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ char *Whisper(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()) in = in.bandjoin(255);
|
if (!in.has_alpha()) in = in.bandjoin(255);
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ char *Whisper(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;
|
||||||
img_frame = img_frame.composite2(
|
img_frame = img_frame.composite2(
|
||||||
textImg, VIPS_BLEND_MODE_OVER,
|
textImg, VIPS_BLEND_MODE_OVER,
|
||||||
VImage::option()
|
VImage::option()
|
||||||
|
@ -77,8 +77,9 @@ char *Whisper(string *type, char *BufferData, size_t BufferLength,
|
||||||
|
|
||||||
void *buf;
|
void *buf;
|
||||||
final.write_to_buffer(
|
final.write_to_buffer(
|
||||||
("." + *type).c_str(), &buf, DataSize,
|
("." + *outType).c_str(), &buf, DataSize,
|
||||||
*type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
*outType == "gif"
|
||||||
|
? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||||
: 0);
|
: 0);
|
||||||
|
|
||||||
return (char *)buf;
|
return (char *)buf;
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Whisper(string* type, char* BufferData, size_t BufferLength,
|
char* Whisper(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
|
@ -5,7 +5,7 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace vips;
|
using namespace vips;
|
||||||
|
|
||||||
char *Zamn(string *type, char *BufferData, size_t BufferLength,
|
char *Zamn(string type, string *outType, 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");
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ char *Zamn(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()) in = in.bandjoin(255);
|
if (!in.has_alpha()) in = in.bandjoin(255);
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ char *Zamn(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 = tmpl.insert(
|
VImage composited = tmpl.insert(
|
||||||
img_frame.extract_band(0, VImage::option()->set("n", 3))
|
img_frame.extract_band(0, VImage::option()->set("n", 3))
|
||||||
.bandjoin(255)
|
.bandjoin(255)
|
||||||
|
@ -41,7 +41,7 @@ char *Zamn(string *type, char *BufferData, size_t BufferLength,
|
||||||
final.set(VIPS_META_PAGE_HEIGHT, 516);
|
final.set(VIPS_META_PAGE_HEIGHT, 516);
|
||||||
|
|
||||||
void *buf;
|
void *buf;
|
||||||
final.write_to_buffer(("." + *type).c_str(), &buf, DataSize);
|
final.write_to_buffer(("." + *outType).c_str(), &buf, DataSize);
|
||||||
|
|
||||||
return (char *)buf;
|
return (char *)buf;
|
||||||
}
|
}
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
char* Zamn(string* type, char* BufferData, size_t BufferLength,
|
char* Zamn(string type, string* outType, char* BufferData, size_t BufferLength,
|
||||||
ArgumentMap Arguments, size_t* DataSize);
|
ArgumentMap Arguments, size_t* DataSize);
|
30
package.json
30
package.json
|
@ -29,37 +29,37 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"dotenv": "^16.0.3",
|
"dotenv": "^16.0.3",
|
||||||
"emoji-regex": "^10.2.1",
|
"emoji-regex": "^10.2.1",
|
||||||
"file-type": "^18.0.0",
|
"file-type": "^18.2.1",
|
||||||
"format-duration": "^2.0.0",
|
"format-duration": "^3.0.2",
|
||||||
"jsqr": "^1.4.0",
|
"jsqr": "^1.4.0",
|
||||||
"node-addon-api": "^5.0.0",
|
"node-addon-api": "^5.1.0",
|
||||||
"node-emoji": "^1.11.0",
|
"node-emoji": "^1.11.0",
|
||||||
"oceanic.js": "1.3.2",
|
"oceanic.js": "1.5.1",
|
||||||
"qrcode": "^1.5.1",
|
"qrcode": "^1.5.1",
|
||||||
"sharp": "^0.31.2",
|
"sharp": "^0.31.3",
|
||||||
"shoukaku": "^3.2.2",
|
"shoukaku": "^3.3.1",
|
||||||
"undici": "^5.14.0",
|
"undici": "^5.20.0",
|
||||||
"winston": "^3.8.2",
|
"winston": "^3.8.2",
|
||||||
"winston-daily-rotate-file": "^4.7.1"
|
"winston-daily-rotate-file": "^4.7.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.20.5",
|
"@babel/core": "^7.21.0",
|
||||||
"@babel/eslint-parser": "^7.19.1",
|
"@babel/eslint-parser": "^7.19.1",
|
||||||
"@babel/eslint-plugin": "^7.19.1",
|
"@babel/eslint-plugin": "^7.19.1",
|
||||||
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
||||||
"cmake-js": "^7.0.0",
|
"cmake-js": "^7.2.1",
|
||||||
"eslint": "^8.29.0",
|
"eslint": "^8.35.0",
|
||||||
"eslint-plugin-unicorn": "^45.0.2"
|
"eslint-plugin-unicorn": "^46.0.0"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"better-sqlite3": "^8.0.1",
|
"better-sqlite3": "^8.1.0",
|
||||||
"bufferutil": "^4.0.7",
|
"bufferutil": "^4.0.7",
|
||||||
"erlpack": "^0.1.4",
|
"erlpack": "^0.1.4",
|
||||||
"pm2": "^5.2.2",
|
"pm2": "^5.2.2",
|
||||||
"postgres": "^3.3.2",
|
"postgres": "^3.3.4",
|
||||||
"uuid": "^9.0.0",
|
"uuid": "^9.0.0",
|
||||||
"ws": "^8.11.0",
|
"ws": "^8.12.1",
|
||||||
"zlib-sync": "^0.1.7"
|
"zlib-sync": "^0.1.8"
|
||||||
},
|
},
|
||||||
"binary": {
|
"binary": {
|
||||||
"napi_versions": [
|
"napi_versions": [
|
||||||
|
|
631
pnpm-lock.yaml
631
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
|
@ -138,7 +138,7 @@ export default async (client, info, pages, timeout = 120000) => {
|
||||||
} catch {
|
} catch {
|
||||||
// no-op
|
// no-op
|
||||||
}
|
}
|
||||||
page = Number(response.data.values[0]);
|
page = Number(response.data.values.raw[0]);
|
||||||
currentPage = await currentPage.edit(Object.assign(pages[page], options, components));
|
currentPage = await currentPage.edit(Object.assign(pages[page], options, components));
|
||||||
ended = true;
|
ended = true;
|
||||||
dropdownCollector.stop();
|
dropdownCollector.stop();
|
||||||
|
|
Loading…
Reference in a new issue