64 lines
1.6 KiB
HTML
64 lines
1.6 KiB
HTML
<!DOCTYPE html>
|
|
<script>
|
|
(async () => {
|
|
const W = 255, H = 255;
|
|
const maskRowSize = Math.floor((W + 31) / 32) * 4;
|
|
const maskBytes = maskRowSize * H;
|
|
const bytesInRes = 40 + 12 + maskBytes;
|
|
|
|
function buildChunk1() {
|
|
const c = new Uint8Array(62);
|
|
c.set([0,0, 1,0, 1,0], 0);
|
|
c[6] = W; c[7] = H;
|
|
c[10] = 1; c[12] = 32;
|
|
c[14] = bytesInRes & 0xff;
|
|
c[15] = (bytesInRes >> 8) & 0xff;
|
|
c[16] = (bytesInRes >> 16) & 0xff;
|
|
c[17] = (bytesInRes >> 24) & 0xff;
|
|
c[18] = 22;
|
|
const bih = new DataView(c.buffer, 22, 40);
|
|
bih.setUint32(0, 40, true);
|
|
bih.setInt32(4, W, true);
|
|
bih.setInt32(8, H * 2, true);
|
|
bih.setUint16(12, 1, true);
|
|
bih.setUint16(14, 32, true);
|
|
bih.setUint32(16, 3, true);
|
|
bih.setUint32(20, 0, true);
|
|
return c;
|
|
}
|
|
|
|
function buildChunk2() {
|
|
const c = new Uint8Array(12 + maskBytes);
|
|
const bf = new DataView(c.buffer, 0, 12);
|
|
bf.setUint32(0, 0x00FF0000, true);
|
|
bf.setUint32(4, 0x0000FF00, true);
|
|
bf.setUint32(8, 0x000000FF, true);
|
|
return c;
|
|
}
|
|
|
|
let deliver2;
|
|
const stream = new ReadableStream({
|
|
async start(controller) {
|
|
controller.enqueue(buildChunk1());
|
|
await new Promise(r => { deliver2 = r; });
|
|
controller.enqueue(buildChunk2());
|
|
controller.close();
|
|
}
|
|
});
|
|
|
|
const decoder = new ImageDecoder({
|
|
type: 'image/x-icon',
|
|
data: stream,
|
|
desiredWidth: 16,
|
|
desiredHeight: 16,
|
|
});
|
|
|
|
await decoder.tracks.ready;
|
|
const decodePromise = decoder.decode();
|
|
await new Promise(r => step_timeout(r, 500));
|
|
deliver2();
|
|
try { await decodePromise; } catch(e) {}
|
|
await new Promise(r => step_timeout(r, 2000));
|
|
})();
|
|
</script>
|