/*
* 21.04.2004 Original verion. davagin@udm.ru.
*-----------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*----------------------------------------------------------------------
*/
package davaguine.jmac.decoder;
import davaguine.jmac.tools.ByteArrayReader;
import davaguine.jmac.tools.File;
import davaguine.jmac.tools.JMACException;
import java.io.IOException;
/**
* Author: Dmitry Vaguine
* Date: 04.03.2004
* Time: 14:51:31
*/
public class UnBitArrayBase {
private final static long POWERS_OF_TWO_MINUS_ONE[] = {0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535, 131071, 262143, 524287, 1048575, 2097151, 4194303, 8388607, 16777215, 33554431, 67108863, 134217727, 268435455, 536870911, 1073741823, 2147483647, 4294967295L};
//construction/destruction
public UnBitArrayBase() {
}
//functions
public void FillBitArray() throws IOException {
//get the bit array index
long nBitArrayIndex = m_nCurrentBitIndex >> 5;
long al[];
int j;
//move the remaining data to the front
System.arraycopy(al = m_pBitArray, j = (int) nBitArrayIndex, al, 0, (int) (al.length - nBitArrayIndex));
//read the new data
ByteArrayReader reader = m_pReader;
reader.reset(m_pIO, j << 2);
long l1;
int i = (int) ((l1 = m_nElements) - nBitArrayIndex);
if ((long) i < l1)
do {
al[i] = reader.readUnsignedInt();
i++;
} while ((long) i < l1);
//adjust the m_Bit pointer
m_nCurrentBitIndex &= 31;
}
public void FillAndResetBitArray() throws IOException {
FillAndResetBitArray(-1, 0);
}
public void FillAndResetBitArray(int nFileLocation) throws IOException {
FillAndResetBitArray(nFileLocation, 0);
}
public void FillAndResetBitArray(int nFileLocation, int nNewBitIndex) throws IOException {
//reset the bit index
m_nCurrentBitIndex = nNewBitIndex;
//seek if necessary
if (nFileLocation != -1)
m_pIO.seek(nFileLocation);
//read the new data into the bit array
ByteArrayReader reader = m_pReader;
reader.reset(m_pIO, (int) m_nBytes);
long al[] = m_pBitArray;
long l = m_nElements;
for (int i = 0; i < l; i++)
al[i] = reader.readUnsignedInt();
}
public void GenerateArray(int[] pOutputArray, int nElements) throws IOException {
GenerateArray(pOutputArray, nElements, -1);
}
public void GenerateArray(int[] pOutputArray, int nElements, int nBytesRequired) throws IOException {
}
public long DecodeValue(int DecodeMethod) throws IOException {
return DecodeValue(DecodeMethod, 0, 0);
}
public long DecodeValue(int DecodeMethod, int nParam1) throws IOException {
return DecodeValue(DecodeMethod, nParam1, 0);
}
public long DecodeValue(int DecodeMethod, int nParam1, int nParam2) throws IOException {
return 0;
}
public void AdvanceToByteBoundary() {
long nMod = m_nCurrentBitIndex % 8L;
if (nMod != 0)
m_nCurrentBitIndex += 8L - nMod;
}
public int DecodeValueRange(UnBitArrayState BitArrayState) throws IOException {
return 0;
}
public void FlushState(UnBitArrayState BitArrayState) {
}
public void FlushBitArray() {
}
public void Finalize() {
}
protected void CreateHelper(File pIO, int nBytes, int nVersion) {
//check the parameters
if ((pIO == null) || (nBytes <= 0))
throw new JMACException("Bad Parameter");
//save the size
m_nElements = nBytes / 4;
m_nBytes = m_nElements * 4;
m_nBits = m_nBytes * 8;
//set the variables
m_pIO = pIO;
m_nVersion = nVersion;
m_nCurrentBitIndex = 0;
//create the bitarray
m_pBitArray = new long[(int) m_nElements];
m_pReader = new ByteArrayReader((int) m_nBytes);
}
protected long DecodeValueXBits(long nBits) throws IOException {
//get more data if necessary
long nBitArrayIndex;
if (((nBitArrayIndex = m_nCurrentBitIndex) + nBits) >= m_nBits)
FillBitArray();
//variable declares
long nLeftBits = 32 - (nBitArrayIndex & 31);
nBitArrayIndex >>= 5;
m_nCurrentBitIndex += nBits;
//if their isn't an overflow to the right value, get the value and exit
if (nLeftBits >= nBits)
return ((long) (m_pBitArray[(int) nBitArrayIndex] & (POWERS_OF_TWO_MINUS_ONE[(int) nLeftBits]))) >> (nLeftBits - nBits);
//must get the "split" value from left and right
long nRightBits = nBits - nLeftBits;
long nLeftValue = ((long) (m_pBitArray[(int) nBitArrayIndex] & POWERS_OF_TWO_MINUS_ONE[(int) nLeftBits])) << nRightBits;
long nRightValue = (m_pBitArray[(int) nBitArrayIndex + 1] >> (32 - nRightBits));
return (nLeftValue | nRightValue);
}
public static UnBitArrayBase CreateUnBitArray(IAPEDecompress pAPEDecompress, int nVersion) {
if (nVersion >= 3900)
return (UnBitArrayBase) new UnBitArray(pAPEDecompress.getApeInfoIoSource(), nVersion);
else
return (UnBitArrayBase) new UnBitArrayOld(pAPEDecompress, nVersion);
}
protected long m_nElements;
protected long m_nBytes;
protected long m_nBits;
protected int m_nVersion;
protected File m_pIO;
protected long m_nCurrentBitIndex;
protected long[] m_pBitArray;
protected ByteArrayReader m_pReader;
}