export class GifFrame { public transparentFlag : boolean ; public delayCentiSeconds : number ; public transparentColorIndex : number ; public x : number ; public y : number ; public width : number ; public height : number ; public localTableSize : number ; public lzwCode : number ; public localColorTable : Uint8Array ; public compressedData : Uint8Array ; public pixelData : Uint8Array ; public static init ( width , height ) { const frame = new GifFrame ( ) ; frame . transparentFlag = false ; frame . delayCentiSeconds = 0 ; frame . transparentColorIndex = 0 ; frame . x = 0 ; frame . y = 0 ; frame . width = width || 1 ; frame . height = height || 1 ; frame . localTableSize = 0 ; frame . lzwCode = 4 ; frame . pixelData = new Uint8Array ( frame . width * frame . height ) ; return frame ; } public decompress ( ) { this . pixelData = this . lzwDecode ( this . lzwCode , this . compressedData , this . width * this . height ) ; } private lzwDecode ( minCodeSize , data , len ) { let pos = 0 ; const readCode = function ( size ) : number { let code = 0 ; for ( let i = 0 ; i < size ; ++ i ) { if ( data [ pos >> 3 ] & ( 1 << ( pos & 7 ) ) ) { code |= 1 << i ; } ++ pos ; } return code ; } ; const output = new Uint8Array ( len ) ; const clearCode = 1 << minCodeSize ; const eoiCode = clearCode + 1 ; let codeSize = minCodeSize + 1 ; let dict = [ ] ; const clear = ( ) : void => { dict = [ ] ; codeSize = minCodeSize + 1 ; for ( let i = 0 ; i < clearCode ; ++ i ) { dict [ i ] = [ i ] ; } dict [ clearCode ] = [ ] ; } ; let code = 0 ; let last ; let offset = 0 ; while ( true ) { last = code ; code = readCode ( codeSize ) ; if ( code === clearCode ) { clear ( ) ; continue ; } if ( code === eoiCode ) break ; if ( code < dict . length ) { if ( last !== clearCode ) { dict . push ( dict [ last ] . concat ( dict [ code ] [ 0 ] ) ) ; } } else { if ( code !== dict . length ) throw new Error ( "Invalid LZW code." ) ; dict . push ( dict [ last ] . concat ( dict [ last ] [ 0 ] ) ) ; } output . set ( dict [ code ] , offset ) ; offset += dict [ code ] . length ; if ( dict . length === 1 << codeSize && codeSize < 12 ) { codeSize ++ ; } } return output ; } }