diff --git a/src/icon.ts b/src/icon.ts index 74a05ae..2dd34e0 100644 --- a/src/icon.ts +++ b/src/icon.ts @@ -18,7 +18,7 @@ export abstract class Icon { * @returns Image data. */ protected _decodePngToRgba(data: Readonly) { - const image = UPNG.decode(data as Buffer); + const image = UPNG.decode(data); return { width: image.width, height: image.height, diff --git a/src/util.test.ts b/src/util.test.ts index bafa7f9..7e1c168 100644 --- a/src/util.test.ts +++ b/src/util.test.ts @@ -11,7 +11,7 @@ void describe('util', () => { // eslint-disable-next-line no-loop-func void it(`${name}: ${size}`, async () => { const info = pngIhdr( - await readFile(specIconFilePng(name, size)) + new Uint8Array(await readFile(specIconFilePng(name, size))) ); strictEqual(info.width, size); diff --git a/src/util.ts b/src/util.ts index 02b3d5e..4b8bc3b 100644 --- a/src/util.ts +++ b/src/util.ts @@ -6,31 +6,43 @@ import {IPngIhdr} from './types'; * @param data PNG data. * @returns PNG IHDR. */ -export function pngIhdr(data: Readonly): IPngIhdr { - if (data.toString('ascii', 0, 8) !== '\tPNG\r\n\x1a\n') { +export function pngIhdr(data: Readonly): IPngIhdr { + let i = 0; + if ( + data[i++] !== 137 || + data[i++] !== 80 || + data[i++] !== 78 || + data[i++] !== 71 || + data[i++] !== 13 || + data[i++] !== 10 || + data[i++] !== 26 || + data[i++] !== 10 + ) { throw new Error('Invalid PNG header signature'); } // Seek out IHDR tag, which should be first (spec requires, some ignore). - let offset = 8; - while (offset < data.length) { - const size = data.readUInt32BE(offset); - offset += 4; - const name = data.toString('ascii', offset, offset + 4); - offset += 4; - if (name === 'IHDR') { - const d = data.subarray(offset, offset + size); + const dv = new DataView(data.buffer, data.byteOffset, data.byteLength); + while (i < data.length) { + const size = dv.getUint32(i, false); + i += 4; + const na = data[i++]; + const nb = data[i++]; + const nc = data[i++]; + const nd = data[i++]; + if (na === 73 && nb === 72 && nc === 68 && nd === 82) { + const d = new DataView(dv.buffer, dv.byteOffset + i, size); return { - width: d.readUInt32BE(0), - height: d.readUInt32BE(4), - bitDepth: d.readUInt8(8), - colorType: d.readUInt8(9), - compressionMethod: d.readUInt8(10), - filterMethod: d.readUInt8(11), - interlacemethod: d.readUInt8(12) + width: d.getUint32(0, false), + height: d.getUint32(4, false), + bitDepth: d.getUint8(8), + colorType: d.getUint8(9), + compressionMethod: d.getUint8(10), + filterMethod: d.getUint8(11), + interlacemethod: d.getUint8(12) }; } - offset += size; + i += size; } throw new Error('Missing PNG IHDR tag');