2019-08-29 17:17:07 +02:00
/ * *
* @ 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" ;
2019-09-04 14:54:59 +02:00
import Utils from "../Utils.mjs" ;
import { isImage } from "../lib/FileType.mjs" ;
2019-08-29 17:17:07 +02:00
import { runHash } from "../lib/Hash.mjs" ;
2019-09-04 14:54:59 +02:00
import { toBase64 } from "../lib/Base64.mjs" ;
2019-08-29 17:17:07 +02:00
import jimp from "jimp" ;
/ * *
* Randomize Colour Palette operation
* /
class RandomizeColourPalette extends Operation {
/ * *
* RandomizeColourPalette constructor
* /
constructor ( ) {
super ( ) ;
this . name = "Randomize Colour Palette" ;
this . module = "Image" ;
2019-09-04 14:54:59 +02:00
this . description = "Randomizes each colour in an image's colour palette. This can often reveal text or symbols that were previously a very similar colour to their surroundings, a technique sometimes used in Steganography." ;
this . infoURL = "https://wikipedia.org/wiki/Indexed_color" ;
this . inputType = "ArrayBuffer" ;
this . outputType = "ArrayBuffer" ;
2019-08-29 17:17:07 +02:00
this . presentType = "html" ;
this . args = [
{
name : "Seed" ,
type : "string" ,
value : ""
}
] ;
}
/ * *
2019-09-04 14:54:59 +02:00
* @ param { ArrayBuffer } input
2019-08-29 17:17:07 +02:00
* @ param { Object [ ] } args
2019-09-04 14:54:59 +02:00
* @ returns { ArrayBuffer }
2019-08-29 17:17:07 +02:00
* /
async run ( input , args ) {
if ( ! isImage ( input ) ) throw new OperationError ( "Please enter a valid image file." ) ;
2019-09-04 14:54:59 +02:00
const seed = args [ 0 ] || ( Math . random ( ) . toString ( ) . substr ( 2 ) ) ,
parsedImage = await jimp . read ( input ) ,
2019-08-29 17:17:07 +02:00
width = parsedImage . bitmap . width ,
height = parsedImage . bitmap . height ;
let rgbString , rgbHash , rgbHex ;
parsedImage . scan ( 0 , 0 , width , height , function ( x , y , idx ) {
rgbString = this . bitmap . data . slice ( idx , idx + 3 ) . join ( "." ) ;
rgbHash = runHash ( "md5" , Utils . strToArrayBuffer ( seed + rgbString ) ) ;
rgbHex = rgbHash . substr ( 0 , 6 ) + "ff" ;
parsedImage . setPixelColor ( parseInt ( rgbHex , 16 ) , x , y ) ;
} ) ;
const imageBuffer = await parsedImage . getBufferAsync ( jimp . AUTO ) ;
2019-09-04 14:54:59 +02:00
return new Uint8Array ( imageBuffer ) . buffer ;
2019-08-29 17:17:07 +02:00
}
/ * *
* Displays the extracted data as an image for web apps .
2019-09-04 14:54:59 +02:00
* @ param { ArrayBuffer } data
2019-08-29 17:17:07 +02:00
* @ returns { html }
* /
present ( data ) {
2019-09-04 14:54:59 +02:00
if ( ! data . byteLength ) return "" ;
2019-08-29 17:17:07 +02:00
const type = isImage ( data ) ;
return ` <img src="data: ${ type } ;base64, ${ toBase64 ( data ) } "> ` ;
}
}
export default RandomizeColourPalette ;