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