1 #include "All.h" 2 #include "UnBitArrayBase.h" 3 #include "APEInfo.h" 4 #include "UnBitArray.h" 5 6 #undef BACKWARDS_COMPATIBILITY 7 8 #ifdef BACKWARDS_COMPATIBILITY 9 #include "Old/APEDecompressOld.h" 10 #include "Old/UnBitArrayOld.h" 11 #endif 12 13 const uint32 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,4294967295}; 14 15 CUnBitArrayBase * CreateUnBitArray(IAPEDecompress * pAPEDecompress, int nVersion) 16 { 17 #ifdef BACKWARDS_COMPATIBILITY 18 if (nVersion >= 3900) 19 return (CUnBitArrayBase * ) new CUnBitArray(GET_IO(pAPEDecompress), nVersion); 20 else 21 return (CUnBitArrayBase * ) new CUnBitArrayOld(pAPEDecompress, nVersion); 22 #else 23 return (CUnBitArrayBase * ) new CUnBitArray(GET_IO(pAPEDecompress), nVersion); 24 #endif 25 } 26 27 void CUnBitArrayBase::AdvanceToByteBoundary() 28 { 29 int nMod = m_nCurrentBitIndex % 8; 30 if (nMod != 0) { m_nCurrentBitIndex += 8 - nMod; } 31 } 32 33 uint32 CUnBitArrayBase::DecodeValueXBits(uint32 nBits) 34 { 35 // get more data if necessary 36 if ((m_nCurrentBitIndex + nBits) >= m_nBits) 37 FillBitArray(); 38 39 // variable declares 40 uint32 nLeftBits = 32 - (m_nCurrentBitIndex & 31); 41 uint32 nBitArrayIndex = m_nCurrentBitIndex >> 5; 42 m_nCurrentBitIndex += nBits; 43 44 // if their isn't an overflow to the right value, get the value and exit 45 if (nLeftBits >= nBits) 46 return (m_pBitArray[nBitArrayIndex] & (POWERS_OF_TWO_MINUS_ONE[nLeftBits])) >> (nLeftBits - nBits); 47 48 // must get the "split" value from left and right 49 int nRightBits = nBits - nLeftBits; 50 51 uint32 nLeftValue = ((m_pBitArray[nBitArrayIndex] & POWERS_OF_TWO_MINUS_ONE[nLeftBits]) << nRightBits); 52 uint32 nRightValue = (m_pBitArray[nBitArrayIndex + 1] >> (32 - nRightBits)); 53 return (nLeftValue | nRightValue); 54 } 55 56 int CUnBitArrayBase::FillAndResetBitArray(int nFileLocation, int nNewBitIndex) 57 { 58 // reset the bit index 59 m_nCurrentBitIndex = nNewBitIndex; 60 61 // seek if necessary 62 if (nFileLocation != -1) 63 { 64 if (m_pIO->Seek(nFileLocation, FILE_BEGIN) != 0) 65 return ERROR_IO_READ; 66 } 67 68 // read the new data into the bit array 69 unsigned int nBytesRead = 0; 70 if (m_pIO->Read(((unsigned char *) m_pBitArray), m_nBytes, &nBytesRead) != 0) 71 return ERROR_IO_READ; 72 73 return 0; 74 } 75 76 int CUnBitArrayBase::FillBitArray() 77 { 78 // get the bit array index 79 uint32 nBitArrayIndex = m_nCurrentBitIndex >> 5; 80 81 // move the remaining data to the front 82 memmove((void *) (m_pBitArray), (const void *) (m_pBitArray + nBitArrayIndex), m_nBytes - (nBitArrayIndex * 4)); 83 84 // read the new data 85 int nBytesToRead = nBitArrayIndex * 4; 86 unsigned int nBytesRead = 0; 87 int nRetVal = m_pIO->Read((unsigned char *) (m_pBitArray + m_nElements - nBitArrayIndex), nBytesToRead, &nBytesRead); 88 89 // adjust the m_Bit pointer 90 m_nCurrentBitIndex = m_nCurrentBitIndex & 31; 91 92 // return 93 return (nRetVal == 0) ? 0 : ERROR_IO_READ; 94 } 95 96 int CUnBitArrayBase::CreateHelper(CIO * pIO, int nBytes, int nVersion) 97 { 98 // check the parameters 99 if ((pIO == NULL) || (nBytes <= 0)) { return ERROR_BAD_PARAMETER; } 100 101 // save the size 102 m_nElements = nBytes / 4; 103 m_nBytes = m_nElements * 4; 104 m_nBits = m_nBytes * 8; 105 106 // set the variables 107 m_pIO = pIO; 108 m_nVersion = nVersion; 109 m_nCurrentBitIndex = 0; 110 111 // create the bitarray 112 m_pBitArray = new uint32 [m_nElements]; 113 114 return (m_pBitArray != NULL) ? 0 : ERROR_INSUFFICIENT_MEMORY; 115 } 116