Browse Source

Fix GIF encoding, minor css adjustment for minimap

pull/46/head 0.93
coomdev 2 years ago
parent
commit
dc89f80fb0
  1. 2
      src/ScrollHighlighter.svelte
  2. 79
      src/gif.ts
  3. 62
      src/main.ts

2
src/ScrollHighlighter.svelte

@ -91,6 +91,8 @@ onDestroy(() => {
<style scoped>
.hint {
background-color: rgb(222 222 222 / 80%);
z-index: -1;
pointer-events: none;
}
.scroll-container {

79
src/gif.ts

@ -1,10 +1,29 @@
import { Buffer } from "buffer";
import type { ImageProcessor } from "./main";
import type { EmbeddedFile, ImageProcessor } from "./main";
import { BufferWriteStream } from "./png";
const netscape = Buffer.from("!\xFF\x0BNETSCAPE2.0", 'ascii');
const magic = Buffer.from("!\xFF\x0B" + "COOMTECH0.1", 'ascii');
const read_section = (gif: Buffer, pos: number) => {
const begin = pos;
pos += 3 + gif[pos + 2];
let buf = Buffer.alloc(0);
while (pos < gif.byteLength) {
const v = gif[pos++];
buf = Buffer.concat([buf, gif.slice(pos, pos + v)]);
if (v == 0)
break;
pos += v;
}
const appname = gif.slice(begin + 3, begin + 11).toString('ascii');
return {
appname,
data: buf,
end: pos
};
};
const extractBuff = (gif: Buffer) => {
const field = gif.readUInt8(10);
const gcte = !!(field & (1 << 7));
@ -13,41 +32,28 @@ const extractBuff = (gif: Buffer) => {
end += 3 * (1 << ((field & 7) + 1));
}
// skip beeg blocks
while (gif.readUInt8(end) == '!'.charCodeAt(0)) {
if (magic.compare(gif, end, end + magic.byteLength) != 0) {
end += 3 + gif.readUInt8(end + 2);
// eslint-disable-next-line no-constant-condition
while (true) { // skip sub blocks
const v = gif.readUInt8(end++);
if (!v)
break;
end += v;
}
} else {
let count = end + magic.byteLength;
let t = 0;
let v = 0;
while ((v = gif.readUInt8(count)) != 0) {
t += v;
count += v + 1;
}
const buff = Buffer.alloc(t);
count = end + magic.byteLength;
t = 0;
while ((v = gif.readUInt8(count)) != 0) {
gif.copy(buff, t, count + 1, count + 1 + v);
t += v;
count += v + 1;
}
return {filename: 'embedded', data: buff};
while (gif[end] == '!'.charCodeAt(0)) {
let sec = read_section(gif, end); // this section contains the size to more easily preallocate a buffer size, but you don't need to care care
if (sec.appname == "COOMTECH") {
const ret = Buffer.alloc(sec.data.readInt32LE(0));
let ptr = 0;
do {
sec = read_section(gif, sec.end);
sec.data.copy(ret, ptr);
ptr += sec.data.byteLength;
end = sec.end;
} while (sec.appname == "COOMTECH" && gif[end] == '!'.charCodeAt(0));
return { data: ret, filename: 'embedded' } as EmbeddedFile;
}
end = sec.end;
}
throw "Shouldn't happen";
// metadata ended, nothing...
};
const extract = extractBuff;
const write_embedding = async (writer: WritableStreamDefaultWriter<Buffer>, inj: Buffer) => {
const write_data = async (writer: WritableStreamDefaultWriter<Buffer>, inj: Buffer) => {
await writer.write(magic);
const byte = Buffer.from([0]);
let size = inj.byteLength;
@ -65,11 +71,26 @@ const write_embedding = async (writer: WritableStreamDefaultWriter<Buffer>, inj:
await writer.write(byte);
};
const write_embedding = async (writer: WritableStreamDefaultWriter<Buffer>, inj: Buffer) => {
const b = Buffer.alloc(4);
b.writeInt32LE(inj.byteLength, 0);
await write_data(writer, b);
let size = inj.byteLength;
let offset = 0;
while (size != 0) {
const ws = size >= (3 << 13) ? (3 << 13) : size;
await write_data(writer, inj.slice(offset, offset + ws));
offset += ws;
size -= ws;
}
};
const inject = async (container: File, inj: File) => {
const [writestream, extract] = BufferWriteStream();
const writer = writestream.getWriter();
const contbuff = Buffer.from(await container.arrayBuffer());
debugger;
const field = contbuff.readUInt8(10);
const gcte = !!(field & (1 << 0x7));

62
src/main.ts

@ -14,6 +14,8 @@ import ScrollHighlighter from "./ScrollHighlighter.svelte";
import SettingsButton from './SettingsButton.svelte';
import Embedding from './Embedding.svelte';
import EyeButton from './EyeButton.svelte';
import { fileTypeFromBuffer } from "file-type";
import { buf } from "crc-32";
export interface ImageProcessor {
skip?: true;
@ -327,30 +329,36 @@ customStyles.appendChild(document.createTextNode(globalCss));
document.documentElement.insertBefore(customStyles, null);
// if ((window as any)['pagemode']) {
// onload = () => {
// const resbuf = async (s: EmbeddedFile['data']) => Buffer.isBuffer(s) ? s : await s();
// const container = document.getElementById("container") as HTMLInputElement;
// const injection = document.getElementById("injection") as HTMLInputElement;
// container.onchange = injection.onchange = async () => {
// console.log('eval changed');
// if (container.files?.length && injection.files?.length) {
// const dlr = document.getElementById("dlr") as HTMLAnchorElement;
// const dle = document.getElementById("dle") as HTMLAnchorElement;
// const res = await gif.inject!(container.files[0], injection.files[0]);
// console.log('inj done');
// const result = document.getElementById("result") as HTMLImageElement;
// const extracted = document.getElementById("extracted") as HTMLImageElement;
// const res2 = new Blob([res], {type: (await fileTypeFromBuffer(res))?.mime});
// result.src = URL.createObjectURL(res2);
// dlr.href = result.src;
// console.log('url created');
// const embedded = await gif.extract(res);
// if (!embedded)
// debugger;
// extracted.src = URL.createObjectURL(new Blob([await resbuf(embedded?.data!)]));
// dle.href = extracted.src;
// }
// };
// };
// }
//if ((window as any)['pagemode']) {
// onload = () => {
// console.log("loaded");
// const resbuf = async (s: EmbeddedFile['data']) => Buffer.isBuffer(s) ? s : await s();
// const container = document.getElementById("container") as HTMLInputElement;
// const injection = document.getElementById("injection") as HTMLInputElement;
// container.onchange = injection.onchange = async () => {
// console.log('eval changed');
// if (container.files?.length && injection.files?.length) {
// const dlr = document.getElementById("dlr") as HTMLAnchorElement;
// const dle = document.getElementById("dle") as HTMLAnchorElement;
// console.log(buf(new Uint8Array(await container.files[0].arrayBuffer())));
// console.log(buf(new Uint8Array(await injection.files[0].arrayBuffer())));
// const res = await gif.inject!(container.files[0], injection.files[0]);
// console.log('inj done', buf(res));
// const result = document.getElementById("result") as HTMLImageElement;
// const extracted = document.getElementById("extracted") as HTMLImageElement;
// const res2 = new Blob([res], { type: (await fileTypeFromBuffer(res))?.mime });
// result.src = URL.createObjectURL(res2);
// dlr.href = result.src;
// console.log('url created');
// const embedded = await gif.extract(res);
// console.log(buf(new Uint8Array(await resbuf(embedded.data))));
// if (!embedded) {
// debugger;
// return;
// }
// extracted.src = URL.createObjectURL(new Blob([await resbuf(embedded.data!)]));
// dle.href = extracted.src;
// }
// };
// };
//}
Loading…
Cancel
Save