SOURCE / PINNED RELEASE
Made of little things.
Powder Tool V600Billion
- Release
- 142767edcab8…
- Author-recorded commit
- 6d92971effd0…
- License
- LICENSE
- Author’s source reference
- nostr://npub1fllw8kw0thjj55wds0uugcnp5kej2nfxd36eruq39d56wwz8r44q5q78wj/wss%3A%2F%2Fgit.napplet.soy%2F/powder-toy
Archive hash verified: ed7d6a8ea7083197…. The source-to-build association is the author’s claim; it has not been independently rebuilt.
/** Minimal PNG reader for tests: 8-bit RGB/RGBA, non-interlaced (what Chromium and our encoder write). */
import { inflateSync } from 'node:zlib';
export function readPng(buffer) {
const bytes = Buffer.from(buffer);
if (bytes.readUInt32BE(0) !== 0x89504e47) throw new Error('not a PNG');
let offset = 8, width = 0, height = 0, colorType = 0, bitDepth = 0;
const idat = [];
while (offset < bytes.length) {
const length = bytes.readUInt32BE(offset);
const type = bytes.toString('latin1', offset + 4, offset + 8);
const data = bytes.subarray(offset + 8, offset + 8 + length);
if (type === 'IHDR') {
width = data.readUInt32BE(0); height = data.readUInt32BE(4);
bitDepth = data[8]; colorType = data[9];
if (data[12] !== 0) throw new Error('interlaced PNG not supported');
} else if (type === 'IDAT') idat.push(data);
else if (type === 'IEND') break;
offset += 12 + length;
}
if (bitDepth !== 8 || (colorType !== 2 && colorType !== 6)) throw new Error(`unsupported PNG ${bitDepth}/${colorType}`);
const channels = colorType === 6 ? 4 : 3;
const raw = inflateSync(Buffer.concat(idat));
const stride = width * channels;
const pixels = new Uint8Array(width * height * 4);
let previous = new Uint8Array(stride);
for (let y = 0; y < height; y++) {
const filter = raw[y * (stride + 1)];
const line = raw.subarray(y * (stride + 1) + 1, (y + 1) * (stride + 1));
const current = new Uint8Array(stride);
for (let x = 0; x < stride; x++) {
const a = x >= channels ? current[x - channels] : 0, b = previous[x], c = x >= channels ? previous[x - channels] : 0;
let value = line[x];
if (filter === 1) value += a;
else if (filter === 2) value += b;
else if (filter === 3) value += (a + b) >> 1;
else if (filter === 4) { const p = a + b - c, pa = Math.abs(p - a), pb = Math.abs(p - b), pc = Math.abs(p - c); value += pa <= pb && pa <= pc ? a : pb <= pc ? b : c; }
current[x] = value & 0xff;
}
for (let x = 0; x < width; x++) {
const i = (y * width + x) * 4;
pixels[i] = current[x * channels]; pixels[i + 1] = current[x * channels + 1]; pixels[i + 2] = current[x * channels + 2];
pixels[i + 3] = channels === 4 ? current[x * channels + 3] : 255;
}
previous = current;
}
return { width, height, pixels, at(x, y) { const i = (y * width + x) * 4; return [pixels[i], pixels[i + 1], pixels[i + 2], pixels[i + 3]]; } };
}
/** Share of pixels in a box that are not (near) black. */
export function litShare(image, { x, y, w, h }) {
let lit = 0, total = 0;
for (let j = y; j < y + h; j++) for (let i = x; i < x + w; i++) {
const [r, g, b] = image.at(i, j);
total++;
if (r + g + b > 60) lit++;
}
return total ? lit / total : 0;
}
