2022-01-13 12:40:14 +00:00
|
|
|
import { Buffer } from "buffer";
|
|
|
|
import type { ImageProcessor } from "./main";
|
2022-07-24 17:22:39 +00:00
|
|
|
import { f5stego } from './f5stego';
|
2022-07-19 15:29:49 +00:00
|
|
|
import { settings } from "./stores";
|
|
|
|
import { decodeCoom3Payload } from "./utils";
|
|
|
|
|
|
|
|
const key = Buffer.from("CUNNYCUNNYCUNNY");
|
2022-07-23 13:30:46 +00:00
|
|
|
const f5inst = new f5stego(key);
|
2022-07-19 15:29:49 +00:00
|
|
|
|
2022-07-23 13:30:46 +00:00
|
|
|
const inject = async (b: File, links: string[]) => {
|
2022-07-19 15:29:49 +00:00
|
|
|
// TODO: maybe do a lossless crop/embed/concat?
|
|
|
|
if (b.size / 20 < links.join(' ').length)
|
|
|
|
throw "Image too small to embed.";
|
2022-07-22 16:36:46 +00:00
|
|
|
const arr = new Uint8Array(new Uint8Array(await b.arrayBuffer()));
|
2022-07-23 13:30:46 +00:00
|
|
|
const buff = f5inst.embed(arr, new TextEncoder().encode(links.join(' ')), 1);
|
2022-07-19 15:29:49 +00:00
|
|
|
return Buffer.from(buff);
|
|
|
|
};
|
|
|
|
|
|
|
|
// unfortunately, because of the way f5 work, we can't determine
|
|
|
|
// if there's an embedded message until we have the complete file
|
|
|
|
// but the way PEE was designed forces us to just try to extract something until it works
|
|
|
|
const has_embed = (b: Buffer) => {
|
|
|
|
try {
|
|
|
|
const res = f5inst.extract(b);
|
|
|
|
if (!res)
|
2022-07-23 13:30:46 +00:00
|
|
|
return false; // unsure
|
2022-07-19 15:29:49 +00:00
|
|
|
if (res.length > 1024) // probably garbage, allows for ~20 links from take-me-to.space, should be enough
|
2022-07-23 13:30:46 +00:00
|
|
|
return false; // unsure
|
2022-07-19 15:29:49 +00:00
|
|
|
const str = Buffer.from(res).toString();
|
|
|
|
if (!str.match(/^[a-zA-Z0-9:/.\-_ ]+$/))
|
2022-07-23 13:30:46 +00:00
|
|
|
return false; // unsure
|
2022-07-19 15:29:49 +00:00
|
|
|
return str; // sure
|
|
|
|
} catch {
|
2022-07-23 13:30:46 +00:00
|
|
|
return false; // unsure
|
2022-07-19 15:29:49 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const extract = (b: Buffer, ex: string) => {
|
|
|
|
// if we reached here then ex is heckin cute and valid
|
|
|
|
return decodeCoom3Payload(Buffer.from(ex));
|
|
|
|
};
|
|
|
|
|
2022-01-13 12:40:14 +00:00
|
|
|
export default {
|
|
|
|
match: fn => !!fn.match(/\.jpe?g$/),
|
2022-07-19 15:29:49 +00:00
|
|
|
has_embed,
|
|
|
|
extract,
|
2022-01-13 12:40:14 +00:00
|
|
|
inject
|
|
|
|
} as ImageProcessor;
|