#include "All.h" #include "UnBitArrayBase.h" #include "APEInfo.h" #include "UnBitArray.h" #ifdef BACKWARDS_COMPATIBILITY #include "Old/APEDecompressOld.h" #include "Old/UnBitArrayOld.h" #endif const unsigned __int32 POWERS_OF_TWO_MINUS_ONE[33] = {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,4294967295LU}; CUnBitArrayBase * CreateUnBitArray(IAPEDecompress *pAPEDecompress, int nVersion) { #ifdef BACKWARDS_COMPATIBILITY if (nVersion >= 3900) return (CUnBitArrayBase * ) new CUnBitArray(pAPEDecompress, nVersion); else return (CUnBitArrayBase * ) new CUnBitArrayOld(pAPEDecompress, nVersion); #else return (CUnBitArrayBase * ) new CUnBitArray(pAPEDecompress, nVersion); #endif } void CUnBitArrayBase::AdvanceToByteBoundary() { #if 0 m_nCurrentBitIndex--; m_nCurrentBitIndex |= 7; m_nCurrentBitIndex++; #else int nMod = m_nCurrentBitIndex % 8; if (nMod != 0) { m_nCurrentBitIndex += 8 - nMod; } #endif } unsigned __int32 CUnBitArrayBase::DecodeValueXBits(unsigned __int32 nBits) { //get more data if necessary if ((m_nCurrentBitIndex + nBits) >= m_nBits) FillBitArray(); //variable declares unsigned __int32 nLeftBits = 32 - (m_nCurrentBitIndex & 31); unsigned __int32 nBitArrayIndex = m_nCurrentBitIndex >> 5; m_nCurrentBitIndex += nBits; //if their isn't an overflow to the right value, get the value and exit if (nLeftBits >= nBits) return (m_pBitArray[nBitArrayIndex] & (POWERS_OF_TWO_MINUS_ONE[nLeftBits])) >> (nLeftBits - nBits); //must get the "split" value from left and right int nRightBits = nBits - nLeftBits; unsigned __int32 nLeftValue = ((m_pBitArray[nBitArrayIndex] & POWERS_OF_TWO_MINUS_ONE[nLeftBits]) << nRightBits); unsigned __int32 nRightValue = (m_pBitArray[nBitArrayIndex + 1] >> (32 - nRightBits)); return (nLeftValue | nRightValue); } int CUnBitArrayBase::FillAndResetBitArray(int nFileLocation, int nNewBitIndex) { //reset the bit index m_nCurrentBitIndex = nNewBitIndex; //seek if necessary if (nFileLocation != -1) { if (GET_IO(m_pAPEDecompress)->Seek(nFileLocation, FILE_BEGIN) != 0) return ERROR_IO_READ; } //read the new data into the bit array unsigned int nBytesRead = 0; if (GET_IO(m_pAPEDecompress)->Read(((unsigned char *) m_pBitArray), m_nBytes, &nBytesRead) != 0) return ERROR_IO_READ; return 0; } int CUnBitArrayBase::FillBitArray() { //get the bit array index unsigned __int32 nBitArrayIndex = m_nCurrentBitIndex >> 5; //move the remaining data to the front memmove((void *) (m_pBitArray), (const void *) (m_pBitArray + nBitArrayIndex), m_nBytes - (nBitArrayIndex * 4)); //read the new data int nBytesToRead = nBitArrayIndex * 4; unsigned int nBytesRead = 0; int nRetVal = GET_IO(m_pAPEDecompress)->Read((unsigned char *) (m_pBitArray + m_nElements - nBitArrayIndex), nBytesToRead, &nBytesRead); //adjust the m_Bit pointer m_nCurrentBitIndex = m_nCurrentBitIndex & 31; //return return (nRetVal == 0) ? 0 : ERROR_IO_READ; } int CUnBitArrayBase::CreateHelper(IAPEDecompress *pAPEDecompress, int nBytes, int nVersion) { //check the parameters if ((pAPEDecompress == NULL) || (nBytes <= 0)) { return ERROR_BAD_PARAMETER; } //save the size m_nElements = nBytes / 4; m_nBytes = m_nElements * 4; m_nBits = m_nBytes * 8; //set the variables m_pAPEDecompress = pAPEDecompress; m_nVersion = nVersion; m_nCurrentBitIndex = 0; //create the bitarray m_pBitArray = new unsigned __int32 [m_nElements]; return (m_pBitArray != NULL) ? 0 : ERROR_INSUFFICIENT_MEMORY; }