| 1 | import { crc32 } from 'crc'; |
| 2 | |
| 3 | /** |
| 4 | * Encodes PNG chunks into a PNG file format buffer. |
| 5 | * @param {Array<{ name: string; data: Uint8Array }>} chunks Array of PNG chunks |
| 6 | * @returns {Uint8Array} Encoded PNG data |
| 7 | * @copyright Based on https://github.com/hughsk/png-chunks-encode (MIT) |
| 8 | */ |
| 9 | export default function encode(chunks) { |
| 10 | const uint8 = new Uint8Array(4); |
| 11 | const int32 = new Int32Array(uint8.buffer); |
| 12 | const uint32 = new Uint32Array(uint8.buffer); |
| 13 | |
| 14 | let totalSize = 8; |
| 15 | let idx = totalSize; |
| 16 | |
| 17 | for (let i = 0; i < chunks.length; i++) { |
| 18 | totalSize += chunks[i].data.length; |
| 19 | totalSize += 12; |
| 20 | } |
| 21 | |
| 22 | const output = new Uint8Array(totalSize); |
| 23 | |
| 24 | output[0] = 0x89; |
| 25 | output[1] = 0x50; |
| 26 | output[2] = 0x4E; |
| 27 | output[3] = 0x47; |
| 28 | output[4] = 0x0D; |
| 29 | output[5] = 0x0A; |
| 30 | output[6] = 0x1A; |
| 31 | output[7] = 0x0A; |
| 32 | |
| 33 | for (let i = 0; i < chunks.length; i++) { |
| 34 | const { name, data } = chunks[i]; |
| 35 | const size = data.length; |
| 36 | const nameChars = [ |
| 37 | name.charCodeAt(0), |
| 38 | name.charCodeAt(1), |
| 39 | name.charCodeAt(2), |
| 40 | name.charCodeAt(3), |
| 41 | ]; |
| 42 | |
| 43 | uint32[0] = size; |
| 44 | output[idx++] = uint8[3]; |
| 45 | output[idx++] = uint8[2]; |
| 46 | output[idx++] = uint8[1]; |
| 47 | output[idx++] = uint8[0]; |
| 48 | |
| 49 | output[idx++] = nameChars[0]; |
| 50 | output[idx++] = nameChars[1]; |
| 51 | output[idx++] = nameChars[2]; |
| 52 | output[idx++] = nameChars[3]; |
| 53 | |
| 54 | for (let j = 0; j < size;) { |
| 55 | output[idx++] = data[j++]; |
| 56 | } |
| 57 | |
| 58 | const crc = crc32(data, crc32(new Uint8Array(nameChars))); |
| 59 | |
| 60 | int32[0] = crc; |
| 61 | output[idx++] = uint8[3]; |
| 62 | output[idx++] = uint8[2]; |
| 63 | output[idx++] = uint8[1]; |
| 64 | output[idx++] = uint8[0]; |
| 65 | } |
| 66 | |
| 67 | return output; |
| 68 | } |