xref: /haiku/src/add-ons/media/plugins/ape_reader/MAClib/UnBitArrayBase.cpp (revision 3be9edf8da228afd9fec0390f408c964766122aa)
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