/** Max length of PackBits literal. */ const MAX_LITERAL_LENGTH = 127 ; param src param srcBegin param dest param destBegin param size const arrayCopy = ( src , srcBegin , dest , destBegin , size ) => { if ( src . length <= srcBegin || src . length < size || dest . length <= destBegin || dest . length < size ) { return ; } for ( let i = srcBegin , j = destBegin , k = 0 ; k < size ; ++ i , ++ j , ++ k ) { dest [ j ] = src [ i ] ; } } ; param value return const toUInt8 = ( value ) => { return value & 0xff ; } ; param value return see https const toInt8 = ( value ) => { return ( value << 24 ) >> 24 ; } ; param literals return export const packBitsLiteralToResult = ( literals ) => { return literals . length === 0 ? [ ] : [ toUInt8 ( literals . length - 1 ) ] . concat ( literals ) ; } ; param src return see https see http export const unpackBits = ( src ) => { const dest = [ ] ; for ( let i = 0 , max = src . length ; i < max ; ++ i ) { const count = toInt8 ( toUInt8 ( src [ i ] ) ) ; if ( count === - 128 ) { } else if ( 0 <= count ) { const total = count + 1 ; for ( let j = 0 ; j < total ; ++ j ) { dest . push ( toUInt8 ( src [ i + j + 1 ] ) ) ; } i += total ; } else { const total = Math . abs ( count ) + 1 ; for ( let j = 0 ; j < total ; ++ j ) { dest . push ( toUInt8 ( src [ i + 1 ] ) ) ; } ++ i ; } } return dest ; } ; param src return see https export const packICNS = ( src ) => { const packedData = new Array ( src . length * 2 ) . fill ( 0 ) ; let output = 0 ; for ( let input = 0 ; input < src . length ; ) { let literalStart = input ; let currentData = src [ input ++ ] ; let readBytes = 1 ; let repeatedBytes = 0 ; while ( input < src . length && readBytes < 128 && repeatedBytes < 3 ) { const nextData = src [ input ++ ] ; if ( nextData === currentData ) { if ( repeatedBytes === 0 ) { repeatedBytes = 2 ; } else { repeatedBytes ++ ; } } else { repeatedBytes = 0 ; } readBytes ++ ; currentData = nextData ; } let literalBytes = 0 ; if ( repeatedBytes < 3 ) { literalBytes = readBytes ; repeatedBytes = 0 ; } else { literalBytes = readBytes - repeatedBytes ; } if ( 0 < literalBytes ) { packedData [ output ++ ] = toUInt8 ( literalBytes - 1 ) ; arrayCopy ( src , literalStart , packedData , output , literalBytes ) ; output += literalBytes ; } while ( input < src . length && src [ input ] === currentData && repeatedBytes < 130 ) { repeatedBytes ++ ; input ++ ; } if ( 3 <= repeatedBytes ) { packedData [ output ++ ] = toUInt8 ( repeatedBytes + 125 ) ; packedData [ output ++ ] = currentData ; } else { input -= repeatedBytes ; } } const dest = new Array ( output ) . fill ( 0 ) ; arrayCopy ( packedData , 0 , dest , 0 , output ) ; return dest ; } ; param src return see https see http export const packBits = ( src ) => { if ( ! ( src && src . length && 0 < src . length ) ) { return [ ] ; } let dest = [ ] ; let literals = [ ] ; for ( let i = 0 , max = src . length ; i < max ; ++ i ) { const current = toUInt8 ( src [ i ] ) ; if ( i + 1 < max ) { const next = toUInt8 ( src [ i + 1 ] ) ; if ( current === next ) { dest = dest . concat ( packBitsLiteralToResult ( literals ) ) ; literals = [ ] ; const maxJ = max <= i + MAX_LITERAL_LENGTH ? max - i - 1 : MAX_LITERAL_LENGTH ; let hitMax = true ; let runLength = 1 ; for ( let j = 2 ; j <= maxJ ; ++ j ) { const run = src [ i + j ] ; if ( current !== run ) { hitMax = false ; const count = toUInt8 ( 0 - runLength ) ; i += j - 1 ; dest . push ( count ) ; dest . push ( current ) ; break ; } ++ runLength ; } if ( hitMax ) { dest . push ( toUInt8 ( 0 - maxJ ) ) ; dest . push ( current ) ; i += maxJ ; } } else { literals . push ( current ) ; if ( literals . length === MAX_LITERAL_LENGTH ) { dest = dest . concat ( packBitsLiteralToResult ( literals ) ) ; literals = [ ] ; } } } else { literals . push ( current ) ; dest = dest . concat ( packBitsLiteralToResult ( literals ) ) ; literals = [ ] ; } } return dest ; } ;