mirror of
https://github.com/google/brotli.git
synced 2024-12-04 00:21:04 +00:00
further preparations for Kotlin transpilation
PiperOrigin-RevId: 603638823
This commit is contained in:
parent
200f37984a
commit
c1362a7903
@ -146,9 +146,9 @@ final class BitReader {
|
|||||||
* otherwise BitReader will become broken.
|
* otherwise BitReader will become broken.
|
||||||
*/
|
*/
|
||||||
static int readFewBits(State s, int n) {
|
static int readFewBits(State s, int n) {
|
||||||
final int val = peekBits(s) & ((1 << n) - 1);
|
final int v = peekBits(s) & ((1 << n) - 1);
|
||||||
s.bitOffset += n;
|
s.bitOffset += n;
|
||||||
return val;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int readBits(State s, int n) {
|
static int readBits(State s, int n) {
|
||||||
@ -212,31 +212,33 @@ final class BitReader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void copyRawBytes(State s, byte[] data, int offset, int length) {
|
static void copyRawBytes(State s, byte[] data, int offset, int length) {
|
||||||
|
int pos = offset;
|
||||||
|
int len = length;
|
||||||
if ((s.bitOffset & 7) != 0) {
|
if ((s.bitOffset & 7) != 0) {
|
||||||
throw new BrotliRuntimeException("Unaligned copyBytes");
|
throw new BrotliRuntimeException("Unaligned copyBytes");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Drain accumulator.
|
// Drain accumulator.
|
||||||
while ((s.bitOffset != BITNESS) && (length != 0)) {
|
while ((s.bitOffset != BITNESS) && (len != 0)) {
|
||||||
data[offset++] = (byte) peekBits(s);
|
data[pos++] = (byte) peekBits(s);
|
||||||
s.bitOffset += 8;
|
s.bitOffset += 8;
|
||||||
length--;
|
len--;
|
||||||
}
|
}
|
||||||
if (length == 0) {
|
if (len == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get data from shadow buffer with "sizeof(int)" granularity.
|
// Get data from shadow buffer with "sizeof(int)" granularity.
|
||||||
final int copyNibbles = Math.min(halfAvailable(s), length >> LOG_HALF_SIZE);
|
final int copyNibbles = Math.min(halfAvailable(s), len >> LOG_HALF_SIZE);
|
||||||
if (copyNibbles > 0) {
|
if (copyNibbles > 0) {
|
||||||
final int readOffset = s.halfOffset << LOG_HALF_SIZE;
|
final int readOffset = s.halfOffset << LOG_HALF_SIZE;
|
||||||
final int delta = copyNibbles << LOG_HALF_SIZE;
|
final int delta = copyNibbles << LOG_HALF_SIZE;
|
||||||
System.arraycopy(s.byteBuffer, readOffset, data, offset, delta);
|
System.arraycopy(s.byteBuffer, readOffset, data, pos, delta);
|
||||||
offset += delta;
|
pos += delta;
|
||||||
length -= delta;
|
len -= delta;
|
||||||
s.halfOffset += copyNibbles;
|
s.halfOffset += copyNibbles;
|
||||||
}
|
}
|
||||||
if (length == 0) {
|
if (len == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,23 +246,23 @@ final class BitReader {
|
|||||||
if (halfAvailable(s) > 0) {
|
if (halfAvailable(s) > 0) {
|
||||||
// length = 1..3
|
// length = 1..3
|
||||||
fillBitWindow(s);
|
fillBitWindow(s);
|
||||||
while (length != 0) {
|
while (len != 0) {
|
||||||
data[offset++] = (byte) peekBits(s);
|
data[pos++] = (byte) peekBits(s);
|
||||||
s.bitOffset += 8;
|
s.bitOffset += 8;
|
||||||
length--;
|
len--;
|
||||||
}
|
}
|
||||||
checkHealth(s, 0);
|
checkHealth(s, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now it is possible to copy bytes directly.
|
// Now it is possible to copy bytes directly.
|
||||||
while (length > 0) {
|
while (len > 0) {
|
||||||
final int len = Utils.readInput(s, data, offset, length);
|
final int chunkLen = Utils.readInput(s, data, pos, len);
|
||||||
if (len == -1) {
|
if (chunkLen == -1) {
|
||||||
throw new BrotliRuntimeException("Unexpected end of input");
|
throw new BrotliRuntimeException("Unexpected end of input");
|
||||||
}
|
}
|
||||||
offset += len;
|
pos += chunkLen;
|
||||||
length -= len;
|
len -= chunkLen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,16 +275,16 @@ final class BitReader {
|
|||||||
if (BITNESS == 64) {
|
if (BITNESS == 64) {
|
||||||
final int[] intBuffer = s.intBuffer;
|
final int[] intBuffer = s.intBuffer;
|
||||||
for (int i = 0; i < halfLen; ++i) {
|
for (int i = 0; i < halfLen; ++i) {
|
||||||
intBuffer[i] = ((byteBuffer[i * 4] & 0xFF))
|
intBuffer[i] = ((int) byteBuffer[i * 4] & 0xFF)
|
||||||
| ((byteBuffer[(i * 4) + 1] & 0xFF) << 8)
|
| (((int) byteBuffer[(i * 4) + 1] & 0xFF) << 8)
|
||||||
| ((byteBuffer[(i * 4) + 2] & 0xFF) << 16)
|
| (((int) byteBuffer[(i * 4) + 2] & 0xFF) << 16)
|
||||||
| ((byteBuffer[(i * 4) + 3] & 0xFF) << 24);
|
| (((int) byteBuffer[(i * 4) + 3] & 0xFF) << 24);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
final short[] shortBuffer = s.shortBuffer;
|
final short[] shortBuffer = s.shortBuffer;
|
||||||
for (int i = 0; i < halfLen; ++i) {
|
for (int i = 0; i < halfLen; ++i) {
|
||||||
shortBuffer[i] = (short) ((byteBuffer[i * 2] & 0xFF)
|
shortBuffer[i] = (short) (((int) byteBuffer[i * 2] & 0xFF)
|
||||||
| ((byteBuffer[(i * 2) + 1] & 0xFF) << 8));
|
| (((int) byteBuffer[(i * 2) + 1] & 0xFF) << 8));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ final class Context {
|
|||||||
}
|
}
|
||||||
// UTF8
|
// UTF8
|
||||||
for (int i = 0; i < 128; ++i) {
|
for (int i = 0; i < 128; ++i) {
|
||||||
lookup[1024 + i] = 4 * (map.charAt(i) - 32);
|
lookup[1024 + i] = 4 * ((int) map.charAt(i) - 32);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 64; ++i) {
|
for (int i = 0; i < 64; ++i) {
|
||||||
lookup[1152 + i] = i & 1;
|
lookup[1152 + i] = i & 1;
|
||||||
@ -35,7 +35,7 @@ final class Context {
|
|||||||
int offset = 1280;
|
int offset = 1280;
|
||||||
for (int k = 0; k < 19; ++k) {
|
for (int k = 0; k < 19; ++k) {
|
||||||
final int value = k & 3;
|
final int value = k & 3;
|
||||||
final int rep = rle.charAt(k) - 32;
|
final int rep = (int) rle.charAt(k) - 32;
|
||||||
for (int i = 0; i < rep; ++i) {
|
for (int i = 0; i < rep; ++i) {
|
||||||
lookup[offset++] = value;
|
lookup[offset++] = value;
|
||||||
}
|
}
|
||||||
|
@ -137,14 +137,16 @@ final class Decode {
|
|||||||
private static int log2floor(int i) {
|
private static int log2floor(int i) {
|
||||||
int result = -1;
|
int result = -1;
|
||||||
int step = 16;
|
int step = 16;
|
||||||
|
int v = i;
|
||||||
while (step > 0) {
|
while (step > 0) {
|
||||||
if ((i >>> step) != 0) {
|
int next = v >>> step;
|
||||||
|
if (next != 0) {
|
||||||
result += step;
|
result += step;
|
||||||
i = i >>> step;
|
v = next;
|
||||||
}
|
}
|
||||||
step = step >> 1;
|
step = step >> 1;
|
||||||
}
|
}
|
||||||
return result + i;
|
return result + v;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int calculateDistanceAlphabetSize(int npostfix, int ndirect, int maxndistbits) {
|
private static int calculateDistanceAlphabetSize(int npostfix, int ndirect, int maxndistbits) {
|
||||||
@ -164,14 +166,12 @@ final class Decode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void unpackCommandLookupTable(short[] cmdLookup) {
|
private static void unpackCommandLookupTable(short[] cmdLookup) {
|
||||||
final short[] insertLengthOffsets = new short[24];
|
final int[] insertLengthOffsets = new int[24];
|
||||||
final short[] copyLengthOffsets = new short[24];
|
final int[] copyLengthOffsets = new int[24];
|
||||||
copyLengthOffsets[0] = 2;
|
copyLengthOffsets[0] = 2;
|
||||||
for (int i = 0; i < 23; ++i) {
|
for (int i = 0; i < 23; ++i) {
|
||||||
insertLengthOffsets[i + 1] =
|
insertLengthOffsets[i + 1] = insertLengthOffsets[i] + (1 << (int) INSERT_LENGTH_N_BITS[i]);
|
||||||
(short) (insertLengthOffsets[i] + (1 << INSERT_LENGTH_N_BITS[i]));
|
copyLengthOffsets[i + 1] = copyLengthOffsets[i] + (1 << (int) COPY_LENGTH_N_BITS[i]);
|
||||||
copyLengthOffsets[i + 1] =
|
|
||||||
(short) (copyLengthOffsets[i] + (1 << COPY_LENGTH_N_BITS[i]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int cmdCode = 0; cmdCode < NUM_COMMAND_CODES; ++cmdCode) {
|
for (int cmdCode = 0; cmdCode < NUM_COMMAND_CODES; ++cmdCode) {
|
||||||
@ -184,14 +184,15 @@ final class Decode {
|
|||||||
}
|
}
|
||||||
final int insertCode = (((0x29850 >>> (rangeIdx * 2)) & 0x3) << 3) | ((cmdCode >>> 3) & 7);
|
final int insertCode = (((0x29850 >>> (rangeIdx * 2)) & 0x3) << 3) | ((cmdCode >>> 3) & 7);
|
||||||
final int copyCode = (((0x26244 >>> (rangeIdx * 2)) & 0x3) << 3) | (cmdCode & 7);
|
final int copyCode = (((0x26244 >>> (rangeIdx * 2)) & 0x3) << 3) | (cmdCode & 7);
|
||||||
final short copyLengthOffset = copyLengthOffsets[copyCode];
|
final int copyLengthOffset = copyLengthOffsets[copyCode];
|
||||||
final int distanceContext =
|
final int distanceContext =
|
||||||
distanceContextOffset + (copyLengthOffset > 4 ? 3 : copyLengthOffset - 2);
|
distanceContextOffset + (copyLengthOffset > 4 ? 3 : (copyLengthOffset - 2));
|
||||||
final int index = cmdCode * 4;
|
final int index = cmdCode * 4;
|
||||||
cmdLookup[index + 0] =
|
cmdLookup[index + 0] =
|
||||||
(short) (INSERT_LENGTH_N_BITS[insertCode] | (COPY_LENGTH_N_BITS[copyCode] << 8));
|
(short)
|
||||||
cmdLookup[index + 1] = insertLengthOffsets[insertCode];
|
((int) INSERT_LENGTH_N_BITS[insertCode] | ((int) COPY_LENGTH_N_BITS[copyCode] << 8));
|
||||||
cmdLookup[index + 2] = copyLengthOffsets[copyCode];
|
cmdLookup[index + 1] = (short) insertLengthOffsets[insertCode];
|
||||||
|
cmdLookup[index + 2] = (short) copyLengthOffsets[copyCode];
|
||||||
cmdLookup[index + 3] = (short) distanceContext;
|
cmdLookup[index + 3] = (short) distanceContext;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -357,7 +358,7 @@ final class Decode {
|
|||||||
if (bits == 0 && i + 1 == sizeBytes && sizeBytes > 1) {
|
if (bits == 0 && i + 1 == sizeBytes && sizeBytes > 1) {
|
||||||
throw new BrotliRuntimeException("Exuberant nibble");
|
throw new BrotliRuntimeException("Exuberant nibble");
|
||||||
}
|
}
|
||||||
s.metaBlockLength |= bits << (i * 8);
|
s.metaBlockLength += bits << (i * 8);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < sizeNibbles; ++i) {
|
for (int i = 0; i < sizeNibbles; ++i) {
|
||||||
@ -366,7 +367,7 @@ final class Decode {
|
|||||||
if (bits == 0 && i + 1 == sizeNibbles && sizeNibbles > 4) {
|
if (bits == 0 && i + 1 == sizeNibbles && sizeNibbles > 4) {
|
||||||
throw new BrotliRuntimeException("Exuberant nibble");
|
throw new BrotliRuntimeException("Exuberant nibble");
|
||||||
}
|
}
|
||||||
s.metaBlockLength |= bits << (i * 4);
|
s.metaBlockLength += bits << (i * 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.metaBlockLength++;
|
s.metaBlockLength++;
|
||||||
@ -380,8 +381,8 @@ final class Decode {
|
|||||||
*/
|
*/
|
||||||
private static int readSymbol(int[] tableGroup, int tableIdx, State s) {
|
private static int readSymbol(int[] tableGroup, int tableIdx, State s) {
|
||||||
int offset = tableGroup[tableIdx];
|
int offset = tableGroup[tableIdx];
|
||||||
final int val = BitReader.peekBits(s);
|
final int v = BitReader.peekBits(s);
|
||||||
offset += val & HUFFMAN_TABLE_MASK;
|
offset += v & HUFFMAN_TABLE_MASK;
|
||||||
final int bits = tableGroup[offset] >> 16;
|
final int bits = tableGroup[offset] >> 16;
|
||||||
final int sym = tableGroup[offset] & 0xFFFF;
|
final int sym = tableGroup[offset] & 0xFFFF;
|
||||||
if (bits <= HUFFMAN_TABLE_BITS) {
|
if (bits <= HUFFMAN_TABLE_BITS) {
|
||||||
@ -390,7 +391,7 @@ final class Decode {
|
|||||||
}
|
}
|
||||||
offset += sym;
|
offset += sym;
|
||||||
final int mask = (1 << bits) - 1;
|
final int mask = (1 << bits) - 1;
|
||||||
offset += (val & mask) >>> HUFFMAN_TABLE_BITS;
|
offset += (v & mask) >>> HUFFMAN_TABLE_BITS;
|
||||||
s.bitOffset += ((tableGroup[offset] >> 16) + HUFFMAN_TABLE_BITS);
|
s.bitOffset += ((tableGroup[offset] >> 16) + HUFFMAN_TABLE_BITS);
|
||||||
return tableGroup[offset] & 0xFFFF;
|
return tableGroup[offset] & 0xFFFF;
|
||||||
}
|
}
|
||||||
@ -404,10 +405,11 @@ final class Decode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void moveToFront(int[] v, int index) {
|
private static void moveToFront(int[] v, int index) {
|
||||||
final int value = v[index];
|
int i = index;
|
||||||
while (index > 0) {
|
final int value = v[i];
|
||||||
v[index] = v[index - 1];
|
while (i > 0) {
|
||||||
index--;
|
v[i] = v[i - 1];
|
||||||
|
i--;
|
||||||
}
|
}
|
||||||
v[0] = value;
|
v[0] = value;
|
||||||
}
|
}
|
||||||
@ -418,7 +420,7 @@ final class Decode {
|
|||||||
mtf[i] = i;
|
mtf[i] = i;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < vLen; ++i) {
|
for (int i = 0; i < vLen; ++i) {
|
||||||
final int index = v[i] & 0xFF;
|
final int index = (int) v[i] & 0xFF;
|
||||||
v[i] = (byte) mtf[index];
|
v[i] = (byte) mtf[index];
|
||||||
if (index != 0) {
|
if (index != 0) {
|
||||||
moveToFront(mtf, index);
|
moveToFront(mtf, index);
|
||||||
@ -463,7 +465,7 @@ final class Decode {
|
|||||||
final int oldRepeat = repeat;
|
final int oldRepeat = repeat;
|
||||||
if (repeat > 0) {
|
if (repeat > 0) {
|
||||||
repeat -= 2;
|
repeat -= 2;
|
||||||
repeat <<= extraBits;
|
repeat = repeat << extraBits;
|
||||||
}
|
}
|
||||||
BitReader.fillBitWindow(s);
|
BitReader.fillBitWindow(s);
|
||||||
repeat += BitReader.readFewBits(s, extraBits) + 3;
|
repeat += BitReader.readFewBits(s, extraBits) + 3;
|
||||||
@ -689,8 +691,8 @@ final class Decode {
|
|||||||
s.literalBlockLength = decodeBlockTypeAndLength(s, 0, s.numLiteralBlockTypes);
|
s.literalBlockLength = decodeBlockTypeAndLength(s, 0, s.numLiteralBlockTypes);
|
||||||
final int literalBlockType = s.rings[5];
|
final int literalBlockType = s.rings[5];
|
||||||
s.contextMapSlice = literalBlockType << LITERAL_CONTEXT_BITS;
|
s.contextMapSlice = literalBlockType << LITERAL_CONTEXT_BITS;
|
||||||
s.literalTreeIdx = s.contextMap[s.contextMapSlice] & 0xFF;
|
s.literalTreeIdx = (int) s.contextMap[s.contextMapSlice] & 0xFF;
|
||||||
final int contextMode = s.contextModes[literalBlockType];
|
final int contextMode = (int) s.contextModes[literalBlockType];
|
||||||
s.contextLookupOffset1 = contextMode << 9;
|
s.contextLookupOffset1 = contextMode << 9;
|
||||||
s.contextLookupOffset2 = s.contextLookupOffset1 + 256;
|
s.contextLookupOffset2 = s.contextLookupOffset1 + 256;
|
||||||
}
|
}
|
||||||
@ -711,7 +713,7 @@ final class Decode {
|
|||||||
/* TODO(eustas): Handle 2GB+ cases more gracefully. */
|
/* TODO(eustas): Handle 2GB+ cases more gracefully. */
|
||||||
final int minimalNewSize = s.expectedTotalSize;
|
final int minimalNewSize = s.expectedTotalSize;
|
||||||
while ((newSize >> 1) > minimalNewSize) {
|
while ((newSize >> 1) > minimalNewSize) {
|
||||||
newSize >>= 1;
|
newSize = newSize >> 1;
|
||||||
}
|
}
|
||||||
if ((s.inputEnd == 0) && newSize < 16384 && s.maxRingBufferSize >= 16384) {
|
if ((s.inputEnd == 0) && newSize < 16384 && s.maxRingBufferSize >= 16384) {
|
||||||
newSize = 16384;
|
newSize = 16384;
|
||||||
@ -722,8 +724,9 @@ final class Decode {
|
|||||||
}
|
}
|
||||||
final int ringBufferSizeWithSlack = newSize + MAX_TRANSFORMED_WORD_LENGTH;
|
final int ringBufferSizeWithSlack = newSize + MAX_TRANSFORMED_WORD_LENGTH;
|
||||||
final byte[] newBuffer = new byte[ringBufferSizeWithSlack];
|
final byte[] newBuffer = new byte[ringBufferSizeWithSlack];
|
||||||
if (s.ringBuffer.length != 0) {
|
final byte[] oldBuffer = s.ringBuffer;
|
||||||
System.arraycopy(s.ringBuffer, 0, newBuffer, 0, s.ringBufferSize);
|
if (oldBuffer.length != 0) {
|
||||||
|
System.arraycopy(oldBuffer, 0, newBuffer, 0, s.ringBufferSize);
|
||||||
}
|
}
|
||||||
s.ringBuffer = newBuffer;
|
s.ringBuffer = newBuffer;
|
||||||
s.ringBufferSize = newSize;
|
s.ringBufferSize = newSize;
|
||||||
@ -850,7 +853,7 @@ final class Decode {
|
|||||||
final int numLiteralTrees = decodeContextMap(contextMapLength, s.contextMap, s);
|
final int numLiteralTrees = decodeContextMap(contextMapLength, s.contextMap, s);
|
||||||
s.trivialLiteralContext = 1;
|
s.trivialLiteralContext = 1;
|
||||||
for (int j = 0; j < contextMapLength; ++j) {
|
for (int j = 0; j < contextMapLength; ++j) {
|
||||||
if (s.contextMap[j] != j >> LITERAL_CONTEXT_BITS) {
|
if ((int) s.contextMap[j] != j >> LITERAL_CONTEXT_BITS) {
|
||||||
s.trivialLiteralContext = 0;
|
s.trivialLiteralContext = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1021,7 +1024,7 @@ final class Decode {
|
|||||||
if (s.cdBlockBits == -1) {
|
if (s.cdBlockBits == -1) {
|
||||||
initializeCompoundDictionary(s);
|
initializeCompoundDictionary(s);
|
||||||
}
|
}
|
||||||
int index = s.cdBlockMap[address >>> s.cdBlockBits];
|
int index = (int) s.cdBlockMap[address >>> s.cdBlockBits];
|
||||||
while (address >= s.cdChunkOffsets[index + 1]) {
|
while (address >= s.cdChunkOffsets[index + 1]) {
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
@ -1123,10 +1126,10 @@ final class Decode {
|
|||||||
s.commandBlockLength--;
|
s.commandBlockLength--;
|
||||||
BitReader.fillBitWindow(s);
|
BitReader.fillBitWindow(s);
|
||||||
final int cmdCode = readSymbol(s.commandTreeGroup, s.commandTreeIdx, s) << 2;
|
final int cmdCode = readSymbol(s.commandTreeGroup, s.commandTreeIdx, s) << 2;
|
||||||
final short insertAndCopyExtraBits = CMD_LOOKUP[cmdCode];
|
final int insertAndCopyExtraBits = (int) CMD_LOOKUP[cmdCode];
|
||||||
final int insertLengthOffset = CMD_LOOKUP[cmdCode + 1];
|
final int insertLengthOffset = (int) CMD_LOOKUP[cmdCode + 1];
|
||||||
final int copyLengthOffset = CMD_LOOKUP[cmdCode + 2];
|
final int copyLengthOffset = (int) CMD_LOOKUP[cmdCode + 2];
|
||||||
s.distanceCode = CMD_LOOKUP[cmdCode + 3];
|
s.distanceCode = (int) CMD_LOOKUP[cmdCode + 3];
|
||||||
BitReader.fillBitWindow(s);
|
BitReader.fillBitWindow(s);
|
||||||
{
|
{
|
||||||
final int insertLengthExtraBits = insertAndCopyExtraBits & 0xFF;
|
final int insertLengthExtraBits = insertAndCopyExtraBits & 0xFF;
|
||||||
@ -1161,8 +1164,8 @@ final class Decode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int prevByte1 = ringBuffer[(s.pos - 1) & ringBufferMask] & 0xFF;
|
int prevByte1 = (int) ringBuffer[(s.pos - 1) & ringBufferMask] & 0xFF;
|
||||||
int prevByte2 = ringBuffer[(s.pos - 2) & ringBufferMask] & 0xFF;
|
int prevByte2 = (int) ringBuffer[(s.pos - 2) & ringBufferMask] & 0xFF;
|
||||||
while (s.j < s.insertLength) {
|
while (s.j < s.insertLength) {
|
||||||
BitReader.readMoreInput(s);
|
BitReader.readMoreInput(s);
|
||||||
if (s.literalBlockLength == 0) {
|
if (s.literalBlockLength == 0) {
|
||||||
@ -1170,7 +1173,8 @@ final class Decode {
|
|||||||
}
|
}
|
||||||
final int literalContext = Context.LOOKUP[s.contextLookupOffset1 + prevByte1]
|
final int literalContext = Context.LOOKUP[s.contextLookupOffset1 + prevByte1]
|
||||||
| Context.LOOKUP[s.contextLookupOffset2 + prevByte2];
|
| Context.LOOKUP[s.contextLookupOffset2 + prevByte2];
|
||||||
final int literalTreeIdx = s.contextMap[s.contextMapSlice + literalContext] & 0xFF;
|
final int literalTreeIdx =
|
||||||
|
(int) s.contextMap[s.contextMapSlice + literalContext] & 0xFF;
|
||||||
s.literalBlockLength--;
|
s.literalBlockLength--;
|
||||||
prevByte2 = prevByte1;
|
prevByte2 = prevByte1;
|
||||||
BitReader.fillBitWindow(s);
|
BitReader.fillBitWindow(s);
|
||||||
@ -1204,7 +1208,8 @@ final class Decode {
|
|||||||
}
|
}
|
||||||
s.distanceBlockLength--;
|
s.distanceBlockLength--;
|
||||||
BitReader.fillBitWindow(s);
|
BitReader.fillBitWindow(s);
|
||||||
final int distTreeIdx = s.distContextMap[s.distContextMapSlice + distanceCode] & 0xFF;
|
final int distTreeIdx =
|
||||||
|
(int) s.distContextMap[s.distContextMapSlice + distanceCode] & 0xFF;
|
||||||
distanceCode = readSymbol(s.distanceTreeGroup, distTreeIdx, s);
|
distanceCode = readSymbol(s.distanceTreeGroup, distTreeIdx, s);
|
||||||
if (distanceCode < NUM_DISTANCE_SHORT_CODES) {
|
if (distanceCode < NUM_DISTANCE_SHORT_CODES) {
|
||||||
final int index =
|
final int index =
|
||||||
@ -1214,7 +1219,7 @@ final class Decode {
|
|||||||
throw new BrotliRuntimeException("Negative distance"); // COV_NF_LINE
|
throw new BrotliRuntimeException("Negative distance"); // COV_NF_LINE
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
final int extraBits = s.distExtraBits[distanceCode];
|
final int extraBits = (int) s.distExtraBits[distanceCode];
|
||||||
int bits;
|
int bits;
|
||||||
if (s.bitOffset + extraBits <= BitReader.BITNESS) {
|
if (s.bitOffset + extraBits <= BitReader.BITNESS) {
|
||||||
bits = BitReader.readFewBits(s, extraBits);
|
bits = BitReader.readFewBits(s, extraBits);
|
||||||
@ -1337,7 +1342,7 @@ final class Decode {
|
|||||||
if (s.pos > s.ringBufferSize) {
|
if (s.pos > s.ringBufferSize) {
|
||||||
Utils.copyBytesWithin(ringBuffer, 0, s.ringBufferSize, s.pos);
|
Utils.copyBytesWithin(ringBuffer, 0, s.ringBufferSize, s.pos);
|
||||||
}
|
}
|
||||||
s.pos &= ringBufferMask;
|
s.pos = s.pos & ringBufferMask;
|
||||||
s.ringBufferBytesWritten = 0;
|
s.ringBufferBytesWritten = 0;
|
||||||
}
|
}
|
||||||
s.runningState = s.nextRunningState;
|
s.runningState = s.nextRunningState;
|
||||||
|
@ -45,20 +45,20 @@ final class DictionaryData {
|
|||||||
int offset = 0;
|
int offset = 0;
|
||||||
final int n = skipFlip.length() >> 1;
|
final int n = skipFlip.length() >> 1;
|
||||||
for (int i = 0; i < n; ++i) {
|
for (int i = 0; i < n; ++i) {
|
||||||
final int skip = skipFlip.charAt(2 * i) - 36;
|
final int skip = (int) skipFlip.charAt(2 * i) - 36;
|
||||||
final int flip = skipFlip.charAt(2 * i + 1) - 36;
|
final int flip = (int) skipFlip.charAt(2 * i + 1) - 36;
|
||||||
for (int j = 0; j < skip; ++j) {
|
for (int j = 0; j < skip; ++j) {
|
||||||
dict[offset] ^= 3;
|
dict[offset] = (byte) ((int) dict[offset] ^ 3);
|
||||||
offset++;
|
offset++;
|
||||||
}
|
}
|
||||||
for (int j = 0; j < flip; ++j) {
|
for (int j = 0; j < flip; ++j) {
|
||||||
dict[offset] ^= 236;
|
dict[offset] = (byte) ((int) dict[offset] ^ 236);
|
||||||
offset++;
|
offset++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < sizeBitsData.length(); ++i) {
|
for (int i = 0; i < sizeBitsData.length(); ++i) {
|
||||||
sizeBits[i] = sizeBitsData.charAt(i) - 65;
|
sizeBits[i] = (int) sizeBitsData.charAt(i) - 65;
|
||||||
}
|
}
|
||||||
|
|
||||||
dictionary.put(dict);
|
dictionary.put(dict);
|
||||||
|
@ -21,7 +21,7 @@ final class Huffman {
|
|||||||
private static int getNextKey(int key, int len) {
|
private static int getNextKey(int key, int len) {
|
||||||
int step = 1 << (len - 1);
|
int step = 1 << (len - 1);
|
||||||
while ((key & step) != 0) {
|
while ((key & step) != 0) {
|
||||||
step >>= 1;
|
step = step >> 1;
|
||||||
}
|
}
|
||||||
return (key & (step - 1)) + step;
|
return (key & (step - 1)) + step;
|
||||||
}
|
}
|
||||||
@ -32,10 +32,11 @@ final class Huffman {
|
|||||||
* <p> Assumes that end is an integer multiple of step.
|
* <p> Assumes that end is an integer multiple of step.
|
||||||
*/
|
*/
|
||||||
private static void replicateValue(int[] table, int offset, int step, int end, int item) {
|
private static void replicateValue(int[] table, int offset, int step, int end, int item) {
|
||||||
|
int pos = end;
|
||||||
do {
|
do {
|
||||||
end -= step;
|
pos -= step;
|
||||||
table[offset + end] = item;
|
table[offset + pos] = item;
|
||||||
} while (end > 0);
|
} while (pos > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -44,16 +45,17 @@ final class Huffman {
|
|||||||
* @return table width of the next 2nd level table.
|
* @return table width of the next 2nd level table.
|
||||||
*/
|
*/
|
||||||
private static int nextTableBitSize(int[] count, int len, int rootBits) {
|
private static int nextTableBitSize(int[] count, int len, int rootBits) {
|
||||||
int left = 1 << (len - rootBits);
|
int bits = len;
|
||||||
while (len < MAX_LENGTH) {
|
int left = 1 << (bits - rootBits);
|
||||||
left -= count[len];
|
while (bits < MAX_LENGTH) {
|
||||||
|
left -= count[bits];
|
||||||
if (left <= 0) {
|
if (left <= 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
len++;
|
bits++;
|
||||||
left <<= 1;
|
left = left << 1;
|
||||||
}
|
}
|
||||||
return len - rootBits;
|
return bits - rootBits;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -104,7 +106,7 @@ final class Huffman {
|
|||||||
int symbol = 0;
|
int symbol = 0;
|
||||||
int step = 1;
|
int step = 1;
|
||||||
for (int len = 1; len <= rootBits; ++len) {
|
for (int len = 1; len <= rootBits; ++len) {
|
||||||
step <<= 1;
|
step = step << 1;
|
||||||
while (count[len] > 0) {
|
while (count[len] > 0) {
|
||||||
replicateValue(tableGroup, tableOffset + key, step, tableSize,
|
replicateValue(tableGroup, tableOffset + key, step, tableSize,
|
||||||
len << 16 | sorted[symbol++]);
|
len << 16 | sorted[symbol++]);
|
||||||
@ -119,7 +121,7 @@ final class Huffman {
|
|||||||
int currentOffset = tableOffset;
|
int currentOffset = tableOffset;
|
||||||
step = 1;
|
step = 1;
|
||||||
for (int len = rootBits + 1; len <= MAX_LENGTH; ++len) {
|
for (int len = rootBits + 1; len <= MAX_LENGTH; ++len) {
|
||||||
step <<= 1;
|
step = step << 1;
|
||||||
while (count[len] > 0) {
|
while (count[len] > 0) {
|
||||||
if ((key & mask) != low) {
|
if ((key & mask) != low) {
|
||||||
currentOffset += tableSize;
|
currentOffset += tableSize;
|
||||||
|
@ -87,7 +87,7 @@ final class State {
|
|||||||
int cdBlockBits;
|
int cdBlockBits;
|
||||||
byte[] cdBlockMap;
|
byte[] cdBlockMap;
|
||||||
|
|
||||||
InputStream /* @Nullable */ input; // BitReader
|
InputStream input = Utils.makeEmptyInput(); // BitReader
|
||||||
|
|
||||||
State() {
|
State() {
|
||||||
this.ringBuffer = new byte[0];
|
this.ringBuffer = new byte[0];
|
||||||
|
@ -80,7 +80,7 @@ final class Transform {
|
|||||||
int index = 1;
|
int index = 1;
|
||||||
int j = 0;
|
int j = 0;
|
||||||
for (int i = 0; i < n; ++i) {
|
for (int i = 0; i < n; ++i) {
|
||||||
final char c = prefixSuffixSrc.charAt(i);
|
final int c = (int) prefixSuffixSrc.charAt(i);
|
||||||
if (c == 35) { // == #
|
if (c == 35) { // == #
|
||||||
prefixSuffixHeads[index++] = j;
|
prefixSuffixHeads[index++] = j;
|
||||||
} else {
|
} else {
|
||||||
@ -89,7 +89,7 @@ final class Transform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < NUM_RFC_TRANSFORMS * 3; ++i) {
|
for (int i = 0; i < NUM_RFC_TRANSFORMS * 3; ++i) {
|
||||||
transforms[i] = transformsSrc.charAt(i) - 32;
|
transforms[i] = (int) transformsSrc.charAt(i) - 32;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +99,7 @@ final class Transform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int transformDictionaryWord(byte[] dst, int dstOffset, ByteBuffer src, int srcOffset,
|
static int transformDictionaryWord(byte[] dst, int dstOffset, ByteBuffer src, int srcOffset,
|
||||||
int len, Transforms transforms, int transformIndex) {
|
int wordLen, Transforms transforms, int transformIndex) {
|
||||||
int offset = dstOffset;
|
int offset = dstOffset;
|
||||||
final int[] triplets = transforms.triplets;
|
final int[] triplets = transforms.triplets;
|
||||||
final byte[] prefixSuffixStorage = transforms.prefixSuffixStorage;
|
final byte[] prefixSuffixStorage = transforms.prefixSuffixStorage;
|
||||||
@ -127,16 +127,17 @@ final class Transform {
|
|||||||
dst[offset++] = prefixSuffixStorage[prefix++];
|
dst[offset++] = prefixSuffixStorage[prefix++];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int len = wordLen;
|
||||||
// Copy trimmed word.
|
// Copy trimmed word.
|
||||||
if (omitFirst > len) {
|
if (omitFirst > len) {
|
||||||
omitFirst = len;
|
omitFirst = len;
|
||||||
}
|
}
|
||||||
srcOffset += omitFirst;
|
int dictOffset = srcOffset + omitFirst;
|
||||||
len -= omitFirst;
|
len -= omitFirst;
|
||||||
len -= omitLast;
|
len -= omitLast;
|
||||||
int i = len;
|
int i = len;
|
||||||
while (i > 0) {
|
while (i > 0) {
|
||||||
dst[offset++] = src.get(srcOffset++);
|
dst[offset++] = src.get(dictOffset++);
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,31 +148,31 @@ final class Transform {
|
|||||||
len = 1;
|
len = 1;
|
||||||
}
|
}
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
final int c0 = dst[uppercaseOffset] & 0xFF;
|
final int c0 = (int) dst[uppercaseOffset] & 0xFF;
|
||||||
if (c0 < 0xC0) {
|
if (c0 < 0xC0) {
|
||||||
if (c0 >= 97 && c0 <= 122) { // in [a..z] range
|
if (c0 >= 97 && c0 <= 122) { // in [a..z] range
|
||||||
dst[uppercaseOffset] ^= (byte) 32;
|
dst[uppercaseOffset] = (byte) ((int) dst[uppercaseOffset] ^ 32);
|
||||||
}
|
}
|
||||||
uppercaseOffset += 1;
|
uppercaseOffset += 1;
|
||||||
len -= 1;
|
len -= 1;
|
||||||
} else if (c0 < 0xE0) {
|
} else if (c0 < 0xE0) {
|
||||||
dst[uppercaseOffset + 1] ^= (byte) 32;
|
dst[uppercaseOffset + 1] = (byte) ((int) dst[uppercaseOffset + 1] ^ 32);
|
||||||
uppercaseOffset += 2;
|
uppercaseOffset += 2;
|
||||||
len -= 2;
|
len -= 2;
|
||||||
} else {
|
} else {
|
||||||
dst[uppercaseOffset + 2] ^= (byte) 5;
|
dst[uppercaseOffset + 2] = (byte) ((int) dst[uppercaseOffset + 2] ^ 5);
|
||||||
uppercaseOffset += 3;
|
uppercaseOffset += 3;
|
||||||
len -= 3;
|
len -= 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (transformType == SHIFT_FIRST || transformType == SHIFT_ALL) {
|
} else if (transformType == SHIFT_FIRST || transformType == SHIFT_ALL) {
|
||||||
int shiftOffset = offset - len;
|
int shiftOffset = offset - len;
|
||||||
final short param = transforms.params[transformIndex];
|
final int param = (int) transforms.params[transformIndex];
|
||||||
/* Limited sign extension: scalar < (1 << 24). */
|
/* Limited sign extension: scalar < (1 << 24). */
|
||||||
int scalar = (param & 0x7FFF) + (0x1000000 - (param & 0x8000));
|
int scalar = (param & 0x7FFF) + (0x1000000 - (param & 0x8000));
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
int step = 1;
|
int step = 1;
|
||||||
final int c0 = dst[shiftOffset] & 0xFF;
|
final int c0 = (int) dst[shiftOffset] & 0xFF;
|
||||||
if (c0 < 0x80) {
|
if (c0 < 0x80) {
|
||||||
/* 1-byte rune / 0sssssss / 7 bit scalar (ASCII). */
|
/* 1-byte rune / 0sssssss / 7 bit scalar (ASCII). */
|
||||||
scalar += c0;
|
scalar += c0;
|
||||||
@ -181,7 +182,7 @@ final class Transform {
|
|||||||
} else if (c0 < 0xE0) {
|
} else if (c0 < 0xE0) {
|
||||||
/* 2-byte rune / 110sssss AAssssss / 11 bit scalar. */
|
/* 2-byte rune / 110sssss AAssssss / 11 bit scalar. */
|
||||||
if (len >= 2) {
|
if (len >= 2) {
|
||||||
final byte c1 = dst[shiftOffset + 1];
|
final int c1 = (int) dst[shiftOffset + 1];
|
||||||
scalar += (c1 & 0x3F) | ((c0 & 0x1F) << 6);
|
scalar += (c1 & 0x3F) | ((c0 & 0x1F) << 6);
|
||||||
dst[shiftOffset] = (byte) (0xC0 | ((scalar >> 6) & 0x1F));
|
dst[shiftOffset] = (byte) (0xC0 | ((scalar >> 6) & 0x1F));
|
||||||
dst[shiftOffset + 1] = (byte) ((c1 & 0xC0) | (scalar & 0x3F));
|
dst[shiftOffset + 1] = (byte) ((c1 & 0xC0) | (scalar & 0x3F));
|
||||||
@ -192,8 +193,8 @@ final class Transform {
|
|||||||
} else if (c0 < 0xF0) {
|
} else if (c0 < 0xF0) {
|
||||||
/* 3-byte rune / 1110ssss AAssssss BBssssss / 16 bit scalar. */
|
/* 3-byte rune / 1110ssss AAssssss BBssssss / 16 bit scalar. */
|
||||||
if (len >= 3) {
|
if (len >= 3) {
|
||||||
final byte c1 = dst[shiftOffset + 1];
|
final int c1 = (int) dst[shiftOffset + 1];
|
||||||
final byte c2 = dst[shiftOffset + 2];
|
final int c2 = (int) dst[shiftOffset + 2];
|
||||||
scalar += (c2 & 0x3F) | ((c1 & 0x3F) << 6) | ((c0 & 0x0F) << 12);
|
scalar += (c2 & 0x3F) | ((c1 & 0x3F) << 6) | ((c0 & 0x0F) << 12);
|
||||||
dst[shiftOffset] = (byte) (0xE0 | ((scalar >> 12) & 0x0F));
|
dst[shiftOffset] = (byte) (0xE0 | ((scalar >> 12) & 0x0F));
|
||||||
dst[shiftOffset + 1] = (byte) ((c1 & 0xC0) | ((scalar >> 6) & 0x3F));
|
dst[shiftOffset + 1] = (byte) ((c1 & 0xC0) | ((scalar >> 6) & 0x3F));
|
||||||
@ -205,9 +206,9 @@ final class Transform {
|
|||||||
} else if (c0 < 0xF8) {
|
} else if (c0 < 0xF8) {
|
||||||
/* 4-byte rune / 11110sss AAssssss BBssssss CCssssss / 21 bit scalar. */
|
/* 4-byte rune / 11110sss AAssssss BBssssss CCssssss / 21 bit scalar. */
|
||||||
if (len >= 4) {
|
if (len >= 4) {
|
||||||
final byte c1 = dst[shiftOffset + 1];
|
final int c1 = (int) dst[shiftOffset + 1];
|
||||||
final byte c2 = dst[shiftOffset + 2];
|
final int c2 = (int) dst[shiftOffset + 2];
|
||||||
final byte c3 = dst[shiftOffset + 3];
|
final int c3 = (int) dst[shiftOffset + 3];
|
||||||
scalar += (c3 & 0x3F) | ((c2 & 0x3F) << 6) | ((c1 & 0x3F) << 12) | ((c0 & 0x07) << 18);
|
scalar += (c3 & 0x3F) | ((c2 & 0x3F) << 6) | ((c1 & 0x3F) << 12) | ((c0 & 0x07) << 18);
|
||||||
dst[shiftOffset] = (byte) (0xF0 | ((scalar >> 18) & 0x07));
|
dst[shiftOffset] = (byte) (0xF0 | ((scalar >> 18) & 0x07));
|
||||||
dst[shiftOffset + 1] = (byte) ((c1 & 0xC0) | ((scalar >> 12) & 0x3F));
|
dst[shiftOffset + 1] = (byte) ((c1 & 0xC0) | ((scalar >> 12) & 0x3F));
|
||||||
|
@ -6,7 +6,9 @@
|
|||||||
|
|
||||||
package org.brotli.dec;
|
package org.brotli.dec;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.nio.Buffer;
|
import java.nio.Buffer;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
@ -74,11 +76,13 @@ final class Utils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static InputStream makeEmptyInput() {
|
||||||
|
return new ByteArrayInputStream(new byte[0]);
|
||||||
|
}
|
||||||
|
|
||||||
static void closeInput(State s) throws IOException {
|
static void closeInput(State s) throws IOException {
|
||||||
if (s.input != null) {
|
s.input.close();
|
||||||
s.input.close();
|
s.input = makeEmptyInput();
|
||||||
s.input = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static byte[] toUsAsciiBytes(String src) {
|
static byte[] toUsAsciiBytes(String src) {
|
||||||
|
253
js/decode.js
253
js/decode.js
@ -47,14 +47,16 @@ let makeBrotliDecode = () => {
|
|||||||
function log2floor(i) {
|
function log2floor(i) {
|
||||||
let /** @type {number} */ result = -1;
|
let /** @type {number} */ result = -1;
|
||||||
let /** @type {number} */ step = 16;
|
let /** @type {number} */ step = 16;
|
||||||
|
let /** @type {number} */ v = i;
|
||||||
while (step > 0) {
|
while (step > 0) {
|
||||||
if ((i >>> step) !== 0) {
|
let /** @type {number} */ next = v >>> step;
|
||||||
|
if (next !== 0) {
|
||||||
result += step;
|
result += step;
|
||||||
i = i >>> step;
|
v = next;
|
||||||
}
|
}
|
||||||
step = step >> 1;
|
step = step >> 1;
|
||||||
}
|
}
|
||||||
return result + i;
|
return result + v;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @param {number} npostfix
|
* @param {number} npostfix
|
||||||
@ -85,12 +87,12 @@ let makeBrotliDecode = () => {
|
|||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
function unpackCommandLookupTable(cmdLookup) {
|
function unpackCommandLookupTable(cmdLookup) {
|
||||||
const /** @type {!Int16Array} */ insertLengthOffsets = new Int16Array(24);
|
const /** @type {!Int32Array} */ insertLengthOffsets = new Int32Array(24);
|
||||||
const /** @type {!Int16Array} */ copyLengthOffsets = new Int16Array(24);
|
const /** @type {!Int32Array} */ copyLengthOffsets = new Int32Array(24);
|
||||||
copyLengthOffsets[0] = 2;
|
copyLengthOffsets[0] = 2;
|
||||||
for (let /** @type {number} */ i = 0; i < 23; ++i) {
|
for (let /** @type {number} */ i = 0; i < 23; ++i) {
|
||||||
insertLengthOffsets[i + 1] = (insertLengthOffsets[i] + (1 << INSERT_LENGTH_N_BITS[i]));
|
insertLengthOffsets[i + 1] = insertLengthOffsets[i] + (1 << INSERT_LENGTH_N_BITS[i]);
|
||||||
copyLengthOffsets[i + 1] = (copyLengthOffsets[i] + (1 << COPY_LENGTH_N_BITS[i]));
|
copyLengthOffsets[i + 1] = copyLengthOffsets[i] + (1 << COPY_LENGTH_N_BITS[i]);
|
||||||
}
|
}
|
||||||
for (let /** @type {number} */ cmdCode = 0; cmdCode < 704; ++cmdCode) {
|
for (let /** @type {number} */ cmdCode = 0; cmdCode < 704; ++cmdCode) {
|
||||||
let /** @type {number} */ rangeIdx = cmdCode >>> 6;
|
let /** @type {number} */ rangeIdx = cmdCode >>> 6;
|
||||||
@ -102,9 +104,9 @@ let makeBrotliDecode = () => {
|
|||||||
const /** @type {number} */ insertCode = (((0x29850 >>> (rangeIdx * 2)) & 0x3) << 3) | ((cmdCode >>> 3) & 7);
|
const /** @type {number} */ insertCode = (((0x29850 >>> (rangeIdx * 2)) & 0x3) << 3) | ((cmdCode >>> 3) & 7);
|
||||||
const /** @type {number} */ copyCode = (((0x26244 >>> (rangeIdx * 2)) & 0x3) << 3) | (cmdCode & 7);
|
const /** @type {number} */ copyCode = (((0x26244 >>> (rangeIdx * 2)) & 0x3) << 3) | (cmdCode & 7);
|
||||||
const /** @type {number} */ copyLengthOffset = copyLengthOffsets[copyCode];
|
const /** @type {number} */ copyLengthOffset = copyLengthOffsets[copyCode];
|
||||||
const /** @type {number} */ distanceContext = distanceContextOffset + (copyLengthOffset > 4 ? 3 : copyLengthOffset - 2);
|
const /** @type {number} */ distanceContext = distanceContextOffset + (copyLengthOffset > 4 ? 3 : (copyLengthOffset - 2));
|
||||||
const /** @type {number} */ index = cmdCode * 4;
|
const /** @type {number} */ index = cmdCode * 4;
|
||||||
cmdLookup[index] = (INSERT_LENGTH_N_BITS[insertCode] | (COPY_LENGTH_N_BITS[copyCode] << 8));
|
cmdLookup[index] = INSERT_LENGTH_N_BITS[insertCode] | (COPY_LENGTH_N_BITS[copyCode] << 8);
|
||||||
cmdLookup[index + 1] = insertLengthOffsets[insertCode];
|
cmdLookup[index + 1] = insertLengthOffsets[insertCode];
|
||||||
cmdLookup[index + 2] = copyLengthOffsets[copyCode];
|
cmdLookup[index + 2] = copyLengthOffsets[copyCode];
|
||||||
cmdLookup[index + 3] = distanceContext;
|
cmdLookup[index + 3] = distanceContext;
|
||||||
@ -220,7 +222,7 @@ let makeBrotliDecode = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
s.runningState = 11;
|
s.runningState = 11;
|
||||||
s.input = null;
|
s.input = new InputStream(new Int8Array(0));
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @param {!State} s
|
* @param {!State} s
|
||||||
@ -267,7 +269,7 @@ let makeBrotliDecode = () => {
|
|||||||
if (sizeBytes === 0) {
|
if (sizeBytes === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (let /** @type {number} */ i = 0; i < sizeBytes; i++) {
|
for (let /** @type {number} */ i = 0; i < sizeBytes; ++i) {
|
||||||
if (s.bitOffset >= 16) {
|
if (s.bitOffset >= 16) {
|
||||||
s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
|
s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
|
||||||
s.bitOffset -= 16;
|
s.bitOffset -= 16;
|
||||||
@ -276,10 +278,10 @@ let makeBrotliDecode = () => {
|
|||||||
if (bits === 0 && i + 1 === sizeBytes && sizeBytes > 1) {
|
if (bits === 0 && i + 1 === sizeBytes && sizeBytes > 1) {
|
||||||
throw new Error("Exuberant nibble");
|
throw new Error("Exuberant nibble");
|
||||||
}
|
}
|
||||||
s.metaBlockLength |= bits << (i * 8);
|
s.metaBlockLength += bits << (i * 8);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (let /** @type {number} */ i = 0; i < sizeNibbles; i++) {
|
for (let /** @type {number} */ i = 0; i < sizeNibbles; ++i) {
|
||||||
if (s.bitOffset >= 16) {
|
if (s.bitOffset >= 16) {
|
||||||
s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
|
s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
|
||||||
s.bitOffset -= 16;
|
s.bitOffset -= 16;
|
||||||
@ -288,7 +290,7 @@ let makeBrotliDecode = () => {
|
|||||||
if (bits === 0 && i + 1 === sizeNibbles && sizeNibbles > 4) {
|
if (bits === 0 && i + 1 === sizeNibbles && sizeNibbles > 4) {
|
||||||
throw new Error("Exuberant nibble");
|
throw new Error("Exuberant nibble");
|
||||||
}
|
}
|
||||||
s.metaBlockLength |= bits << (i * 4);
|
s.metaBlockLength += bits << (i * 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.metaBlockLength++;
|
s.metaBlockLength++;
|
||||||
@ -304,8 +306,8 @@ let makeBrotliDecode = () => {
|
|||||||
*/
|
*/
|
||||||
function readSymbol(tableGroup, tableIdx, s) {
|
function readSymbol(tableGroup, tableIdx, s) {
|
||||||
let /** @type {number} */ offset = tableGroup[tableIdx];
|
let /** @type {number} */ offset = tableGroup[tableIdx];
|
||||||
const /** @type {number} */ val = (s.accumulator32 >>> s.bitOffset);
|
const /** @type {number} */ v = s.accumulator32 >>> s.bitOffset;
|
||||||
offset += val & 0xFF;
|
offset += v & 0xFF;
|
||||||
const /** @type {number} */ bits = tableGroup[offset] >> 16;
|
const /** @type {number} */ bits = tableGroup[offset] >> 16;
|
||||||
const /** @type {number} */ sym = tableGroup[offset] & 0xFFFF;
|
const /** @type {number} */ sym = tableGroup[offset] & 0xFFFF;
|
||||||
if (bits <= 8) {
|
if (bits <= 8) {
|
||||||
@ -314,8 +316,8 @@ let makeBrotliDecode = () => {
|
|||||||
}
|
}
|
||||||
offset += sym;
|
offset += sym;
|
||||||
const /** @type {number} */ mask = (1 << bits) - 1;
|
const /** @type {number} */ mask = (1 << bits) - 1;
|
||||||
offset += (val & mask) >>> 8;
|
offset += (v & mask) >>> 8;
|
||||||
s.bitOffset += ((tableGroup[offset] >> 16) + 8);
|
s.bitOffset += (tableGroup[offset] >> 16) + 8;
|
||||||
return tableGroup[offset] & 0xFFFF;
|
return tableGroup[offset] & 0xFFFF;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -343,9 +345,11 @@ let makeBrotliDecode = () => {
|
|||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
function moveToFront(v, index) {
|
function moveToFront(v, index) {
|
||||||
const /** @type {number} */ value = v[index];
|
let /** @type {number} */ i = index;
|
||||||
for (; index > 0; index--) {
|
const /** @type {number} */ value = v[i];
|
||||||
v[index] = v[index - 1];
|
while (i > 0) {
|
||||||
|
v[i] = v[i - 1];
|
||||||
|
i--;
|
||||||
}
|
}
|
||||||
v[0] = value;
|
v[0] = value;
|
||||||
}
|
}
|
||||||
@ -356,10 +360,10 @@ let makeBrotliDecode = () => {
|
|||||||
*/
|
*/
|
||||||
function inverseMoveToFrontTransform(v, vLen) {
|
function inverseMoveToFrontTransform(v, vLen) {
|
||||||
const /** @type {!Int32Array} */ mtf = new Int32Array(256);
|
const /** @type {!Int32Array} */ mtf = new Int32Array(256);
|
||||||
for (let /** @type {number} */ i = 0; i < 256; i++) {
|
for (let /** @type {number} */ i = 0; i < 256; ++i) {
|
||||||
mtf[i] = i;
|
mtf[i] = i;
|
||||||
}
|
}
|
||||||
for (let /** @type {number} */ i = 0; i < vLen; i++) {
|
for (let /** @type {number} */ i = 0; i < vLen; ++i) {
|
||||||
const /** @type {number} */ index = v[i] & 0xFF;
|
const /** @type {number} */ index = v[i] & 0xFF;
|
||||||
v[i] = mtf[index];
|
v[i] = mtf[index];
|
||||||
if (index !== 0) {
|
if (index !== 0) {
|
||||||
@ -414,7 +418,7 @@ let makeBrotliDecode = () => {
|
|||||||
const /** @type {number} */ oldRepeat = repeat;
|
const /** @type {number} */ oldRepeat = repeat;
|
||||||
if (repeat > 0) {
|
if (repeat > 0) {
|
||||||
repeat -= 2;
|
repeat -= 2;
|
||||||
repeat <<= extraBits;
|
repeat = repeat << extraBits;
|
||||||
}
|
}
|
||||||
if (s.bitOffset >= 16) {
|
if (s.bitOffset >= 16) {
|
||||||
s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
|
s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
|
||||||
@ -425,7 +429,7 @@ let makeBrotliDecode = () => {
|
|||||||
if (symbol + repeatDelta > numSymbols) {
|
if (symbol + repeatDelta > numSymbols) {
|
||||||
throw new Error("symbol + repeatDelta > numSymbols");
|
throw new Error("symbol + repeatDelta > numSymbols");
|
||||||
}
|
}
|
||||||
for (let /** @type {number} */ i = 0; i < repeatDelta; i++) {
|
for (let /** @type {number} */ i = 0; i < repeatDelta; ++i) {
|
||||||
codeLengths[symbol++] = repeatCodeLen;
|
codeLengths[symbol++] = repeatCodeLen;
|
||||||
}
|
}
|
||||||
if (repeatCodeLen !== 0) {
|
if (repeatCodeLen !== 0) {
|
||||||
@ -465,7 +469,7 @@ let makeBrotliDecode = () => {
|
|||||||
const /** @type {!Int32Array} */ symbols = new Int32Array(4);
|
const /** @type {!Int32Array} */ symbols = new Int32Array(4);
|
||||||
const /** @type {number} */ maxBits = 1 + log2floor(alphabetSizeMax - 1);
|
const /** @type {number} */ maxBits = 1 + log2floor(alphabetSizeMax - 1);
|
||||||
const /** @type {number} */ numSymbols = readFewBits(s, 2) + 1;
|
const /** @type {number} */ numSymbols = readFewBits(s, 2) + 1;
|
||||||
for (let /** @type {number} */ i = 0; i < numSymbols; i++) {
|
for (let /** @type {number} */ i = 0; i < numSymbols; ++i) {
|
||||||
if (s.bitOffset >= 16) {
|
if (s.bitOffset >= 16) {
|
||||||
s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
|
s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
|
||||||
s.bitOffset -= 16;
|
s.bitOffset -= 16;
|
||||||
@ -524,7 +528,7 @@ let makeBrotliDecode = () => {
|
|||||||
const /** @type {!Int32Array} */ codeLengthCodeLengths = new Int32Array(18);
|
const /** @type {!Int32Array} */ codeLengthCodeLengths = new Int32Array(18);
|
||||||
let /** @type {number} */ space = 32;
|
let /** @type {number} */ space = 32;
|
||||||
let /** @type {number} */ numCodes = 0;
|
let /** @type {number} */ numCodes = 0;
|
||||||
for (let /** @type {number} */ i = skip; i < 18 && space > 0; i++) {
|
for (let /** @type {number} */ i = skip; i < 18; ++i) {
|
||||||
const /** @type {number} */ codeLenIdx = CODE_LENGTH_CODE_ORDER[i];
|
const /** @type {number} */ codeLenIdx = CODE_LENGTH_CODE_ORDER[i];
|
||||||
if (s.bitOffset >= 16) {
|
if (s.bitOffset >= 16) {
|
||||||
s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
|
s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
|
||||||
@ -535,8 +539,10 @@ let makeBrotliDecode = () => {
|
|||||||
const /** @type {number} */ v = FIXED_TABLE[p] & 0xFFFF;
|
const /** @type {number} */ v = FIXED_TABLE[p] & 0xFFFF;
|
||||||
codeLengthCodeLengths[codeLenIdx] = v;
|
codeLengthCodeLengths[codeLenIdx] = v;
|
||||||
if (v !== 0) {
|
if (v !== 0) {
|
||||||
space -= (32 >> v);
|
space -= 32 >> v;
|
||||||
numCodes++;
|
numCodes++;
|
||||||
|
if (space <= 0)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (space !== 0 && numCodes !== 1) {
|
if (space !== 0 && numCodes !== 1) {
|
||||||
@ -597,7 +603,8 @@ let makeBrotliDecode = () => {
|
|||||||
const /** @type {!Int32Array} */ table = new Int32Array(tableSize + 1);
|
const /** @type {!Int32Array} */ table = new Int32Array(tableSize + 1);
|
||||||
const /** @type {number} */ tableIdx = table.length - 1;
|
const /** @type {number} */ tableIdx = table.length - 1;
|
||||||
readHuffmanCode(alphabetSize, alphabetSize, table, tableIdx, s);
|
readHuffmanCode(alphabetSize, alphabetSize, table, tableIdx, s);
|
||||||
for (let /** @type {number} */ i = 0; i < contextMapSize; ) {
|
let /** @type {number} */ i = 0;
|
||||||
|
while (i < contextMapSize) {
|
||||||
if (s.halfOffset > 2030) {
|
if (s.halfOffset > 2030) {
|
||||||
doReadMoreInput(s);
|
doReadMoreInput(s);
|
||||||
}
|
}
|
||||||
@ -624,7 +631,7 @@ let makeBrotliDecode = () => {
|
|||||||
reps--;
|
reps--;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
contextMap[i] = (code - maxRunLengthPrefix);
|
contextMap[i] = code - maxRunLengthPrefix;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -704,7 +711,7 @@ let makeBrotliDecode = () => {
|
|||||||
if (newSize > s.expectedTotalSize) {
|
if (newSize > s.expectedTotalSize) {
|
||||||
const /** @type {number} */ minimalNewSize = s.expectedTotalSize;
|
const /** @type {number} */ minimalNewSize = s.expectedTotalSize;
|
||||||
while ((newSize >> 1) > minimalNewSize) {
|
while ((newSize >> 1) > minimalNewSize) {
|
||||||
newSize >>= 1;
|
newSize = newSize >> 1;
|
||||||
}
|
}
|
||||||
if ((s.inputEnd === 0) && newSize < 16384 && s.maxRingBufferSize >= 16384) {
|
if ((s.inputEnd === 0) && newSize < 16384 && s.maxRingBufferSize >= 16384) {
|
||||||
newSize = 16384;
|
newSize = 16384;
|
||||||
@ -715,8 +722,9 @@ let makeBrotliDecode = () => {
|
|||||||
}
|
}
|
||||||
const /** @type {number} */ ringBufferSizeWithSlack = newSize + 37;
|
const /** @type {number} */ ringBufferSizeWithSlack = newSize + 37;
|
||||||
const /** @type {!Int8Array} */ newBuffer = new Int8Array(ringBufferSizeWithSlack);
|
const /** @type {!Int8Array} */ newBuffer = new Int8Array(ringBufferSizeWithSlack);
|
||||||
if (s.ringBuffer.length !== 0) {
|
const /** @type {!Int8Array} */ oldBuffer = s.ringBuffer;
|
||||||
newBuffer.set(s.ringBuffer.subarray(0, s.ringBufferSize), 0);
|
if (oldBuffer.length !== 0) {
|
||||||
|
newBuffer.set(oldBuffer.subarray(0, s.ringBufferSize), 0);
|
||||||
}
|
}
|
||||||
s.ringBuffer = newBuffer;
|
s.ringBuffer = newBuffer;
|
||||||
s.ringBufferSize = newSize;
|
s.ringBufferSize = newSize;
|
||||||
@ -830,23 +838,26 @@ let makeBrotliDecode = () => {
|
|||||||
s.distancePostfixBits = readFewBits(s, 2);
|
s.distancePostfixBits = readFewBits(s, 2);
|
||||||
s.numDirectDistanceCodes = readFewBits(s, 4) << s.distancePostfixBits;
|
s.numDirectDistanceCodes = readFewBits(s, 4) << s.distancePostfixBits;
|
||||||
s.contextModes = new Int8Array(s.numLiteralBlockTypes);
|
s.contextModes = new Int8Array(s.numLiteralBlockTypes);
|
||||||
for (let /** @type {number} */ i = 0; i < s.numLiteralBlockTypes; ) {
|
let /** @type {number} */ i = 0;
|
||||||
|
while (i < s.numLiteralBlockTypes) {
|
||||||
const /** @type {number} */ limit = Math.min(i + 96, s.numLiteralBlockTypes);
|
const /** @type {number} */ limit = Math.min(i + 96, s.numLiteralBlockTypes);
|
||||||
for (; i < limit; ++i) {
|
while (i < limit) {
|
||||||
if (s.bitOffset >= 16) {
|
if (s.bitOffset >= 16) {
|
||||||
s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
|
s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
|
||||||
s.bitOffset -= 16;
|
s.bitOffset -= 16;
|
||||||
}
|
}
|
||||||
s.contextModes[i] = readFewBits(s, 2);
|
s.contextModes[i] = readFewBits(s, 2);
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
if (s.halfOffset > 2030) {
|
if (s.halfOffset > 2030) {
|
||||||
doReadMoreInput(s);
|
doReadMoreInput(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.contextMap = new Int8Array(s.numLiteralBlockTypes << 6);
|
const /** @type {number} */ contextMapLength = s.numLiteralBlockTypes << 6;
|
||||||
const /** @type {number} */ numLiteralTrees = decodeContextMap(s.numLiteralBlockTypes << 6, s.contextMap, s);
|
s.contextMap = new Int8Array(contextMapLength);
|
||||||
|
const /** @type {number} */ numLiteralTrees = decodeContextMap(contextMapLength, s.contextMap, s);
|
||||||
s.trivialLiteralContext = 1;
|
s.trivialLiteralContext = 1;
|
||||||
for (let /** @type {number} */ j = 0; j < s.numLiteralBlockTypes << 6; j++) {
|
for (let /** @type {number} */ j = 0; j < contextMapLength; ++j) {
|
||||||
if (s.contextMap[j] !== j >> 6) {
|
if (s.contextMap[j] !== j >> 6) {
|
||||||
s.trivialLiteralContext = 0;
|
s.trivialLiteralContext = 0;
|
||||||
break;
|
break;
|
||||||
@ -1264,7 +1275,8 @@ let makeBrotliDecode = () => {
|
|||||||
const /** @type {number} */ dstEnd = dst + copyLength;
|
const /** @type {number} */ dstEnd = dst + copyLength;
|
||||||
if ((srcEnd < ringBufferMask) && (dstEnd < ringBufferMask)) {
|
if ((srcEnd < ringBufferMask) && (dstEnd < ringBufferMask)) {
|
||||||
if (copyLength < 12 || (srcEnd > dst && dstEnd > src)) {
|
if (copyLength < 12 || (srcEnd > dst && dstEnd > src)) {
|
||||||
for (let /** @type {number} */ k = 0; k < copyLength; k += 4) {
|
const /** @type {number} */ numQuads = (copyLength + 3) >> 2;
|
||||||
|
for (let /** @type {number} */ k = 0; k < numQuads; ++k) {
|
||||||
ringBuffer[dst++] = ringBuffer[src++];
|
ringBuffer[dst++] = ringBuffer[src++];
|
||||||
ringBuffer[dst++] = ringBuffer[src++];
|
ringBuffer[dst++] = ringBuffer[src++];
|
||||||
ringBuffer[dst++] = ringBuffer[src++];
|
ringBuffer[dst++] = ringBuffer[src++];
|
||||||
@ -1277,7 +1289,7 @@ let makeBrotliDecode = () => {
|
|||||||
s.metaBlockLength -= copyLength;
|
s.metaBlockLength -= copyLength;
|
||||||
s.pos += copyLength;
|
s.pos += copyLength;
|
||||||
} else {
|
} else {
|
||||||
for (; s.j < s.copyLength; ) {
|
while (s.j < s.copyLength) {
|
||||||
ringBuffer[s.pos] = ringBuffer[(s.pos - s.distance) & ringBufferMask];
|
ringBuffer[s.pos] = ringBuffer[(s.pos - s.distance) & ringBufferMask];
|
||||||
s.metaBlockLength--;
|
s.metaBlockLength--;
|
||||||
s.pos++;
|
s.pos++;
|
||||||
@ -1336,7 +1348,7 @@ let makeBrotliDecode = () => {
|
|||||||
if (s.pos > s.ringBufferSize) {
|
if (s.pos > s.ringBufferSize) {
|
||||||
ringBuffer.copyWithin(0, s.ringBufferSize, s.pos);
|
ringBuffer.copyWithin(0, s.ringBufferSize, s.pos);
|
||||||
}
|
}
|
||||||
s.pos &= ringBufferMask;
|
s.pos = s.pos & ringBufferMask;
|
||||||
s.ringBufferBytesWritten = 0;
|
s.ringBufferBytesWritten = 0;
|
||||||
}
|
}
|
||||||
s.runningState = s.nextRunningState;
|
s.runningState = s.nextRunningState;
|
||||||
@ -1413,12 +1425,12 @@ let makeBrotliDecode = () => {
|
|||||||
* @param {number} dstOffset
|
* @param {number} dstOffset
|
||||||
* @param {!Int8Array} src
|
* @param {!Int8Array} src
|
||||||
* @param {number} srcOffset
|
* @param {number} srcOffset
|
||||||
* @param {number} len
|
* @param {number} wordLen
|
||||||
* @param {!Transforms} transforms
|
* @param {!Transforms} transforms
|
||||||
* @param {number} transformIndex
|
* @param {number} transformIndex
|
||||||
* @return {number}
|
* @return {number}
|
||||||
*/
|
*/
|
||||||
function transformDictionaryWord(dst, dstOffset, src, srcOffset, len, transforms, transformIndex) {
|
function transformDictionaryWord(dst, dstOffset, src, srcOffset, wordLen, transforms, transformIndex) {
|
||||||
let /** @type {number} */ offset = dstOffset;
|
let /** @type {number} */ offset = dstOffset;
|
||||||
const /** @type {!Int32Array} */ triplets = transforms.triplets;
|
const /** @type {!Int32Array} */ triplets = transforms.triplets;
|
||||||
const /** @type {!Int8Array} */ prefixSuffixStorage = transforms.prefixSuffixStorage;
|
const /** @type {!Int8Array} */ prefixSuffixStorage = transforms.prefixSuffixStorage;
|
||||||
@ -1442,15 +1454,16 @@ let makeBrotliDecode = () => {
|
|||||||
while (prefix !== prefixEnd) {
|
while (prefix !== prefixEnd) {
|
||||||
dst[offset++] = prefixSuffixStorage[prefix++];
|
dst[offset++] = prefixSuffixStorage[prefix++];
|
||||||
}
|
}
|
||||||
|
let /** @type {number} */ len = wordLen;
|
||||||
if (omitFirst > len) {
|
if (omitFirst > len) {
|
||||||
omitFirst = len;
|
omitFirst = len;
|
||||||
}
|
}
|
||||||
srcOffset += omitFirst;
|
let /** @type {number} */ dictOffset = srcOffset + omitFirst;
|
||||||
len -= omitFirst;
|
len -= omitFirst;
|
||||||
len -= omitLast;
|
len -= omitLast;
|
||||||
let /** @type {number} */ i = len;
|
let /** @type {number} */ i = len;
|
||||||
while (i > 0) {
|
while (i > 0) {
|
||||||
dst[offset++] = src[srcOffset++];
|
dst[offset++] = src[dictOffset++];
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
if (transformType === 10 || transformType === 11) {
|
if (transformType === 10 || transformType === 11) {
|
||||||
@ -1462,16 +1475,16 @@ let makeBrotliDecode = () => {
|
|||||||
const /** @type {number} */ c0 = dst[uppercaseOffset] & 0xFF;
|
const /** @type {number} */ c0 = dst[uppercaseOffset] & 0xFF;
|
||||||
if (c0 < 0xC0) {
|
if (c0 < 0xC0) {
|
||||||
if (c0 >= 97 && c0 <= 122) {
|
if (c0 >= 97 && c0 <= 122) {
|
||||||
dst[uppercaseOffset] ^= 32;
|
dst[uppercaseOffset] = dst[uppercaseOffset] ^ 32;
|
||||||
}
|
}
|
||||||
uppercaseOffset += 1;
|
uppercaseOffset += 1;
|
||||||
len -= 1;
|
len -= 1;
|
||||||
} else if (c0 < 0xE0) {
|
} else if (c0 < 0xE0) {
|
||||||
dst[uppercaseOffset + 1] ^= 32;
|
dst[uppercaseOffset + 1] = dst[uppercaseOffset + 1] ^ 32;
|
||||||
uppercaseOffset += 2;
|
uppercaseOffset += 2;
|
||||||
len -= 2;
|
len -= 2;
|
||||||
} else {
|
} else {
|
||||||
dst[uppercaseOffset + 2] ^= 5;
|
dst[uppercaseOffset + 2] = dst[uppercaseOffset + 2] ^ 5;
|
||||||
uppercaseOffset += 3;
|
uppercaseOffset += 3;
|
||||||
len -= 3;
|
len -= 3;
|
||||||
}
|
}
|
||||||
@ -1485,14 +1498,14 @@ let makeBrotliDecode = () => {
|
|||||||
const /** @type {number} */ c0 = dst[shiftOffset] & 0xFF;
|
const /** @type {number} */ c0 = dst[shiftOffset] & 0xFF;
|
||||||
if (c0 < 0x80) {
|
if (c0 < 0x80) {
|
||||||
scalar += c0;
|
scalar += c0;
|
||||||
dst[shiftOffset] = (scalar & 0x7F);
|
dst[shiftOffset] = scalar & 0x7F;
|
||||||
} else if (c0 < 0xC0) {
|
} else if (c0 < 0xC0) {
|
||||||
} else if (c0 < 0xE0) {
|
} else if (c0 < 0xE0) {
|
||||||
if (len >= 2) {
|
if (len >= 2) {
|
||||||
const /** @type {number} */ c1 = dst[shiftOffset + 1];
|
const /** @type {number} */ c1 = dst[shiftOffset + 1];
|
||||||
scalar += (c1 & 0x3F) | ((c0 & 0x1F) << 6);
|
scalar += (c1 & 0x3F) | ((c0 & 0x1F) << 6);
|
||||||
dst[shiftOffset] = (0xC0 | ((scalar >> 6) & 0x1F));
|
dst[shiftOffset] = 0xC0 | ((scalar >> 6) & 0x1F);
|
||||||
dst[shiftOffset + 1] = ((c1 & 0xC0) | (scalar & 0x3F));
|
dst[shiftOffset + 1] = (c1 & 0xC0) | (scalar & 0x3F);
|
||||||
step = 2;
|
step = 2;
|
||||||
} else {
|
} else {
|
||||||
step = len;
|
step = len;
|
||||||
@ -1502,9 +1515,9 @@ let makeBrotliDecode = () => {
|
|||||||
const /** @type {number} */ c1 = dst[shiftOffset + 1];
|
const /** @type {number} */ c1 = dst[shiftOffset + 1];
|
||||||
const /** @type {number} */ c2 = dst[shiftOffset + 2];
|
const /** @type {number} */ c2 = dst[shiftOffset + 2];
|
||||||
scalar += (c2 & 0x3F) | ((c1 & 0x3F) << 6) | ((c0 & 0x0F) << 12);
|
scalar += (c2 & 0x3F) | ((c1 & 0x3F) << 6) | ((c0 & 0x0F) << 12);
|
||||||
dst[shiftOffset] = (0xE0 | ((scalar >> 12) & 0x0F));
|
dst[shiftOffset] = 0xE0 | ((scalar >> 12) & 0x0F);
|
||||||
dst[shiftOffset + 1] = ((c1 & 0xC0) | ((scalar >> 6) & 0x3F));
|
dst[shiftOffset + 1] = (c1 & 0xC0) | ((scalar >> 6) & 0x3F);
|
||||||
dst[shiftOffset + 2] = ((c2 & 0xC0) | (scalar & 0x3F));
|
dst[shiftOffset + 2] = (c2 & 0xC0) | (scalar & 0x3F);
|
||||||
step = 3;
|
step = 3;
|
||||||
} else {
|
} else {
|
||||||
step = len;
|
step = len;
|
||||||
@ -1515,10 +1528,10 @@ let makeBrotliDecode = () => {
|
|||||||
const /** @type {number} */ c2 = dst[shiftOffset + 2];
|
const /** @type {number} */ c2 = dst[shiftOffset + 2];
|
||||||
const /** @type {number} */ c3 = dst[shiftOffset + 3];
|
const /** @type {number} */ c3 = dst[shiftOffset + 3];
|
||||||
scalar += (c3 & 0x3F) | ((c2 & 0x3F) << 6) | ((c1 & 0x3F) << 12) | ((c0 & 0x07) << 18);
|
scalar += (c3 & 0x3F) | ((c2 & 0x3F) << 6) | ((c1 & 0x3F) << 12) | ((c0 & 0x07) << 18);
|
||||||
dst[shiftOffset] = (0xF0 | ((scalar >> 18) & 0x07));
|
dst[shiftOffset] = 0xF0 | ((scalar >> 18) & 0x07);
|
||||||
dst[shiftOffset + 1] = ((c1 & 0xC0) | ((scalar >> 12) & 0x3F));
|
dst[shiftOffset + 1] = (c1 & 0xC0) | ((scalar >> 12) & 0x3F);
|
||||||
dst[shiftOffset + 2] = ((c2 & 0xC0) | ((scalar >> 6) & 0x3F));
|
dst[shiftOffset + 2] = (c2 & 0xC0) | ((scalar >> 6) & 0x3F);
|
||||||
dst[shiftOffset + 3] = ((c3 & 0xC0) | (scalar & 0x3F));
|
dst[shiftOffset + 3] = (c3 & 0xC0) | (scalar & 0x3F);
|
||||||
step = 4;
|
step = 4;
|
||||||
} else {
|
} else {
|
||||||
step = len;
|
step = len;
|
||||||
@ -1545,7 +1558,7 @@ let makeBrotliDecode = () => {
|
|||||||
function getNextKey(key, len) {
|
function getNextKey(key, len) {
|
||||||
let /** @type {number} */ step = 1 << (len - 1);
|
let /** @type {number} */ step = 1 << (len - 1);
|
||||||
while ((key & step) !== 0) {
|
while ((key & step) !== 0) {
|
||||||
step >>= 1;
|
step = step >> 1;
|
||||||
}
|
}
|
||||||
return (key & (step - 1)) + step;
|
return (key & (step - 1)) + step;
|
||||||
}
|
}
|
||||||
@ -1558,10 +1571,11 @@ let makeBrotliDecode = () => {
|
|||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
function replicateValue(table, offset, step, end, item) {
|
function replicateValue(table, offset, step, end, item) {
|
||||||
|
let /** @type {number} */ pos = end;
|
||||||
do {
|
do {
|
||||||
end -= step;
|
pos -= step;
|
||||||
table[offset + end] = item;
|
table[offset + pos] = item;
|
||||||
} while (end > 0);
|
} while (pos > 0);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @param {!Int32Array} count
|
* @param {!Int32Array} count
|
||||||
@ -1570,16 +1584,17 @@ let makeBrotliDecode = () => {
|
|||||||
* @return {number}
|
* @return {number}
|
||||||
*/
|
*/
|
||||||
function nextTableBitSize(count, len, rootBits) {
|
function nextTableBitSize(count, len, rootBits) {
|
||||||
let /** @type {number} */ left = 1 << (len - rootBits);
|
let /** @type {number} */ bits = len;
|
||||||
while (len < 15) {
|
let /** @type {number} */ left = 1 << (bits - rootBits);
|
||||||
left -= count[len];
|
while (bits < 15) {
|
||||||
|
left -= count[bits];
|
||||||
if (left <= 0) {
|
if (left <= 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
len++;
|
bits++;
|
||||||
left <<= 1;
|
left = left << 1;
|
||||||
}
|
}
|
||||||
return len - rootBits;
|
return bits - rootBits;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @param {!Int32Array} tableGroup
|
* @param {!Int32Array} tableGroup
|
||||||
@ -1591,45 +1606,48 @@ let makeBrotliDecode = () => {
|
|||||||
*/
|
*/
|
||||||
function buildHuffmanTable(tableGroup, tableIdx, rootBits, codeLengths, codeLengthsSize) {
|
function buildHuffmanTable(tableGroup, tableIdx, rootBits, codeLengths, codeLengthsSize) {
|
||||||
const /** @type {number} */ tableOffset = tableGroup[tableIdx];
|
const /** @type {number} */ tableOffset = tableGroup[tableIdx];
|
||||||
let /** @type {number} */ key;
|
|
||||||
const /** @type {!Int32Array} */ sorted = new Int32Array(codeLengthsSize);
|
const /** @type {!Int32Array} */ sorted = new Int32Array(codeLengthsSize);
|
||||||
const /** @type {!Int32Array} */ count = new Int32Array(16);
|
const /** @type {!Int32Array} */ count = new Int32Array(16);
|
||||||
const /** @type {!Int32Array} */ offset = new Int32Array(16);
|
const /** @type {!Int32Array} */ offset = new Int32Array(16);
|
||||||
let /** @type {number} */ symbol;
|
for (let /** @type {number} */ sym = 0; sym < codeLengthsSize; ++sym) {
|
||||||
for (symbol = 0; symbol < codeLengthsSize; symbol++) {
|
count[codeLengths[sym]]++;
|
||||||
count[codeLengths[symbol]]++;
|
|
||||||
}
|
}
|
||||||
offset[1] = 0;
|
offset[1] = 0;
|
||||||
for (let /** @type {number} */ len = 1; len < 15; len++) {
|
for (let /** @type {number} */ len = 1; len < 15; ++len) {
|
||||||
offset[len + 1] = offset[len] + count[len];
|
offset[len + 1] = offset[len] + count[len];
|
||||||
}
|
}
|
||||||
for (symbol = 0; symbol < codeLengthsSize; symbol++) {
|
for (let /** @type {number} */ sym = 0; sym < codeLengthsSize; ++sym) {
|
||||||
if (codeLengths[symbol] !== 0) {
|
if (codeLengths[sym] !== 0) {
|
||||||
sorted[offset[codeLengths[symbol]]++] = symbol;
|
sorted[offset[codeLengths[sym]]++] = sym;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let /** @type {number} */ tableBits = rootBits;
|
let /** @type {number} */ tableBits = rootBits;
|
||||||
let /** @type {number} */ tableSize = 1 << tableBits;
|
let /** @type {number} */ tableSize = 1 << tableBits;
|
||||||
let /** @type {number} */ totalSize = tableSize;
|
let /** @type {number} */ totalSize = tableSize;
|
||||||
if (offset[15] === 1) {
|
if (offset[15] === 1) {
|
||||||
for (key = 0; key < totalSize; key++) {
|
for (let /** @type {number} */ k = 0; k < totalSize; ++k) {
|
||||||
tableGroup[tableOffset + key] = sorted[0];
|
tableGroup[tableOffset + k] = sorted[0];
|
||||||
}
|
}
|
||||||
return totalSize;
|
return totalSize;
|
||||||
}
|
}
|
||||||
key = 0;
|
let /** @type {number} */ key = 0;
|
||||||
symbol = 0;
|
let /** @type {number} */ symbol = 0;
|
||||||
for (let /** @type {number} */ len = 1, /** @type {number} */ step = 2; len <= rootBits; len++, step <<= 1) {
|
let /** @type {number} */ step = 1;
|
||||||
for (; count[len] > 0; count[len]--) {
|
for (let /** @type {number} */ len = 1; len <= rootBits; ++len) {
|
||||||
|
step = step << 1;
|
||||||
|
while (count[len] > 0) {
|
||||||
replicateValue(tableGroup, tableOffset + key, step, tableSize, len << 16 | sorted[symbol++]);
|
replicateValue(tableGroup, tableOffset + key, step, tableSize, len << 16 | sorted[symbol++]);
|
||||||
key = getNextKey(key, len);
|
key = getNextKey(key, len);
|
||||||
|
count[len]--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const /** @type {number} */ mask = totalSize - 1;
|
const /** @type {number} */ mask = totalSize - 1;
|
||||||
let /** @type {number} */ low = -1;
|
let /** @type {number} */ low = -1;
|
||||||
let /** @type {number} */ currentOffset = tableOffset;
|
let /** @type {number} */ currentOffset = tableOffset;
|
||||||
for (let /** @type {number} */ len = rootBits + 1, /** @type {number} */ step = 2; len <= 15; len++, step <<= 1) {
|
step = 1;
|
||||||
for (; count[len] > 0; count[len]--) {
|
for (let /** @type {number} */ len = rootBits + 1; len <= 15; ++len) {
|
||||||
|
step = step << 1;
|
||||||
|
while (count[len] > 0) {
|
||||||
if ((key & mask) !== low) {
|
if ((key & mask) !== low) {
|
||||||
currentOffset += tableSize;
|
currentOffset += tableSize;
|
||||||
tableBits = nextTableBitSize(count, len, rootBits);
|
tableBits = nextTableBitSize(count, len, rootBits);
|
||||||
@ -1640,6 +1658,7 @@ let makeBrotliDecode = () => {
|
|||||||
}
|
}
|
||||||
replicateValue(tableGroup, currentOffset + (key >> rootBits), step, tableSize, (len - rootBits) << 16 | sorted[symbol++]);
|
replicateValue(tableGroup, currentOffset + (key >> rootBits), step, tableSize, (len - rootBits) << 16 | sorted[symbol++]);
|
||||||
key = getNextKey(key, len);
|
key = getNextKey(key, len);
|
||||||
|
count[len]--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return totalSize;
|
return totalSize;
|
||||||
@ -1696,9 +1715,9 @@ let makeBrotliDecode = () => {
|
|||||||
* @return {number}
|
* @return {number}
|
||||||
*/
|
*/
|
||||||
function readFewBits(s, n) {
|
function readFewBits(s, n) {
|
||||||
const /** @type {number} */ val = (s.accumulator32 >>> s.bitOffset) & ((1 << n) - 1);
|
const /** @type {number} */ v = (s.accumulator32 >>> s.bitOffset) & ((1 << n) - 1);
|
||||||
s.bitOffset += n;
|
s.bitOffset += n;
|
||||||
return val;
|
return v;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @param {!State} s
|
* @param {!State} s
|
||||||
@ -1779,27 +1798,29 @@ let makeBrotliDecode = () => {
|
|||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
function copyRawBytes(s, data, offset, length) {
|
function copyRawBytes(s, data, offset, length) {
|
||||||
|
let /** @type {number} */ pos = offset;
|
||||||
|
let /** @type {number} */ len = length;
|
||||||
if ((s.bitOffset & 7) !== 0) {
|
if ((s.bitOffset & 7) !== 0) {
|
||||||
throw new Error("Unaligned copyBytes");
|
throw new Error("Unaligned copyBytes");
|
||||||
}
|
}
|
||||||
while ((s.bitOffset !== 32) && (length !== 0)) {
|
while ((s.bitOffset !== 32) && (len !== 0)) {
|
||||||
data[offset++] = (s.accumulator32 >>> s.bitOffset);
|
data[pos++] = s.accumulator32 >>> s.bitOffset;
|
||||||
s.bitOffset += 8;
|
s.bitOffset += 8;
|
||||||
length--;
|
len--;
|
||||||
}
|
}
|
||||||
if (length === 0) {
|
if (len === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const /** @type {number} */ copyNibbles = Math.min(halfAvailable(s), length >> 1);
|
const /** @type {number} */ copyNibbles = Math.min(halfAvailable(s), len >> 1);
|
||||||
if (copyNibbles > 0) {
|
if (copyNibbles > 0) {
|
||||||
const /** @type {number} */ readOffset = s.halfOffset << 1;
|
const /** @type {number} */ readOffset = s.halfOffset << 1;
|
||||||
const /** @type {number} */ delta = copyNibbles << 1;
|
const /** @type {number} */ delta = copyNibbles << 1;
|
||||||
data.set(s.byteBuffer.subarray(readOffset, readOffset + delta), offset);
|
data.set(s.byteBuffer.subarray(readOffset, readOffset + delta), pos);
|
||||||
offset += delta;
|
pos += delta;
|
||||||
length -= delta;
|
len -= delta;
|
||||||
s.halfOffset += copyNibbles;
|
s.halfOffset += copyNibbles;
|
||||||
}
|
}
|
||||||
if (length === 0) {
|
if (len === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (halfAvailable(s) > 0) {
|
if (halfAvailable(s) > 0) {
|
||||||
@ -1807,21 +1828,21 @@ let makeBrotliDecode = () => {
|
|||||||
s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
|
s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
|
||||||
s.bitOffset -= 16;
|
s.bitOffset -= 16;
|
||||||
}
|
}
|
||||||
while (length !== 0) {
|
while (len !== 0) {
|
||||||
data[offset++] = (s.accumulator32 >>> s.bitOffset);
|
data[pos++] = s.accumulator32 >>> s.bitOffset;
|
||||||
s.bitOffset += 8;
|
s.bitOffset += 8;
|
||||||
length--;
|
len--;
|
||||||
}
|
}
|
||||||
checkHealth(s, 0);
|
checkHealth(s, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (length > 0) {
|
while (len > 0) {
|
||||||
const /** @type {number} */ len = readInput(s, data, offset, length);
|
const /** @type {number} */ chunkLen = readInput(s, data, pos, len);
|
||||||
if (len === -1) {
|
if (chunkLen === -1) {
|
||||||
throw new Error("Unexpected end of input");
|
throw new Error("Unexpected end of input");
|
||||||
}
|
}
|
||||||
offset += len;
|
pos += chunkLen;
|
||||||
length -= len;
|
len -= chunkLen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -1834,7 +1855,7 @@ let makeBrotliDecode = () => {
|
|||||||
const /** @type {number} */ halfLen = byteLen >> 1;
|
const /** @type {number} */ halfLen = byteLen >> 1;
|
||||||
const /** @type {!Int16Array} */ shortBuffer = s.shortBuffer;
|
const /** @type {!Int16Array} */ shortBuffer = s.shortBuffer;
|
||||||
for (let /** @type {number} */ i = 0; i < halfLen; ++i) {
|
for (let /** @type {number} */ i = 0; i < halfLen; ++i) {
|
||||||
shortBuffer[i] = ((byteBuffer[i * 2] & 0xFF) | ((byteBuffer[(i * 2) + 1] & 0xFF) << 8));
|
shortBuffer[i] = (byteBuffer[i * 2] & 0xFF) | ((byteBuffer[(i * 2) + 1] & 0xFF) << 8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2028,8 +2049,8 @@ let makeBrotliDecode = () => {
|
|||||||
this.cdBlockBits = 0;
|
this.cdBlockBits = 0;
|
||||||
/** @type {!Int8Array} */
|
/** @type {!Int8Array} */
|
||||||
this.cdBlockMap = new Int8Array(0);
|
this.cdBlockMap = new Int8Array(0);
|
||||||
/** @type {!InputStream|null} */
|
/** @type {!InputStream} */
|
||||||
this.input = null;
|
this.input = new InputStream(new Int8Array(0));
|
||||||
this.ringBuffer = new Int8Array(0);
|
this.ringBuffer = new Int8Array(0);
|
||||||
this.rings = new Int32Array(10);
|
this.rings = new Int32Array(10);
|
||||||
this.rings[0] = 16;
|
this.rings[0] = 16;
|
||||||
@ -2100,16 +2121,16 @@ let makeBrotliDecode = () => {
|
|||||||
throw new Error("Corrupted brotli dictionary");
|
throw new Error("Corrupted brotli dictionary");
|
||||||
}
|
}
|
||||||
let /** @type {number} */ offset = 0;
|
let /** @type {number} */ offset = 0;
|
||||||
const /** @type {number} */ n = skipFlip.length;
|
const /** @type {number} */ n = skipFlip.length >> 1;
|
||||||
for (let /** @type {number} */ i = 0; i < n; i += 2) {
|
for (let /** @type {number} */ i = 0; i < n; ++i) {
|
||||||
const /** @type {number} */ skip = skipFlip.charCodeAt(i) - 36;
|
const /** @type {number} */ skip = skipFlip.charCodeAt(2 * i) - 36;
|
||||||
const /** @type {number} */ flip = skipFlip.charCodeAt(i + 1) - 36;
|
const /** @type {number} */ flip = skipFlip.charCodeAt(2 * i + 1) - 36;
|
||||||
for (let /** @type {number} */ j = 0; j < skip; ++j) {
|
for (let /** @type {number} */ j = 0; j < skip; ++j) {
|
||||||
dict[offset] ^= 3;
|
dict[offset] = dict[offset] ^ 3;
|
||||||
offset++;
|
offset++;
|
||||||
}
|
}
|
||||||
for (let /** @type {number} */ j = 0; j < flip; ++j) {
|
for (let /** @type {number} */ j = 0; j < flip; ++j) {
|
||||||
dict[offset] ^= 236;
|
dict[offset] = dict[offset] ^ 236;
|
||||||
offset++;
|
offset++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2158,8 +2179,8 @@ let makeBrotliDecode = () => {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
const /** @type {!InputStream} */ src = s.input;
|
const /** @type {!InputStream} */ src = s.input;
|
||||||
let /** @type {number} */ end = Math.min(src.offset + length, src.data.length);
|
const /** @type {number} */ end = Math.min(src.offset + length, src.data.length);
|
||||||
let /** @type {number} */ bytesRead = end - src.offset;
|
const /** @type {number} */ bytesRead = end - src.offset;
|
||||||
dst.set(src.data.subarray(src.offset, end), offset);
|
dst.set(src.data.subarray(src.offset, end), offset);
|
||||||
src.offset += bytesRead;
|
src.offset += bytesRead;
|
||||||
return bytesRead;
|
return bytesRead;
|
||||||
@ -2169,8 +2190,8 @@ let makeBrotliDecode = () => {
|
|||||||
* @return {!Int8Array}
|
* @return {!Int8Array}
|
||||||
*/
|
*/
|
||||||
function toUsAsciiBytes(src) {
|
function toUsAsciiBytes(src) {
|
||||||
let /** @type {number} */ n = src.length;
|
const /** @type {number} */ n = src.length;
|
||||||
let /** @type {!Int8Array} */ result = new Int8Array(n);
|
const /** @type {!Int8Array} */ result = new Int8Array(n);
|
||||||
for (let /** @type {number} */ i = 0; i < n; ++i) {
|
for (let /** @type {number} */ i = 0; i < n; ++i) {
|
||||||
result[i] = src.charCodeAt(i);
|
result[i] = src.charCodeAt(i);
|
||||||
}
|
}
|
||||||
|
2
js/decode.min.js
vendored
2
js/decode.min.js
vendored
File diff suppressed because one or more lines are too long
241
js/decode.ts
241
js/decode.ts
@ -25,14 +25,16 @@ const CMD_LOOKUP = new Int16Array(2816);
|
|||||||
function log2floor(i: number): number {
|
function log2floor(i: number): number {
|
||||||
let result: number = -1;
|
let result: number = -1;
|
||||||
let step = 16;
|
let step = 16;
|
||||||
|
let v: number = i;
|
||||||
while (step > 0) {
|
while (step > 0) {
|
||||||
if ((i >>> step) !== 0) {
|
let next: number = v >>> step;
|
||||||
|
if (next !== 0) {
|
||||||
result += step;
|
result += step;
|
||||||
i = i >>> step;
|
v = next;
|
||||||
}
|
}
|
||||||
step = step >> 1;
|
step = step >> 1;
|
||||||
}
|
}
|
||||||
return result + i;
|
return result + v;
|
||||||
}
|
}
|
||||||
function calculateDistanceAlphabetSize(npostfix: number, ndirect: number, maxndistbits: number): number {
|
function calculateDistanceAlphabetSize(npostfix: number, ndirect: number, maxndistbits: number): number {
|
||||||
return 16 + ndirect + 2 * (maxndistbits << npostfix);
|
return 16 + ndirect + 2 * (maxndistbits << npostfix);
|
||||||
@ -47,12 +49,12 @@ function calculateDistanceAlphabetLimit(maxDistance: number, npostfix: number, n
|
|||||||
return ((group - 1) << npostfix) + (1 << npostfix) + ndirect + 16;
|
return ((group - 1) << npostfix) + (1 << npostfix) + ndirect + 16;
|
||||||
}
|
}
|
||||||
function unpackCommandLookupTable(cmdLookup: Int16Array): void {
|
function unpackCommandLookupTable(cmdLookup: Int16Array): void {
|
||||||
const insertLengthOffsets = new Int16Array(24);
|
const insertLengthOffsets = new Int32Array(24);
|
||||||
const copyLengthOffsets = new Int16Array(24);
|
const copyLengthOffsets = new Int32Array(24);
|
||||||
copyLengthOffsets[0] = 2;
|
copyLengthOffsets[0] = 2;
|
||||||
for (let i = 0; i < 23; ++i) {
|
for (let i = 0; i < 23; ++i) {
|
||||||
insertLengthOffsets[i + 1] = (insertLengthOffsets[i] + (1 << INSERT_LENGTH_N_BITS[i]));
|
insertLengthOffsets[i + 1] = insertLengthOffsets[i] + (1 << INSERT_LENGTH_N_BITS[i]);
|
||||||
copyLengthOffsets[i + 1] = (copyLengthOffsets[i] + (1 << COPY_LENGTH_N_BITS[i]));
|
copyLengthOffsets[i + 1] = copyLengthOffsets[i] + (1 << COPY_LENGTH_N_BITS[i]);
|
||||||
}
|
}
|
||||||
for (let cmdCode = 0; cmdCode < 704; ++cmdCode) {
|
for (let cmdCode = 0; cmdCode < 704; ++cmdCode) {
|
||||||
let rangeIdx: number = cmdCode >>> 6;
|
let rangeIdx: number = cmdCode >>> 6;
|
||||||
@ -64,9 +66,9 @@ function unpackCommandLookupTable(cmdLookup: Int16Array): void {
|
|||||||
const insertCode: number = (((0x29850 >>> (rangeIdx * 2)) & 0x3) << 3) | ((cmdCode >>> 3) & 7);
|
const insertCode: number = (((0x29850 >>> (rangeIdx * 2)) & 0x3) << 3) | ((cmdCode >>> 3) & 7);
|
||||||
const copyCode: number = (((0x26244 >>> (rangeIdx * 2)) & 0x3) << 3) | (cmdCode & 7);
|
const copyCode: number = (((0x26244 >>> (rangeIdx * 2)) & 0x3) << 3) | (cmdCode & 7);
|
||||||
const copyLengthOffset: number = copyLengthOffsets[copyCode];
|
const copyLengthOffset: number = copyLengthOffsets[copyCode];
|
||||||
const distanceContext: number = distanceContextOffset + (copyLengthOffset > 4 ? 3 : copyLengthOffset - 2);
|
const distanceContext: number = distanceContextOffset + (copyLengthOffset > 4 ? 3 : (copyLengthOffset - 2));
|
||||||
const index: number = cmdCode * 4;
|
const index: number = cmdCode * 4;
|
||||||
cmdLookup[index] = (INSERT_LENGTH_N_BITS[insertCode] | (COPY_LENGTH_N_BITS[copyCode] << 8));
|
cmdLookup[index] = INSERT_LENGTH_N_BITS[insertCode] | (COPY_LENGTH_N_BITS[copyCode] << 8);
|
||||||
cmdLookup[index + 1] = insertLengthOffsets[insertCode];
|
cmdLookup[index + 1] = insertLengthOffsets[insertCode];
|
||||||
cmdLookup[index + 2] = copyLengthOffsets[copyCode];
|
cmdLookup[index + 2] = copyLengthOffsets[copyCode];
|
||||||
cmdLookup[index + 3] = distanceContext;
|
cmdLookup[index + 3] = distanceContext;
|
||||||
@ -157,7 +159,7 @@ function close(s: State): void {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
s.runningState = 11;
|
s.runningState = 11;
|
||||||
s.input = null;
|
s.input = new InputStream(new Int8Array(0));
|
||||||
}
|
}
|
||||||
function decodeVarLenUnsignedByte(s: State): number {
|
function decodeVarLenUnsignedByte(s: State): number {
|
||||||
if (s.bitOffset >= 16) {
|
if (s.bitOffset >= 16) {
|
||||||
@ -196,7 +198,7 @@ function decodeMetaBlockLength(s: State): void {
|
|||||||
if (sizeBytes === 0) {
|
if (sizeBytes === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (let i = 0; i < sizeBytes; i++) {
|
for (let i = 0; i < sizeBytes; ++i) {
|
||||||
if (s.bitOffset >= 16) {
|
if (s.bitOffset >= 16) {
|
||||||
s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
|
s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
|
||||||
s.bitOffset -= 16;
|
s.bitOffset -= 16;
|
||||||
@ -205,10 +207,10 @@ function decodeMetaBlockLength(s: State): void {
|
|||||||
if (bits === 0 && i + 1 === sizeBytes && sizeBytes > 1) {
|
if (bits === 0 && i + 1 === sizeBytes && sizeBytes > 1) {
|
||||||
throw new Error("Exuberant nibble");
|
throw new Error("Exuberant nibble");
|
||||||
}
|
}
|
||||||
s.metaBlockLength |= bits << (i * 8);
|
s.metaBlockLength += bits << (i * 8);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (let i = 0; i < sizeNibbles; i++) {
|
for (let i = 0; i < sizeNibbles; ++i) {
|
||||||
if (s.bitOffset >= 16) {
|
if (s.bitOffset >= 16) {
|
||||||
s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
|
s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
|
||||||
s.bitOffset -= 16;
|
s.bitOffset -= 16;
|
||||||
@ -217,7 +219,7 @@ function decodeMetaBlockLength(s: State): void {
|
|||||||
if (bits === 0 && i + 1 === sizeNibbles && sizeNibbles > 4) {
|
if (bits === 0 && i + 1 === sizeNibbles && sizeNibbles > 4) {
|
||||||
throw new Error("Exuberant nibble");
|
throw new Error("Exuberant nibble");
|
||||||
}
|
}
|
||||||
s.metaBlockLength |= bits << (i * 4);
|
s.metaBlockLength += bits << (i * 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.metaBlockLength++;
|
s.metaBlockLength++;
|
||||||
@ -227,8 +229,8 @@ function decodeMetaBlockLength(s: State): void {
|
|||||||
}
|
}
|
||||||
function readSymbol(tableGroup: Int32Array, tableIdx: number, s: State): number {
|
function readSymbol(tableGroup: Int32Array, tableIdx: number, s: State): number {
|
||||||
let offset: number = tableGroup[tableIdx];
|
let offset: number = tableGroup[tableIdx];
|
||||||
const val: number = (s.accumulator32 >>> s.bitOffset);
|
const v: number = s.accumulator32 >>> s.bitOffset;
|
||||||
offset += val & 0xFF;
|
offset += v & 0xFF;
|
||||||
const bits: number = tableGroup[offset] >> 16;
|
const bits: number = tableGroup[offset] >> 16;
|
||||||
const sym: number = tableGroup[offset] & 0xFFFF;
|
const sym: number = tableGroup[offset] & 0xFFFF;
|
||||||
if (bits <= 8) {
|
if (bits <= 8) {
|
||||||
@ -237,8 +239,8 @@ function readSymbol(tableGroup: Int32Array, tableIdx: number, s: State): number
|
|||||||
}
|
}
|
||||||
offset += sym;
|
offset += sym;
|
||||||
const mask: number = (1 << bits) - 1;
|
const mask: number = (1 << bits) - 1;
|
||||||
offset += (val & mask) >>> 8;
|
offset += (v & mask) >>> 8;
|
||||||
s.bitOffset += ((tableGroup[offset] >> 16) + 8);
|
s.bitOffset += (tableGroup[offset] >> 16) + 8;
|
||||||
return tableGroup[offset] & 0xFFFF;
|
return tableGroup[offset] & 0xFFFF;
|
||||||
}
|
}
|
||||||
function readBlockLength(tableGroup: Int32Array, tableIdx: number, s: State): number {
|
function readBlockLength(tableGroup: Int32Array, tableIdx: number, s: State): number {
|
||||||
@ -255,18 +257,20 @@ function readBlockLength(tableGroup: Int32Array, tableIdx: number, s: State): nu
|
|||||||
return BLOCK_LENGTH_OFFSET[code] + ((n <= 16) ? readFewBits(s, n) : readManyBits(s, n));
|
return BLOCK_LENGTH_OFFSET[code] + ((n <= 16) ? readFewBits(s, n) : readManyBits(s, n));
|
||||||
}
|
}
|
||||||
function moveToFront(v: Int32Array, index: number): void {
|
function moveToFront(v: Int32Array, index: number): void {
|
||||||
const value: number = v[index];
|
let i: number = index;
|
||||||
for (; index > 0; index--) {
|
const value: number = v[i];
|
||||||
v[index] = v[index - 1];
|
while (i > 0) {
|
||||||
|
v[i] = v[i - 1];
|
||||||
|
i--;
|
||||||
}
|
}
|
||||||
v[0] = value;
|
v[0] = value;
|
||||||
}
|
}
|
||||||
function inverseMoveToFrontTransform(v: Int8Array, vLen: number): void {
|
function inverseMoveToFrontTransform(v: Int8Array, vLen: number): void {
|
||||||
const mtf = new Int32Array(256);
|
const mtf = new Int32Array(256);
|
||||||
for (let i = 0; i < 256; i++) {
|
for (let i = 0; i < 256; ++i) {
|
||||||
mtf[i] = i;
|
mtf[i] = i;
|
||||||
}
|
}
|
||||||
for (let i = 0; i < vLen; i++) {
|
for (let i = 0; i < vLen; ++i) {
|
||||||
const index: number = v[i] & 0xFF;
|
const index: number = v[i] & 0xFF;
|
||||||
v[i] = mtf[index];
|
v[i] = mtf[index];
|
||||||
if (index !== 0) {
|
if (index !== 0) {
|
||||||
@ -314,7 +318,7 @@ function readHuffmanCodeLengths(codeLengthCodeLengths: Int32Array, numSymbols: n
|
|||||||
const oldRepeat: number = repeat;
|
const oldRepeat: number = repeat;
|
||||||
if (repeat > 0) {
|
if (repeat > 0) {
|
||||||
repeat -= 2;
|
repeat -= 2;
|
||||||
repeat <<= extraBits;
|
repeat = repeat << extraBits;
|
||||||
}
|
}
|
||||||
if (s.bitOffset >= 16) {
|
if (s.bitOffset >= 16) {
|
||||||
s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
|
s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
|
||||||
@ -325,7 +329,7 @@ function readHuffmanCodeLengths(codeLengthCodeLengths: Int32Array, numSymbols: n
|
|||||||
if (symbol + repeatDelta > numSymbols) {
|
if (symbol + repeatDelta > numSymbols) {
|
||||||
throw new Error("symbol + repeatDelta > numSymbols");
|
throw new Error("symbol + repeatDelta > numSymbols");
|
||||||
}
|
}
|
||||||
for (let i = 0; i < repeatDelta; i++) {
|
for (let i = 0; i < repeatDelta; ++i) {
|
||||||
codeLengths[symbol++] = repeatCodeLen;
|
codeLengths[symbol++] = repeatCodeLen;
|
||||||
}
|
}
|
||||||
if (repeatCodeLen !== 0) {
|
if (repeatCodeLen !== 0) {
|
||||||
@ -352,7 +356,7 @@ function readSimpleHuffmanCode(alphabetSizeMax: number, alphabetSizeLimit: numbe
|
|||||||
const symbols = new Int32Array(4);
|
const symbols = new Int32Array(4);
|
||||||
const maxBits: number = 1 + log2floor(alphabetSizeMax - 1);
|
const maxBits: number = 1 + log2floor(alphabetSizeMax - 1);
|
||||||
const numSymbols: number = readFewBits(s, 2) + 1;
|
const numSymbols: number = readFewBits(s, 2) + 1;
|
||||||
for (let i = 0; i < numSymbols; i++) {
|
for (let i = 0; i < numSymbols; ++i) {
|
||||||
if (s.bitOffset >= 16) {
|
if (s.bitOffset >= 16) {
|
||||||
s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
|
s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
|
||||||
s.bitOffset -= 16;
|
s.bitOffset -= 16;
|
||||||
@ -403,7 +407,7 @@ function readComplexHuffmanCode(alphabetSizeLimit: number, skip: number, tableGr
|
|||||||
const codeLengthCodeLengths = new Int32Array(18);
|
const codeLengthCodeLengths = new Int32Array(18);
|
||||||
let space = 32;
|
let space = 32;
|
||||||
let numCodes = 0;
|
let numCodes = 0;
|
||||||
for (let i: number = skip; i < 18 && space > 0; i++) {
|
for (let i: number = skip; i < 18; ++i) {
|
||||||
const codeLenIdx: number = CODE_LENGTH_CODE_ORDER[i];
|
const codeLenIdx: number = CODE_LENGTH_CODE_ORDER[i];
|
||||||
if (s.bitOffset >= 16) {
|
if (s.bitOffset >= 16) {
|
||||||
s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
|
s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
|
||||||
@ -414,8 +418,10 @@ function readComplexHuffmanCode(alphabetSizeLimit: number, skip: number, tableGr
|
|||||||
const v: number = FIXED_TABLE[p] & 0xFFFF;
|
const v: number = FIXED_TABLE[p] & 0xFFFF;
|
||||||
codeLengthCodeLengths[codeLenIdx] = v;
|
codeLengthCodeLengths[codeLenIdx] = v;
|
||||||
if (v !== 0) {
|
if (v !== 0) {
|
||||||
space -= (32 >> v);
|
space -= 32 >> v;
|
||||||
numCodes++;
|
numCodes++;
|
||||||
|
if (space <= 0)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (space !== 0 && numCodes !== 1) {
|
if (space !== 0 && numCodes !== 1) {
|
||||||
@ -462,7 +468,8 @@ function decodeContextMap(contextMapSize: number, contextMap: Int8Array, s: Stat
|
|||||||
const table = new Int32Array(tableSize + 1);
|
const table = new Int32Array(tableSize + 1);
|
||||||
const tableIdx: number = table.length - 1;
|
const tableIdx: number = table.length - 1;
|
||||||
readHuffmanCode(alphabetSize, alphabetSize, table, tableIdx, s);
|
readHuffmanCode(alphabetSize, alphabetSize, table, tableIdx, s);
|
||||||
for (let i = 0; i < contextMapSize; ) {
|
let i = 0;
|
||||||
|
while (i < contextMapSize) {
|
||||||
if (s.halfOffset > 2030) {
|
if (s.halfOffset > 2030) {
|
||||||
doReadMoreInput(s);
|
doReadMoreInput(s);
|
||||||
}
|
}
|
||||||
@ -489,7 +496,7 @@ function decodeContextMap(contextMapSize: number, contextMap: Int8Array, s: Stat
|
|||||||
reps--;
|
reps--;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
contextMap[i] = (code - maxRunLengthPrefix);
|
contextMap[i] = code - maxRunLengthPrefix;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -547,7 +554,7 @@ function maybeReallocateRingBuffer(s: State): void {
|
|||||||
if (newSize > s.expectedTotalSize) {
|
if (newSize > s.expectedTotalSize) {
|
||||||
const minimalNewSize: number = s.expectedTotalSize;
|
const minimalNewSize: number = s.expectedTotalSize;
|
||||||
while ((newSize >> 1) > minimalNewSize) {
|
while ((newSize >> 1) > minimalNewSize) {
|
||||||
newSize >>= 1;
|
newSize = newSize >> 1;
|
||||||
}
|
}
|
||||||
if ((s.inputEnd === 0) && newSize < 16384 && s.maxRingBufferSize >= 16384) {
|
if ((s.inputEnd === 0) && newSize < 16384 && s.maxRingBufferSize >= 16384) {
|
||||||
newSize = 16384;
|
newSize = 16384;
|
||||||
@ -558,8 +565,9 @@ function maybeReallocateRingBuffer(s: State): void {
|
|||||||
}
|
}
|
||||||
const ringBufferSizeWithSlack: number = newSize + 37;
|
const ringBufferSizeWithSlack: number = newSize + 37;
|
||||||
const newBuffer = new Int8Array(ringBufferSizeWithSlack);
|
const newBuffer = new Int8Array(ringBufferSizeWithSlack);
|
||||||
if (s.ringBuffer.length !== 0) {
|
const oldBuffer: Int8Array = s.ringBuffer;
|
||||||
newBuffer.set(s.ringBuffer.subarray(0, s.ringBufferSize), 0);
|
if (oldBuffer.length !== 0) {
|
||||||
|
newBuffer.set(oldBuffer.subarray(0, s.ringBufferSize), 0);
|
||||||
}
|
}
|
||||||
s.ringBuffer = newBuffer;
|
s.ringBuffer = newBuffer;
|
||||||
s.ringBufferSize = newSize;
|
s.ringBufferSize = newSize;
|
||||||
@ -654,23 +662,26 @@ function readMetablockHuffmanCodesAndContextMaps(s: State): void {
|
|||||||
s.distancePostfixBits = readFewBits(s, 2);
|
s.distancePostfixBits = readFewBits(s, 2);
|
||||||
s.numDirectDistanceCodes = readFewBits(s, 4) << s.distancePostfixBits;
|
s.numDirectDistanceCodes = readFewBits(s, 4) << s.distancePostfixBits;
|
||||||
s.contextModes = new Int8Array(s.numLiteralBlockTypes);
|
s.contextModes = new Int8Array(s.numLiteralBlockTypes);
|
||||||
for (let i = 0; i < s.numLiteralBlockTypes; ) {
|
let i = 0;
|
||||||
|
while (i < s.numLiteralBlockTypes) {
|
||||||
const limit: number = Math.min(i + 96, s.numLiteralBlockTypes);
|
const limit: number = Math.min(i + 96, s.numLiteralBlockTypes);
|
||||||
for (; i < limit; ++i) {
|
while (i < limit) {
|
||||||
if (s.bitOffset >= 16) {
|
if (s.bitOffset >= 16) {
|
||||||
s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
|
s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
|
||||||
s.bitOffset -= 16;
|
s.bitOffset -= 16;
|
||||||
}
|
}
|
||||||
s.contextModes[i] = readFewBits(s, 2);
|
s.contextModes[i] = readFewBits(s, 2);
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
if (s.halfOffset > 2030) {
|
if (s.halfOffset > 2030) {
|
||||||
doReadMoreInput(s);
|
doReadMoreInput(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.contextMap = new Int8Array(s.numLiteralBlockTypes << 6);
|
const contextMapLength: number = s.numLiteralBlockTypes << 6;
|
||||||
const numLiteralTrees: number = decodeContextMap(s.numLiteralBlockTypes << 6, s.contextMap, s);
|
s.contextMap = new Int8Array(contextMapLength);
|
||||||
|
const numLiteralTrees: number = decodeContextMap(contextMapLength, s.contextMap, s);
|
||||||
s.trivialLiteralContext = 1;
|
s.trivialLiteralContext = 1;
|
||||||
for (let j = 0; j < s.numLiteralBlockTypes << 6; j++) {
|
for (let j = 0; j < contextMapLength; ++j) {
|
||||||
if (s.contextMap[j] !== j >> 6) {
|
if (s.contextMap[j] !== j >> 6) {
|
||||||
s.trivialLiteralContext = 0;
|
s.trivialLiteralContext = 0;
|
||||||
break;
|
break;
|
||||||
@ -1054,7 +1065,8 @@ function decompress(s: State): void {
|
|||||||
const dstEnd: number = dst + copyLength;
|
const dstEnd: number = dst + copyLength;
|
||||||
if ((srcEnd < ringBufferMask) && (dstEnd < ringBufferMask)) {
|
if ((srcEnd < ringBufferMask) && (dstEnd < ringBufferMask)) {
|
||||||
if (copyLength < 12 || (srcEnd > dst && dstEnd > src)) {
|
if (copyLength < 12 || (srcEnd > dst && dstEnd > src)) {
|
||||||
for (let k = 0; k < copyLength; k += 4) {
|
const numQuads: number = (copyLength + 3) >> 2;
|
||||||
|
for (let k = 0; k < numQuads; ++k) {
|
||||||
ringBuffer[dst++] = ringBuffer[src++];
|
ringBuffer[dst++] = ringBuffer[src++];
|
||||||
ringBuffer[dst++] = ringBuffer[src++];
|
ringBuffer[dst++] = ringBuffer[src++];
|
||||||
ringBuffer[dst++] = ringBuffer[src++];
|
ringBuffer[dst++] = ringBuffer[src++];
|
||||||
@ -1067,7 +1079,7 @@ function decompress(s: State): void {
|
|||||||
s.metaBlockLength -= copyLength;
|
s.metaBlockLength -= copyLength;
|
||||||
s.pos += copyLength;
|
s.pos += copyLength;
|
||||||
} else {
|
} else {
|
||||||
for (; s.j < s.copyLength; ) {
|
while (s.j < s.copyLength) {
|
||||||
ringBuffer[s.pos] = ringBuffer[(s.pos - s.distance) & ringBufferMask];
|
ringBuffer[s.pos] = ringBuffer[(s.pos - s.distance) & ringBufferMask];
|
||||||
s.metaBlockLength--;
|
s.metaBlockLength--;
|
||||||
s.pos++;
|
s.pos++;
|
||||||
@ -1129,7 +1141,7 @@ function decompress(s: State): void {
|
|||||||
if (s.pos > s.ringBufferSize) {
|
if (s.pos > s.ringBufferSize) {
|
||||||
ringBuffer.copyWithin(0, s.ringBufferSize, s.pos);
|
ringBuffer.copyWithin(0, s.ringBufferSize, s.pos);
|
||||||
}
|
}
|
||||||
s.pos &= ringBufferMask;
|
s.pos = s.pos & ringBufferMask;
|
||||||
s.ringBufferBytesWritten = 0;
|
s.ringBufferBytesWritten = 0;
|
||||||
}
|
}
|
||||||
s.runningState = s.nextRunningState;
|
s.runningState = s.nextRunningState;
|
||||||
@ -1182,7 +1194,7 @@ function unpackTransforms(prefixSuffix: Int8Array, prefixSuffixHeads: Int32Array
|
|||||||
{
|
{
|
||||||
unpackTransforms(RFC_TRANSFORMS.prefixSuffixStorage, RFC_TRANSFORMS.prefixSuffixHeads, RFC_TRANSFORMS.triplets, "# #s #, #e #.# the #.com/#\xC2\xA0# 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");
|
unpackTransforms(RFC_TRANSFORMS.prefixSuffixStorage, RFC_TRANSFORMS.prefixSuffixHeads, RFC_TRANSFORMS.triplets, "# #s #, #e #.# the #.com/#\xC2\xA0# 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");
|
||||||
}
|
}
|
||||||
function transformDictionaryWord(dst: Int8Array, dstOffset: number, src: ByteBuffer, srcOffset: number, len: number, transforms: Transforms, transformIndex: number): number {
|
function transformDictionaryWord(dst: Int8Array, dstOffset: number, src: ByteBuffer, srcOffset: number, wordLen: number, transforms: Transforms, transformIndex: number): number {
|
||||||
let offset: number = dstOffset;
|
let offset: number = dstOffset;
|
||||||
const triplets: Int32Array = transforms.triplets;
|
const triplets: Int32Array = transforms.triplets;
|
||||||
const prefixSuffixStorage: Int8Array = transforms.prefixSuffixStorage;
|
const prefixSuffixStorage: Int8Array = transforms.prefixSuffixStorage;
|
||||||
@ -1206,15 +1218,16 @@ function transformDictionaryWord(dst: Int8Array, dstOffset: number, src: ByteBuf
|
|||||||
while (prefix !== prefixEnd) {
|
while (prefix !== prefixEnd) {
|
||||||
dst[offset++] = prefixSuffixStorage[prefix++];
|
dst[offset++] = prefixSuffixStorage[prefix++];
|
||||||
}
|
}
|
||||||
|
let len: number = wordLen;
|
||||||
if (omitFirst > len) {
|
if (omitFirst > len) {
|
||||||
omitFirst = len;
|
omitFirst = len;
|
||||||
}
|
}
|
||||||
srcOffset += omitFirst;
|
let dictOffset: number = srcOffset + omitFirst;
|
||||||
len -= omitFirst;
|
len -= omitFirst;
|
||||||
len -= omitLast;
|
len -= omitLast;
|
||||||
let i: number = len;
|
let i: number = len;
|
||||||
while (i > 0) {
|
while (i > 0) {
|
||||||
dst[offset++] = src[srcOffset++];
|
dst[offset++] = src[dictOffset++];
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
if (transformType === 10 || transformType === 11) {
|
if (transformType === 10 || transformType === 11) {
|
||||||
@ -1226,16 +1239,16 @@ function transformDictionaryWord(dst: Int8Array, dstOffset: number, src: ByteBuf
|
|||||||
const c0: number = dst[uppercaseOffset] & 0xFF;
|
const c0: number = dst[uppercaseOffset] & 0xFF;
|
||||||
if (c0 < 0xC0) {
|
if (c0 < 0xC0) {
|
||||||
if (c0 >= 97 && c0 <= 122) {
|
if (c0 >= 97 && c0 <= 122) {
|
||||||
dst[uppercaseOffset] ^= 32;
|
dst[uppercaseOffset] = dst[uppercaseOffset] ^ 32;
|
||||||
}
|
}
|
||||||
uppercaseOffset += 1;
|
uppercaseOffset += 1;
|
||||||
len -= 1;
|
len -= 1;
|
||||||
} else if (c0 < 0xE0) {
|
} else if (c0 < 0xE0) {
|
||||||
dst[uppercaseOffset + 1] ^= 32;
|
dst[uppercaseOffset + 1] = dst[uppercaseOffset + 1] ^ 32;
|
||||||
uppercaseOffset += 2;
|
uppercaseOffset += 2;
|
||||||
len -= 2;
|
len -= 2;
|
||||||
} else {
|
} else {
|
||||||
dst[uppercaseOffset + 2] ^= 5;
|
dst[uppercaseOffset + 2] = dst[uppercaseOffset + 2] ^ 5;
|
||||||
uppercaseOffset += 3;
|
uppercaseOffset += 3;
|
||||||
len -= 3;
|
len -= 3;
|
||||||
}
|
}
|
||||||
@ -1249,14 +1262,14 @@ function transformDictionaryWord(dst: Int8Array, dstOffset: number, src: ByteBuf
|
|||||||
const c0: number = dst[shiftOffset] & 0xFF;
|
const c0: number = dst[shiftOffset] & 0xFF;
|
||||||
if (c0 < 0x80) {
|
if (c0 < 0x80) {
|
||||||
scalar += c0;
|
scalar += c0;
|
||||||
dst[shiftOffset] = (scalar & 0x7F);
|
dst[shiftOffset] = scalar & 0x7F;
|
||||||
} else if (c0 < 0xC0) {
|
} else if (c0 < 0xC0) {
|
||||||
} else if (c0 < 0xE0) {
|
} else if (c0 < 0xE0) {
|
||||||
if (len >= 2) {
|
if (len >= 2) {
|
||||||
const c1: number = dst[shiftOffset + 1];
|
const c1: number = dst[shiftOffset + 1];
|
||||||
scalar += (c1 & 0x3F) | ((c0 & 0x1F) << 6);
|
scalar += (c1 & 0x3F) | ((c0 & 0x1F) << 6);
|
||||||
dst[shiftOffset] = (0xC0 | ((scalar >> 6) & 0x1F));
|
dst[shiftOffset] = 0xC0 | ((scalar >> 6) & 0x1F);
|
||||||
dst[shiftOffset + 1] = ((c1 & 0xC0) | (scalar & 0x3F));
|
dst[shiftOffset + 1] = (c1 & 0xC0) | (scalar & 0x3F);
|
||||||
step = 2;
|
step = 2;
|
||||||
} else {
|
} else {
|
||||||
step = len;
|
step = len;
|
||||||
@ -1266,9 +1279,9 @@ function transformDictionaryWord(dst: Int8Array, dstOffset: number, src: ByteBuf
|
|||||||
const c1: number = dst[shiftOffset + 1];
|
const c1: number = dst[shiftOffset + 1];
|
||||||
const c2: number = dst[shiftOffset + 2];
|
const c2: number = dst[shiftOffset + 2];
|
||||||
scalar += (c2 & 0x3F) | ((c1 & 0x3F) << 6) | ((c0 & 0x0F) << 12);
|
scalar += (c2 & 0x3F) | ((c1 & 0x3F) << 6) | ((c0 & 0x0F) << 12);
|
||||||
dst[shiftOffset] = (0xE0 | ((scalar >> 12) & 0x0F));
|
dst[shiftOffset] = 0xE0 | ((scalar >> 12) & 0x0F);
|
||||||
dst[shiftOffset + 1] = ((c1 & 0xC0) | ((scalar >> 6) & 0x3F));
|
dst[shiftOffset + 1] = (c1 & 0xC0) | ((scalar >> 6) & 0x3F);
|
||||||
dst[shiftOffset + 2] = ((c2 & 0xC0) | (scalar & 0x3F));
|
dst[shiftOffset + 2] = (c2 & 0xC0) | (scalar & 0x3F);
|
||||||
step = 3;
|
step = 3;
|
||||||
} else {
|
} else {
|
||||||
step = len;
|
step = len;
|
||||||
@ -1279,10 +1292,10 @@ function transformDictionaryWord(dst: Int8Array, dstOffset: number, src: ByteBuf
|
|||||||
const c2: number = dst[shiftOffset + 2];
|
const c2: number = dst[shiftOffset + 2];
|
||||||
const c3: number = dst[shiftOffset + 3];
|
const c3: number = dst[shiftOffset + 3];
|
||||||
scalar += (c3 & 0x3F) | ((c2 & 0x3F) << 6) | ((c1 & 0x3F) << 12) | ((c0 & 0x07) << 18);
|
scalar += (c3 & 0x3F) | ((c2 & 0x3F) << 6) | ((c1 & 0x3F) << 12) | ((c0 & 0x07) << 18);
|
||||||
dst[shiftOffset] = (0xF0 | ((scalar >> 18) & 0x07));
|
dst[shiftOffset] = 0xF0 | ((scalar >> 18) & 0x07);
|
||||||
dst[shiftOffset + 1] = ((c1 & 0xC0) | ((scalar >> 12) & 0x3F));
|
dst[shiftOffset + 1] = (c1 & 0xC0) | ((scalar >> 12) & 0x3F);
|
||||||
dst[shiftOffset + 2] = ((c2 & 0xC0) | ((scalar >> 6) & 0x3F));
|
dst[shiftOffset + 2] = (c2 & 0xC0) | ((scalar >> 6) & 0x3F);
|
||||||
dst[shiftOffset + 3] = ((c3 & 0xC0) | (scalar & 0x3F));
|
dst[shiftOffset + 3] = (c3 & 0xC0) | (scalar & 0x3F);
|
||||||
step = 4;
|
step = 4;
|
||||||
} else {
|
} else {
|
||||||
step = len;
|
step = len;
|
||||||
@ -1304,69 +1317,74 @@ function transformDictionaryWord(dst: Int8Array, dstOffset: number, src: ByteBuf
|
|||||||
function getNextKey(key: number, len: number): number {
|
function getNextKey(key: number, len: number): number {
|
||||||
let step: number = 1 << (len - 1);
|
let step: number = 1 << (len - 1);
|
||||||
while ((key & step) !== 0) {
|
while ((key & step) !== 0) {
|
||||||
step >>= 1;
|
step = step >> 1;
|
||||||
}
|
}
|
||||||
return (key & (step - 1)) + step;
|
return (key & (step - 1)) + step;
|
||||||
}
|
}
|
||||||
function replicateValue(table: Int32Array, offset: number, step: number, end: number, item: number): void {
|
function replicateValue(table: Int32Array, offset: number, step: number, end: number, item: number): void {
|
||||||
|
let pos: number = end;
|
||||||
do {
|
do {
|
||||||
end -= step;
|
pos -= step;
|
||||||
table[offset + end] = item;
|
table[offset + pos] = item;
|
||||||
} while (end > 0);
|
} while (pos > 0);
|
||||||
}
|
}
|
||||||
function nextTableBitSize(count: Int32Array, len: number, rootBits: number): number {
|
function nextTableBitSize(count: Int32Array, len: number, rootBits: number): number {
|
||||||
let left: number = 1 << (len - rootBits);
|
let bits: number = len;
|
||||||
while (len < 15) {
|
let left: number = 1 << (bits - rootBits);
|
||||||
left -= count[len];
|
while (bits < 15) {
|
||||||
|
left -= count[bits];
|
||||||
if (left <= 0) {
|
if (left <= 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
len++;
|
bits++;
|
||||||
left <<= 1;
|
left = left << 1;
|
||||||
}
|
}
|
||||||
return len - rootBits;
|
return bits - rootBits;
|
||||||
}
|
}
|
||||||
function buildHuffmanTable(tableGroup: Int32Array, tableIdx: number, rootBits: number, codeLengths: Int32Array, codeLengthsSize: number): number {
|
function buildHuffmanTable(tableGroup: Int32Array, tableIdx: number, rootBits: number, codeLengths: Int32Array, codeLengthsSize: number): number {
|
||||||
const tableOffset: number = tableGroup[tableIdx];
|
const tableOffset: number = tableGroup[tableIdx];
|
||||||
let key: number;
|
|
||||||
const sorted = new Int32Array(codeLengthsSize);
|
const sorted = new Int32Array(codeLengthsSize);
|
||||||
const count = new Int32Array(16);
|
const count = new Int32Array(16);
|
||||||
const offset = new Int32Array(16);
|
const offset = new Int32Array(16);
|
||||||
let symbol: number;
|
for (let sym = 0; sym < codeLengthsSize; ++sym) {
|
||||||
for (symbol = 0; symbol < codeLengthsSize; symbol++) {
|
count[codeLengths[sym]]++;
|
||||||
count[codeLengths[symbol]]++;
|
|
||||||
}
|
}
|
||||||
offset[1] = 0;
|
offset[1] = 0;
|
||||||
for (let len = 1; len < 15; len++) {
|
for (let len = 1; len < 15; ++len) {
|
||||||
offset[len + 1] = offset[len] + count[len];
|
offset[len + 1] = offset[len] + count[len];
|
||||||
}
|
}
|
||||||
for (symbol = 0; symbol < codeLengthsSize; symbol++) {
|
for (let sym = 0; sym < codeLengthsSize; ++sym) {
|
||||||
if (codeLengths[symbol] !== 0) {
|
if (codeLengths[sym] !== 0) {
|
||||||
sorted[offset[codeLengths[symbol]]++] = symbol;
|
sorted[offset[codeLengths[sym]]++] = sym;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let tableBits: number = rootBits;
|
let tableBits: number = rootBits;
|
||||||
let tableSize: number = 1 << tableBits;
|
let tableSize: number = 1 << tableBits;
|
||||||
let totalSize: number = tableSize;
|
let totalSize: number = tableSize;
|
||||||
if (offset[15] === 1) {
|
if (offset[15] === 1) {
|
||||||
for (key = 0; key < totalSize; key++) {
|
for (let k = 0; k < totalSize; ++k) {
|
||||||
tableGroup[tableOffset + key] = sorted[0];
|
tableGroup[tableOffset + k] = sorted[0];
|
||||||
}
|
}
|
||||||
return totalSize;
|
return totalSize;
|
||||||
}
|
}
|
||||||
key = 0;
|
let key = 0;
|
||||||
symbol = 0;
|
let symbol = 0;
|
||||||
for (let len = 1, step = 2; len <= rootBits; len++, step <<= 1) {
|
let step = 1;
|
||||||
for (; count[len] > 0; count[len]--) {
|
for (let len = 1; len <= rootBits; ++len) {
|
||||||
|
step = step << 1;
|
||||||
|
while (count[len] > 0) {
|
||||||
replicateValue(tableGroup, tableOffset + key, step, tableSize, len << 16 | sorted[symbol++]);
|
replicateValue(tableGroup, tableOffset + key, step, tableSize, len << 16 | sorted[symbol++]);
|
||||||
key = getNextKey(key, len);
|
key = getNextKey(key, len);
|
||||||
|
count[len]--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const mask: number = totalSize - 1;
|
const mask: number = totalSize - 1;
|
||||||
let low: number = -1;
|
let low: number = -1;
|
||||||
let currentOffset: number = tableOffset;
|
let currentOffset: number = tableOffset;
|
||||||
for (let len: number = rootBits + 1, step = 2; len <= 15; len++, step <<= 1) {
|
step = 1;
|
||||||
for (; count[len] > 0; count[len]--) {
|
for (let len: number = rootBits + 1; len <= 15; ++len) {
|
||||||
|
step = step << 1;
|
||||||
|
while (count[len] > 0) {
|
||||||
if ((key & mask) !== low) {
|
if ((key & mask) !== low) {
|
||||||
currentOffset += tableSize;
|
currentOffset += tableSize;
|
||||||
tableBits = nextTableBitSize(count, len, rootBits);
|
tableBits = nextTableBitSize(count, len, rootBits);
|
||||||
@ -1377,6 +1395,7 @@ function buildHuffmanTable(tableGroup: Int32Array, tableIdx: number, rootBits: n
|
|||||||
}
|
}
|
||||||
replicateValue(tableGroup, currentOffset + (key >> rootBits), step, tableSize, (len - rootBits) << 16 | sorted[symbol++]);
|
replicateValue(tableGroup, currentOffset + (key >> rootBits), step, tableSize, (len - rootBits) << 16 | sorted[symbol++]);
|
||||||
key = getNextKey(key, len);
|
key = getNextKey(key, len);
|
||||||
|
count[len]--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return totalSize;
|
return totalSize;
|
||||||
@ -1419,9 +1438,9 @@ function checkHealth(s: State, endOfStream: number): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
function readFewBits(s: State, n: number): number {
|
function readFewBits(s: State, n: number): number {
|
||||||
const val: number = (s.accumulator32 >>> s.bitOffset) & ((1 << n) - 1);
|
const v: number = (s.accumulator32 >>> s.bitOffset) & ((1 << n) - 1);
|
||||||
s.bitOffset += n;
|
s.bitOffset += n;
|
||||||
return val;
|
return v;
|
||||||
}
|
}
|
||||||
function readManyBits(s: State, n: number): number {
|
function readManyBits(s: State, n: number): number {
|
||||||
const low: number = readFewBits(s, 16);
|
const low: number = readFewBits(s, 16);
|
||||||
@ -1470,27 +1489,29 @@ function halfAvailable(s: State): number {
|
|||||||
return limit - s.halfOffset;
|
return limit - s.halfOffset;
|
||||||
}
|
}
|
||||||
function copyRawBytes(s: State, data: Int8Array, offset: number, length: number): void {
|
function copyRawBytes(s: State, data: Int8Array, offset: number, length: number): void {
|
||||||
|
let pos: number = offset;
|
||||||
|
let len: number = length;
|
||||||
if ((s.bitOffset & 7) !== 0) {
|
if ((s.bitOffset & 7) !== 0) {
|
||||||
throw new Error("Unaligned copyBytes");
|
throw new Error("Unaligned copyBytes");
|
||||||
}
|
}
|
||||||
while ((s.bitOffset !== 32) && (length !== 0)) {
|
while ((s.bitOffset !== 32) && (len !== 0)) {
|
||||||
data[offset++] = (s.accumulator32 >>> s.bitOffset);
|
data[pos++] = s.accumulator32 >>> s.bitOffset;
|
||||||
s.bitOffset += 8;
|
s.bitOffset += 8;
|
||||||
length--;
|
len--;
|
||||||
}
|
}
|
||||||
if (length === 0) {
|
if (len === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const copyNibbles: number = Math.min(halfAvailable(s), length >> 1);
|
const copyNibbles: number = Math.min(halfAvailable(s), len >> 1);
|
||||||
if (copyNibbles > 0) {
|
if (copyNibbles > 0) {
|
||||||
const readOffset: number = s.halfOffset << 1;
|
const readOffset: number = s.halfOffset << 1;
|
||||||
const delta: number = copyNibbles << 1;
|
const delta: number = copyNibbles << 1;
|
||||||
data.set(s.byteBuffer.subarray(readOffset, readOffset + delta), offset);
|
data.set(s.byteBuffer.subarray(readOffset, readOffset + delta), pos);
|
||||||
offset += delta;
|
pos += delta;
|
||||||
length -= delta;
|
len -= delta;
|
||||||
s.halfOffset += copyNibbles;
|
s.halfOffset += copyNibbles;
|
||||||
}
|
}
|
||||||
if (length === 0) {
|
if (len === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (halfAvailable(s) > 0) {
|
if (halfAvailable(s) > 0) {
|
||||||
@ -1498,21 +1519,21 @@ function copyRawBytes(s: State, data: Int8Array, offset: number, length: number)
|
|||||||
s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
|
s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
|
||||||
s.bitOffset -= 16;
|
s.bitOffset -= 16;
|
||||||
}
|
}
|
||||||
while (length !== 0) {
|
while (len !== 0) {
|
||||||
data[offset++] = (s.accumulator32 >>> s.bitOffset);
|
data[pos++] = s.accumulator32 >>> s.bitOffset;
|
||||||
s.bitOffset += 8;
|
s.bitOffset += 8;
|
||||||
length--;
|
len--;
|
||||||
}
|
}
|
||||||
checkHealth(s, 0);
|
checkHealth(s, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (length > 0) {
|
while (len > 0) {
|
||||||
const len: number = readInput(s, data, offset, length);
|
const chunkLen: number = readInput(s, data, pos, len);
|
||||||
if (len === -1) {
|
if (chunkLen === -1) {
|
||||||
throw new Error("Unexpected end of input");
|
throw new Error("Unexpected end of input");
|
||||||
}
|
}
|
||||||
offset += len;
|
pos += chunkLen;
|
||||||
length -= len;
|
len -= chunkLen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function bytesToNibbles(s: State, byteLen: number): void {
|
function bytesToNibbles(s: State, byteLen: number): void {
|
||||||
@ -1520,7 +1541,7 @@ function bytesToNibbles(s: State, byteLen: number): void {
|
|||||||
const halfLen: number = byteLen >> 1;
|
const halfLen: number = byteLen >> 1;
|
||||||
const shortBuffer: Int16Array = s.shortBuffer;
|
const shortBuffer: Int16Array = s.shortBuffer;
|
||||||
for (let i = 0; i < halfLen; ++i) {
|
for (let i = 0; i < halfLen; ++i) {
|
||||||
shortBuffer[i] = ((byteBuffer[i * 2] & 0xFF) | ((byteBuffer[(i * 2) + 1] & 0xFF) << 8));
|
shortBuffer[i] = (byteBuffer[i * 2] & 0xFF) | ((byteBuffer[(i * 2) + 1] & 0xFF) << 8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1632,7 +1653,7 @@ class State {
|
|||||||
cdChunkOffsets = new Int32Array(0);
|
cdChunkOffsets = new Int32Array(0);
|
||||||
cdBlockBits = 0;
|
cdBlockBits = 0;
|
||||||
cdBlockMap = new Int8Array(0);
|
cdBlockMap = new Int8Array(0);
|
||||||
input: InputStream|null = null;
|
input = new InputStream(new Int8Array(0));
|
||||||
constructor () {
|
constructor () {
|
||||||
this.ringBuffer = new Int8Array(0);
|
this.ringBuffer = new Int8Array(0);
|
||||||
this.rings = new Int32Array(10);
|
this.rings = new Int32Array(10);
|
||||||
@ -1688,16 +1709,16 @@ function unpackDictionaryData(dictionary: ByteBuffer, data0: string, data1: stri
|
|||||||
throw new Error("Corrupted brotli dictionary");
|
throw new Error("Corrupted brotli dictionary");
|
||||||
}
|
}
|
||||||
let offset = 0;
|
let offset = 0;
|
||||||
const n: number = skipFlip.length;
|
const n: number = skipFlip.length >> 1;
|
||||||
for (let i = 0; i < n; i += 2) {
|
for (let i = 0; i < n; ++i) {
|
||||||
const skip: number = skipFlip.charCodeAt(i) - 36;
|
const skip: number = skipFlip.charCodeAt(2 * i) - 36;
|
||||||
const flip: number = skipFlip.charCodeAt(i + 1) - 36;
|
const flip: number = skipFlip.charCodeAt(2 * i + 1) - 36;
|
||||||
for (let j = 0; j < skip; ++j) {
|
for (let j = 0; j < skip; ++j) {
|
||||||
dict[offset] ^= 3;
|
dict[offset] = dict[offset] ^ 3;
|
||||||
offset++;
|
offset++;
|
||||||
}
|
}
|
||||||
for (let j = 0; j < flip; ++j) {
|
for (let j = 0; j < flip; ++j) {
|
||||||
dict[offset] ^= 236;
|
dict[offset] = dict[offset] ^ 236;
|
||||||
offset++;
|
offset++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user