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