diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 188d6783..6f71cf72 100755 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -378,6 +378,7 @@ "Remove EXIF", "Extract EXIF", "Split Colour Channels", + "Extract RGBA", "View Bit Plane", "Extract LSB", "Rotate Image", diff --git a/src/core/lib/Delim.mjs b/src/core/lib/Delim.mjs index 5ad3ddb3..eb390e64 100644 --- a/src/core/lib/Delim.mjs +++ b/src/core/lib/Delim.mjs @@ -72,3 +72,12 @@ export const JOIN_DELIM_OPTIONS = [ {name: "Nothing (join chars)", value: ""} ]; +/* + RGBA list delimiters. +*/ +export const RGBA_DELIM_OPTIONS = [ + {name: "Comma", value: ","}, + {name: "Space", value: " "}, + {name: "CRLF", value: "\\r\\n"}, + {name: "Line Feed", value: "\n"} +]; diff --git a/src/core/operations/ExtractRGBA.mjs b/src/core/operations/ExtractRGBA.mjs new file mode 100644 index 00000000..a215f58b --- /dev/null +++ b/src/core/operations/ExtractRGBA.mjs @@ -0,0 +1,65 @@ +/** + * @author Ge0rg3 [georgeomnet+cyberchef@gmail.com] + * @copyright Crown Copyright 2019 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import OperationError from "../errors/OperationError.mjs"; +import { isImage } from "../lib/FileType"; +import jimp from "jimp"; + +import {RGBA_DELIM_OPTIONS} from "../lib/Delim.mjs"; + +/** + * Extract RGBA operation + */ +class ExtractRGBA extends Operation { + + /** + * ExtractRGBA constructor + */ + constructor() { + super(); + + this.name = "Extract RGBA"; + this.module = "Image"; + this.description = "Extracts each pixel's RGBA value in an image. These are sometimes used in Steganography to hide text or data."; + this.infoURL = "https://en.wikipedia.org/wiki/RGBA_color_space"; + this.inputType = "byteArray"; + this.outputType = "string"; + this.args = [ + { + name: "Delimiter", + type: "editableOption", + value: RGBA_DELIM_OPTIONS + }, + { + name: "Include Alpha", + type: "boolean", + value: true + } + ]; + } + + /** + * @param {byteArray} input + * @param {Object[]} args + * @returns {string} + */ + async run(input, args) { + if (!isImage(input)) throw new OperationError("Please enter a valid image file."); + + const delimiter = args[0], + includeAlpha = args[1], + parsedImage = await jimp.read(Buffer.from(input)); + + let bitmap = parsedImage.bitmap.data; + bitmap = includeAlpha ? bitmap : bitmap.filter((val, idx) => idx % 4 !== 3); + + return bitmap.join(delimiter); + } + +} + +export default ExtractRGBA;