const canvas = document.querySelector("canvas"); canvas.width = 480; canvas.height = 480; const context = canvas.getContext("2d"); const imageData = context.createImageData(canvas.width, canvas.height); const cstride = canvas.width * 4; for (let y = 0; y < canvas.height; y++) { for (let x = 0; x < canvas.width; x++) { imageData.data[y * cstride + x * 4 + 0] = x; imageData.data[y * cstride + x * 4 + 1] = y; imageData.data[y * cstride + x * 4 + 2] = 0; imageData.data[y * cstride + x * 4 + 3] = 255; } } context.putImageData(imageData, 0, 0); const memoryBlocks = 129 + 128 * 10; const memorySize = memoryBlocks * (64 * 1024); const memory = new WebAssembly.Memory({ initial: memoryBlocks }); const memoryU8 = new Uint8Array(memory.buffer); function round(n, m) { return (n + (m - 1)) & ~(m - 1); } class Allocator { constructor(size) { this.size = size; this.offset = 0; } alloc(size) { const address = this.offset; this.offset += round(size, 32); if (this.offset > this.size) { throw new Error(`allocator overflow: ${this.offset} > ${this.size}`); } return address; } } function memoryString(mem, offset) { const s = []; var i = offset; while (mem[i] != 0 && (i - offset) < 256) { s.push(mem[i]); i++; } return new TextDecoder().decode(new Uint8Array(s)); } const m = new Allocator(memorySize); m.offset = (129 + 64) * 64 * 1024; const crcTableA = m.alloc(256 * 4); const png = await WebAssembly.instantiateStreaming(fetch("png.wasm"), { env: { memory: memory } }); /* const test = await WebAssembly.instantiateStreaming(fetch("test.wasm"), { env: { memory: memory } }); const res = test.instance.exports.test(); console.log("res", res); console.log(memoryString(memoryU8, res)); */ png.instance.exports.build_crc_table(crcTableA); /* const crcTable = new Uint32Array(memory.buffer, crcTableA); for (let i = 0; i < 256; i++) { console.log(crcTable[i].toString(16).padStart(8, '0')); } */ const pngResponse = await fetch("../gltf/Image_0.png"); const pngBuffer = await pngResponse.arrayBuffer(); console.log(pngBuffer.byteLength); const pngA = m.alloc(pngBuffer.byteLength); const pngBufferU8 = new Uint8Array(pngBuffer); memoryU8.set(pngBufferU8, pngA); console.log("a0", memoryU8[pngA], pngBufferU8[0]); const headerA = m.alloc(7 * 4); const obufSize = canvas.width * canvas.height * 3; const obufA = m.alloc(obufSize); console.log("obufA", obufA, obufSize); const errorA = m.alloc(4); const ret = png.instance.exports.decode(crcTableA, pngA, pngBuffer.byteLength, headerA, obufA, obufSize, errorA); if (ret < 0) { const address = new Uint32Array(memory.buffer, errorA); console.log("error3", ret, crcTableA, address[0], memoryString(memoryU8, address[0])); //for (let i = 0; i < 256; i++) { //console.log(memoryU8[(-ret) + i]); //} } console.log(ret); if (ret >= 0) { console.log("ret", ret); const pstride = canvas.width * 3; for (let y = 0; y < canvas.height; y++) { for (let x = 0; x < canvas.width; x++) { imageData.data[y * cstride + x * 4 + 0] = memoryU8[obufA + pstride * y + x * 3 + 0]; imageData.data[y * cstride + x * 4 + 1] = memoryU8[obufA + pstride * y + x * 3 + 1]; imageData.data[y * cstride + x * 4 + 2] = memoryU8[obufA + pstride * y + x * 3 + 2]; imageData.data[y * cstride + x * 4 + 3] = 255; } } context.putImageData(imageData, 0, 0); }