Skip to content

Instantly share code, notes, and snippets.

@danbri
Created December 26, 2025 12:30
Show Gist options
  • Select an option

  • Save danbri/bc4e253f8227bca4d4a323145ff44bae to your computer and use it in GitHub Desktop.

Select an option

Save danbri/bc4e253f8227bca4d4a323145ff44bae to your computer and use it in GitHub Desktop.
x1.service_pack_1
<!-- take a PBM image; decode it and paint it onto a canvas -->
<!DOCTYPE html>
<html>
<body>
<canvas id="display" style="image-rendering: pixelated; width: 100%;"></canvas>
</body>
<script>
const rawimg = [ 0x50, 0x34, 0x0a, 0x31, 0x32, 0x38, 0x20, 0x36, 0x34, 0x0a, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff,
0xff, 0xcf, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfc, 0xff, 0xff, 0xcf, 0xff, 0xcc, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xcf, 0xff, 0xfc,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x1c, 0xe0,
0xc1, 0xc1, 0xcc, 0xc8, 0x38, 0x70, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfc, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0xcc, 0xf3, 0x33, 0x3f, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xcc, 0xcc, 0xe0, 0xcc, 0xcc, 0xcc,
0xf0, 0x33, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xcc, 0xcc,
0xcc, 0xcc, 0xcc, 0xcc, 0xf3, 0xf3, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfe, 0x1c, 0xe0, 0xc0, 0xc1, 0xe0, 0xcc, 0x38, 0x33, 0x3f, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe1,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x77, 0xfd, 0xf7, 0xdf, 0xff, 0xff, 0xef, 0xff,
0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0x77, 0xff, 0xf7, 0xff,
0xff, 0xff, 0xd7, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff,
0x76, 0x79, 0xc1, 0x9d, 0x38, 0xff, 0xde, 0x34, 0xff, 0x8e, 0x74, 0xe5,
0xff, 0xff, 0xff, 0xff, 0x57, 0xbd, 0xf7, 0xdc, 0xd6, 0x7f, 0x8d, 0xd3,
0x7f, 0x77, 0xb3, 0x59, 0xff, 0xff, 0xff, 0xff, 0x56, 0x3d, 0xf7, 0xdd,
0xd6, 0x7f, 0xdd, 0xd7, 0xff, 0x7e, 0x37, 0xdd, 0xff, 0xff, 0xff, 0xff,
0x55, 0xbd, 0xf5, 0xdd, 0xd9, 0x7f, 0xdd, 0xd7, 0xff, 0x75, 0xb7, 0xd9,
0xff, 0xff, 0xff, 0xff, 0xae, 0x18, 0xfb, 0x8d, 0xdf, 0x7f, 0xde, 0x37,
0xff, 0x8e, 0x17, 0xe5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x02, 0x27, 0x3c, 0xf8,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00,
0x03, 0x68, 0xa2, 0x80, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf0, 0x00, 0x02, 0xa8, 0xa2, 0x80, 0x00, 0x00, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x02, 0xa8, 0xbc, 0xf0,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00,
0x02, 0xa8, 0xa8, 0x80, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf0, 0x00, 0x02, 0x28, 0xa4, 0x80, 0x00, 0x00, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x02, 0x27, 0x22, 0xf8,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00 ];
render(rawimg, document.getElementById("display"));
function render(data, canvas) {
// Check that we have a P4 image
if (data[0] != 80 || data[1] != 52 || data[2] != 10) {
console.log("Not a P4 image. Ignoring");
return;
};
// Extract the Width and Height from the second line.
//
var dims = "", i = 3;
while(data[i] != 10)
dims += String.fromCharCode(data[i++]);
const [w,h] = dims.split(" ");
i++; // skip trailing \n
// ADD THESE TWO LINES:
canvas.width = w;
canvas.height = h;
console.log(x);
console.log(y);
// Remainder is pure bytes; with a set bit for white; unset for black per pixel
//
const ctx = canvas.getContext("2d");
const raw = ctx.createImageData(w, h);
var j = 0;
for(var y = 0; y < h; y++)
for(var x = 0; x < w; x++) {
const o = x + y * w;
const bv = data[ i + (o >> 3)] & (1<< (7-(o & 7))) ? 0 : 255;
raw.data[j++] = bv; // Red
raw.data[j++] = bv; // Green
raw.data[j++] = bv; // Blue
raw.data[j++] = 255; // opacity
}
ctx.putImageData(raw, 0,0);
}
</script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment