2017-08-28 09:31:29 +00:00
/ * C o p y r i g h t 2 0 1 7 G o o g l e I n c . A l l R i g h t s R e s e r v e d .
Distributed under MIT license .
See file LICENSE for detail or copy at https : //opensource.org/licenses/MIT
* /
2017-10-09 15:07:34 +00:00
/** @return {function(!Int8Array):!Int8Array} */
function BrotliDecodeClosure ( ) {
2017-08-28 09:31:29 +00:00
"use strict" ;
/** @type {!Int8Array} */
var DICTIONARY _DATA = new Int8Array ( 0 ) ;
/ * *
* @ constructor
* @ param { ! Int8Array } bytes
* @ struct
* /
function InputStream ( bytes ) {
/** @type {!Int8Array} */
this . data = bytes ;
/** @type {!number} */
this . offset = 0 ;
}
2019-04-12 11:57:42 +00:00
var MAX _HUFFMAN _TABLE _SIZE = Int32Array . from ( [ 256 , 402 , 436 , 468 , 500 , 534 , 566 , 598 , 630 , 662 , 694 , 726 , 758 , 790 , 822 , 854 , 886 , 920 , 952 , 984 , 1016 , 1048 , 1080 ] ) ;
2017-08-28 09:31:29 +00:00
var CODE _LENGTH _CODE _ORDER = Int32Array . from ( [ 1 , 2 , 3 , 4 , 0 , 5 , 17 , 6 , 16 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 ] ) ;
2019-04-12 11:57:42 +00:00
var DISTANCE _SHORT _CODE _INDEX _OFFSET = Int32Array . from ( [ 0 , 3 , 2 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 3 , 3 , 3 , 3 , 3 , 3 ] ) ;
2017-08-28 09:31:29 +00:00
var DISTANCE _SHORT _CODE _VALUE _OFFSET = Int32Array . from ( [ 0 , 0 , 0 , 0 , - 1 , 1 , - 2 , 2 , - 3 , 3 , - 1 , 1 , - 2 , 2 , - 3 , 3 ] ) ;
var FIXED _TABLE = Int32Array . from ( [ 0x020000 , 0x020004 , 0x020003 , 0x030002 , 0x020000 , 0x020004 , 0x020003 , 0x040001 , 0x020000 , 0x020004 , 0x020003 , 0x030002 , 0x020000 , 0x020004 , 0x020003 , 0x040005 ] ) ;
var DICTIONARY _OFFSETS _BY _LENGTH = Int32Array . from ( [ 0 , 0 , 0 , 0 , 0 , 4096 , 9216 , 21504 , 35840 , 44032 , 53248 , 63488 , 74752 , 87040 , 93696 , 100864 , 104704 , 106752 , 108928 , 113536 , 115968 , 118528 , 119872 , 121280 , 122016 ] ) ;
var DICTIONARY _SIZE _BITS _BY _LENGTH = Int32Array . from ( [ 0 , 0 , 0 , 0 , 10 , 10 , 11 , 11 , 10 , 10 , 10 , 10 , 10 , 9 , 9 , 8 , 7 , 7 , 8 , 7 , 7 , 6 , 6 , 5 , 5 ] ) ;
var BLOCK _LENGTH _OFFSET = Int32Array . from ( [ 1 , 5 , 9 , 13 , 17 , 25 , 33 , 41 , 49 , 65 , 81 , 97 , 113 , 145 , 177 , 209 , 241 , 305 , 369 , 497 , 753 , 1265 , 2289 , 4337 , 8433 , 16625 ] ) ;
var BLOCK _LENGTH _N _BITS = Int32Array . from ( [ 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 6 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 24 ] ) ;
2019-04-12 11:57:42 +00:00
var INSERT _LENGTH _N _BITS = Int16Array . from ( [ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 , 0x01 , 0x02 , 0x02 , 0x03 , 0x03 , 0x04 , 0x04 , 0x05 , 0x05 , 0x06 , 0x07 , 0x08 , 0x09 , 0x0A , 0x0C , 0x0E , 0x18 ] ) ;
var COPY _LENGTH _N _BITS = Int16Array . from ( [ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 , 0x01 , 0x02 , 0x02 , 0x03 , 0x03 , 0x04 , 0x04 , 0x05 , 0x05 , 0x06 , 0x07 , 0x08 , 0x09 , 0x0A , 0x18 ] ) ;
var CMD _LOOKUP = new Int16Array ( 2816 ) ;
{
unpackCommandLookupTable ( CMD _LOOKUP ) ;
}
/ * *
* @ param { number } i
* @ return { number }
* /
function log2floor ( i ) {
var /** number */ result = - 1 ;
var /** number */ step = 16 ;
while ( step > 0 ) {
if ( ( i >>> step ) != 0 ) {
result += step ;
i = i >>> step ;
}
step = step >> 1 ;
}
return result + i ;
}
/ * *
* @ param { number } npostfix
* @ param { number } ndirect
* @ param { number } maxndistbits
* @ return { number }
* /
function calculateDistanceAlphabetSize ( npostfix , ndirect , maxndistbits ) {
return 16 + ndirect + 2 * ( maxndistbits << npostfix ) ;
}
/ * *
* @ param { number } maxDistance
* @ param { number } npostfix
* @ param { number } ndirect
* @ return { number }
* /
function calculateDistanceAlphabetLimit ( maxDistance , npostfix , ndirect ) {
if ( maxDistance < ndirect + ( 2 << npostfix ) ) {
throw "maxDistance is too small" ;
}
var /** number */ offset = ( ( maxDistance - ndirect ) >> npostfix ) + 4 ;
var /** number */ ndistbits = log2floor ( offset ) - 1 ;
var /** number */ group = ( ( ndistbits - 1 ) << 1 ) | ( ( offset >> ndistbits ) & 1 ) ;
return ( ( group - 1 ) << npostfix ) + ( 1 << npostfix ) + ndirect + 16 ;
}
/ * *
* @ param { ! Int16Array } cmdLookup
* @ return { void }
* /
function unpackCommandLookupTable ( cmdLookup ) {
var /** !Int16Array */ insertLengthOffsets = new Int16Array ( 24 ) ;
var /** !Int16Array */ copyLengthOffsets = new Int16Array ( 24 ) ;
copyLengthOffsets [ 0 ] = 2 ;
for ( var /** number */ i = 0 ; i < 23 ; ++ i ) {
insertLengthOffsets [ i + 1 ] = ( insertLengthOffsets [ i ] + ( 1 << INSERT _LENGTH _N _BITS [ i ] ) ) ;
copyLengthOffsets [ i + 1 ] = ( copyLengthOffsets [ i ] + ( 1 << COPY _LENGTH _N _BITS [ i ] ) ) ;
}
for ( var /** number */ cmdCode = 0 ; cmdCode < 704 ; ++ cmdCode ) {
var /** number */ rangeIdx = cmdCode >>> 6 ;
var /** number */ distanceContextOffset = - 4 ;
if ( rangeIdx >= 2 ) {
rangeIdx -= 2 ;
distanceContextOffset = 0 ;
}
var /** number */ insertCode = ( ( ( 0x29850 >>> ( rangeIdx * 2 ) ) & 0x3 ) << 3 ) | ( ( cmdCode >>> 3 ) & 7 ) ;
var /** number */ copyCode = ( ( ( 0x26244 >>> ( rangeIdx * 2 ) ) & 0x3 ) << 3 ) | ( cmdCode & 7 ) ;
var /** number */ copyLengthOffset = copyLengthOffsets [ copyCode ] ;
var /** number */ distanceContext = distanceContextOffset + ( copyLengthOffset > 4 ? 3 : copyLengthOffset - 2 ) ;
var /** number */ index = cmdCode * 4 ;
cmdLookup [ index + 0 ] = ( INSERT _LENGTH _N _BITS [ insertCode ] | ( COPY _LENGTH _N _BITS [ copyCode ] << 8 ) ) ;
cmdLookup [ index + 1 ] = insertLengthOffsets [ insertCode ] ;
cmdLookup [ index + 2 ] = copyLengthOffsets [ copyCode ] ;
cmdLookup [ index + 3 ] = distanceContext ;
}
}
2017-08-28 09:31:29 +00:00
/ * *
* @ param { ! State } s
2019-04-12 11:57:42 +00:00
* @ return { number }
2017-08-28 09:31:29 +00:00
* /
function decodeWindowBits ( s ) {
2019-04-12 11:57:42 +00:00
var /** number */ largeWindowEnabled = s . isLargeWindow ;
s . isLargeWindow = 0 ;
2017-08-28 09:31:29 +00:00
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
if ( readFewBits ( s , 1 ) == 0 ) {
return 16 ;
}
2019-04-12 11:57:42 +00:00
var /** number */ n = readFewBits ( s , 3 ) ;
2017-08-28 09:31:29 +00:00
if ( n != 0 ) {
return 17 + n ;
}
n = readFewBits ( s , 3 ) ;
if ( n != 0 ) {
2019-04-12 11:57:42 +00:00
if ( n == 1 ) {
if ( largeWindowEnabled == 0 ) {
return - 1 ;
}
s . isLargeWindow = 1 ;
if ( readFewBits ( s , 1 ) == 1 ) {
return - 1 ;
}
n = readFewBits ( s , 6 ) ;
if ( n < 10 || n > 30 ) {
return - 1 ;
}
return n ;
} else {
return 8 + n ;
}
2017-08-28 09:31:29 +00:00
}
return 17 ;
}
2019-04-12 11:57:42 +00:00
/ * *
* @ param { ! State } s
* @ return { void }
* /
function enableEagerOutput ( s ) {
if ( s . runningState != 1 ) {
throw "State MUST be freshly initialized" ;
}
s . isEager = 1 ;
}
/ * *
* @ param { ! State } s
* @ return { void }
* /
function enableLargeWindow ( s ) {
if ( s . runningState != 1 ) {
throw "State MUST be freshly initialized" ;
}
s . isLargeWindow = 1 ;
}
2017-08-28 09:31:29 +00:00
/ * *
* @ param { ! State } s
* @ param { ! InputStream } input
2017-10-09 15:07:34 +00:00
* @ return { void }
2017-08-28 09:31:29 +00:00
* /
function initState ( s , input ) {
if ( s . runningState != 0 ) {
throw "State MUST be uninitialized" ;
}
2019-04-12 11:57:42 +00:00
s . blockTrees = new Int32Array ( 3091 ) ;
s . blockTrees [ 0 ] = 7 ;
s . distRbIdx = 3 ;
var /** number */ maxDistanceAlphabetLimit = calculateDistanceAlphabetLimit ( 0x7FFFFFFC , 3 , 15 << 3 ) ;
s . distExtraBits = new Int8Array ( maxDistanceAlphabetLimit ) ;
s . distOffset = new Int32Array ( maxDistanceAlphabetLimit ) ;
2017-08-28 09:31:29 +00:00
s . input = input ;
initBitReader ( s ) ;
s . runningState = 1 ;
}
/ * *
* @ param { ! State } s
2017-10-09 15:07:34 +00:00
* @ return { void }
2017-08-28 09:31:29 +00:00
* /
function close ( s ) {
if ( s . runningState == 0 ) {
throw "State MUST be initialized" ;
}
2019-04-12 11:57:42 +00:00
if ( s . runningState == 11 ) {
2017-08-28 09:31:29 +00:00
return ;
}
2019-04-12 11:57:42 +00:00
s . runningState = 11 ;
2017-08-28 09:31:29 +00:00
if ( s . input != null ) {
closeInput ( s . input ) ;
s . input = null ;
}
}
/ * *
* @ param { ! State } s
2019-04-12 11:57:42 +00:00
* @ return { number }
2017-08-28 09:31:29 +00:00
* /
function decodeVarLenUnsignedByte ( s ) {
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
if ( readFewBits ( s , 1 ) != 0 ) {
2019-04-12 11:57:42 +00:00
var /** number */ n = readFewBits ( s , 3 ) ;
2017-08-28 09:31:29 +00:00
if ( n == 0 ) {
return 1 ;
} else {
return readFewBits ( s , n ) + ( 1 << n ) ;
}
}
return 0 ;
}
/ * *
* @ param { ! State } s
2017-10-09 15:07:34 +00:00
* @ return { void }
2017-08-28 09:31:29 +00:00
* /
function decodeMetaBlockLength ( s ) {
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
s . inputEnd = readFewBits ( s , 1 ) ;
s . metaBlockLength = 0 ;
s . isUncompressed = 0 ;
s . isMetadata = 0 ;
if ( ( s . inputEnd != 0 ) && readFewBits ( s , 1 ) != 0 ) {
return ;
}
2019-04-12 11:57:42 +00:00
var /** number */ sizeNibbles = readFewBits ( s , 2 ) + 4 ;
2017-08-28 09:31:29 +00:00
if ( sizeNibbles == 7 ) {
s . isMetadata = 1 ;
if ( readFewBits ( s , 1 ) != 0 ) {
throw "Corrupted reserved bit" ;
}
2019-04-12 11:57:42 +00:00
var /** number */ sizeBytes = readFewBits ( s , 2 ) ;
2017-08-28 09:31:29 +00:00
if ( sizeBytes == 0 ) {
return ;
}
2019-04-12 11:57:42 +00:00
for ( var /** number */ i = 0 ; i < sizeBytes ; i ++ ) {
2017-08-28 09:31:29 +00:00
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
2019-04-12 11:57:42 +00:00
var /** number */ bits = readFewBits ( s , 8 ) ;
2017-08-28 09:31:29 +00:00
if ( bits == 0 && i + 1 == sizeBytes && sizeBytes > 1 ) {
throw "Exuberant nibble" ;
}
s . metaBlockLength |= bits << ( i * 8 ) ;
}
} else {
2019-04-12 11:57:42 +00:00
for ( var /** number */ i = 0 ; i < sizeNibbles ; i ++ ) {
2017-08-28 09:31:29 +00:00
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
2019-04-12 11:57:42 +00:00
var /** number */ bits = readFewBits ( s , 4 ) ;
2017-08-28 09:31:29 +00:00
if ( bits == 0 && i + 1 == sizeNibbles && sizeNibbles > 4 ) {
throw "Exuberant nibble" ;
}
s . metaBlockLength |= bits << ( i * 4 ) ;
}
}
s . metaBlockLength ++ ;
if ( s . inputEnd == 0 ) {
s . isUncompressed = readFewBits ( s , 1 ) ;
}
}
/ * *
2019-04-12 11:57:42 +00:00
* @ param { ! Int32Array } tableGroup
* @ param { number } tableIdx
2017-08-28 09:31:29 +00:00
* @ param { ! State } s
2019-04-12 11:57:42 +00:00
* @ return { number }
2017-08-28 09:31:29 +00:00
* /
2019-04-12 11:57:42 +00:00
function readSymbol ( tableGroup , tableIdx , s ) {
var /** number */ offset = tableGroup [ tableIdx ] ;
var /** number */ val = ( s . accumulator32 >>> s . bitOffset ) ;
2017-08-28 09:31:29 +00:00
offset += val & 0xFF ;
2019-04-12 11:57:42 +00:00
var /** number */ bits = tableGroup [ offset ] >> 16 ;
var /** number */ sym = tableGroup [ offset ] & 0xFFFF ;
2017-08-28 09:31:29 +00:00
if ( bits <= 8 ) {
s . bitOffset += bits ;
return sym ;
}
offset += sym ;
2019-04-12 11:57:42 +00:00
var /** number */ mask = ( 1 << bits ) - 1 ;
2017-08-28 09:31:29 +00:00
offset += ( val & mask ) >>> 8 ;
2019-04-12 11:57:42 +00:00
s . bitOffset += ( ( tableGroup [ offset ] >> 16 ) + 8 ) ;
return tableGroup [ offset ] & 0xFFFF ;
2017-08-28 09:31:29 +00:00
}
/ * *
2019-04-12 11:57:42 +00:00
* @ param { ! Int32Array } tableGroup
* @ param { number } tableIdx
2017-08-28 09:31:29 +00:00
* @ param { ! State } s
2019-04-12 11:57:42 +00:00
* @ return { number }
2017-08-28 09:31:29 +00:00
* /
2019-04-12 11:57:42 +00:00
function readBlockLength ( tableGroup , tableIdx , s ) {
2017-08-28 09:31:29 +00:00
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
2019-04-12 11:57:42 +00:00
var /** number */ code = readSymbol ( tableGroup , tableIdx , s ) ;
var /** number */ n = BLOCK _LENGTH _N _BITS [ code ] ;
2017-08-28 09:31:29 +00:00
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
return BLOCK _LENGTH _OFFSET [ code ] + ( ( n <= 16 ) ? readFewBits ( s , n ) : readManyBits ( s , n ) ) ;
}
/ * *
* @ param { ! Int32Array } v
2019-04-12 11:57:42 +00:00
* @ param { number } index
2017-10-09 15:07:34 +00:00
* @ return { void }
2017-08-28 09:31:29 +00:00
* /
function moveToFront ( v , index ) {
2019-04-12 11:57:42 +00:00
var /** number */ value = v [ index ] ;
2017-08-28 09:31:29 +00:00
for ( ; index > 0 ; index -- ) {
v [ index ] = v [ index - 1 ] ;
}
v [ 0 ] = value ;
}
/ * *
* @ param { ! Int8Array } v
2019-04-12 11:57:42 +00:00
* @ param { number } vLen
2017-10-09 15:07:34 +00:00
* @ return { void }
2017-08-28 09:31:29 +00:00
* /
function inverseMoveToFrontTransform ( v , vLen ) {
var /** !Int32Array */ mtf = new Int32Array ( 256 ) ;
2019-04-12 11:57:42 +00:00
for ( var /** number */ i = 0 ; i < 256 ; i ++ ) {
2017-08-28 09:31:29 +00:00
mtf [ i ] = i ;
}
2019-04-12 11:57:42 +00:00
for ( var /** number */ i = 0 ; i < vLen ; i ++ ) {
var /** number */ index = v [ i ] & 0xFF ;
2017-08-28 09:31:29 +00:00
v [ i ] = mtf [ index ] ;
if ( index != 0 ) {
moveToFront ( mtf , index ) ;
}
}
}
/ * *
* @ param { ! Int32Array } codeLengthCodeLengths
2019-04-12 11:57:42 +00:00
* @ param { number } numSymbols
2017-08-28 09:31:29 +00:00
* @ param { ! Int32Array } codeLengths
* @ param { ! State } s
2017-10-09 15:07:34 +00:00
* @ return { void }
2017-08-28 09:31:29 +00:00
* /
function readHuffmanCodeLengths ( codeLengthCodeLengths , numSymbols , codeLengths , s ) {
2019-04-12 11:57:42 +00:00
var /** number */ symbol = 0 ;
var /** number */ prevCodeLen = 8 ;
var /** number */ repeat = 0 ;
var /** number */ repeatCodeLen = 0 ;
var /** number */ space = 32768 ;
var /** !Int32Array */ table = new Int32Array ( 32 + 1 ) ;
var /** number */ tableIdx = table . length - 1 ;
buildHuffmanTable ( table , tableIdx , 5 , codeLengthCodeLengths , 18 ) ;
2017-08-28 09:31:29 +00:00
while ( symbol < numSymbols && space > 0 ) {
if ( s . halfOffset > 2030 ) {
doReadMoreInput ( s ) ;
}
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
2019-04-12 11:57:42 +00:00
var /** number */ p = ( s . accumulator32 >>> s . bitOffset ) & 31 ;
2017-08-28 09:31:29 +00:00
s . bitOffset += table [ p ] >> 16 ;
2019-04-12 11:57:42 +00:00
var /** number */ codeLen = table [ p ] & 0xFFFF ;
2017-08-28 09:31:29 +00:00
if ( codeLen < 16 ) {
repeat = 0 ;
codeLengths [ symbol ++ ] = codeLen ;
if ( codeLen != 0 ) {
prevCodeLen = codeLen ;
space -= 32768 >> codeLen ;
}
} else {
2019-04-12 11:57:42 +00:00
var /** number */ extraBits = codeLen - 14 ;
var /** number */ newLen = 0 ;
2017-08-28 09:31:29 +00:00
if ( codeLen == 16 ) {
newLen = prevCodeLen ;
}
if ( repeatCodeLen != newLen ) {
repeat = 0 ;
repeatCodeLen = newLen ;
}
2019-04-12 11:57:42 +00:00
var /** number */ oldRepeat = repeat ;
2017-08-28 09:31:29 +00:00
if ( repeat > 0 ) {
repeat -= 2 ;
repeat <<= extraBits ;
}
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
repeat += readFewBits ( s , extraBits ) + 3 ;
2019-04-12 11:57:42 +00:00
var /** number */ repeatDelta = repeat - oldRepeat ;
2017-08-28 09:31:29 +00:00
if ( symbol + repeatDelta > numSymbols ) {
throw "symbol + repeatDelta > numSymbols" ;
}
2019-04-12 11:57:42 +00:00
for ( var /** number */ i = 0 ; i < repeatDelta ; i ++ ) {
2017-08-28 09:31:29 +00:00
codeLengths [ symbol ++ ] = repeatCodeLen ;
}
if ( repeatCodeLen != 0 ) {
space -= repeatDelta << ( 15 - repeatCodeLen ) ;
}
}
}
if ( space != 0 ) {
throw "Unused space" ;
}
codeLengths . fill ( 0 , symbol , numSymbols ) ;
}
/ * *
* @ param { ! Int32Array } symbols
2019-04-12 11:57:42 +00:00
* @ param { number } length
* @ return { void }
2017-08-28 09:31:29 +00:00
* /
function checkDupes ( symbols , length ) {
2019-04-12 11:57:42 +00:00
for ( var /** number */ i = 0 ; i < length - 1 ; ++ i ) {
for ( var /** number */ j = i + 1 ; j < length ; ++ j ) {
2017-08-28 09:31:29 +00:00
if ( symbols [ i ] == symbols [ j ] ) {
2019-04-12 11:57:42 +00:00
throw "Duplicate simple Huffman code symbol" ;
2017-08-28 09:31:29 +00:00
}
}
}
}
/ * *
2019-04-12 11:57:42 +00:00
* @ param { number } alphabetSizeMax
* @ param { number } alphabetSizeLimit
* @ param { ! Int32Array } tableGroup
* @ param { number } tableIdx
2017-08-28 09:31:29 +00:00
* @ param { ! State } s
2019-04-12 11:57:42 +00:00
* @ return { number }
* /
function readSimpleHuffmanCode ( alphabetSizeMax , alphabetSizeLimit , tableGroup , tableIdx , s ) {
var /** !Int32Array */ codeLengths = new Int32Array ( alphabetSizeLimit ) ;
var /** !Int32Array */ symbols = new Int32Array ( 4 ) ;
var /** number */ maxBits = 1 + log2floor ( alphabetSizeMax - 1 ) ;
var /** number */ numSymbols = readFewBits ( s , 2 ) + 1 ;
for ( var /** number */ i = 0 ; i < numSymbols ; i ++ ) {
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
var /** number */ symbol = readFewBits ( s , maxBits ) ;
if ( symbol >= alphabetSizeLimit ) {
throw "Can't readHuffmanCode" ;
}
symbols [ i ] = symbol ;
}
checkDupes ( symbols , numSymbols ) ;
var /** number */ histogramId = numSymbols ;
if ( numSymbols == 4 ) {
histogramId += readFewBits ( s , 1 ) ;
}
switch ( histogramId ) {
case 1 :
codeLengths [ symbols [ 0 ] ] = 1 ;
break ;
case 2 :
codeLengths [ symbols [ 0 ] ] = 1 ;
codeLengths [ symbols [ 1 ] ] = 1 ;
break ;
case 3 :
codeLengths [ symbols [ 0 ] ] = 1 ;
codeLengths [ symbols [ 1 ] ] = 2 ;
codeLengths [ symbols [ 2 ] ] = 2 ;
break ;
case 4 :
codeLengths [ symbols [ 0 ] ] = 2 ;
codeLengths [ symbols [ 1 ] ] = 2 ;
codeLengths [ symbols [ 2 ] ] = 2 ;
codeLengths [ symbols [ 3 ] ] = 2 ;
break ;
case 5 :
codeLengths [ symbols [ 0 ] ] = 1 ;
codeLengths [ symbols [ 1 ] ] = 2 ;
codeLengths [ symbols [ 2 ] ] = 3 ;
codeLengths [ symbols [ 3 ] ] = 3 ;
break ;
default :
break ;
}
return buildHuffmanTable ( tableGroup , tableIdx , 8 , codeLengths , alphabetSizeLimit ) ;
}
/ * *
* @ param { number } alphabetSizeLimit
* @ param { number } skip
* @ param { ! Int32Array } tableGroup
* @ param { number } tableIdx
* @ param { ! State } s
* @ return { number }
* /
function readComplexHuffmanCode ( alphabetSizeLimit , skip , tableGroup , tableIdx , s ) {
var /** !Int32Array */ codeLengths = new Int32Array ( alphabetSizeLimit ) ;
var /** !Int32Array */ codeLengthCodeLengths = new Int32Array ( 18 ) ;
var /** number */ space = 32 ;
var /** number */ numCodes = 0 ;
for ( var /** number */ i = skip ; i < 18 && space > 0 ; i ++ ) {
var /** number */ codeLenIdx = CODE _LENGTH _CODE _ORDER [ i ] ;
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
var /** number */ p = ( s . accumulator32 >>> s . bitOffset ) & 15 ;
s . bitOffset += FIXED _TABLE [ p ] >> 16 ;
var /** number */ v = FIXED _TABLE [ p ] & 0xFFFF ;
codeLengthCodeLengths [ codeLenIdx ] = v ;
if ( v != 0 ) {
space -= ( 32 >> v ) ;
numCodes ++ ;
}
}
if ( space != 0 && numCodes != 1 ) {
throw "Corrupted Huffman code histogram" ;
}
readHuffmanCodeLengths ( codeLengthCodeLengths , alphabetSizeLimit , codeLengths , s ) ;
return buildHuffmanTable ( tableGroup , tableIdx , 8 , codeLengths , alphabetSizeLimit ) ;
}
/ * *
* @ param { number } alphabetSizeMax
* @ param { number } alphabetSizeLimit
* @ param { ! Int32Array } tableGroup
* @ param { number } tableIdx
* @ param { ! State } s
* @ return { number }
2017-08-28 09:31:29 +00:00
* /
2019-04-12 11:57:42 +00:00
function readHuffmanCode ( alphabetSizeMax , alphabetSizeLimit , tableGroup , tableIdx , s ) {
2017-08-28 09:31:29 +00:00
if ( s . halfOffset > 2030 ) {
doReadMoreInput ( s ) ;
}
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
2019-04-12 11:57:42 +00:00
var /** number */ simpleCodeOrSkip = readFewBits ( s , 2 ) ;
2017-08-28 09:31:29 +00:00
if ( simpleCodeOrSkip == 1 ) {
2019-04-12 11:57:42 +00:00
return readSimpleHuffmanCode ( alphabetSizeMax , alphabetSizeLimit , tableGroup , tableIdx , s ) ;
2017-08-28 09:31:29 +00:00
} else {
2019-04-12 11:57:42 +00:00
return readComplexHuffmanCode ( alphabetSizeLimit , simpleCodeOrSkip , tableGroup , tableIdx , s ) ;
2017-08-28 09:31:29 +00:00
}
}
/ * *
2019-04-12 11:57:42 +00:00
* @ param { number } contextMapSize
2017-08-28 09:31:29 +00:00
* @ param { ! Int8Array } contextMap
* @ param { ! State } s
2019-04-12 11:57:42 +00:00
* @ return { number }
2017-08-28 09:31:29 +00:00
* /
function decodeContextMap ( contextMapSize , contextMap , s ) {
if ( s . halfOffset > 2030 ) {
doReadMoreInput ( s ) ;
}
2019-04-12 11:57:42 +00:00
var /** number */ numTrees = decodeVarLenUnsignedByte ( s ) + 1 ;
2017-08-28 09:31:29 +00:00
if ( numTrees == 1 ) {
contextMap . fill ( 0 , 0 , contextMapSize ) ;
return numTrees ;
}
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
2019-04-12 11:57:42 +00:00
var /** number */ useRleForZeros = readFewBits ( s , 1 ) ;
var /** number */ maxRunLengthPrefix = 0 ;
2017-08-28 09:31:29 +00:00
if ( useRleForZeros != 0 ) {
maxRunLengthPrefix = readFewBits ( s , 4 ) + 1 ;
}
2019-04-12 11:57:42 +00:00
var /** number */ alphabetSize = numTrees + maxRunLengthPrefix ;
var /** number */ tableSize = MAX _HUFFMAN _TABLE _SIZE [ ( alphabetSize + 31 ) >> 5 ] ;
var /** !Int32Array */ table = new Int32Array ( tableSize + 1 ) ;
var /** number */ tableIdx = table . length - 1 ;
readHuffmanCode ( alphabetSize , alphabetSize , table , tableIdx , s ) ;
for ( var /** number */ i = 0 ; i < contextMapSize ; ) {
2017-08-28 09:31:29 +00:00
if ( s . halfOffset > 2030 ) {
doReadMoreInput ( s ) ;
}
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
2019-04-12 11:57:42 +00:00
var /** number */ code = readSymbol ( table , tableIdx , s ) ;
2017-08-28 09:31:29 +00:00
if ( code == 0 ) {
contextMap [ i ] = 0 ;
i ++ ;
} else if ( code <= maxRunLengthPrefix ) {
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
2019-04-12 11:57:42 +00:00
var /** number */ reps = ( 1 << code ) + readFewBits ( s , code ) ;
2017-08-28 09:31:29 +00:00
while ( reps != 0 ) {
if ( i >= contextMapSize ) {
throw "Corrupted context map" ;
}
contextMap [ i ] = 0 ;
i ++ ;
reps -- ;
}
} else {
contextMap [ i ] = ( code - maxRunLengthPrefix ) ;
i ++ ;
}
}
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
if ( readFewBits ( s , 1 ) == 1 ) {
inverseMoveToFrontTransform ( contextMap , contextMapSize ) ;
}
return numTrees ;
}
/ * *
* @ param { ! State } s
2019-04-12 11:57:42 +00:00
* @ param { number } treeType
* @ param { number } numBlockTypes
* @ return { number }
2017-08-28 09:31:29 +00:00
* /
function decodeBlockTypeAndLength ( s , treeType , numBlockTypes ) {
var /** !Int32Array */ ringBuffers = s . rings ;
2019-04-12 11:57:42 +00:00
var /** number */ offset = 4 + treeType * 2 ;
2017-08-28 09:31:29 +00:00
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
2019-04-12 11:57:42 +00:00
var /** number */ blockType = readSymbol ( s . blockTrees , 2 * treeType , s ) ;
var /** number */ result = readBlockLength ( s . blockTrees , 2 * treeType + 1 , s ) ;
2017-08-28 09:31:29 +00:00
if ( blockType == 1 ) {
blockType = ringBuffers [ offset + 1 ] + 1 ;
} else if ( blockType == 0 ) {
blockType = ringBuffers [ offset ] ;
} else {
blockType -= 2 ;
}
if ( blockType >= numBlockTypes ) {
blockType -= numBlockTypes ;
}
ringBuffers [ offset ] = ringBuffers [ offset + 1 ] ;
ringBuffers [ offset + 1 ] = blockType ;
return result ;
}
/ * *
* @ param { ! State } s
2017-10-09 15:07:34 +00:00
* @ return { void }
2017-08-28 09:31:29 +00:00
* /
function decodeLiteralBlockSwitch ( s ) {
s . literalBlockLength = decodeBlockTypeAndLength ( s , 0 , s . numLiteralBlockTypes ) ;
2019-04-12 11:57:42 +00:00
var /** number */ literalBlockType = s . rings [ 5 ] ;
2017-08-28 09:31:29 +00:00
s . contextMapSlice = literalBlockType << 6 ;
2019-04-12 11:57:42 +00:00
s . literalTreeIdx = s . contextMap [ s . contextMapSlice ] & 0xFF ;
var /** number */ contextMode = s . contextModes [ literalBlockType ] ;
2017-08-28 09:31:29 +00:00
s . contextLookupOffset1 = contextMode << 9 ;
s . contextLookupOffset2 = s . contextLookupOffset1 + 256 ;
}
/ * *
* @ param { ! State } s
2017-10-09 15:07:34 +00:00
* @ return { void }
2017-08-28 09:31:29 +00:00
* /
function decodeCommandBlockSwitch ( s ) {
s . commandBlockLength = decodeBlockTypeAndLength ( s , 1 , s . numCommandBlockTypes ) ;
2019-04-12 11:57:42 +00:00
s . commandTreeIdx = s . rings [ 7 ] ;
2017-08-28 09:31:29 +00:00
}
/ * *
* @ param { ! State } s
2017-10-09 15:07:34 +00:00
* @ return { void }
2017-08-28 09:31:29 +00:00
* /
function decodeDistanceBlockSwitch ( s ) {
s . distanceBlockLength = decodeBlockTypeAndLength ( s , 2 , s . numDistanceBlockTypes ) ;
s . distContextMapSlice = s . rings [ 9 ] << 2 ;
}
/ * *
* @ param { ! State } s
2017-10-09 15:07:34 +00:00
* @ return { void }
2017-08-28 09:31:29 +00:00
* /
function maybeReallocateRingBuffer ( s ) {
2019-04-12 11:57:42 +00:00
var /** number */ newSize = s . maxRingBufferSize ;
2017-08-28 09:31:29 +00:00
if ( newSize > s . expectedTotalSize ) {
2019-04-12 11:57:42 +00:00
var /** number */ minimalNewSize = s . expectedTotalSize ;
2017-08-28 09:31:29 +00:00
while ( ( newSize >> 1 ) > minimalNewSize ) {
newSize >>= 1 ;
}
if ( ( s . inputEnd == 0 ) && newSize < 16384 && s . maxRingBufferSize >= 16384 ) {
newSize = 16384 ;
}
}
if ( newSize <= s . ringBufferSize ) {
return ;
}
2019-04-12 11:57:42 +00:00
var /** number */ ringBufferSizeWithSlack = newSize + 37 ;
2017-08-28 09:31:29 +00:00
var /** !Int8Array */ newBuffer = new Int8Array ( ringBufferSizeWithSlack ) ;
if ( s . ringBuffer . length != 0 ) {
newBuffer . set ( s . ringBuffer . subarray ( 0 , 0 + s . ringBufferSize ) , 0 ) ;
}
s . ringBuffer = newBuffer ;
s . ringBufferSize = newSize ;
}
/ * *
* @ param { ! State } s
2017-10-09 15:07:34 +00:00
* @ return { void }
2017-08-28 09:31:29 +00:00
* /
function readNextMetablockHeader ( s ) {
if ( s . inputEnd != 0 ) {
2019-04-12 11:57:42 +00:00
s . nextRunningState = 10 ;
s . runningState = 12 ;
2017-08-28 09:31:29 +00:00
return ;
}
2019-04-12 11:57:42 +00:00
s . literalTreeGroup = new Int32Array ( 0 ) ;
s . commandTreeGroup = new Int32Array ( 0 ) ;
s . distanceTreeGroup = new Int32Array ( 0 ) ;
2017-08-28 09:31:29 +00:00
if ( s . halfOffset > 2030 ) {
doReadMoreInput ( s ) ;
}
decodeMetaBlockLength ( s ) ;
if ( ( s . metaBlockLength == 0 ) && ( s . isMetadata == 0 ) ) {
return ;
}
if ( ( s . isUncompressed != 0 ) || ( s . isMetadata != 0 ) ) {
jumpToByteBoundary ( s ) ;
2019-04-12 11:57:42 +00:00
s . runningState = ( s . isMetadata != 0 ) ? 5 : 6 ;
2017-08-28 09:31:29 +00:00
} else {
2019-04-12 11:57:42 +00:00
s . runningState = 3 ;
2017-08-28 09:31:29 +00:00
}
if ( s . isMetadata != 0 ) {
return ;
}
s . expectedTotalSize += s . metaBlockLength ;
if ( s . expectedTotalSize > 1 << 30 ) {
s . expectedTotalSize = 1 << 30 ;
}
if ( s . ringBufferSize < s . maxRingBufferSize ) {
maybeReallocateRingBuffer ( s ) ;
}
}
/ * *
* @ param { ! State } s
2019-04-12 11:57:42 +00:00
* @ param { number } treeType
* @ param { number } numBlockTypes
* @ return { number }
2017-08-28 09:31:29 +00:00
* /
function readMetablockPartition ( s , treeType , numBlockTypes ) {
2019-04-12 11:57:42 +00:00
var /** number */ offset = s . blockTrees [ 2 * treeType ] ;
2017-08-28 09:31:29 +00:00
if ( numBlockTypes <= 1 ) {
2019-04-12 11:57:42 +00:00
s . blockTrees [ 2 * treeType + 1 ] = offset ;
s . blockTrees [ 2 * treeType + 2 ] = offset ;
2017-08-28 09:31:29 +00:00
return 1 << 28 ;
}
2019-04-12 11:57:42 +00:00
var /** number */ blockTypeAlphabetSize = numBlockTypes + 2 ;
offset += readHuffmanCode ( blockTypeAlphabetSize , blockTypeAlphabetSize , s . blockTrees , 2 * treeType , s ) ;
s . blockTrees [ 2 * treeType + 1 ] = offset ;
var /** number */ blockLengthAlphabetSize = 26 ;
offset += readHuffmanCode ( blockLengthAlphabetSize , blockLengthAlphabetSize , s . blockTrees , 2 * treeType + 1 , s ) ;
s . blockTrees [ 2 * treeType + 2 ] = offset ;
return readBlockLength ( s . blockTrees , 2 * treeType + 1 , s ) ;
}
/ * *
* @ param { ! State } s
* @ param { number } alphabetSizeLimit
* @ return { void }
* /
function calculateDistanceLut ( s , alphabetSizeLimit ) {
var /** !Int8Array */ distExtraBits = s . distExtraBits ;
var /** !Int32Array */ distOffset = s . distOffset ;
var /** number */ npostfix = s . distancePostfixBits ;
var /** number */ ndirect = s . numDirectDistanceCodes ;
var /** number */ postfix = 1 << npostfix ;
var /** number */ bits = 1 ;
var /** number */ half = 0 ;
var /** number */ i = 16 ;
for ( var /** number */ j = 0 ; j < ndirect ; ++ j ) {
distExtraBits [ i ] = 0 ;
distOffset [ i ] = j + 1 ;
++ i ;
}
while ( i < alphabetSizeLimit ) {
var /** number */ base = ndirect + ( ( ( ( 2 + half ) << bits ) - 4 ) << npostfix ) + 1 ;
for ( var /** number */ j = 0 ; j < postfix ; ++ j ) {
distExtraBits [ i ] = bits ;
distOffset [ i ] = base + j ;
++ i ;
}
bits = bits + half ;
half = half ^ 1 ;
}
2017-08-28 09:31:29 +00:00
}
/ * *
* @ param { ! State } s
2017-10-09 15:07:34 +00:00
* @ return { void }
2017-08-28 09:31:29 +00:00
* /
function readMetablockHuffmanCodesAndContextMaps ( s ) {
s . numLiteralBlockTypes = decodeVarLenUnsignedByte ( s ) + 1 ;
s . literalBlockLength = readMetablockPartition ( s , 0 , s . numLiteralBlockTypes ) ;
s . numCommandBlockTypes = decodeVarLenUnsignedByte ( s ) + 1 ;
s . commandBlockLength = readMetablockPartition ( s , 1 , s . numCommandBlockTypes ) ;
s . numDistanceBlockTypes = decodeVarLenUnsignedByte ( s ) + 1 ;
s . distanceBlockLength = readMetablockPartition ( s , 2 , s . numDistanceBlockTypes ) ;
if ( s . halfOffset > 2030 ) {
doReadMoreInput ( s ) ;
}
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
s . distancePostfixBits = readFewBits ( s , 2 ) ;
2019-04-12 11:57:42 +00:00
s . numDirectDistanceCodes = readFewBits ( s , 4 ) << s . distancePostfixBits ;
2017-08-28 09:31:29 +00:00
s . distancePostfixMask = ( 1 << s . distancePostfixBits ) - 1 ;
s . contextModes = new Int8Array ( s . numLiteralBlockTypes ) ;
2019-04-12 11:57:42 +00:00
for ( var /** number */ i = 0 ; i < s . numLiteralBlockTypes ; ) {
var /** number */ limit = min ( i + 96 , s . numLiteralBlockTypes ) ;
2017-08-28 09:31:29 +00:00
for ( ; i < limit ; ++ i ) {
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
2019-04-12 11:57:42 +00:00
s . contextModes [ i ] = readFewBits ( s , 2 ) ;
2017-08-28 09:31:29 +00:00
}
if ( s . halfOffset > 2030 ) {
doReadMoreInput ( s ) ;
}
}
s . contextMap = new Int8Array ( s . numLiteralBlockTypes << 6 ) ;
2019-04-12 11:57:42 +00:00
var /** number */ numLiteralTrees = decodeContextMap ( s . numLiteralBlockTypes << 6 , s . contextMap , s ) ;
2017-08-28 09:31:29 +00:00
s . trivialLiteralContext = 1 ;
2019-04-12 11:57:42 +00:00
for ( var /** number */ j = 0 ; j < s . numLiteralBlockTypes << 6 ; j ++ ) {
2017-08-28 09:31:29 +00:00
if ( s . contextMap [ j ] != j >> 6 ) {
s . trivialLiteralContext = 0 ;
break ;
}
}
s . distContextMap = new Int8Array ( s . numDistanceBlockTypes << 2 ) ;
2019-04-12 11:57:42 +00:00
var /** number */ numDistTrees = decodeContextMap ( s . numDistanceBlockTypes << 2 , s . distContextMap , s ) ;
s . literalTreeGroup = decodeHuffmanTreeGroup ( 256 , 256 , numLiteralTrees , s ) ;
s . commandTreeGroup = decodeHuffmanTreeGroup ( 704 , 704 , s . numCommandBlockTypes , s ) ;
var /** number */ distanceAlphabetSizeMax = calculateDistanceAlphabetSize ( s . distancePostfixBits , s . numDirectDistanceCodes , 24 ) ;
var /** number */ distanceAlphabetSizeLimit = distanceAlphabetSizeMax ;
if ( s . isLargeWindow == 1 ) {
distanceAlphabetSizeMax = calculateDistanceAlphabetSize ( s . distancePostfixBits , s . numDirectDistanceCodes , 62 ) ;
distanceAlphabetSizeLimit = calculateDistanceAlphabetLimit ( 0x7FFFFFFC , s . distancePostfixBits , s . numDirectDistanceCodes ) ;
}
s . distanceTreeGroup = decodeHuffmanTreeGroup ( distanceAlphabetSizeMax , distanceAlphabetSizeLimit , numDistTrees , s ) ;
calculateDistanceLut ( s , distanceAlphabetSizeLimit ) ;
2017-08-28 09:31:29 +00:00
s . contextMapSlice = 0 ;
s . distContextMapSlice = 0 ;
2019-04-12 11:57:42 +00:00
s . contextLookupOffset1 = s . contextModes [ 0 ] * 512 ;
2017-08-28 09:31:29 +00:00
s . contextLookupOffset2 = s . contextLookupOffset1 + 256 ;
2019-04-12 11:57:42 +00:00
s . literalTreeIdx = 0 ;
s . commandTreeIdx = 0 ;
2017-08-28 09:31:29 +00:00
s . rings [ 4 ] = 1 ;
s . rings [ 5 ] = 0 ;
s . rings [ 6 ] = 1 ;
s . rings [ 7 ] = 0 ;
s . rings [ 8 ] = 1 ;
s . rings [ 9 ] = 0 ;
}
/ * *
* @ param { ! State } s
2017-10-09 15:07:34 +00:00
* @ return { void }
2017-08-28 09:31:29 +00:00
* /
function copyUncompressedData ( s ) {
var /** !Int8Array */ ringBuffer = s . ringBuffer ;
if ( s . metaBlockLength <= 0 ) {
reload ( s ) ;
2019-04-12 11:57:42 +00:00
s . runningState = 2 ;
2017-08-28 09:31:29 +00:00
return ;
}
2019-04-12 11:57:42 +00:00
var /** number */ chunkLength = min ( s . ringBufferSize - s . pos , s . metaBlockLength ) ;
2017-08-28 09:31:29 +00:00
copyBytes ( s , ringBuffer , s . pos , chunkLength ) ;
s . metaBlockLength -= chunkLength ;
s . pos += chunkLength ;
if ( s . pos == s . ringBufferSize ) {
2019-04-12 11:57:42 +00:00
s . nextRunningState = 6 ;
s . runningState = 12 ;
2017-08-28 09:31:29 +00:00
return ;
}
reload ( s ) ;
2019-04-12 11:57:42 +00:00
s . runningState = 2 ;
2017-08-28 09:31:29 +00:00
}
/ * *
* @ param { ! State } s
2019-04-12 11:57:42 +00:00
* @ return { number }
2017-08-28 09:31:29 +00:00
* /
function writeRingBuffer ( s ) {
2019-04-12 11:57:42 +00:00
var /** number */ toWrite = min ( s . outputLength - s . outputUsed , s . ringBufferBytesReady - s . ringBufferBytesWritten ) ;
2017-08-28 09:31:29 +00:00
if ( toWrite != 0 ) {
2018-09-13 12:09:32 +00:00
s . output . set ( s . ringBuffer . subarray ( s . ringBufferBytesWritten , s . ringBufferBytesWritten + toWrite ) , s . outputOffset + s . outputUsed ) ;
2017-08-28 09:31:29 +00:00
s . outputUsed += toWrite ;
2018-09-13 12:09:32 +00:00
s . ringBufferBytesWritten += toWrite ;
2017-08-28 09:31:29 +00:00
}
if ( s . outputUsed < s . outputLength ) {
return 1 ;
} else {
return 0 ;
}
}
/ * *
2019-04-12 11:57:42 +00:00
* @ param { number } alphabetSizeMax
* @ param { number } alphabetSizeLimit
* @ param { number } n
2017-08-28 09:31:29 +00:00
* @ param { ! State } s
* @ return { ! Int32Array }
* /
2019-04-12 11:57:42 +00:00
function decodeHuffmanTreeGroup ( alphabetSizeMax , alphabetSizeLimit , n , s ) {
var /** number */ maxTableSize = MAX _HUFFMAN _TABLE _SIZE [ ( alphabetSizeLimit + 31 ) >> 5 ] ;
var /** !Int32Array */ group = new Int32Array ( n + n * maxTableSize ) ;
var /** number */ next = n ;
for ( var /** number */ i = 0 ; i < n ; ++ i ) {
2017-08-28 09:31:29 +00:00
group [ i ] = next ;
2019-04-12 11:57:42 +00:00
next += readHuffmanCode ( alphabetSizeMax , alphabetSizeLimit , group , i , s ) ;
2017-08-28 09:31:29 +00:00
}
return group ;
}
2018-09-13 12:09:32 +00:00
/ * *
* @ param { ! State } s
2019-04-12 11:57:42 +00:00
* @ return { number }
2018-09-13 12:09:32 +00:00
* /
function calculateFence ( s ) {
2019-04-12 11:57:42 +00:00
var /** number */ result = s . ringBufferSize ;
2018-09-13 12:09:32 +00:00
if ( s . isEager != 0 ) {
result = min ( result , s . ringBufferBytesWritten + s . outputLength - s . outputUsed ) ;
}
return result ;
}
2017-08-28 09:31:29 +00:00
/ * *
* @ param { ! State } s
2017-10-09 15:07:34 +00:00
* @ return { void }
2017-08-28 09:31:29 +00:00
* /
function decompress ( s ) {
if ( s . runningState == 0 ) {
throw "Can't decompress until initialized" ;
}
2019-04-12 11:57:42 +00:00
if ( s . runningState == 11 ) {
2017-08-28 09:31:29 +00:00
throw "Can't decompress after close" ;
}
2019-04-12 11:57:42 +00:00
if ( s . runningState == 1 ) {
var /** number */ windowBits = decodeWindowBits ( s ) ;
if ( windowBits == - 1 ) {
throw "Invalid 'windowBits' code" ;
}
s . maxRingBufferSize = 1 << windowBits ;
s . maxBackwardDistance = s . maxRingBufferSize - 16 ;
s . runningState = 2 ;
}
var /** number */ fence = calculateFence ( s ) ;
var /** number */ ringBufferMask = s . ringBufferSize - 1 ;
2017-08-28 09:31:29 +00:00
var /** !Int8Array */ ringBuffer = s . ringBuffer ;
2019-04-12 11:57:42 +00:00
while ( s . runningState != 10 ) {
2017-08-28 09:31:29 +00:00
switch ( s . runningState ) {
2019-04-12 11:57:42 +00:00
case 2 :
2017-08-28 09:31:29 +00:00
if ( s . metaBlockLength < 0 ) {
throw "Invalid metablock length" ;
}
readNextMetablockHeader ( s ) ;
2018-09-13 12:09:32 +00:00
fence = calculateFence ( s ) ;
2017-08-28 09:31:29 +00:00
ringBufferMask = s . ringBufferSize - 1 ;
ringBuffer = s . ringBuffer ;
continue ;
case 3 :
2019-04-12 11:57:42 +00:00
readMetablockHuffmanCodesAndContextMaps ( s ) ;
s . runningState = 4 ;
case 4 :
2017-08-28 09:31:29 +00:00
if ( s . metaBlockLength <= 0 ) {
2019-04-12 11:57:42 +00:00
s . runningState = 2 ;
2017-08-28 09:31:29 +00:00
continue ;
}
if ( s . halfOffset > 2030 ) {
doReadMoreInput ( s ) ;
}
if ( s . commandBlockLength == 0 ) {
decodeCommandBlockSwitch ( s ) ;
}
s . commandBlockLength -- ;
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
2019-04-12 11:57:42 +00:00
var /** number */ cmdCode = readSymbol ( s . commandTreeGroup , s . commandTreeIdx , s ) << 2 ;
var /** number */ insertAndCopyExtraBits = CMD _LOOKUP [ cmdCode ] ;
var /** number */ insertLengthOffset = CMD _LOOKUP [ cmdCode + 1 ] ;
var /** number */ copyLengthOffset = CMD _LOOKUP [ cmdCode + 2 ] ;
s . distanceCode = CMD _LOOKUP [ cmdCode + 3 ] ;
2017-08-28 09:31:29 +00:00
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
2019-04-12 11:57:42 +00:00
var /** number */ extraBits = insertAndCopyExtraBits & 0xFF ;
s . insertLength = insertLengthOffset + ( ( extraBits <= 16 ) ? readFewBits ( s , extraBits ) : readManyBits ( s , extraBits ) ) ;
2017-08-28 09:31:29 +00:00
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
2019-04-12 11:57:42 +00:00
var /** number */ extraBits = insertAndCopyExtraBits >> 8 ;
s . copyLength = copyLengthOffset + ( ( extraBits <= 16 ) ? readFewBits ( s , extraBits ) : readManyBits ( s , extraBits ) ) ;
2017-08-28 09:31:29 +00:00
s . j = 0 ;
2019-04-12 11:57:42 +00:00
s . runningState = 7 ;
case 7 :
2017-08-28 09:31:29 +00:00
if ( s . trivialLiteralContext != 0 ) {
while ( s . j < s . insertLength ) {
if ( s . halfOffset > 2030 ) {
doReadMoreInput ( s ) ;
}
if ( s . literalBlockLength == 0 ) {
decodeLiteralBlockSwitch ( s ) ;
}
s . literalBlockLength -- ;
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
2019-04-12 11:57:42 +00:00
ringBuffer [ s . pos ] = readSymbol ( s . literalTreeGroup , s . literalTreeIdx , s ) ;
2018-09-13 12:09:32 +00:00
s . pos ++ ;
2017-08-28 09:31:29 +00:00
s . j ++ ;
2018-09-13 12:09:32 +00:00
if ( s . pos >= fence ) {
2019-04-12 11:57:42 +00:00
s . nextRunningState = 7 ;
s . runningState = 12 ;
2017-08-28 09:31:29 +00:00
break ;
}
}
} else {
2019-04-12 11:57:42 +00:00
var /** number */ prevByte1 = ringBuffer [ ( s . pos - 1 ) & ringBufferMask ] & 0xFF ;
var /** number */ prevByte2 = ringBuffer [ ( s . pos - 2 ) & ringBufferMask ] & 0xFF ;
2017-08-28 09:31:29 +00:00
while ( s . j < s . insertLength ) {
if ( s . halfOffset > 2030 ) {
doReadMoreInput ( s ) ;
}
if ( s . literalBlockLength == 0 ) {
decodeLiteralBlockSwitch ( s ) ;
}
2019-04-12 11:57:42 +00:00
var /** number */ literalContext = LOOKUP [ s . contextLookupOffset1 + prevByte1 ] | LOOKUP [ s . contextLookupOffset2 + prevByte2 ] ;
var /** number */ literalTreeIdx = s . contextMap [ s . contextMapSlice + literalContext ] & 0xFF ;
2017-08-28 09:31:29 +00:00
s . literalBlockLength -- ;
prevByte2 = prevByte1 ;
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
2019-04-12 11:57:42 +00:00
prevByte1 = readSymbol ( s . literalTreeGroup , literalTreeIdx , s ) ;
2017-08-28 09:31:29 +00:00
ringBuffer [ s . pos ] = prevByte1 ;
2018-09-13 12:09:32 +00:00
s . pos ++ ;
2017-08-28 09:31:29 +00:00
s . j ++ ;
2018-09-13 12:09:32 +00:00
if ( s . pos >= fence ) {
2019-04-12 11:57:42 +00:00
s . nextRunningState = 7 ;
s . runningState = 12 ;
2017-08-28 09:31:29 +00:00
break ;
}
}
}
2019-04-12 11:57:42 +00:00
if ( s . runningState != 7 ) {
2017-08-28 09:31:29 +00:00
continue ;
}
s . metaBlockLength -= s . insertLength ;
if ( s . metaBlockLength <= 0 ) {
2019-04-12 11:57:42 +00:00
s . runningState = 4 ;
2017-08-28 09:31:29 +00:00
continue ;
}
2019-04-12 11:57:42 +00:00
var /** number */ distanceCode = s . distanceCode ;
if ( distanceCode < 0 ) {
s . distance = s . rings [ s . distRbIdx ] ;
} else {
2017-08-28 09:31:29 +00:00
if ( s . halfOffset > 2030 ) {
doReadMoreInput ( s ) ;
}
if ( s . distanceBlockLength == 0 ) {
decodeDistanceBlockSwitch ( s ) ;
}
s . distanceBlockLength -- ;
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
2019-04-12 11:57:42 +00:00
var /** number */ distTreeIdx = s . distContextMap [ s . distContextMapSlice + distanceCode ] & 0xFF ;
distanceCode = readSymbol ( s . distanceTreeGroup , distTreeIdx , s ) ;
if ( distanceCode < 16 ) {
var /** number */ index = ( s . distRbIdx + DISTANCE _SHORT _CODE _INDEX _OFFSET [ distanceCode ] ) & 0x3 ;
s . distance = s . rings [ index ] + DISTANCE _SHORT _CODE _VALUE _OFFSET [ distanceCode ] ;
if ( s . distance < 0 ) {
throw "Negative distance" ;
}
} else {
var /** number */ extraBits = s . distExtraBits [ distanceCode ] ;
var /** number */ bits ;
if ( s . bitOffset + extraBits <= 32 ) {
bits = readFewBits ( s , extraBits ) ;
} else {
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
bits = ( ( extraBits <= 16 ) ? readFewBits ( s , extraBits ) : readManyBits ( s , extraBits ) ) ;
2017-08-28 09:31:29 +00:00
}
2019-04-12 11:57:42 +00:00
s . distance = s . distOffset [ distanceCode ] + ( bits << s . distancePostfixBits ) ;
2017-08-28 09:31:29 +00:00
}
}
if ( s . maxDistance != s . maxBackwardDistance && s . pos < s . maxBackwardDistance ) {
s . maxDistance = s . pos ;
} else {
s . maxDistance = s . maxBackwardDistance ;
}
if ( s . distance > s . maxDistance ) {
2019-04-12 11:57:42 +00:00
s . runningState = 9 ;
2017-08-28 09:31:29 +00:00
continue ;
}
2019-04-12 11:57:42 +00:00
if ( distanceCode > 0 ) {
s . distRbIdx = ( s . distRbIdx + 1 ) & 0x3 ;
s . rings [ s . distRbIdx ] = s . distance ;
2017-08-28 09:31:29 +00:00
}
if ( s . copyLength > s . metaBlockLength ) {
throw "Invalid backward reference" ;
}
s . j = 0 ;
2019-04-12 11:57:42 +00:00
s . runningState = 8 ;
case 8 :
var /** number */ src = ( s . pos - s . distance ) & ringBufferMask ;
var /** number */ dst = s . pos ;
var /** number */ copyLength = s . copyLength - s . j ;
var /** number */ srcEnd = src + copyLength ;
var /** number */ dstEnd = dst + copyLength ;
2017-08-28 09:31:29 +00:00
if ( ( srcEnd < ringBufferMask ) && ( dstEnd < ringBufferMask ) ) {
if ( copyLength < 12 || ( srcEnd > dst && dstEnd > src ) ) {
2019-04-12 11:57:42 +00:00
for ( var /** number */ k = 0 ; k < copyLength ; k += 4 ) {
2017-08-28 09:31:29 +00:00
ringBuffer [ dst ++ ] = ringBuffer [ src ++ ] ;
ringBuffer [ dst ++ ] = ringBuffer [ src ++ ] ;
ringBuffer [ dst ++ ] = ringBuffer [ src ++ ] ;
ringBuffer [ dst ++ ] = ringBuffer [ src ++ ] ;
}
} else {
ringBuffer . copyWithin ( dst , src , srcEnd ) ;
}
s . j += copyLength ;
s . metaBlockLength -= copyLength ;
s . pos += copyLength ;
} else {
for ( ; s . j < s . copyLength ; ) {
ringBuffer [ s . pos ] = ringBuffer [ ( s . pos - s . distance ) & ringBufferMask ] ;
s . metaBlockLength -- ;
2018-09-13 12:09:32 +00:00
s . pos ++ ;
2017-08-28 09:31:29 +00:00
s . j ++ ;
2018-09-13 12:09:32 +00:00
if ( s . pos >= fence ) {
2019-04-12 11:57:42 +00:00
s . nextRunningState = 8 ;
s . runningState = 12 ;
2017-08-28 09:31:29 +00:00
break ;
}
}
}
2019-04-12 11:57:42 +00:00
if ( s . runningState == 8 ) {
s . runningState = 4 ;
2017-08-28 09:31:29 +00:00
}
continue ;
2019-04-12 11:57:42 +00:00
case 9 :
if ( s . distance > 0x7FFFFFFC ) {
throw "Invalid backward reference" ;
}
2017-08-28 09:31:29 +00:00
if ( s . copyLength >= 4 && s . copyLength <= 24 ) {
2019-04-12 11:57:42 +00:00
var /** number */ offset = DICTIONARY _OFFSETS _BY _LENGTH [ s . copyLength ] ;
var /** number */ wordId = s . distance - s . maxDistance - 1 ;
var /** number */ shift = DICTIONARY _SIZE _BITS _BY _LENGTH [ s . copyLength ] ;
var /** number */ mask = ( 1 << shift ) - 1 ;
var /** number */ wordIdx = wordId & mask ;
var /** number */ transformIdx = wordId >>> shift ;
2017-08-28 09:31:29 +00:00
offset += wordIdx * s . copyLength ;
if ( transformIdx < 121 ) {
2019-04-12 11:57:42 +00:00
var /** number */ len = transformDictionaryWord ( ringBuffer , s . pos , DICTIONARY _DATA , offset , s . copyLength , RFC _TRANSFORMS , transformIdx ) ;
2017-08-28 09:31:29 +00:00
s . pos += len ;
s . metaBlockLength -= len ;
2018-09-13 12:09:32 +00:00
if ( s . pos >= fence ) {
2019-04-12 11:57:42 +00:00
s . nextRunningState = 4 ;
s . runningState = 12 ;
2017-08-28 09:31:29 +00:00
continue ;
}
} else {
throw "Invalid backward reference" ;
}
} else {
throw "Invalid backward reference" ;
}
2019-04-12 11:57:42 +00:00
s . runningState = 4 ;
2017-08-28 09:31:29 +00:00
continue ;
2019-04-12 11:57:42 +00:00
case 5 :
2017-08-28 09:31:29 +00:00
while ( s . metaBlockLength > 0 ) {
if ( s . halfOffset > 2030 ) {
doReadMoreInput ( s ) ;
}
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
readFewBits ( s , 8 ) ;
s . metaBlockLength -- ;
}
2019-04-12 11:57:42 +00:00
s . runningState = 2 ;
2017-08-28 09:31:29 +00:00
continue ;
2019-04-12 11:57:42 +00:00
case 6 :
2017-08-28 09:31:29 +00:00
copyUncompressedData ( s ) ;
continue ;
case 12 :
2019-04-12 11:57:42 +00:00
s . ringBufferBytesReady = min ( s . pos , s . ringBufferSize ) ;
s . runningState = 13 ;
case 13 :
2017-08-28 09:31:29 +00:00
if ( writeRingBuffer ( s ) == 0 ) {
return ;
}
if ( s . pos >= s . maxBackwardDistance ) {
s . maxDistance = s . maxBackwardDistance ;
}
2018-09-13 12:09:32 +00:00
if ( s . pos >= s . ringBufferSize ) {
if ( s . pos > s . ringBufferSize ) {
ringBuffer . copyWithin ( 0 , s . ringBufferSize , s . pos ) ;
}
s . pos &= ringBufferMask ;
s . ringBufferBytesWritten = 0 ;
}
2017-08-28 09:31:29 +00:00
s . runningState = s . nextRunningState ;
continue ;
default :
throw "Unexpected state " + s . runningState ;
}
}
2019-04-12 11:57:42 +00:00
if ( s . runningState == 10 ) {
2017-08-28 09:31:29 +00:00
if ( s . metaBlockLength < 0 ) {
throw "Invalid metablock length" ;
}
jumpToByteBoundary ( s ) ;
checkHealth ( s , 1 ) ;
}
}
2019-04-12 11:57:42 +00:00
/ * *
* @ constructor
* @ param { number } numTransforms
* @ param { number } prefixSuffixLen
* @ param { number } prefixSuffixCount
* @ struct
* /
function Transforms ( numTransforms , prefixSuffixLen , prefixSuffixCount ) {
/** @type {!number} */
this . numTransforms = 0 ;
/** @type {!Int32Array} */
this . triplets = new Int32Array ( 0 ) ;
/** @type {!Int8Array} */
this . prefixSuffixStorage = new Int8Array ( 0 ) ;
/** @type {!Int32Array} */
this . prefixSuffixHeads = new Int32Array ( 0 ) ;
/** @type {!Int16Array} */
this . params = new Int16Array ( 0 ) ;
this . numTransforms = numTransforms ;
this . triplets = new Int32Array ( numTransforms * 3 ) ;
this . params = new Int16Array ( numTransforms ) ;
this . prefixSuffixStorage = new Int8Array ( prefixSuffixLen ) ;
this . prefixSuffixHeads = new Int32Array ( prefixSuffixCount + 1 ) ;
}
var RFC _TRANSFORMS = new Transforms ( 121 , 167 , 50 ) ;
2017-08-28 09:31:29 +00:00
/ * *
* @ param { ! Int8Array } prefixSuffix
* @ param { ! Int32Array } prefixSuffixHeads
* @ param { ! Int32Array } transforms
* @ param { ! string } prefixSuffixSrc
* @ param { ! string } transformsSrc
2017-10-09 15:07:34 +00:00
* @ return { void }
2017-08-28 09:31:29 +00:00
* /
function unpackTransforms ( prefixSuffix , prefixSuffixHeads , transforms , prefixSuffixSrc , transformsSrc ) {
2019-04-12 11:57:42 +00:00
var /** number */ n = prefixSuffixSrc . length ;
var /** number */ index = 1 ;
var /** number */ j = 0 ;
for ( var /** number */ i = 0 ; i < n ; ++ i ) {
var /** number */ c = prefixSuffixSrc . charCodeAt ( i ) ;
2017-08-28 09:31:29 +00:00
if ( c == 35 ) {
2019-04-12 11:57:42 +00:00
prefixSuffixHeads [ index ++ ] = j ;
} else {
prefixSuffix [ j ++ ] = c ;
2017-08-28 09:31:29 +00:00
}
}
2019-04-12 11:57:42 +00:00
for ( var /** number */ i = 0 ; i < 363 ; ++ i ) {
2017-08-28 09:31:29 +00:00
transforms [ i ] = transformsSrc . charCodeAt ( i ) - 32 ;
}
}
{
2019-04-12 11:57:42 +00:00
unpackTransforms ( RFC _TRANSFORMS . prefixSuffixStorage , RFC _TRANSFORMS . prefixSuffixHeads , RFC _TRANSFORMS . triplets , "# #s #, #e #.# the #.com/#\u00C2\u00A0# of # and # in # to #\"#\">#\n#]# for # a # that #. # with #'# from # by #. The # on # as # is #ing #\n\t#:#ed #(# at #ly #=\"# of the #. This #,# not #er #al #='#ful #ive #less #est #ize #ous #" , " !! ! , *! &! \" ! ) * * - ! # ! #!*! + ,$ ! - % . / # 0 1 . \" 2 3!* 4% ! # / 5 6 7 8 0 1 & $ 9 + : ; < ' != > ?! 4 @ 4 2 & A *# ( B C& ) % ) !*# *-% A +! *. D! %' & E *6 F G% ! *A *% H! D I!+! J!+ K +- *4! A L!*4 M N +6 O!*% +.! K *G P +%( ! G *D +D Q +# *K!*G!+D!+# +G +A +4!+% +K!+4!*D!+K!*K" ) ;
2017-08-28 09:31:29 +00:00
}
/ * *
* @ param { ! Int8Array } dst
2019-04-12 11:57:42 +00:00
* @ param { number } dstOffset
* @ param { ! Int8Array } src
* @ param { number } srcOffset
* @ param { number } len
* @ param { ! Transforms } transforms
* @ param { number } transformIndex
* @ return { number }
2017-08-28 09:31:29 +00:00
* /
2019-04-12 11:57:42 +00:00
function transformDictionaryWord ( dst , dstOffset , src , srcOffset , len , transforms , transformIndex ) {
var /** number */ offset = dstOffset ;
var /** !Int32Array */ triplets = transforms . triplets ;
var /** !Int8Array */ prefixSuffixStorage = transforms . prefixSuffixStorage ;
var /** !Int32Array */ prefixSuffixHeads = transforms . prefixSuffixHeads ;
var /** number */ transformOffset = 3 * transformIndex ;
var /** number */ prefixIdx = triplets [ transformOffset ] ;
var /** number */ transformType = triplets [ transformOffset + 1 ] ;
var /** number */ suffixIdx = triplets [ transformOffset + 2 ] ;
var /** number */ prefix = prefixSuffixHeads [ prefixIdx ] ;
var /** number */ prefixEnd = prefixSuffixHeads [ prefixIdx + 1 ] ;
var /** number */ suffix = prefixSuffixHeads [ suffixIdx ] ;
var /** number */ suffixEnd = prefixSuffixHeads [ suffixIdx + 1 ] ;
var /** number */ omitFirst = transformType - 11 ;
var /** number */ omitLast = transformType - 0 ;
if ( omitFirst < 1 || omitFirst > 9 ) {
omitFirst = 0 ;
}
if ( omitLast < 1 || omitLast > 9 ) {
omitLast = 0 ;
}
while ( prefix != prefixEnd ) {
dst [ offset ++ ] = prefixSuffixStorage [ prefix ++ ] ;
}
2017-08-28 09:31:29 +00:00
if ( omitFirst > len ) {
omitFirst = len ;
}
2019-04-12 11:57:42 +00:00
srcOffset += omitFirst ;
2017-08-28 09:31:29 +00:00
len -= omitFirst ;
2019-04-12 11:57:42 +00:00
len -= omitLast ;
var /** number */ i = len ;
2017-08-28 09:31:29 +00:00
while ( i > 0 ) {
2019-04-12 11:57:42 +00:00
dst [ offset ++ ] = src [ srcOffset ++ ] ;
2017-08-28 09:31:29 +00:00
i -- ;
}
2019-04-12 11:57:42 +00:00
if ( transformType == 10 || transformType == 11 ) {
var /** number */ uppercaseOffset = offset - len ;
2017-08-28 09:31:29 +00:00
if ( transformType == 10 ) {
len = 1 ;
}
while ( len > 0 ) {
2019-04-12 11:57:42 +00:00
var /** number */ c0 = dst [ uppercaseOffset ] & 0xFF ;
if ( c0 < 0xC0 ) {
if ( c0 >= 97 && c0 <= 122 ) {
2017-08-28 09:31:29 +00:00
dst [ uppercaseOffset ] ^= 32 ;
}
uppercaseOffset += 1 ;
len -= 1 ;
2019-04-12 11:57:42 +00:00
} else if ( c0 < 0xE0 ) {
2017-08-28 09:31:29 +00:00
dst [ uppercaseOffset + 1 ] ^= 32 ;
uppercaseOffset += 2 ;
len -= 2 ;
} else {
dst [ uppercaseOffset + 2 ] ^= 5 ;
uppercaseOffset += 3 ;
len -= 3 ;
}
}
2019-04-12 11:57:42 +00:00
} else if ( transformType == 21 || transformType == 22 ) {
var /** number */ shiftOffset = offset - len ;
var /** number */ param = transforms . params [ transformIndex ] ;
var /** number */ scalar = ( param & 0x7FFF ) + ( 0x1000000 - ( param & 0x8000 ) ) ;
while ( len > 0 ) {
var /** number */ step = 1 ;
var /** number */ c0 = dst [ shiftOffset ] & 0xFF ;
if ( c0 < 0x80 ) {
scalar += c0 ;
dst [ shiftOffset ] = ( scalar & 0x7F ) ;
} else if ( c0 < 0xC0 ) {
} else if ( c0 < 0xE0 ) {
if ( len >= 2 ) {
var /** number */ c1 = dst [ shiftOffset + 1 ] ;
scalar += ( c1 & 0x3F ) | ( ( c0 & 0x1F ) << 6 ) ;
dst [ shiftOffset ] = ( 0xC0 | ( ( scalar >> 6 ) & 0x1F ) ) ;
dst [ shiftOffset + 1 ] = ( ( c1 & 0xC0 ) | ( scalar & 0x3F ) ) ;
step = 2 ;
} else {
step = len ;
}
} else if ( c0 < 0xF0 ) {
if ( len >= 3 ) {
var /** number */ c1 = dst [ shiftOffset + 1 ] ;
var /** number */ c2 = dst [ shiftOffset + 2 ] ;
scalar += ( c2 & 0x3F ) | ( ( c1 & 0x3F ) << 6 ) | ( ( c0 & 0x0F ) << 12 ) ;
dst [ shiftOffset ] = ( 0xE0 | ( ( scalar >> 12 ) & 0x0F ) ) ;
dst [ shiftOffset + 1 ] = ( ( c1 & 0xC0 ) | ( ( scalar >> 6 ) & 0x3F ) ) ;
dst [ shiftOffset + 2 ] = ( ( c2 & 0xC0 ) | ( scalar & 0x3F ) ) ;
step = 3 ;
} else {
step = len ;
}
} else if ( c0 < 0xF8 ) {
if ( len >= 4 ) {
var /** number */ c1 = dst [ shiftOffset + 1 ] ;
var /** number */ c2 = dst [ shiftOffset + 2 ] ;
var /** number */ c3 = dst [ shiftOffset + 3 ] ;
scalar += ( c3 & 0x3F ) | ( ( c2 & 0x3F ) << 6 ) | ( ( c1 & 0x3F ) << 12 ) | ( ( c0 & 0x07 ) << 18 ) ;
dst [ shiftOffset ] = ( 0xF0 | ( ( scalar >> 18 ) & 0x07 ) ) ;
dst [ shiftOffset + 1 ] = ( ( c1 & 0xC0 ) | ( ( scalar >> 12 ) & 0x3F ) ) ;
dst [ shiftOffset + 2 ] = ( ( c2 & 0xC0 ) | ( ( scalar >> 6 ) & 0x3F ) ) ;
dst [ shiftOffset + 3 ] = ( ( c3 & 0xC0 ) | ( scalar & 0x3F ) ) ;
step = 4 ;
} else {
step = len ;
}
}
shiftOffset += step ;
len -= step ;
if ( transformType == 21 ) {
len = 0 ;
}
}
2017-08-28 09:31:29 +00:00
}
2019-04-12 11:57:42 +00:00
while ( suffix != suffixEnd ) {
dst [ offset ++ ] = prefixSuffixStorage [ suffix ++ ] ;
2017-08-28 09:31:29 +00:00
}
return offset - dstOffset ;
}
/ * *
2019-04-12 11:57:42 +00:00
* @ param { number } key
* @ param { number } len
* @ return { number }
2017-08-28 09:31:29 +00:00
* /
function getNextKey ( key , len ) {
2019-04-12 11:57:42 +00:00
var /** number */ step = 1 << ( len - 1 ) ;
2017-08-28 09:31:29 +00:00
while ( ( key & step ) != 0 ) {
step >>= 1 ;
}
return ( key & ( step - 1 ) ) + step ;
}
/ * *
* @ param { ! Int32Array } table
2019-04-12 11:57:42 +00:00
* @ param { number } offset
* @ param { number } step
* @ param { number } end
* @ param { number } item
2017-10-09 15:07:34 +00:00
* @ return { void }
2017-08-28 09:31:29 +00:00
* /
function replicateValue ( table , offset , step , end , item ) {
do {
end -= step ;
table [ offset + end ] = item ;
} while ( end > 0 ) ;
}
/ * *
* @ param { ! Int32Array } count
2019-04-12 11:57:42 +00:00
* @ param { number } len
* @ param { number } rootBits
* @ return { number }
2017-08-28 09:31:29 +00:00
* /
function nextTableBitSize ( count , len , rootBits ) {
2019-04-12 11:57:42 +00:00
var /** number */ left = 1 << ( len - rootBits ) ;
2017-08-28 09:31:29 +00:00
while ( len < 15 ) {
left -= count [ len ] ;
if ( left <= 0 ) {
break ;
}
len ++ ;
left <<= 1 ;
}
return len - rootBits ;
}
/ * *
2019-04-12 11:57:42 +00:00
* @ param { ! Int32Array } tableGroup
* @ param { number } tableIdx
* @ param { number } rootBits
2017-08-28 09:31:29 +00:00
* @ param { ! Int32Array } codeLengths
2019-04-12 11:57:42 +00:00
* @ param { number } codeLengthsSize
* @ return { number }
2017-08-28 09:31:29 +00:00
* /
2019-04-12 11:57:42 +00:00
function buildHuffmanTable ( tableGroup , tableIdx , rootBits , codeLengths , codeLengthsSize ) {
var /** number */ tableOffset = tableGroup [ tableIdx ] ;
var /** number */ key ;
2017-08-28 09:31:29 +00:00
var /** !Int32Array */ sorted = new Int32Array ( codeLengthsSize ) ;
var /** !Int32Array */ count = new Int32Array ( 16 ) ;
var /** !Int32Array */ offset = new Int32Array ( 16 ) ;
2019-04-12 11:57:42 +00:00
var /** number */ symbol ;
2017-08-28 09:31:29 +00:00
for ( symbol = 0 ; symbol < codeLengthsSize ; symbol ++ ) {
count [ codeLengths [ symbol ] ] ++ ;
}
offset [ 1 ] = 0 ;
2019-04-12 11:57:42 +00:00
for ( var /** number */ len = 1 ; len < 15 ; len ++ ) {
2017-08-28 09:31:29 +00:00
offset [ len + 1 ] = offset [ len ] + count [ len ] ;
}
for ( symbol = 0 ; symbol < codeLengthsSize ; symbol ++ ) {
if ( codeLengths [ symbol ] != 0 ) {
sorted [ offset [ codeLengths [ symbol ] ] ++ ] = symbol ;
}
}
2019-04-12 11:57:42 +00:00
var /** number */ tableBits = rootBits ;
var /** number */ tableSize = 1 << tableBits ;
var /** number */ totalSize = tableSize ;
2017-08-28 09:31:29 +00:00
if ( offset [ 15 ] == 1 ) {
for ( key = 0 ; key < totalSize ; key ++ ) {
2019-04-12 11:57:42 +00:00
tableGroup [ tableOffset + key ] = sorted [ 0 ] ;
2017-08-28 09:31:29 +00:00
}
2019-04-12 11:57:42 +00:00
return totalSize ;
2017-08-28 09:31:29 +00:00
}
key = 0 ;
symbol = 0 ;
2019-04-12 11:57:42 +00:00
for ( var /** number */ len = 1 , step = 2 ; len <= rootBits ; len ++ , step <<= 1 ) {
2017-08-28 09:31:29 +00:00
for ( ; count [ len ] > 0 ; count [ len ] -- ) {
2019-04-12 11:57:42 +00:00
replicateValue ( tableGroup , tableOffset + key , step , tableSize , len << 16 | sorted [ symbol ++ ] ) ;
2017-08-28 09:31:29 +00:00
key = getNextKey ( key , len ) ;
}
}
2019-04-12 11:57:42 +00:00
var /** number */ mask = totalSize - 1 ;
var /** number */ low = - 1 ;
var /** number */ currentOffset = tableOffset ;
for ( var /** number */ len = rootBits + 1 , step = 2 ; len <= 15 ; len ++ , step <<= 1 ) {
2017-08-28 09:31:29 +00:00
for ( ; count [ len ] > 0 ; count [ len ] -- ) {
if ( ( key & mask ) != low ) {
currentOffset += tableSize ;
tableBits = nextTableBitSize ( count , len , rootBits ) ;
tableSize = 1 << tableBits ;
totalSize += tableSize ;
low = key & mask ;
2019-04-12 11:57:42 +00:00
tableGroup [ tableOffset + low ] = ( tableBits + rootBits ) << 16 | ( currentOffset - tableOffset - low ) ;
2017-08-28 09:31:29 +00:00
}
2019-04-12 11:57:42 +00:00
replicateValue ( tableGroup , currentOffset + ( key >> rootBits ) , step , tableSize , ( len - rootBits ) << 16 | sorted [ symbol ++ ] ) ;
2017-08-28 09:31:29 +00:00
key = getNextKey ( key , len ) ;
}
}
2019-04-12 11:57:42 +00:00
return totalSize ;
2017-08-28 09:31:29 +00:00
}
/ * *
* @ param { ! State } s
2017-10-09 15:07:34 +00:00
* @ return { void }
2017-08-28 09:31:29 +00:00
* /
function doReadMoreInput ( s ) {
if ( s . endOfStreamReached != 0 ) {
if ( halfAvailable ( s ) >= - 2 ) {
return ;
}
throw "No more input" ;
}
2019-04-12 11:57:42 +00:00
var /** number */ readOffset = s . halfOffset << 1 ;
var /** number */ bytesInBuffer = 4096 - readOffset ;
2017-08-28 09:31:29 +00:00
s . byteBuffer . copyWithin ( 0 , readOffset , 4096 ) ;
s . halfOffset = 0 ;
while ( bytesInBuffer < 4096 ) {
2019-04-12 11:57:42 +00:00
var /** number */ spaceLeft = 4096 - bytesInBuffer ;
var /** number */ len = readInput ( s . input , s . byteBuffer , bytesInBuffer , spaceLeft ) ;
2017-08-28 09:31:29 +00:00
if ( len <= 0 ) {
s . endOfStreamReached = 1 ;
s . tailBytes = bytesInBuffer ;
bytesInBuffer += 1 ;
break ;
}
bytesInBuffer += len ;
}
bytesToNibbles ( s , bytesInBuffer ) ;
}
/ * *
* @ param { ! State } s
2019-04-12 11:57:42 +00:00
* @ param { number } endOfStream
2017-10-09 15:07:34 +00:00
* @ return { void }
2017-08-28 09:31:29 +00:00
* /
function checkHealth ( s , endOfStream ) {
if ( s . endOfStreamReached == 0 ) {
return ;
}
2019-04-12 11:57:42 +00:00
var /** number */ byteOffset = ( s . halfOffset << 1 ) + ( ( s . bitOffset + 7 ) >> 3 ) - 4 ;
2017-08-28 09:31:29 +00:00
if ( byteOffset > s . tailBytes ) {
throw "Read after end" ;
}
if ( ( endOfStream != 0 ) && ( byteOffset != s . tailBytes ) ) {
throw "Unused bytes after end" ;
}
}
/ * *
* @ param { ! State } s
2019-04-12 11:57:42 +00:00
* @ return { void }
* /
function assertAccumulatorHealthy ( s ) {
if ( s . bitOffset > 32 ) {
throw "Accumulator underloaded: " + s . bitOffset ;
}
}
/ * *
* @ param { ! State } s
* @ param { number } n
* @ return { number }
2017-08-28 09:31:29 +00:00
* /
function readFewBits ( s , n ) {
2019-04-12 11:57:42 +00:00
var /** number */ val = ( s . accumulator32 >>> s . bitOffset ) & ( ( 1 << n ) - 1 ) ;
2017-08-28 09:31:29 +00:00
s . bitOffset += n ;
return val ;
}
/ * *
* @ param { ! State } s
2019-04-12 11:57:42 +00:00
* @ param { number } n
* @ return { number }
2017-08-28 09:31:29 +00:00
* /
function readManyBits ( s , n ) {
2019-04-12 11:57:42 +00:00
var /** number */ low = readFewBits ( s , 16 ) ;
2017-08-28 09:31:29 +00:00
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
return low | ( readFewBits ( s , n - 16 ) << 16 ) ;
}
/ * *
* @ param { ! State } s
2017-10-09 15:07:34 +00:00
* @ return { void }
2017-08-28 09:31:29 +00:00
* /
function initBitReader ( s ) {
s . byteBuffer = new Int8Array ( 4160 ) ;
s . accumulator32 = 0 ;
s . shortBuffer = new Int16Array ( 2080 ) ;
s . bitOffset = 32 ;
s . halfOffset = 2048 ;
s . endOfStreamReached = 0 ;
prepare ( s ) ;
}
/ * *
* @ param { ! State } s
2017-10-09 15:07:34 +00:00
* @ return { void }
2017-08-28 09:31:29 +00:00
* /
function prepare ( s ) {
if ( s . halfOffset > 2030 ) {
doReadMoreInput ( s ) ;
}
checkHealth ( s , 0 ) ;
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
/ * *
* @ param { ! State } s
2017-10-09 15:07:34 +00:00
* @ return { void }
2017-08-28 09:31:29 +00:00
* /
function reload ( s ) {
if ( s . bitOffset == 32 ) {
prepare ( s ) ;
}
}
/ * *
* @ param { ! State } s
2017-10-09 15:07:34 +00:00
* @ return { void }
2017-08-28 09:31:29 +00:00
* /
function jumpToByteBoundary ( s ) {
2019-04-12 11:57:42 +00:00
var /** number */ padding = ( 32 - s . bitOffset ) & 7 ;
2017-08-28 09:31:29 +00:00
if ( padding != 0 ) {
2019-04-12 11:57:42 +00:00
var /** number */ paddingBits = readFewBits ( s , padding ) ;
2017-08-28 09:31:29 +00:00
if ( paddingBits != 0 ) {
throw "Corrupted padding bits" ;
}
}
}
/ * *
* @ param { ! State } s
2019-04-12 11:57:42 +00:00
* @ return { number }
2017-08-28 09:31:29 +00:00
* /
function halfAvailable ( s ) {
2019-04-12 11:57:42 +00:00
var /** number */ limit = 2048 ;
2017-08-28 09:31:29 +00:00
if ( s . endOfStreamReached != 0 ) {
limit = ( s . tailBytes + 1 ) >> 1 ;
}
return limit - s . halfOffset ;
}
/ * *
* @ param { ! State } s
* @ param { ! Int8Array } data
2019-04-12 11:57:42 +00:00
* @ param { number } offset
* @ param { number } length
2017-10-09 15:07:34 +00:00
* @ return { void }
2017-08-28 09:31:29 +00:00
* /
function copyBytes ( s , data , offset , length ) {
if ( ( s . bitOffset & 7 ) != 0 ) {
throw "Unaligned copyBytes" ;
}
while ( ( s . bitOffset != 32 ) && ( length != 0 ) ) {
data [ offset ++ ] = ( s . accumulator32 >>> s . bitOffset ) ;
s . bitOffset += 8 ;
length -- ;
}
if ( length == 0 ) {
return ;
}
2019-04-12 11:57:42 +00:00
var /** number */ copyNibbles = min ( halfAvailable ( s ) , length >> 1 ) ;
2017-08-28 09:31:29 +00:00
if ( copyNibbles > 0 ) {
2019-04-12 11:57:42 +00:00
var /** number */ readOffset = s . halfOffset << 1 ;
var /** number */ delta = copyNibbles << 1 ;
2017-08-28 09:31:29 +00:00
data . set ( s . byteBuffer . subarray ( readOffset , readOffset + delta ) , offset ) ;
offset += delta ;
length -= delta ;
s . halfOffset += copyNibbles ;
}
if ( length == 0 ) {
return ;
}
if ( halfAvailable ( s ) > 0 ) {
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
while ( length != 0 ) {
data [ offset ++ ] = ( s . accumulator32 >>> s . bitOffset ) ;
s . bitOffset += 8 ;
length -- ;
}
checkHealth ( s , 0 ) ;
return ;
}
while ( length > 0 ) {
2019-04-12 11:57:42 +00:00
var /** number */ len = readInput ( s . input , data , offset , length ) ;
2017-08-28 09:31:29 +00:00
if ( len == - 1 ) {
throw "Unexpected end of input" ;
}
offset += len ;
length -= len ;
}
}
/ * *
* @ param { ! State } s
2019-04-12 11:57:42 +00:00
* @ param { number } byteLen
2017-10-09 15:07:34 +00:00
* @ return { void }
2017-08-28 09:31:29 +00:00
* /
function bytesToNibbles ( s , byteLen ) {
var /** !Int8Array */ byteBuffer = s . byteBuffer ;
2019-04-12 11:57:42 +00:00
var /** number */ halfLen = byteLen >> 1 ;
2017-08-28 09:31:29 +00:00
var /** !Int16Array */ shortBuffer = s . shortBuffer ;
2019-04-12 11:57:42 +00:00
for ( var /** number */ i = 0 ; i < halfLen ; ++ i ) {
2017-08-28 09:31:29 +00:00
shortBuffer [ i ] = ( ( byteBuffer [ i * 2 ] & 0xFF ) | ( ( byteBuffer [ ( i * 2 ) + 1 ] & 0xFF ) << 8 ) ) ;
}
}
var LOOKUP = new Int32Array ( 2048 ) ;
/ * *
* @ param { ! Int32Array } lookup
* @ param { ! string } map
* @ param { ! string } rle
2017-10-09 15:07:34 +00:00
* @ return { void }
2017-08-28 09:31:29 +00:00
* /
function unpackLookupTable ( lookup , map , rle ) {
2019-04-12 11:57:42 +00:00
for ( var /** number */ i = 0 ; i < 256 ; ++ i ) {
2017-08-28 09:31:29 +00:00
lookup [ i ] = i & 0x3F ;
lookup [ 512 + i ] = i >> 2 ;
lookup [ 1792 + i ] = 2 + ( i >> 6 ) ;
}
2019-04-12 11:57:42 +00:00
for ( var /** number */ i = 0 ; i < 128 ; ++ i ) {
2017-08-28 09:31:29 +00:00
lookup [ 1024 + i ] = 4 * ( map . charCodeAt ( i ) - 32 ) ;
}
2019-04-12 11:57:42 +00:00
for ( var /** number */ i = 0 ; i < 64 ; ++ i ) {
2017-08-28 09:31:29 +00:00
lookup [ 1152 + i ] = i & 1 ;
lookup [ 1216 + i ] = 2 + ( i & 1 ) ;
}
2019-04-12 11:57:42 +00:00
var /** number */ offset = 1280 ;
for ( var /** number */ k = 0 ; k < 19 ; ++ k ) {
var /** number */ value = k & 3 ;
var /** number */ rep = rle . charCodeAt ( k ) - 32 ;
for ( var /** number */ i = 0 ; i < rep ; ++ i ) {
2017-08-28 09:31:29 +00:00
lookup [ offset ++ ] = value ;
}
}
2019-04-12 11:57:42 +00:00
for ( var /** number */ i = 0 ; i < 16 ; ++ i ) {
2017-08-28 09:31:29 +00:00
lookup [ 1792 + i ] = 1 ;
lookup [ 2032 + i ] = 6 ;
}
lookup [ 1792 ] = 0 ;
lookup [ 2047 ] = 7 ;
2019-04-12 11:57:42 +00:00
for ( var /** number */ i = 0 ; i < 256 ; ++ i ) {
2017-08-28 09:31:29 +00:00
lookup [ 1536 + i ] = lookup [ 1792 + i ] << 3 ;
}
}
{
unpackLookupTable ( LOOKUP , " !! ! \"#$##%#$&'##(#)#++++++++++((&*'##,---,---,-----,-----,-----&#'###.///.///./////./////./////&#'# " , "A/* ': & : $ \u0081 @" ) ;
}
/ * *
* @ constructor
* @ struct
* /
function State ( ) {
/** @type {!Int8Array} */
this . ringBuffer = new Int8Array ( 0 ) ;
/** @type {!Int8Array} */
this . contextModes = new Int8Array ( 0 ) ;
/** @type {!Int8Array} */
this . contextMap = new Int8Array ( 0 ) ;
/** @type {!Int8Array} */
this . distContextMap = new Int8Array ( 0 ) ;
/** @type {!Int8Array} */
2019-04-12 11:57:42 +00:00
this . distExtraBits = new Int8Array ( 0 ) ;
/** @type {!Int8Array} */
2017-08-28 09:31:29 +00:00
this . output = new Int8Array ( 0 ) ;
/** @type {!Int8Array} */
this . byteBuffer = new Int8Array ( 0 ) ;
/** @type {!Int16Array} */
this . shortBuffer = new Int16Array ( 0 ) ;
/** @type {!Int32Array} */
this . intBuffer = new Int32Array ( 0 ) ;
/** @type {!Int32Array} */
this . rings = new Int32Array ( 0 ) ;
/** @type {!Int32Array} */
this . blockTrees = new Int32Array ( 0 ) ;
/** @type {!Int32Array} */
2019-04-12 11:57:42 +00:00
this . literalTreeGroup = new Int32Array ( 0 ) ;
/** @type {!Int32Array} */
this . commandTreeGroup = new Int32Array ( 0 ) ;
2017-08-28 09:31:29 +00:00
/** @type {!Int32Array} */
2019-04-12 11:57:42 +00:00
this . distanceTreeGroup = new Int32Array ( 0 ) ;
2017-08-28 09:31:29 +00:00
/** @type {!Int32Array} */
2019-04-12 11:57:42 +00:00
this . distOffset = new Int32Array ( 0 ) ;
2017-08-28 09:31:29 +00:00
/** @type {!number} */
this . runningState = 0 ;
/** @type {!number} */
this . nextRunningState = 0 ;
/** @type {!number} */
this . accumulator32 = 0 ;
/** @type {!number} */
this . bitOffset = 0 ;
/** @type {!number} */
this . halfOffset = 0 ;
/** @type {!number} */
this . tailBytes = 0 ;
/** @type {!number} */
this . endOfStreamReached = 0 ;
/** @type {!number} */
this . metaBlockLength = 0 ;
/** @type {!number} */
this . inputEnd = 0 ;
/** @type {!number} */
this . isUncompressed = 0 ;
/** @type {!number} */
this . isMetadata = 0 ;
/** @type {!number} */
this . literalBlockLength = 0 ;
/** @type {!number} */
this . numLiteralBlockTypes = 0 ;
/** @type {!number} */
this . commandBlockLength = 0 ;
/** @type {!number} */
this . numCommandBlockTypes = 0 ;
/** @type {!number} */
this . distanceBlockLength = 0 ;
/** @type {!number} */
this . numDistanceBlockTypes = 0 ;
/** @type {!number} */
this . pos = 0 ;
/** @type {!number} */
this . maxDistance = 0 ;
/** @type {!number} */
this . distRbIdx = 0 ;
/** @type {!number} */
this . trivialLiteralContext = 0 ;
/** @type {!number} */
2019-04-12 11:57:42 +00:00
this . literalTreeIdx = 0 ;
2017-08-28 09:31:29 +00:00
/** @type {!number} */
2019-04-12 11:57:42 +00:00
this . commandTreeIdx = 0 ;
2017-08-28 09:31:29 +00:00
/** @type {!number} */
this . j = 0 ;
/** @type {!number} */
this . insertLength = 0 ;
/** @type {!number} */
this . contextMapSlice = 0 ;
/** @type {!number} */
this . distContextMapSlice = 0 ;
/** @type {!number} */
this . contextLookupOffset1 = 0 ;
/** @type {!number} */
this . contextLookupOffset2 = 0 ;
/** @type {!number} */
this . distanceCode = 0 ;
/** @type {!number} */
this . numDirectDistanceCodes = 0 ;
/** @type {!number} */
this . distancePostfixMask = 0 ;
/** @type {!number} */
this . distancePostfixBits = 0 ;
/** @type {!number} */
this . distance = 0 ;
/** @type {!number} */
this . copyLength = 0 ;
/** @type {!number} */
this . maxBackwardDistance = 0 ;
/** @type {!number} */
this . maxRingBufferSize = 0 ;
/** @type {!number} */
this . ringBufferSize = 0 ;
/** @type {!number} */
this . expectedTotalSize = 0 ;
/** @type {!number} */
this . outputOffset = 0 ;
/** @type {!number} */
this . outputLength = 0 ;
/** @type {!number} */
this . outputUsed = 0 ;
/** @type {!number} */
2018-09-13 12:09:32 +00:00
this . ringBufferBytesWritten = 0 ;
/** @type {!number} */
this . ringBufferBytesReady = 0 ;
2017-08-28 09:31:29 +00:00
/** @type {!number} */
2018-09-13 12:09:32 +00:00
this . isEager = 0 ;
2019-04-12 11:57:42 +00:00
/** @type {!number} */
this . isLargeWindow = 0 ;
2017-08-28 09:31:29 +00:00
/** @type {!InputStream|null} */
this . input = null ;
this . ringBuffer = new Int8Array ( 0 ) ;
this . rings = new Int32Array ( 10 ) ;
this . rings [ 0 ] = 16 ;
this . rings [ 1 ] = 15 ;
this . rings [ 2 ] = 11 ;
this . rings [ 3 ] = 4 ;
}
/ * *
* @ param { ! Int8Array } dictionary
* @ param { ! string } data0
* @ param { ! string } data1
* @ param { ! string } skipFlip
2017-10-09 15:07:34 +00:00
* @ return { void }
2017-08-28 09:31:29 +00:00
* /
function unpackDictionaryData ( dictionary , data0 , data1 , skipFlip ) {
2018-09-13 12:09:32 +00:00
var /** !Int8Array */ dict = toUsAsciiBytes ( data0 + data1 ) ;
if ( dict . length != dictionary . length ) {
2017-08-28 09:31:29 +00:00
throw "Corrupted brotli dictionary" ;
}
2019-04-12 11:57:42 +00:00
var /** number */ offset = 0 ;
var /** number */ n = skipFlip . length ;
for ( var /** number */ i = 0 ; i < n ; i += 2 ) {
var /** number */ skip = skipFlip . charCodeAt ( i ) - 36 ;
var /** number */ flip = skipFlip . charCodeAt ( i + 1 ) - 36 ;
2017-08-28 09:31:29 +00:00
offset += skip ;
2019-04-12 11:57:42 +00:00
for ( var /** number */ j = 0 ; j < flip ; ++ j ) {
2018-09-13 12:09:32 +00:00
dict [ offset ] |= 0x80 ;
2017-08-28 09:31:29 +00:00
offset ++ ;
}
}
2018-09-13 12:09:32 +00:00
dictionary . set ( dict ) ;
2017-08-28 09:31:29 +00:00
}
{
var /** !Int8Array */ dictionary = new Int8Array ( 122784 ) ;
unpackDictionaryData ( dictionary , "timedownlifeleftbackcodedatashowonlysitecityopenjustlikefreeworktextyearoverbodyloveformbookplaylivelinehelphomesidemorewordlongthemviewfindpagedaysfullheadtermeachareafromtruemarkableuponhighdatelandnewsevennextcasebothpostusedmadehandherewhatnameLinkblogsizebaseheldmakemainuser') +holdendswithNewsreadweresigntakehavegameseencallpathwellplusmenufilmpartjointhislistgoodneedwayswestjobsmindalsologorichuseslastteamarmyfoodkingwilleastwardbestfirePageknowaway.pngmovethanloadgiveselfnotemuchfeedmanyrockicononcelookhidediedHomerulehostajaxinfoclublawslesshalfsomesuchzone100%onescareTimeracebluefourweekfacehopegavehardlostwhenparkkeptpassshiproomHTMLplanTypedonesavekeepflaglinksoldfivetookratetownjumpthusdarkcardfilefearstaykillthatfallautoever.comtalkshopvotedeepmoderestturnbornbandfellroseurl(skinrolecomeactsagesmeetgold.jpgitemvaryfeltthensenddropViewcopy1.0\"</a>stopelseliestourpack.gifpastcss?graymean>rideshotlatesaidroadvar feeljohnrickportfast'UA-dead</b>poorbilltypeU.S.woodmust2px;Inforankwidewantwalllead[0];paulwavesure$('#waitmassarmsgoesgainlangpaid!-- lockunitrootwalkfirmwifexml\"songtest20pxkindrowstoolfontmailsafestarmapscorerainflowbabyspansays4px;6px;artsfootrealwikiheatsteptriporg/lakeweaktoldFormcastfansbankveryrunsjulytask1px;goalgrewslowedgeid=\"sets5px;.js?40pxif (soonseatnonetubezerosentreedfactintogiftharm18pxcamehillboldzoomvoideasyringfillpeakinitcost3px;jacktagsbitsrolleditknewnear<!--growJSONdutyNamesaleyou lotspainjazzcoldeyesfishwww.risktabsprev10pxrise25pxBlueding300,ballfordearnwildbox.fairlackverspairjunetechif(!pickevil$(\"#warmlorddoespull,000ideadrawhugespotfundburnhrefcellkeystickhourlossfuel12pxsuitdealRSS\"agedgreyGET\"easeaimsgirlaids8px;navygridtips#999warsladycars); }php?helltallwhomzh:e*/\r\n 100hall.\n\nA7px;pushchat0px;crew*/</hash75pxflatrare && tellcampontolaidmissskiptentfinemalegetsplot400,\r\n\r\ncoolfeet.php<br>ericmostguidbelldeschairmathatom/imgRluckcent000;tinygonehtmlselldrugFREEnodenick?id=losenullvastwindRSS wearrelybeensamedukenasacapewishgulfT23:hitsslotgatekickblurthey15px''););\">msiewinsbirdsortbetaseekT18:ordstreemall60pxfarmb\u0000\u0019sboys[0].');\" POSTbearkids ) ; } } marytend ( UK ) quadzh : f - siz -- -- prop ');\rliftT19:viceandydebt>RSSpoolneckblowT16:doorevalT17:letsfailoralpollnovacolsgene b\u0000\u0014softrometillross<h3>pourfadepink<tr>mini)|!(minezh:hbarshear00);milk -->ironfreddiskwentsoilputs/js/holyT22:ISBNT20:adamsees<h2>json' , 'contT21: RSSloopasiamoon</p>soulLINEfortcartT14:<h1>80px!--<9px;T04:mike:46ZniceinchYorkricezh:d' ) ) ; puremageparatonebond : 37 Z _of _ ']);000,zh:gtankyardbowlbush:56ZJava30px\n|}\n%C3%:34ZjeffEXPIcashvisagolfsnowzh:iquer.csssickmeatmin.binddellhirepicsrent:36ZHTTP-201fotowolfEND xbox:54ZBODYdick;\n}\nexit:35Zvarsbeat' } ) ; diet999 ; anne } } < /[i].LangkmB2wiretoysaddssealalex;\n\t}echonine.org005)tonyjewssandlegsroof000) 200winegeardogsbootgarycutstyletemption.xmlcockgang$('.50pxPh.Dmiscalanloandeskmileryanunixdisc);}\ndustclip).\n\n70px-200DVDs7]><tapedemoi++)wageeurophiloptsholeFAQsasin-26TlabspetsURL bulkcook;}\r\nHEAD[0])abbrjuan(198leshtwin</i > sonyguysfuckpipe | - \ n ! 002 ) ndow [ 1 ] ; [ ] ; \ nLog salt \ r \ n \ t \ tbangtrimbath ) { \ r \ n00px \ n } ) ; ko : lfeesad > \ rs : // [];tollplug(){\n{\r\n .js'200pdualboat.JPG);\n}quot);\n\n');\n\r\n}\r201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037201320122011201020092008200720062005200420032002200120001999199819971996199519941993199219911990198919881987198619851984198319821981198019791978197719761975197419731972197119701969196819671966196519641963196219611960195919581957195619551954195319521951195010001024139400009999comomC!sesteestaperotodohacecadaaC1obiendC-aasC-vidacasootroforosolootracualdijosidograntipotemadebealgoquC)estonadatrespococasabajotodasinoaguapuesunosantediceluisellamayozonaamorpisoobraclicellodioshoracasiP7P0P=P0P>P<Q\u0000P0Q\u0000Q\u0003Q\u0002P0P=P5P?P>P>Q\u0002P8P7P=P>P4P>Q\u0002P>P6P5P>P=P8Q\u0005P\u001DP0P5P5P1Q\u000BP<Q\u000BP\u0012Q\u000BQ\u0001P>P2Q\u000BP2P>P\u001DP>P>P1P\u001FP>P;P8P=P8P P$P\u001DP5P\u001CQ\u000BQ\u0002Q\u
2018-09-13 12:09:32 +00:00
flipBuffer ( dictionary ) ;
2017-08-28 09:31:29 +00:00
DICTIONARY _DATA = dictionary ;
}
/ * *
* @ param { ! number } a
* @ param { ! number } b
* @ return { ! number }
* /
function min ( a , b ) {
return a <= b ? a : b ;
}
/ * *
* @ param { ! InputStream | null } src
* @ param { ! Int8Array } dst
* @ param { ! number } offset
* @ param { ! number } length
* @ return { ! number }
* /
function readInput ( src , dst , offset , length ) {
if ( src == null ) return - 1 ;
var /** number */ end = min ( src . offset + length , src . data . length ) ;
var /** number */ bytesRead = end - src . offset ;
dst . set ( src . data . subarray ( src . offset , end ) , offset ) ;
src . offset += bytesRead ;
return bytesRead ;
}
/ * *
* @ param { ! InputStream } src
* @ return { ! number }
* /
function closeInput ( src ) { return 0 ; }
2018-09-13 12:09:32 +00:00
/ * *
* @ param { ! Int8Array } buffer
* @ return { void }
* /
function flipBuffer ( buffer ) { /* no-op */ }
/ * *
* @ param { ! string } src
* @ return { ! Int8Array }
* /
function toUsAsciiBytes ( src ) {
var /** !number */ n = src . length ;
var /** !Int8Array */ result = new Int8Array ( n ) ;
for ( var /** !number */ i = 0 ; i < n ; ++ i ) {
result [ i ] = src . charCodeAt ( i ) ;
}
return result ;
}
2017-08-28 09:31:29 +00:00
/ * *
* @ param { ! Int8Array } bytes
* @ return { ! Int8Array }
* /
function decode ( bytes ) {
var /** !State */ s = new State ( ) ;
initState ( s , new InputStream ( bytes ) ) ;
2018-09-13 12:09:32 +00:00
var /** !number */ totalOutput = 0 ;
2017-08-28 09:31:29 +00:00
var /** !Array<!Int8Array> */ chunks = [ ] ;
while ( true ) {
var /** !Int8Array */ chunk = new Int8Array ( 16384 ) ;
chunks . push ( chunk ) ;
s . output = chunk ;
s . outputOffset = 0 ;
s . outputLength = 16384 ;
s . outputUsed = 0 ;
decompress ( s ) ;
2018-09-13 12:09:32 +00:00
totalOutput += s . outputUsed ;
2017-08-28 09:31:29 +00:00
if ( s . outputUsed < 16384 ) break ;
}
close ( s ) ;
2018-09-13 12:09:32 +00:00
var /** !Int8Array */ result = new Int8Array ( totalOutput ) ;
2017-08-28 09:31:29 +00:00
var /** !number */ offset = 0 ;
for ( var /** !number */ i = 0 ; i < chunks . length ; ++ i ) {
var /** !Int8Array */ chunk = chunks [ i ] ;
2018-09-13 12:09:32 +00:00
var /** !number */ end = min ( totalOutput , offset + 16384 ) ;
2017-08-28 09:31:29 +00:00
var /** !number */ len = end - offset ;
if ( len < 16384 ) {
result . set ( chunk . subarray ( 0 , len ) , offset ) ;
} else {
result . set ( chunk , offset ) ;
}
offset += len ;
}
return result ;
}
return decode ;
2017-10-09 15:07:34 +00:00
}
/** @export */
var BrotliDecode = BrotliDecodeClosure ( ) ;
2017-08-28 09:31:29 +00:00
window [ "BrotliDecode" ] = BrotliDecode ;