diff --git a/locales/en-US.json b/locales/en-US.json index 7dd7bb9f..e0418db0 100644 --- a/locales/en-US.json +++ b/locales/en-US.json @@ -996,6 +996,7 @@ "errorCaps": "ERROR", "guildOnly": "This command only works in servers!", "image": { + "animatedAVIF": "Animated AVIF files are currently unsupported.", "couldNotFind": "I couldn't find an image in that message!", "empty": "The resulting output was empty!", "flagNames": { diff --git a/natives/node/worker.cc b/natives/node/worker.cc index 15ae17f4..ea935b1b 100644 --- a/natives/node/worker.cc +++ b/natives/node/worker.cc @@ -15,6 +15,24 @@ void MediaAsyncWorker::Execute() { try { if (bufSize != 0) { + if (type == "avif" && bufSize >= 20) { + uint32_t size = readUint32BE(reinterpret_cast(bufData)); + if (size > bufSize) { + SetError("Invalid file"); + return; + } + + int curSize = size - 16; + while (curSize > 0) { + if (memcmp(bufData + size - curSize, "avis", 4) == 0) { + outType = "avis"; + outData = {nullptr, 0}; + return; + } + curSize -= 4; + } + } + outData = esmb::Image::FunctionMap.at(command)(type, outType, bufData, bufSize, inArgs, &shouldKill); } else { outData = esmb::Image::NoInputFunctionMap.at(command)(type, outType, inArgs, &shouldKill); diff --git a/natives/shared.h b/natives/shared.h index 45db6598..4e64a31b 100644 --- a/natives/shared.h +++ b/natives/shared.h @@ -30,4 +30,9 @@ typedef const std::map FunctionArgs; inline uint32_t readUint32LE(const unsigned char *buffer) { return static_cast(buffer[0]) | (static_cast(buffer[1]) << 8) | (static_cast(buffer[2]) << 16) | (static_cast(buffer[3]) << 24); -} \ No newline at end of file +} + +inline uint32_t readUint32BE(const unsigned char *buffer) { + return static_cast(buffer[3]) | (static_cast(buffer[2]) << 8) | + (static_cast(buffer[1]) << 16) | (static_cast(buffer[0]) << 24); +} diff --git a/src/classes/mediaCommand.ts b/src/classes/mediaCommand.ts index 2a1d5572..880d30f9 100644 --- a/src/classes/mediaCommand.ts +++ b/src/classes/mediaCommand.ts @@ -150,6 +150,7 @@ class MediaCommand extends Command { } if (type === "large") return this.getString("image.large"); if (type === "frames") return this.getString("image.frames"); + if (type === "avis") return this.getString("image.animatedAVIF"); if (type === "unknown") return this.getString("image.unknown"); if (type === "noresult") return this.getString("image.noResult"); if (type === "ratelimit") return this.getString("image.ratelimit"); diff --git a/src/utils/mediaConnection.ts b/src/utils/mediaConnection.ts index 902bf52f..98c2f203 100644 --- a/src/utils/mediaConnection.ts +++ b/src/utils/mediaConnection.ts @@ -25,7 +25,7 @@ interface RequestState { type WaitResponse = { sent: true; data: Buffer } | { sent: false }; -const etcTypes = ["noanim", "nocmd", "text", "empty", "frames", "ratelimit", "nomedia", "large"]; +const etcTypes = ["noanim", "nocmd", "text", "empty", "frames", "ratelimit", "nomedia", "large", "avis"]; class MediaConnection { requests: Map;