prepare java decoder for transpilation to Kotlin

PiperOrigin-RevId: 601023149
This commit is contained in:
Evgenii Kliuchnikov 2024-01-23 23:46:34 -08:00 committed by Copybara-Service
parent d5e697b3c7
commit 200f37984a
3 changed files with 47 additions and 37 deletions

View File

@ -351,7 +351,7 @@ final class Decode {
if (sizeBytes == 0) { if (sizeBytes == 0) {
return; return;
} }
for (int i = 0; i < sizeBytes; i++) { for (int i = 0; i < sizeBytes; ++i) {
BitReader.fillBitWindow(s); BitReader.fillBitWindow(s);
final int bits = BitReader.readFewBits(s, 8); final int bits = BitReader.readFewBits(s, 8);
if (bits == 0 && i + 1 == sizeBytes && sizeBytes > 1) { if (bits == 0 && i + 1 == sizeBytes && sizeBytes > 1) {
@ -360,7 +360,7 @@ final class Decode {
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) {
BitReader.fillBitWindow(s); BitReader.fillBitWindow(s);
final int bits = BitReader.readFewBits(s, 4); final int bits = BitReader.readFewBits(s, 4);
if (bits == 0 && i + 1 == sizeNibbles && sizeNibbles > 4) { if (bits == 0 && i + 1 == sizeNibbles && sizeNibbles > 4) {
@ -405,18 +405,19 @@ final class Decode {
private static void moveToFront(int[] v, int index) { private static void moveToFront(int[] v, int index) {
final int value = v[index]; final int value = v[index];
for (; index > 0; index--) { while (index > 0) {
v[index] = v[index - 1]; v[index] = v[index - 1];
index--;
} }
v[0] = value; v[0] = value;
} }
private static void inverseMoveToFrontTransform(byte[] v, int vLen) { private static void inverseMoveToFrontTransform(byte[] v, int vLen) {
final int[] mtf = new int[256]; final int[] mtf = new int[256];
for (int i = 0; i < 256; i++) { for (int i = 0; i < 256; ++i) {
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 = v[i] & 0xFF;
v[i] = (byte) mtf[index]; v[i] = (byte) mtf[index];
if (index != 0) { if (index != 0) {
@ -470,7 +471,7 @@ final class Decode {
if (symbol + repeatDelta > numSymbols) { if (symbol + repeatDelta > numSymbols) {
throw new BrotliRuntimeException("symbol + repeatDelta > numSymbols"); // COV_NF_LINE throw new BrotliRuntimeException("symbol + repeatDelta > numSymbols"); // COV_NF_LINE
} }
for (int i = 0; i < repeatDelta; i++) { for (int i = 0; i < repeatDelta; ++i) {
codeLengths[symbol++] = repeatCodeLen; codeLengths[symbol++] = repeatCodeLen;
} }
if (repeatCodeLen != 0) { if (repeatCodeLen != 0) {
@ -507,7 +508,7 @@ final class Decode {
final int maxBits = 1 + log2floor(alphabetSizeMax - 1); final int maxBits = 1 + log2floor(alphabetSizeMax - 1);
final int numSymbols = BitReader.readFewBits(s, 2) + 1; final int numSymbols = BitReader.readFewBits(s, 2) + 1;
for (int i = 0; i < numSymbols; i++) { for (int i = 0; i < numSymbols; ++i) {
BitReader.fillBitWindow(s); BitReader.fillBitWindow(s);
final int symbol = BitReader.readFewBits(s, maxBits); final int symbol = BitReader.readFewBits(s, maxBits);
if (symbol >= alphabetSizeLimit) { if (symbol >= alphabetSizeLimit) {
@ -569,7 +570,7 @@ final class Decode {
final int[] codeLengthCodeLengths = new int[CODE_LENGTH_CODES]; final int[] codeLengthCodeLengths = new int[CODE_LENGTH_CODES];
int space = 32; int space = 32;
int numCodes = 0; int numCodes = 0;
for (int i = skip; i < CODE_LENGTH_CODES && space > 0; i++) { for (int i = skip; i < CODE_LENGTH_CODES; ++i) {
final int codeLenIdx = CODE_LENGTH_CODE_ORDER[i]; final int codeLenIdx = CODE_LENGTH_CODE_ORDER[i];
BitReader.fillBitWindow(s); BitReader.fillBitWindow(s);
final int p = BitReader.peekBits(s) & 15; final int p = BitReader.peekBits(s) & 15;
@ -580,6 +581,7 @@ final class Decode {
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) {
@ -630,7 +632,8 @@ final class Decode {
final int[] table = new int[tableSize + 1]; final int[] table = new int[tableSize + 1];
final int tableIdx = table.length - 1; final int tableIdx = table.length - 1;
readHuffmanCode(alphabetSize, alphabetSize, table, tableIdx, s); readHuffmanCode(alphabetSize, alphabetSize, table, tableIdx, s);
for (int i = 0; i < contextMapSize; ) { int i = 0;
while (i < contextMapSize) {
BitReader.readMoreInput(s); BitReader.readMoreInput(s);
BitReader.fillBitWindow(s); BitReader.fillBitWindow(s);
final int code = readSymbol(table, tableIdx, s); final int code = readSymbol(table, tableIdx, s);
@ -829,22 +832,24 @@ final class Decode {
s.numDirectDistanceCodes = BitReader.readFewBits(s, 4) << s.distancePostfixBits; s.numDirectDistanceCodes = BitReader.readFewBits(s, 4) << s.distancePostfixBits;
// TODO(eustas): Reuse? // TODO(eustas): Reuse?
s.contextModes = new byte[s.numLiteralBlockTypes]; s.contextModes = new byte[s.numLiteralBlockTypes];
for (int i = 0; i < s.numLiteralBlockTypes;) { int i = 0;
while (i < s.numLiteralBlockTypes) {
/* Ensure that less than 256 bits read between readMoreInput. */ /* Ensure that less than 256 bits read between readMoreInput. */
final int limit = Math.min(i + 96, s.numLiteralBlockTypes); final int limit = Math.min(i + 96, s.numLiteralBlockTypes);
for (; i < limit; ++i) { while (i < limit) {
BitReader.fillBitWindow(s); BitReader.fillBitWindow(s);
s.contextModes[i] = (byte) BitReader.readFewBits(s, 2); s.contextModes[i] = (byte) BitReader.readFewBits(s, 2);
i++;
} }
BitReader.readMoreInput(s); BitReader.readMoreInput(s);
} }
// TODO(eustas): Reuse? // TODO(eustas): Reuse?
s.contextMap = new byte[s.numLiteralBlockTypes << LITERAL_CONTEXT_BITS]; final int contextMapLength = s.numLiteralBlockTypes << LITERAL_CONTEXT_BITS;
final int numLiteralTrees = decodeContextMap(s.numLiteralBlockTypes << LITERAL_CONTEXT_BITS, s.contextMap = new byte[contextMapLength];
s.contextMap, s); final int numLiteralTrees = decodeContextMap(contextMapLength, s.contextMap, s);
s.trivialLiteralContext = 1; s.trivialLiteralContext = 1;
for (int j = 0; j < s.numLiteralBlockTypes << LITERAL_CONTEXT_BITS; j++) { for (int j = 0; j < contextMapLength; ++j) {
if (s.contextMap[j] != j >> LITERAL_CONTEXT_BITS) { if (s.contextMap[j] != j >> LITERAL_CONTEXT_BITS) {
s.trivialLiteralContext = 0; s.trivialLiteralContext = 0;
break; break;
@ -1253,7 +1258,8 @@ final class Decode {
final int dstEnd = dst + copyLength; final int 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 (int k = 0; k < copyLength; k += 4) { final int numQuads = (copyLength + 3) >> 2;
for (int 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++];
@ -1266,7 +1272,7 @@ final class Decode {
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] =
ringBuffer[(s.pos - s.distance) & ringBufferMask]; ringBuffer[(s.pos - s.distance) & ringBufferMask];
s.metaBlockLength--; s.metaBlockLength--;

View File

@ -43,10 +43,10 @@ final class DictionaryData {
// Toggle high bit using run-length delta encoded "skipFlip". // Toggle high bit using run-length delta encoded "skipFlip".
int offset = 0; int offset = 0;
final int n = skipFlip.length(); final int n = skipFlip.length() >> 1;
for (int i = 0; i < n; i += 2) { for (int i = 0; i < n; ++i) {
final int skip = skipFlip.charAt(i) - 36; final int skip = skipFlip.charAt(2 * i) - 36;
final int flip = skipFlip.charAt(i + 1) - 36; final int flip = 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] ^= 3;
offset++; offset++;

View File

@ -64,28 +64,26 @@ final class Huffman {
static int buildHuffmanTable(int[] tableGroup, int tableIdx, int rootBits, int[] codeLengths, static int buildHuffmanTable(int[] tableGroup, int tableIdx, int rootBits, int[] codeLengths,
int codeLengthsSize) { int codeLengthsSize) {
final int tableOffset = tableGroup[tableIdx]; final int tableOffset = tableGroup[tableIdx];
int key; // Reversed prefix code.
final int[] sorted = new int[codeLengthsSize]; // Symbols sorted by code length. final int[] sorted = new int[codeLengthsSize]; // Symbols sorted by code length.
// TODO(eustas): fill with zeroes? // TODO(eustas): fill with zeroes?
final int[] count = new int[MAX_LENGTH + 1]; // Number of codes of each length. final int[] count = new int[MAX_LENGTH + 1]; // Number of codes of each length.
final int[] offset = new int[MAX_LENGTH + 1]; // Offsets in sorted table for each length. final int[] offset = new int[MAX_LENGTH + 1]; // Offsets in sorted table for each length.
int symbol;
// Build histogram of code lengths. // Build histogram of code lengths.
for (symbol = 0; symbol < codeLengthsSize; symbol++) { for (int sym = 0; sym < codeLengthsSize; ++sym) {
count[codeLengths[symbol]]++; count[codeLengths[sym]]++;
} }
// Generate offsets into sorted symbol table by code length. // Generate offsets into sorted symbol table by code length.
offset[1] = 0; offset[1] = 0;
for (int len = 1; len < MAX_LENGTH; len++) { for (int len = 1; len < MAX_LENGTH; ++len) {
offset[len + 1] = offset[len] + count[len]; offset[len + 1] = offset[len] + count[len];
} }
// Sort symbols by length, by symbol order within each length. // Sort symbols by length, by symbol order within each length.
for (symbol = 0; symbol < codeLengthsSize; symbol++) { for (int sym = 0; sym < codeLengthsSize; ++sym) {
if (codeLengths[symbol] != 0) { if (codeLengths[sym] != 0) {
sorted[offset[codeLengths[symbol]]++] = symbol; sorted[offset[codeLengths[sym]]++] = sym;
} }
} }
@ -95,20 +93,23 @@ final class Huffman {
// Special case code with only one value. // Special case code with only one value.
if (offset[MAX_LENGTH] == 1) { if (offset[MAX_LENGTH] == 1) {
for (key = 0; key < totalSize; key++) { for (int k = 0; k < totalSize; ++k) {
tableGroup[tableOffset + key] = sorted[0]; tableGroup[tableOffset + k] = sorted[0];
} }
return totalSize; return totalSize;
} }
// Fill in root table. // Fill in root table.
key = 0; int key = 0; // Reversed prefix code.
symbol = 0; int symbol = 0;
for (int len = 1, step = 2; len <= rootBits; len++, step <<= 1) { int step = 1;
for (; count[len] > 0; count[len]--) { for (int len = 1; len <= rootBits; ++len) {
step <<= 1;
while (count[len] > 0) {
replicateValue(tableGroup, tableOffset + key, step, tableSize, replicateValue(tableGroup, tableOffset + key, step, tableSize,
len << 16 | sorted[symbol++]); len << 16 | sorted[symbol++]);
key = getNextKey(key, len); key = getNextKey(key, len);
count[len]--;
} }
} }
@ -116,8 +117,10 @@ final class Huffman {
final int mask = totalSize - 1; final int mask = totalSize - 1;
int low = -1; int low = -1;
int currentOffset = tableOffset; int currentOffset = tableOffset;
for (int len = rootBits + 1, step = 2; len <= MAX_LENGTH; len++, step <<= 1) { step = 1;
for (; count[len] > 0; count[len]--) { for (int len = rootBits + 1; len <= MAX_LENGTH; ++len) {
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);
@ -130,6 +133,7 @@ final class Huffman {
replicateValue(tableGroup, currentOffset + (key >> rootBits), step, tableSize, replicateValue(tableGroup, currentOffset + (key >> rootBits), step, tableSize,
(len - rootBits) << 16 | sorted[symbol++]); (len - rootBits) << 16 | sorted[symbol++]);
key = getNextKey(key, len); key = getNextKey(key, len);
count[len]--;
} }
} }
return totalSize; return totalSize;