ByteArray input = new ByteArray(inputLen); input.put(compressed); input.put(COMPRESSION_TERMINATOR); mIncomingSlidingWindow = new ByteArray(mIncomingSlidingWindowBufferSize); int outPos = mIncomingSlidingWindow.length(); byte[] output = mIncomingSlidingWindow.toBytes(outPos); mIncomingSlidingWindow.shrink(mIncomingSlidingWindowBufferSize); mIncomingSlidingWindow.clear();
/** * Add a byte at the current position. */ public void put(int data) { // If the buffer is small. if (mBuffer.capacity() < (mLength + 1)) { expandBuffer(mLength + ADDITIONAL_BUFFER_SIZE); } mBuffer.put((byte)data); ++mLength; }
private static void inflatePlainBlock(ByteArray input, int[] bitIndex, ByteArray output) { // 3.2.4 Non-compressed blocks (BTYPE=00) // Skip any remaining bits in current partially processed byte. int bi = (bitIndex[0] + 7) & ~7; // Data copy is performed on a byte basis, so convert the bit index // to a byte index. int index = bi / 8; // LEN: 2 bytes. The data length. int len = (input.get(index) & 0xFF) + (input.get(index + 1) & 0xFF) * 256; // NLEN: 2 bytes. The one's complement of LEN. // Skip LEN and NLEN. index += 4; // Copy the data to the output. output.put(input, index, len); // Make the bitIndex point to the bit next to // the end of the copied data. bitIndex[0] = (index + len) * 8; }
public boolean readBit(int[] bitIndex) { boolean result = getBit(bitIndex[0]); ++bitIndex[0]; return result; }
public boolean getBit(int bitIndex) { int index = bitIndex / 8; int shift = bitIndex % 8; int value = get(index); // Return true if the bit pointed to by bitIndex is set. return ((value & (1 << shift)) != 0); }
private static void appendEmptyBlock(ByteArray data, int[] bitIndex) { int shift = bitIndex[0] % 8; // ? = used (0 or 1), x = unused (= 0). // // | Current | After 3 bits are appended // ----------+----------+--------------------------- // shift = 1 | xxxxxxx? | xxxx000? // shift = 2 | xxxxxx?? | xxx000?? // shift = 3 | xxxxx??? | xx000??? // shift = 4 | xxxx???? | x000???? // shift = 5 | xxx????? | 000????? // shift = 6 | xx?????? | 00?????? xxxxxxx0 // shift = 7 | x??????? | 0??????? xxxxxx00 // shift = 0 | ???????? | ???????? xxxxx000 switch (shift) { case 6: case 7: case 0: data.put(0); } // Update the bit index for the 3 bits. bitIndex[0] += 3; }
public int readBits(int[] bitIndex, int nBits) { int number = getBits(bitIndex[0], nBits); bitIndex[0] += nBits; return number; }
int codeVal = data.getHuffmanBits(bitIndex[0], codeLen);
private static void inflatePlainBlock(ByteArray input, int[] bitIndex, ByteArray output) { // 3.2.4 Non-compressed blocks (BTYPE=00) // Skip any remaining bits in current partially processed byte. int bi = (bitIndex[0] + 7) & ~7; // Data copy is performed on a byte basis, so convert the bit index // to a byte index. int index = bi / 8; // LEN: 2 bytes. The data length. int len = (input.get(index) & 0xFF) + (input.get(index + 1) & 0xFF) * 256; // NLEN: 2 bytes. The one's complement of LEN. // Skip LEN and NLEN. index += 4; // Copy the data to the output. output.put(input, index, len); // Make the bitIndex point to the bit next to // the end of the copied data. bitIndex[0] = (index + len) * 8; }
public int getBits(int bitIndex, int nBits) { int number = 0; int weight = 1; // Convert consecutive bits into a number. for (int i = 0; i < nBits; ++i, weight *= 2) { // getBit() returns true if the bit is set. if (getBit(bitIndex + i)) { number += weight; } } return number; }
private static int skipPlainBlock(ByteArray input, int[] bitIndex) { // 3.2.4 Non-compressed blocks (BTYPE=00) // Skip any remaining bits in current partially processed byte. int bi = (bitIndex[0] + 7) & ~7; // Data copy is performed on a byte basis, so convert the bit index // to a byte index. int index = bi / 8; // LEN: 2 bytes. The data length. int len = (input.get(index) & 0xFF) + (input.get(index + 1) & 0xFF) * 256; // NLEN: 2 bytes. The one's complement of LEN. // Skip LEN and NLEN. index += 4; // Make the bitIndex point to the bit next to // the end of the copied data. bitIndex[0] = (index + len) * 8; return len; }