mirror of
https://github.com/gchq/CyberChef.git
synced 2026-03-26 16:51:26 -07:00
Merge e24006d809 into d195a51e2e
This commit is contained in:
commit
8a0335d57b
25 changed files with 140 additions and 31 deletions
|
|
@ -188,7 +188,8 @@
|
|||
"vkbeautify": "^0.99.3",
|
||||
"xpath": "0.0.34",
|
||||
"xregexp": "^5.1.2",
|
||||
"zlibjs": "^0.3.1"
|
||||
"zlibjs": "^0.3.1",
|
||||
"@jimp/wasm-webp": "^1.6.0"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "npx grunt dev",
|
||||
|
|
@ -208,4 +209,4 @@
|
|||
"getheapsize": "node -e 'console.log(`node heap limit = ${require(\"v8\").getHeapStatistics().heap_size_limit / (1024 * 1024)} Mb`)'",
|
||||
"setheapsize": "export NODE_OPTIONS=--max_old_space_size=2048"
|
||||
}
|
||||
}
|
||||
}
|
||||
21
src/core/lib/Jimp.mjs
Normal file
21
src/core/lib/Jimp.mjs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/**
|
||||
* Jimp image library with additional plugins.
|
||||
*
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2024
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import { Jimp as BaseJimp, JimpMime, PNGFilterType, ResizeStrategy, EdgeAction } from "jimp";
|
||||
import webp from "@jimp/wasm-webp";
|
||||
|
||||
/**
|
||||
* Configure Jimp with WebP support
|
||||
*/
|
||||
const Jimp = new BaseJimp({
|
||||
plugins: [webp],
|
||||
formats: [webp]
|
||||
});
|
||||
|
||||
export { Jimp, JimpMime, PNGFilterType, ResizeStrategy, EdgeAction };
|
||||
export default Jimp;
|
||||
|
|
@ -16,7 +16,7 @@ import {
|
|||
measureText,
|
||||
measureTextHeight,
|
||||
loadFont,
|
||||
} from "jimp";
|
||||
} from "../lib/Jimp.mjs";
|
||||
|
||||
/**
|
||||
* Add Text To Image operation
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
|
|||
import { isWorkerEnvironment } from "../Utils.mjs";
|
||||
import { isImage } from "../lib/FileType.mjs";
|
||||
import { toBase64 } from "../lib/Base64.mjs";
|
||||
import { Jimp, JimpMime } from "jimp";
|
||||
import { Jimp, JimpMime } from "../lib/Jimp.mjs";
|
||||
|
||||
/**
|
||||
* Blur Image operation
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import {
|
|||
ResizeStrategy,
|
||||
HorizontalAlign,
|
||||
VerticalAlign,
|
||||
} from "jimp";
|
||||
} from "../lib/Jimp.mjs";
|
||||
|
||||
/**
|
||||
* Contain Image operation
|
||||
|
|
|
|||
|
|
@ -8,7 +8,73 @@ import Operation from "../Operation.mjs";
|
|||
import OperationError from "../errors/OperationError.mjs";
|
||||
import { isImage } from "../lib/FileType.mjs";
|
||||
import { toBase64 } from "../lib/Base64.mjs";
|
||||
import { Jimp, JimpMime, PNGFilterType } from "jimp";
|
||||
import { Jimp, JimpMime, PNGFilterType } from "../lib/Jimp.mjs";
|
||||
|
||||
function canTranscodeViaCanvas() {
|
||||
return (
|
||||
typeof globalThis !== "undefined" &&
|
||||
typeof globalThis.Blob !== "undefined" &&
|
||||
typeof globalThis.createImageBitmap === "function" &&
|
||||
(typeof globalThis.OffscreenCanvas !== "undefined" ||
|
||||
(typeof globalThis.document !== "undefined" &&
|
||||
typeof globalThis.document.createElement === "function"))
|
||||
);
|
||||
}
|
||||
|
||||
async function transcodeViaCanvas(input, inputMime, outputMime, quality) {
|
||||
const { Blob: BlobCtor, createImageBitmap: createImageBitmapFn, OffscreenCanvas: OffscreenCanvasCtor, document } =
|
||||
globalThis;
|
||||
|
||||
const inputBytes = input instanceof ArrayBuffer ? new Uint8Array(input) : input;
|
||||
const inputBlob = new BlobCtor([inputBytes], { type: inputMime });
|
||||
|
||||
const bitmap = await createImageBitmapFn(inputBlob);
|
||||
try {
|
||||
let canvas;
|
||||
if (typeof OffscreenCanvasCtor !== "undefined") {
|
||||
canvas = new OffscreenCanvasCtor(bitmap.width, bitmap.height);
|
||||
} else {
|
||||
if (!document) throw new Error("Canvas API not available");
|
||||
canvas = document.createElement("canvas");
|
||||
canvas.width = bitmap.width;
|
||||
canvas.height = bitmap.height;
|
||||
}
|
||||
|
||||
const ctx = canvas.getContext("2d");
|
||||
if (!ctx) throw new Error("Unable to initialise canvas context");
|
||||
|
||||
if (outputMime === "image/jpeg" || outputMime === "image/webp") {
|
||||
ctx.fillStyle = "#ffffff";
|
||||
ctx.fillRect(0, 0, bitmap.width, bitmap.height);
|
||||
}
|
||||
|
||||
ctx.drawImage(bitmap, 0, 0);
|
||||
|
||||
let outputBlob;
|
||||
if (typeof canvas.convertToBlob === "function") {
|
||||
outputBlob = await canvas.convertToBlob({
|
||||
type: outputMime,
|
||||
quality: quality ? quality / 100 : undefined,
|
||||
});
|
||||
} else if (typeof canvas.toBlob === "function") {
|
||||
outputBlob = await new Promise((resolve, reject) => {
|
||||
canvas.toBlob(
|
||||
blob => (blob ? resolve(blob) : reject(new Error("Canvas encode failed"))),
|
||||
outputMime,
|
||||
quality ? quality / 100 : undefined
|
||||
);
|
||||
});
|
||||
} else {
|
||||
throw new Error("Canvas encoding not supported");
|
||||
}
|
||||
|
||||
return await outputBlob.arrayBuffer();
|
||||
} finally {
|
||||
if (bitmap && typeof bitmap.close === "function") {
|
||||
bitmap.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert Image Format operation
|
||||
|
|
@ -23,7 +89,7 @@ class ConvertImageFormat extends Operation {
|
|||
this.name = "Convert Image Format";
|
||||
this.module = "Image";
|
||||
this.description =
|
||||
"Converts an image between different formats. Supported formats:<br><ul><li>Joint Photographic Experts Group (JPEG)</li><li>Portable Network Graphics (PNG)</li><li>Bitmap (BMP)</li><li>Tagged Image File Format (TIFF)</li></ul><br>Note: GIF files are supported for input, but cannot be outputted.";
|
||||
"Converts an image between different formats. Supported output formats:<br><ul><li>Joint Photographic Experts Group (JPEG)</li><li>Portable Network Graphics (PNG)</li><li>Bitmap (BMP)</li><li>Tagged Image File Format (TIFF)</li><li>WebP</li></ul><br>Note: GIF files are supported for input, but cannot be outputted.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Image_file_formats";
|
||||
this.inputType = "ArrayBuffer";
|
||||
this.outputType = "ArrayBuffer";
|
||||
|
|
@ -32,10 +98,10 @@ class ConvertImageFormat extends Operation {
|
|||
{
|
||||
name: "Output Format",
|
||||
type: "option",
|
||||
value: ["JPEG", "PNG", "BMP", "TIFF"],
|
||||
value: ["JPEG", "PNG", "BMP", "TIFF", "WEBP"],
|
||||
},
|
||||
{
|
||||
name: "JPEG Quality",
|
||||
name: "Quality (JPEG/WebP)",
|
||||
type: "number",
|
||||
value: 80,
|
||||
min: 1,
|
||||
|
|
@ -62,12 +128,13 @@ class ConvertImageFormat extends Operation {
|
|||
* @returns {byteArray}
|
||||
*/
|
||||
async run(input, args) {
|
||||
const [format, jpegQuality, pngFilterType, pngDeflateLevel] = args;
|
||||
const [format, quality, pngFilterType, pngDeflateLevel] = args;
|
||||
const formatMap = {
|
||||
JPEG: JimpMime.jpeg,
|
||||
PNG: JimpMime.png,
|
||||
BMP: JimpMime.bmp,
|
||||
TIFF: JimpMime.tiff,
|
||||
WEBP: "image/webp",
|
||||
};
|
||||
|
||||
const pngFilterMap = {
|
||||
|
|
@ -81,9 +148,28 @@ class ConvertImageFormat extends Operation {
|
|||
|
||||
const mime = formatMap[format];
|
||||
|
||||
if (!isImage(input)) {
|
||||
const inputMime = isImage(input);
|
||||
if (!inputMime) {
|
||||
throw new OperationError("Invalid file format.");
|
||||
}
|
||||
|
||||
if (
|
||||
inputMime === "image/webp" &&
|
||||
(mime === JimpMime.jpeg || mime === JimpMime.png) &&
|
||||
canTranscodeViaCanvas()
|
||||
) {
|
||||
try {
|
||||
let outputMime;
|
||||
if (mime === JimpMime.jpeg) outputMime = "image/jpeg";
|
||||
else if (mime === "image/webp") outputMime = "image/webp";
|
||||
else outputMime = "image/png";
|
||||
|
||||
return await transcodeViaCanvas(input, inputMime, outputMime, quality);
|
||||
} catch (err) {
|
||||
// If canvas fails, we can fall back to Jimp
|
||||
}
|
||||
}
|
||||
|
||||
let image;
|
||||
try {
|
||||
image = await Jimp.read(input);
|
||||
|
|
@ -94,8 +180,9 @@ class ConvertImageFormat extends Operation {
|
|||
let buffer;
|
||||
switch (mime) {
|
||||
case JimpMime.jpeg:
|
||||
case "image/webp":
|
||||
buffer = await image.getBuffer(mime, {
|
||||
quality: jpegQuality,
|
||||
quality: quality,
|
||||
});
|
||||
break;
|
||||
case JimpMime.png:
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import {
|
|||
ResizeStrategy,
|
||||
HorizontalAlign,
|
||||
VerticalAlign,
|
||||
} from "jimp";
|
||||
} from "../lib/Jimp.mjs";
|
||||
|
||||
/**
|
||||
* Cover Image operation
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
|
|||
import { isImage } from "../lib/FileType.mjs";
|
||||
import { toBase64 } from "../lib/Base64.mjs";
|
||||
import { isWorkerEnvironment } from "../Utils.mjs";
|
||||
import { Jimp, JimpMime } from "jimp";
|
||||
import { Jimp, JimpMime } from "../lib/Jimp.mjs";
|
||||
|
||||
/**
|
||||
* Crop Image operation
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
|
|||
import { isImage } from "../lib/FileType.mjs";
|
||||
import { toBase64 } from "../lib/Base64.mjs";
|
||||
import { isWorkerEnvironment } from "../Utils.mjs";
|
||||
import { Jimp, JimpMime } from "jimp";
|
||||
import { Jimp, JimpMime } from "../lib/Jimp.mjs";
|
||||
|
||||
/**
|
||||
* Image Dither operation
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
|
|||
import Utils from "../Utils.mjs";
|
||||
import { fromBinary } from "../lib/Binary.mjs";
|
||||
import { isImage } from "../lib/FileType.mjs";
|
||||
import { Jimp } from "jimp";
|
||||
import { Jimp } from "../lib/Jimp.mjs";
|
||||
|
||||
/**
|
||||
* Extract LSB operation
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
import { isImage } from "../lib/FileType.mjs";
|
||||
import { Jimp } from "jimp";
|
||||
import { Jimp } from "../lib/Jimp.mjs";
|
||||
|
||||
import { RGBA_DELIM_OPTIONS } from "../lib/Delim.mjs";
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
|
|||
import { isImage } from "../lib/FileType.mjs";
|
||||
import { toBase64 } from "../lib/Base64.mjs";
|
||||
import { isWorkerEnvironment } from "../Utils.mjs";
|
||||
import { Jimp, JimpMime } from "jimp";
|
||||
import { Jimp, JimpMime } from "../lib/Jimp.mjs";
|
||||
|
||||
/**
|
||||
* Flip Image operation
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import Utils from "../Utils.mjs";
|
|||
import { isImage } from "../lib/FileType.mjs";
|
||||
import { toBase64 } from "../lib/Base64.mjs";
|
||||
import { isWorkerEnvironment } from "../Utils.mjs";
|
||||
import { Jimp, JimpMime, ResizeStrategy, rgbaToInt } from "jimp";
|
||||
import { Jimp, JimpMime, ResizeStrategy, rgbaToInt } from "../lib/Jimp.mjs";
|
||||
|
||||
/**
|
||||
* Generate Image operation
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
|
|||
import { isImage } from "../lib/FileType.mjs";
|
||||
import { toBase64 } from "../lib/Base64.mjs";
|
||||
import { isWorkerEnvironment } from "../Utils.mjs";
|
||||
import { Jimp, JimpMime } from "jimp";
|
||||
import { Jimp, JimpMime } from "../lib/Jimp.mjs";
|
||||
|
||||
/**
|
||||
* Image Brightness / Contrast operation
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
|
|||
import { isImage } from "../lib/FileType.mjs";
|
||||
import { toBase64 } from "../lib/Base64.mjs";
|
||||
import { isWorkerEnvironment } from "../Utils.mjs";
|
||||
import { Jimp, JimpMime } from "jimp";
|
||||
import { Jimp, JimpMime } from "../lib/Jimp.mjs";
|
||||
|
||||
/**
|
||||
* Image Filter operation
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
|
|||
import { isImage } from "../lib/FileType.mjs";
|
||||
import { toBase64 } from "../lib/Base64.mjs";
|
||||
import { isWorkerEnvironment } from "../Utils.mjs";
|
||||
import { Jimp, JimpMime } from "jimp";
|
||||
import { Jimp, JimpMime } from "../lib/Jimp.mjs";
|
||||
|
||||
/**
|
||||
* Image Hue/Saturation/Lightness operation
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
|
|||
import { isImage } from "../lib/FileType.mjs";
|
||||
import { toBase64 } from "../lib/Base64.mjs";
|
||||
import { isWorkerEnvironment } from "../Utils.mjs";
|
||||
import { Jimp, JimpMime } from "jimp";
|
||||
import { Jimp, JimpMime } from "../lib/Jimp.mjs";
|
||||
|
||||
/**
|
||||
* Image Opacity operation
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
|
|||
import { isImage } from "../lib/FileType.mjs";
|
||||
import { toBase64 } from "../lib/Base64.mjs";
|
||||
import { isWorkerEnvironment } from "../Utils.mjs";
|
||||
import { Jimp, JimpMime } from "jimp";
|
||||
import { Jimp, JimpMime } from "../lib/Jimp.mjs";
|
||||
|
||||
/**
|
||||
* Invert Image operation
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import Operation from "../Operation.mjs";
|
|||
import OperationError from "../errors/OperationError.mjs";
|
||||
import { isImage } from "../lib/FileType.mjs";
|
||||
import { toBase64 } from "../lib/Base64.mjs";
|
||||
import { Jimp, JimpMime } from "jimp";
|
||||
import { Jimp, JimpMime } from "../lib/Jimp.mjs";
|
||||
|
||||
/**
|
||||
* Normalise Image operation
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import Utils from "../Utils.mjs";
|
|||
import { isImage } from "../lib/FileType.mjs";
|
||||
import { runHash } from "../lib/Hash.mjs";
|
||||
import { toBase64 } from "../lib/Base64.mjs";
|
||||
import { Jimp } from "jimp";
|
||||
import { Jimp } from "../lib/Jimp.mjs";
|
||||
|
||||
/**
|
||||
* Randomize Colour Palette operation
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
|
|||
import { isImage } from "../lib/FileType.mjs";
|
||||
import { toBase64 } from "../lib/Base64.mjs";
|
||||
import { isWorkerEnvironment } from "../Utils.mjs";
|
||||
import { Jimp, JimpMime, ResizeStrategy } from "jimp";
|
||||
import { Jimp, JimpMime, ResizeStrategy } from "../lib/Jimp.mjs";
|
||||
|
||||
/**
|
||||
* Resize Image operation
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
|
|||
import { isImage } from "../lib/FileType.mjs";
|
||||
import { toBase64 } from "../lib/Base64.mjs";
|
||||
import { isWorkerEnvironment } from "../Utils.mjs";
|
||||
import { Jimp, JimpMime } from "jimp";
|
||||
import { Jimp, JimpMime } from "../lib/Jimp.mjs";
|
||||
|
||||
/**
|
||||
* Rotate Image operation
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
|
|||
import { isImage } from "../lib/FileType.mjs";
|
||||
import { toBase64 } from "../lib/Base64.mjs";
|
||||
import { isWorkerEnvironment } from "../Utils.mjs";
|
||||
import { Jimp, JimpMime } from "jimp";
|
||||
import { Jimp, JimpMime } from "../lib/Jimp.mjs";
|
||||
|
||||
/**
|
||||
* Sharpen Image operation
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import Operation from "../Operation.mjs";
|
|||
import OperationError from "../errors/OperationError.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
import { isImage } from "../lib/FileType.mjs";
|
||||
import { Jimp, JimpMime } from "jimp";
|
||||
import { Jimp, JimpMime } from "../lib/Jimp.mjs";
|
||||
|
||||
/**
|
||||
* Split Colour Channels operation
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
|
|||
import Utils from "../Utils.mjs";
|
||||
import { isImage } from "../lib/FileType.mjs";
|
||||
import { toBase64 } from "../lib/Base64.mjs";
|
||||
import { Jimp } from "jimp";
|
||||
import { Jimp } from "../lib/Jimp.mjs";
|
||||
|
||||
/**
|
||||
* View Bit Plane operation
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue