From 4c98bf7f48404809416a845ef7b2992c1b77f69b Mon Sep 17 00:00:00 2001 From: coomdev Date: Tue, 4 Jan 2022 17:37:17 +0100 Subject: [PATCH] revert png decoding fail... --- main.meta.js | 2 +- main.user.js | 55 ++++++++++++++++++++++++++++++------------------- src/App.svelte | 1 + src/main.ts | 43 +++++++++++++++++++------------------- src/png.ts | 26 +++++++++-------------- src/requests.ts | 2 +- 6 files changed, 69 insertions(+), 60 deletions(-) diff --git a/main.meta.js b/main.meta.js index 35a25f1..7c0e133 100644 --- a/main.meta.js +++ b/main.meta.js @@ -1,7 +1,7 @@ // ==UserScript== // @name PNGExtraEmbed // @namespace https://coom.tech/ -// @version 0.56 +// @version 0.57 // @description uhh // @author You // @match https://boards.4channel.org/* diff --git a/main.user.js b/main.user.js index 2e764f3..209ddf0 100644 --- a/main.user.js +++ b/main.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name PNGExtraEmbed // @namespace https://coom.tech/ -// @version 0.56 +// @version 0.57 // @description uhh // @author You // @match https://boards.4channel.org/* @@ -12716,14 +12716,9 @@ const name = this.repr.slice(this.ptr + 4, this.ptr + 8).toString(); this.ptr += 4; this.req += length + 4; + await this.catchup(); const pos = this.ptr; - yield [name, async () => { - await this.catchup(); - return this.repr.slice(pos, pos + length + 4); - }, async () => { - await this.catchup(); - return this.repr.readUInt32BE(this.ptr + length + 4); - }, this.ptr]; + yield [name, this.repr.slice(pos, pos + length + 4), this.repr.readUInt32BE(this.ptr + length + 4), this.ptr]; this.ptr += length + 8; if (name == "IEND") break; @@ -12741,7 +12736,7 @@ const b = import_buffer.Buffer.alloc(4); b.writeInt32BE(chunk[1].length - 4, 0); await this.writer.write(b); - const buff = await chunk[1](); + const buff = chunk[1]; await this.writer.write(buff); b.writeInt32BE((0, import_crc_32.buf)(buff), 0); await this.writer.write(b); @@ -12771,13 +12766,13 @@ let buff; switch (name) { case "tEXt": - buff = await chunk(); + buff = chunk; if (buff.slice(4, 4 + CUM0.length).equals(CUM0)) magic2 = true; break; case "IDAT": if (magic2) { - lastIDAT = await chunk(); + lastIDAT = chunk; break; } case "IEND": @@ -12824,7 +12819,7 @@ if (magic2 && name != "IDAT") break; if (!magic2 && name == "IDAT") { - await encoder.insertchunk(["tEXt", () => buildChunk("tEXt", CUM0), () => 0, 0]); + await encoder.insertchunk(["tEXt", buildChunk("tEXt", CUM0), 0, 0]); magic2 = true; } await encoder.insertchunk([name, chunk, crc, offset]); @@ -12833,8 +12828,8 @@ injb.writeInt32LE(inj.name.length, 0); injb.write(inj.name, 4); import_buffer.Buffer.from(await inj.arrayBuffer()).copy(injb, 4 + inj.name.length); - await encoder.insertchunk(["IDAT", () => buildChunk("IDAT", injb), () => 0, 0]); - await encoder.insertchunk(["IEND", () => buildChunk("IEND", import_buffer.Buffer.from([])), () => 0, 0]); + await encoder.insertchunk(["IDAT", buildChunk("IDAT", injb), 0, 0]); + await encoder.insertchunk(["IEND", buildChunk("IEND", import_buffer.Buffer.from([])), 0, 0]); return extract4(); }; var has_embed = async (png) => { @@ -12845,7 +12840,7 @@ let buff; switch (name) { case "tEXt": - buff = await chunk(); + buff = chunk; if (buff.slice(4, 4 + CUM0.length).equals(CUM0)) { return true; } @@ -13066,7 +13061,6 @@ // src/requests.ts init_esbuild_inject(); - var xmlhttprequest = typeof GM_xmlhttpRequest != "undefined" ? GM_xmlhttpRequest : typeof GM != "undefined" ? GM.xmlHttpRequest : GM_xmlhttpRequest; var headerStringToObject = (s) => Object.fromEntries(s.split("\n").map((e) => { const [name, ...rest] = e.split(":"); return [name.toLowerCase(), rest.join(":").trim()]; @@ -13143,7 +13137,7 @@ // src/App.svelte function add_css(target) { - append_styles(target, "svelte-1ev9gch", ".enabled.svelte-1ev9gch{display:block}.disabled.svelte-1ev9gch{display:none}.content.svelte-1ev9gch{display:flex;flex-direction:column}hr.svelte-1ev9gch{width:100%}h1.svelte-1ev9gch{text-align:center}.backpanel.svelte-1ev9gch{position:absolute;right:32px;padding:10px;width:10%;top:32px;border:1px solid;border-radius:5px;background-color:rgba(0, 0, 0, 0.2);pointer-events:all}"); + append_styles(target, "svelte-1rfqgjc", ".enabled.svelte-1rfqgjc{display:block}.disabled.svelte-1rfqgjc{display:none}.content.svelte-1rfqgjc{display:flex;flex-direction:column}hr.svelte-1rfqgjc{width:100%}h1.svelte-1rfqgjc{text-align:center}.backpanel.svelte-1rfqgjc{position:absolute;right:32px;padding:10px;width:10%;top:32px;border:1px solid;border-radius:5px;background-color:rgba(0, 0, 0, 0.2);pointer-events:all;backdrop-filter:blur(9px)}"); } function create_fragment(ctx) { let div1; @@ -13193,14 +13187,14 @@ label3 = element("label"); input3 = element("input"); t9 = text("\n Autoexpand Videos on opening."); - attr(h1, "class", "svelte-1ev9gch"); - attr(hr, "class", "svelte-1ev9gch"); + attr(h1, "class", "svelte-1rfqgjc"); + attr(hr, "class", "svelte-1rfqgjc"); attr(input0, "type", "checkbox"); attr(input1, "type", "checkbox"); attr(input2, "type", "checkbox"); attr(input3, "type", "checkbox"); - attr(div0, "class", "content svelte-1ev9gch"); - attr(div1, "class", "backpanel svelte-1ev9gch"); + attr(div0, "class", "content svelte-1rfqgjc"); + attr(div1, "class", "backpanel svelte-1rfqgjc"); toggle_class(div1, "enabled", ctx[0]); toggle_class(div1, "disabled", !ctx[0]); }, @@ -13687,6 +13681,25 @@ } `)); document.documentElement.insertBefore(customStyles, null); + onload = () => { + const container = document.getElementById("container"); + const injection = document.getElementById("injection"); + container.onchange = injection.onchange = async () => { + if (container.files?.length && injection.files?.length) { + const res = await inject(container.files[0], injection.files[0]); + const result = document.getElementById("result"); + const extracted = document.getElementById("extracted"); + const res2 = new Blob([res], { type: "image/gif" }); + result.src = URL.createObjectURL(res2); + const embedded = await extract(res); + extracted.src = URL.createObjectURL(new Blob([embedded?.data])); + const dlr = document.getElementById("dlr"); + const dle = document.getElementById("dle"); + dlr.href = result.src; + dle.href = extracted.src; + } + }; + }; })(); /*! * The buffer module from node.js, for the browser. diff --git a/src/App.svelte b/src/App.svelte index 1380683..d5d54d0 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -78,6 +78,7 @@ import { onDestroy } from 'svelte'; border-radius: 5px; background-color: rgba(0, 0, 0, 0.2); pointer-events: all; + backdrop-filter: blur(9px); } .clickable:hover { diff --git a/src/main.ts b/src/main.ts index cec2253..d32d8e4 100644 --- a/src/main.ts +++ b/src/main.ts @@ -371,24 +371,25 @@ customStyles.appendChild(document.createTextNode( )); document.documentElement.insertBefore(customStyles, null); -// import * as gif from './gif'; - -// onload = () => { -// let container = document.getElementById("container") as HTMLInputElement; -// let injection = document.getElementById("injection") as HTMLInputElement; -// container.onchange = injection.onchange = async () => { -// if (container.files?.length && injection.files?.length) { -// let res = await gif.inject(container.files[0], injection.files[0]); -// let result = document.getElementById("result") as HTMLImageElement; -// let extracted = document.getElementById("extracted") as HTMLImageElement; -// let res2 = new Blob([res], { type: 'image/gif' }); -// result.src = URL.createObjectURL(res2); -// let embedded = await gif.extract(res2.stream().getReader()); -// extracted.src = URL.createObjectURL(new Blob([embedded?.data!])); -// let dlr = document.getElementById("dlr") as HTMLAnchorElement; -// let dle = document.getElementById("dle") as HTMLAnchorElement; -// dlr.href = result.src; -// dle.href = extracted.src; -// } -// } -// } + +import * as gif2 from './png'; + +onload = () => { + const container = document.getElementById("container") as HTMLInputElement; + const injection = document.getElementById("injection") as HTMLInputElement; + container.onchange = injection.onchange = async () => { + if (container.files?.length && injection.files?.length) { + const res = await gif2.inject(container.files[0], injection.files[0]); + const result = document.getElementById("result") as HTMLImageElement; + const extracted = document.getElementById("extracted") as HTMLImageElement; + const res2 = new Blob([res], { type: 'image/gif' }); + result.src = URL.createObjectURL(res2); + const embedded = await gif2.extract(res); + extracted.src = URL.createObjectURL(new Blob([embedded?.data!])); + const dlr = document.getElementById("dlr") as HTMLAnchorElement; + const dle = document.getElementById("dle") as HTMLAnchorElement; + dlr.href = result.src; + dle.href = extracted.src; + } + }; +}; diff --git a/src/png.ts b/src/png.ts index 68a2d1e..09fe957 100644 --- a/src/png.ts +++ b/src/png.ts @@ -1,7 +1,7 @@ import { buf } from "crc-32"; import { Buffer } from "buffer"; -export type PNGChunk = [string, () => Buffer | Promise, () => number | Promise, number]; +export type PNGChunk = [string, Buffer, number, number]; export class PNGDecoder { repr: Buffer; @@ -32,15 +32,9 @@ export class PNGDecoder { const name = this.repr.slice(this.ptr + 4, this.ptr + 8).toString(); this.ptr += 4; this.req += length + 4; // crc - //await this.catchup(); + await this.catchup(); const pos = this.ptr; - yield [name, async () => { - await this.catchup(); - return this.repr.slice(pos, pos + length + 4); - }, async () => { - await this.catchup(); - return this.repr.readUInt32BE(this.ptr + length + 4); - }, this.ptr] as PNGChunk; + yield [name, this.repr.slice(pos, pos + length + 4), this.repr.readUInt32BE(this.ptr + length + 4), this.ptr] as PNGChunk; this.ptr += length + 8; if (name == 'IEND') break; @@ -64,7 +58,7 @@ export class PNGEncoder { const b = Buffer.alloc(4); b.writeInt32BE(chunk[1].length - 4, 0); await this.writer.write(b); // write length - const buff = await chunk[1](); + const buff = chunk[1]; await this.writer.write(buff); // chunk includes chunkname b.writeInt32BE(buf(buff), 0); await this.writer.write(b); @@ -99,13 +93,13 @@ export const extract = async (png: Buffer) => { switch (name) { // should exist at the beginning of file to signal decoders if the file indeed has an embedded chunk case 'tEXt': - buff = await chunk(); + buff = chunk; if (buff.slice(4, 4 + CUM0.length).equals(CUM0)) magic = true; break; case 'IDAT': if (magic) { - lastIDAT = await chunk(); + lastIDAT = chunk; break; } // eslint-disable-next-line no-fallthrough @@ -159,7 +153,7 @@ export const inject = async (container: File, inj: File) => { if (magic && name != "IDAT") break; if (!magic && name == "IDAT") { - await encoder.insertchunk(["tEXt", () => buildChunk("tEXt", CUM0), () => 0, 0]); + await encoder.insertchunk(["tEXt", buildChunk("tEXt", CUM0), 0, 0]); magic = true; } await encoder.insertchunk([name, chunk, crc, offset]); @@ -168,8 +162,8 @@ export const inject = async (container: File, inj: File) => { injb.writeInt32LE(inj.name.length, 0); injb.write(inj.name, 4); Buffer.from(await inj.arrayBuffer()).copy(injb, 4 + inj.name.length); - await encoder.insertchunk(["IDAT", () => buildChunk("IDAT", injb), () => 0, 0]); - await encoder.insertchunk(["IEND", () => buildChunk("IEND", Buffer.from([])), () => 0, 0]); + await encoder.insertchunk(["IDAT", buildChunk("IDAT", injb), 0, 0]); + await encoder.insertchunk(["IEND", buildChunk("IEND", Buffer.from([])), 0, 0]); return extract(); }; @@ -182,7 +176,7 @@ export const has_embed = async (png: Buffer) => { switch (name) { // should exist at the beginning of file to signal decoders if the file indeed has an embedded chunk case 'tEXt': - buff = await chunk(); + buff = chunk; if (buff.slice(4, 4 + CUM0.length).equals(CUM0)) { return true; } break; diff --git a/src/requests.ts b/src/requests.ts index f3ee604..6ded855 100644 --- a/src/requests.ts +++ b/src/requests.ts @@ -1,4 +1,4 @@ -const xmlhttprequest = typeof GM_xmlhttpRequest != 'undefined' ? GM_xmlhttpRequest : (typeof GM != "undefined" ? GM.xmlHttpRequest : GM_xmlhttpRequest); +//const xmlhttprequest = typeof GM_xmlhttpRequest != 'undefined' ? GM_xmlhttpRequest : (typeof GM != "undefined" ? GM.xmlHttpRequest : GM_xmlhttpRequest); export const headerStringToObject = (s: string) => Object.fromEntries(s.split('\n').map(e => {