@@ -85,19 +85,26 @@ export async function decode(array) {
8585 let c_offset = 33 ;
8686 const chunks = [ ] ;
8787
88- let palette ;
89- if ( array [ 25 ] === 3 )
90- palette = new Uint32Array ( 2 ** bpc ) ;
88+ let palette , alphaPalette ;
9189 let type ;
9290 while ( type !== 1229278788 ) {
9391 type = view . getUint32 ( 4 + c_offset ) ;
9492
9593 // IDAT
9694 if ( type === 1229209940 )
9795 chunks . push ( array . subarray ( 8 + c_offset , 8 + c_offset + view . getUint32 ( c_offset ) ) ) ;
98- else if ( type === 1347179589 ) {
96+ else if ( type === 1347179589 ) { // PLTE
97+ if ( palette )
98+ throw new Error ( 'PLTE can only occur once in an image' ) ;
99+ palette = new Uint32Array ( view . getUint32 ( c_offset ) ) ;
99100 for ( let pxlOffset = 0 ; pxlOffset < palette . length * 8 ; pxlOffset += 3 )
100101 palette [ pxlOffset / 3 ] = array [ 8 + c_offset + pxlOffset ] << 24 | array [ 8 + c_offset + pxlOffset + 1 ] << 16 | array [ 8 + c_offset + pxlOffset + 2 ] << 8 | 0xff ;
102+ } else if ( type === 1951551059 ) { // tRNS
103+ if ( alphaPalette )
104+ throw new Error ( 'tRNS can only occur once in an image' ) ;
105+ alphaPalette = new Uint8Array ( view . getUint32 ( c_offset ) ) ;
106+ for ( let i = 0 ; i < alphaPalette . length ; i ++ )
107+ alphaPalette [ i ] = array [ 8 + c_offset + i ] ;
101108 }
102109
103110 c_offset += 4 + 4 + 4 + view . getUint32 ( c_offset ) ;
@@ -118,7 +125,14 @@ export async function decode(array) {
118125 p_offset += row_length ;
119126 }
120127
121- if ( channels === 1 && palette ) {
128+ if ( pixel_type === 3 ) {
129+ if ( ! palette )
130+ throw new Error ( 'Indexed color PNG has no PLTE' ) ;
131+
132+ if ( alphaPalette )
133+ for ( let i = 0 ; i < alphaPalette . length ; i ++ )
134+ palette [ i ] &= 0xffffff00 | alphaPalette [ i ] ;
135+
122136 channels = 4 ;
123137 const newPixels = new Uint8Array ( width * height * 4 ) ;
124138 const pixelView = new DataView ( newPixels . buffer , newPixels . byteOffset , newPixels . byteLength ) ;
@@ -206,4 +220,4 @@ function filter_4(slice, pixels, p_offset, bytespp, row_length) {
206220 pixels [ i + p_offset ] = slice [ i ++ ] + ( ( pa <= pb && pa <= pc ) ? a : ( ( pb <= pc ) ? b : c ) ) ;
207221 }
208222 }
209- }
223+ }
0 commit comments