Spaces:
Running
Running
import { crc32 } from 'crc'; | |
/** | |
* Encodes PNG chunks into a PNG file format buffer. | |
* @param {Array<{ name: string; data: Uint8Array }>} chunks Array of PNG chunks | |
* @returns {Uint8Array} Encoded PNG data | |
* @copyright Based on https://github.com/hughsk/png-chunks-encode (MIT) | |
*/ | |
export default function encode(chunks) { | |
const uint8 = new Uint8Array(4); | |
const int32 = new Int32Array(uint8.buffer); | |
const uint32 = new Uint32Array(uint8.buffer); | |
let totalSize = 8; | |
let idx = totalSize; | |
for (let i = 0; i < chunks.length; i++) { | |
totalSize += chunks[i].data.length; | |
totalSize += 12; | |
} | |
const output = new Uint8Array(totalSize); | |
output[0] = 0x89; | |
output[1] = 0x50; | |
output[2] = 0x4E; | |
output[3] = 0x47; | |
output[4] = 0x0D; | |
output[5] = 0x0A; | |
output[6] = 0x1A; | |
output[7] = 0x0A; | |
for (let i = 0; i < chunks.length; i++) { | |
const { name, data } = chunks[i]; | |
const size = data.length; | |
const nameChars = [ | |
name.charCodeAt(0), | |
name.charCodeAt(1), | |
name.charCodeAt(2), | |
name.charCodeAt(3), | |
]; | |
uint32[0] = size; | |
output[idx++] = uint8[3]; | |
output[idx++] = uint8[2]; | |
output[idx++] = uint8[1]; | |
output[idx++] = uint8[0]; | |
output[idx++] = nameChars[0]; | |
output[idx++] = nameChars[1]; | |
output[idx++] = nameChars[2]; | |
output[idx++] = nameChars[3]; | |
for (let j = 0; j < size;) { | |
output[idx++] = data[j++]; | |
} | |
const crc = crc32(data, crc32(new Uint8Array(nameChars))); | |
int32[0] = crc; | |
output[idx++] = uint8[3]; | |
output[idx++] = uint8[2]; | |
output[idx++] = uint8[1]; | |
output[idx++] = uint8[0]; | |
} | |
return output; | |
} | |