fast-png
Version:
PNG image decoder and encoder written entirely in JavaScript
66 lines (60 loc) • 1.41 kB
text/typescript
import type { IOBuffer } from 'iobuffer';
const crcTable: number[] = [];
for (let n = 0; n < 256; n++) {
let c = n;
for (let k = 0; k < 8; k++) {
if (c & 1) {
c = 0xedb88320 ^ (c >>> 1);
} else {
c = c >>> 1;
}
}
crcTable[n] = c;
}
const initialCrc = 0xffffffff;
function updateCrc(
currentCrc: number,
data: Uint8Array,
length: number,
): number {
let c = currentCrc;
for (let n = 0; n < length; n++) {
c = crcTable[(c ^ data[n]) & 0xff] ^ (c >>> 8);
}
return c;
}
function crc(data: Uint8Array, length: number): number {
return (updateCrc(initialCrc, data, length) ^ initialCrc) >>> 0;
}
export function checkCrc(
buffer: IOBuffer,
crcLength: number,
chunkName: string,
) {
const expectedCrc = buffer.readUint32();
const actualCrc = crc(
new Uint8Array(
buffer.buffer,
buffer.byteOffset + buffer.offset - crcLength - 4,
crcLength,
),
crcLength,
); // "- 4" because we already advanced by reading the CRC
if (actualCrc !== expectedCrc) {
throw new Error(
`CRC mismatch for chunk ${chunkName}. Expected ${expectedCrc}, found ${actualCrc}`,
);
}
}
export function writeCrc(buffer: IOBuffer, length: number) {
buffer.writeUint32(
crc(
new Uint8Array(
buffer.buffer,
buffer.byteOffset + buffer.offset - length,
length,
),
length,
),
);
}