00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef _SUPPORT_BITSTREAM_READER_H_
00014 #define _SUPPORT_BITSTREAM_READER_H_
00015
00016 #include <support/Buffer.h>
00017 #include <support/ByteOrder.h>
00018 #include <support/StdIO.h>
00019 #include <assert.h>
00020
00021 #if _SUPPORTS_NAMESPACE
00022 namespace palmos {
00023 namespace support {
00024 #endif
00025
00026 #if BYTE_ORDER == LITTLE_ENDIAN
00027 #define SWAP_INT32(uarg) \
00028 { \
00029 uint32_t swapped = uarg ^ ((uarg<<16)|(uarg>>16)); \
00030 swapped &= 0xFF00FFFF; \
00031 uarg = (uarg>>8)|(uarg<<24); \
00032 uarg = (swapped >> 8) ^ uarg; \
00033 }
00034 #else
00035 #define SWAP_INT32(uarg)
00036 #endif
00037
00038
00039 class SBitstreamReader
00040 {
00041 public:
00042 SBitstreamReader();
00043 SBitstreamReader(const SBuffer& sourceBuffer);
00044 SBitstreamReader(const void * data, size_t size);
00045 ~SBitstreamReader();
00046
00047 inline status_t SetSource(const SBuffer& sourceBuffer);
00048 inline status_t SetSource(const void * data, size_t size);
00049
00050 inline bool IsInRange() const;
00051
00052 inline uint32_t PeekBits(size_t bits) const;
00053 inline uint32_t GetBits(size_t bits);
00054
00055 inline void SkipBit();
00056 inline void SkipByte();
00057 inline void SkipBits(size_t bits);
00058 inline void SkipToByteBoundary();
00059
00060 inline void RewindBits(size_t bits);
00061
00062 inline bool Find(uint32_t pattern, size_t bits);
00063 inline bool FindByteAligned(uint32_t pattern, size_t bits);
00064 inline bool FindReverse(uint32_t pattern, size_t bits);
00065 inline bool FindByteAlignedReverse(uint32_t pattern, size_t bits);
00066
00067 inline size_t BytePosition() const;
00068 inline size_t BitPosition() const;
00069
00070
00071
00072
00073 inline size_t BitsAvailable() const
00074 {
00075 if (m_cacheOffset > m_cacheSize) return 0;
00076 return m_cacheSize - m_cacheOffset;
00077 }
00078
00079 inline size_t BytesAvailable() const;
00080
00081 inline status_t SetBytePosition(size_t pos);
00082 inline status_t SetBitPosition(size_t pos);
00083
00084 inline size_t ByteLength() const;
00085
00086 private:
00087 struct SFragment
00088 {
00089 const uint8_t * data;
00090 size_t size;
00091 size_t offset;
00092 };
00093
00094 uint32_t m_cache[2];
00095 size_t m_cacheOffset;
00096 const uint8_t * m_fragmentPointer;
00097 size_t m_fragmentRemaining;
00098
00099 size_t m_cacheSize;
00100
00101 SFragment * m_fragments;
00102 size_t m_fragmentCount;
00103 size_t m_fragmentIndex;
00104
00105 inline size_t fill_forward(size_t fillOffset)
00106 {
00107 assert (fillOffset == 0 || fillOffset == 4);
00108 size_t n;
00109
00110 m_cache[fillOffset >> 2] = 0;
00111 uint8_t * cacheByte = (uint8_t*)m_cache + fillOffset;
00112 size_t toCache = 4;
00113
00114 assert (m_fragmentPointer >= m_fragments[m_fragmentIndex].data);
00115
00116
00117 while (true)
00118 {
00119 while (m_fragmentRemaining == 0)
00120 {
00121 if (m_fragmentIndex + 1 < m_fragmentCount)
00122 {
00123 m_fragmentIndex++;
00124 m_fragmentPointer = m_fragments[m_fragmentIndex].data;
00125 m_fragmentRemaining = m_fragments[m_fragmentIndex].size;
00126 }
00127 else
00128 {
00129 toCache = 0;
00130 break;
00131 }
00132 }
00133
00134 if (m_fragmentRemaining >= toCache) break;
00135
00136 *cacheByte = *m_fragmentPointer;
00137 m_fragmentPointer++;
00138 cacheByte++;
00139 toCache--;
00140 m_fragmentRemaining--;
00141 }
00142
00143 size_t shift = 0;
00144 while (toCache > 0)
00145 {
00146 assert (m_fragmentPointer >= m_fragments[m_fragmentIndex].data);
00147 assert (m_fragmentRemaining >= toCache);
00148
00149
00150
00151
00152 size_t align = 4 - (uint32_t(m_fragmentPointer) & 0x3);
00153
00154 if (align == 4 && toCache == 4)
00155 {
00156
00157 m_cache[fillOffset >> 2] = *(uint32_t*)m_fragmentPointer;
00158 m_fragmentPointer += 4;
00159 m_fragmentRemaining -= toCache;
00160 cacheByte += 4;
00161 break;
00162 }
00163 else
00164 {
00165 size_t toRead;
00166 if (align != 4 && align < toCache)
00167 {
00168 toRead = align;
00169
00170
00171
00172
00173
00174 shift = toCache - align;
00175 if (shift > 4) shift -= 4;
00176
00177 toCache -= shift;
00178
00179 shift <<= 3;
00180
00181 m_cacheOffset += shift;
00182 }
00183 else
00184 {
00185 toRead = toCache;
00186 }
00187
00188 for (n = 0; n < toRead; n++)
00189 {
00190 *cacheByte = *m_fragmentPointer;
00191 m_fragmentPointer++;
00192 m_fragmentRemaining--;
00193 cacheByte++;
00194 }
00195 toCache -= toRead;
00196 }
00197 }
00198
00199 if (fillOffset == 0)
00200 {
00201 SWAP_INT32(m_cache[0]);
00202 }
00203 SWAP_INT32(m_cache[1]);
00204
00205 if (shift > 0)
00206 {
00207 uint32_t v = m_cache[0];
00208 m_cache[0] >>= shift;
00209 m_cache[1] >>= shift;
00210 m_cache[1] |= (v << (32-shift));
00211 cacheByte += (shift >> 3);
00212 }
00213
00214 size_t writeOffset = (cacheByte - (uint8_t*)m_cache);
00215 return (writeOffset - fillOffset) << 3;
00216 }
00217
00218 inline void fill_reverse()
00219 {
00220
00221 size_t cachedBytes = (m_cacheSize >> 3);
00222
00223 m_cache[0] = 0;
00224 uint8_t * cacheByte = ((uint8_t*)&m_cache[0]) + 3;
00225 size_t toRead = 4;
00226
00227
00228 const uint8_t * fptr = m_fragmentPointer;
00229 size_t findex = m_fragmentIndex;
00230 int32_t toRewind = cachedBytes;
00231 int32_t dataLeft = m_fragmentPointer - m_fragments[m_fragmentIndex].data;
00232 while (toRewind > 0)
00233 {
00234 if (toRewind >= dataLeft)
00235 {
00236 toRewind -= dataLeft;
00237 assert (findex > 0);
00238 --findex;
00239 dataLeft = m_fragments[findex].size;
00240 fptr = m_fragments[findex].data + dataLeft;
00241 }
00242 else
00243 {
00244 fptr -= toRewind;
00245 dataLeft -= toRewind;
00246 break;
00247 }
00248 }
00249
00250
00251 while (toRead > 0)
00252 {
00253 fptr--;
00254 dataLeft--;
00255 if (dataLeft < 0)
00256 {
00257 if (findex == 0)
00258 {
00259
00260 fptr++;
00261 break;
00262 }
00263 --findex;
00264 dataLeft = m_fragments[findex].size - 1;
00265 fptr = m_fragments[findex].data + dataLeft;
00266 }
00267
00268 *cacheByte = *fptr;
00269 cacheByte--;
00270 toRead--;
00271 }
00272
00273 if (m_cacheSize < 32)
00274 {
00275 m_cacheSize += 32;
00276 }
00277 else
00278 {
00279 m_cacheSize = 64;
00280 }
00281
00282 cachedBytes = (m_cacheSize >> 3) - toRead;
00283
00284 SWAP_INT32(m_cache[0]);
00285
00286
00287 size_t toAdvance = cachedBytes;
00288 size_t foffset = fptr - m_fragments[findex].data;
00289 size_t fremaining = m_fragments[findex].size - foffset;
00290 while (toAdvance > 0)
00291 {
00292 if (toAdvance > fremaining)
00293 {
00294 toAdvance -= fremaining;
00295 assert (findex + 1 < m_fragmentCount);
00296 ++findex;
00297 fremaining = m_fragments[findex].size;
00298 fptr = m_fragments[findex].data;
00299 }
00300 else
00301 {
00302 fptr += toAdvance;
00303 fremaining -= toAdvance;
00304 break;
00305 }
00306 }
00307 m_fragmentPointer = fptr;
00308 m_fragmentIndex = findex;
00309 m_fragmentRemaining = fremaining;
00310 }
00311
00312 inline void next_word()
00313 {
00314
00315 assert (m_cacheOffset >= 32);
00316
00317
00318 m_cache[0] = m_cache[1];
00319 m_cacheOffset -= 32;
00320
00321 if (m_fragmentRemaining >= 4 &&
00322 ((uint32_t)m_fragmentPointer & 0x3) == 0)
00323 {
00324
00325 m_cache[1] = *(uint32_t*)m_fragmentPointer;
00326 m_fragmentPointer += 4;
00327 m_fragmentRemaining -= 4;
00328 SWAP_INT32(m_cache[1]);
00329 }
00330 else
00331 {
00332
00333 if (m_cacheSize == 64)
00334 {
00335
00336 size_t readCount = fill_forward(4);
00337 m_cacheSize = 32 + readCount;
00338 }
00339 else
00340 if (m_cacheSize > 32)
00341 {
00342 m_cacheSize -= 32;
00343 }
00344 else
00345 {
00346 m_cacheSize = 0;
00347 }
00348 }
00349 }
00350 };
00351
00352
00353
00354 inline
00355 SBitstreamReader::SBitstreamReader()
00356 : m_cacheOffset(0),
00357 m_fragmentRemaining(0),
00358 m_cacheSize(0),
00359 m_fragments(0),
00360 m_fragmentCount(0),
00361 m_fragmentIndex(0)
00362 {
00363 }
00364
00365 inline
00366 SBitstreamReader::SBitstreamReader(const SBuffer& sourceBuffer)
00367 : m_fragments(0)
00368 {
00369 SetSource(sourceBuffer);
00370 }
00371
00372 inline
00373 SBitstreamReader::SBitstreamReader(const void * data, size_t size)
00374 : m_fragments(0)
00375 {
00376 SetSource(data, size);
00377 }
00378
00379 inline
00380 SBitstreamReader::~SBitstreamReader()
00381 {
00382 if (m_fragments != 0)
00383 {
00384 delete [] m_fragments;
00385 }
00386 }
00387
00388 inline status_t
00389 SBitstreamReader::SetSource(const SBuffer& sourceBuffer)
00390 {
00391 if (m_fragments != 0)
00392 {
00393 delete [] m_fragments;
00394 }
00395
00396
00397 m_fragmentCount = 0;
00398 const SBuffer * i;
00399 for (i = &sourceBuffer; i; i = i->next)
00400 {
00401 ++m_fragmentCount;
00402 }
00403 m_fragments = new SFragment[m_fragmentCount];
00404 if (m_fragments == 0)
00405 {
00406 assert (!"SBitstreamReader: no memory for fragment list");
00407 return B_NO_MEMORY;
00408 }
00409 size_t n;
00410 size_t offset = 0;
00411 for (n = 0, i = &sourceBuffer; i; i = i->next, n++)
00412 {
00413 m_fragments[n].data = (const uint8_t*)i->Data();
00414 m_fragments[n].size = i->Size();
00415 m_fragments[n].offset = offset;
00416 offset += m_fragments[n].size;
00417 }
00418
00419 m_cacheOffset = 0;
00420 m_fragmentIndex = 0;
00421 m_fragmentPointer = m_fragments[0].data;
00422 m_fragmentRemaining = m_fragments[0].size;
00423
00424 m_cacheSize = fill_forward(0);
00425 m_cacheSize += fill_forward(4);
00426
00427 return B_OK;
00428 }
00429
00430 inline status_t
00431 SBitstreamReader::SetSource(const void * data, size_t size)
00432 {
00433 if (m_fragments != 0)
00434 {
00435 delete [] m_fragments;
00436 }
00437 m_fragmentCount = 1;
00438 m_fragments = new SFragment[1];
00439 if (m_fragments == 0)
00440 {
00441 assert (!"SBitstreamReader: no memory for fragment list");
00442 return B_NO_MEMORY;
00443 }
00444 m_fragments[0].data = (const uint8_t*)data;
00445 m_fragments[0].size = size;
00446 m_fragments[0].offset = 0;
00447
00448 m_cacheOffset = 0;
00449 m_fragmentIndex = 0;
00450 m_fragmentPointer = (const uint8_t*)data;
00451 m_fragmentRemaining = size;
00452
00453 m_cacheSize = fill_forward(0);
00454 m_cacheSize += fill_forward(4);
00455
00456 return B_OK;
00457 }
00458
00459 inline bool
00460 SBitstreamReader::IsInRange() const
00461 {
00462 return (m_cacheSize > 0);
00463 }
00464
00465 inline uint32_t
00466 SBitstreamReader::PeekBits(size_t bits) const
00467 {
00468 assert (m_cacheOffset + bits <= m_cacheSize);
00469
00470 uint32_t result = m_cache[0] << m_cacheOffset;
00471 if (bits > (32-m_cacheOffset))
00472 {
00473 uint32_t v = m_cache[1] >> (32-m_cacheOffset);
00474 result |= v;
00475 }
00476 return result >> (32-bits);
00477 }
00478
00479 inline uint32_t
00480 SBitstreamReader::GetBits(size_t bits)
00481 {
00482 assert (m_cacheOffset + bits <= m_cacheSize);
00483
00484 uint32_t result = m_cache[0] << m_cacheOffset;
00485 if (bits > (32-m_cacheOffset))
00486 {
00487 uint32_t v = m_cache[1] >> (32-m_cacheOffset);
00488 result |= v;
00489 }
00490 m_cacheOffset += bits;
00491 if (m_cacheOffset >= 32)
00492 {
00493 next_word();
00494 }
00495 return result >> (32-bits);
00496 }
00497
00498 inline void
00499 SBitstreamReader::SkipBit()
00500 {
00501 m_cacheOffset++;
00502 if (m_cacheOffset >= 32)
00503 {
00504 next_word();
00505 }
00506 }
00507
00508 inline void
00509 SBitstreamReader::SkipByte()
00510 {
00511 m_cacheOffset += 8;
00512 if (m_cacheOffset >= 32)
00513 {
00514 next_word();
00515 }
00516 }
00517
00518 inline void
00519 SBitstreamReader::SkipBits(size_t bits)
00520 {
00521 m_cacheOffset += bits;
00522 while (m_cacheOffset >= 32)
00523 {
00524 next_word();
00525 }
00526 }
00527
00528 inline void
00529 SBitstreamReader::SkipToByteBoundary()
00530 {
00531 m_cacheOffset = (m_cacheOffset + 7) & ~7;
00532 if (m_cacheOffset >= 32)
00533 {
00534 next_word();
00535 }
00536 }
00537
00538 inline void
00539 SBitstreamReader::RewindBits(size_t bits)
00540 {
00541 assert (bits > 0);
00542 assert (bits <= 32);
00543
00544
00545 if (m_cacheOffset >= bits)
00546 {
00547 m_cacheOffset -= bits;
00548
00549 return;
00550 }
00551 m_cache[1] = m_cache[0];
00552 fill_reverse();
00553 m_cacheOffset += (32 - bits);
00554
00555
00556
00557
00558 }
00559
00560 inline bool
00561 SBitstreamReader::Find(uint32_t pattern, size_t bits)
00562 {
00563 while (BitsAvailable() >= bits)
00564 {
00565 uint32_t v = PeekBits(bits);
00566 if (v == pattern) return true;
00567
00568 SkipBit();
00569 }
00570 return false;
00571 }
00572
00573 inline bool
00574 SBitstreamReader::FindByteAligned(uint32_t pattern, size_t bits)
00575 {
00576 SkipToByteBoundary();
00577 while (BitsAvailable() >= bits)
00578 {
00579 uint32_t v = PeekBits(bits);
00580 if (v == pattern) return true;
00581
00582 SkipByte();
00583 }
00584
00585 return false;
00586 }
00587
00588 inline bool
00589 SBitstreamReader::FindReverse(uint32_t pattern, size_t bits)
00590 {
00591
00592 if (BitPosition() < bits)
00593 {
00594 return false;
00595 }
00596 RewindBits(bits);
00597 while (true)
00598 {
00599 uint32_t v = PeekBits(bits);
00600 if (v == pattern) return true;
00601
00602 if (BitPosition() == 0)
00603 {
00604 break;
00605 }
00606 RewindBits(1);
00607 }
00608 return false;
00609 }
00610
00611 inline bool
00612 SBitstreamReader::FindByteAlignedReverse(uint32_t pattern, size_t bits)
00613 {
00614 int32_t pos = (int32_t)BitPosition();
00615 pos -= (bits + 7);
00616 pos = (pos + 0x7) & ~0x7;
00617 if (pos < 0)
00618 {
00619 return false;
00620 }
00621 SetBytePosition(pos >> 3);
00622 while (true)
00623 {
00624 uint32_t v = PeekBits(bits);
00625 if (v == pattern) return true;
00626
00627 if (BitPosition() == 0)
00628 {
00629 break;
00630 }
00631 RewindBits(8);
00632 }
00633
00634 return false;
00635 }
00636
00637 inline size_t
00638 SBitstreamReader::BytesAvailable() const
00639 {
00640 return ByteLength() - BytePosition();
00641 }
00642
00643 inline size_t
00644 SBitstreamReader::BytePosition() const
00645 {
00646 const SFragment& f = m_fragments[m_fragmentIndex];
00647 size_t pos = f.offset + (f.size - m_fragmentRemaining);
00648 pos -= ((m_cacheSize - m_cacheOffset) >> 3);
00649 return pos;
00650 }
00651
00652 inline size_t
00653 SBitstreamReader::BitPosition() const
00654 {
00655 const SFragment& f = m_fragments[m_fragmentIndex];
00656 size_t pos = f.offset + (f.size - m_fragmentRemaining);
00657 pos <<= 3;
00658 pos -= (m_cacheSize - m_cacheOffset);
00659 return pos;
00660 }
00661
00662 inline status_t
00663 SBitstreamReader::SetBytePosition(size_t pos)
00664 {
00665
00666 size_t findex;
00667 for (findex = 0; findex < m_fragmentCount; findex++)
00668 {
00669 const SFragment & f = m_fragments[findex];
00670 size_t offset = f.offset;
00671 size_t end = offset + f.size;
00672 if (offset <= pos && end >= pos)
00673 {
00674
00675 m_fragmentIndex = findex;
00676 m_fragmentPointer = m_fragments[findex].data + (pos - offset);
00677 m_fragmentRemaining = end - pos;
00678 m_cacheOffset = 0;
00679 m_cacheSize = fill_forward(0);
00680 m_cacheSize += fill_forward(4);
00681 return B_OK;
00682 }
00683 }
00684 return B_OUT_OF_RANGE;
00685 }
00686
00687 inline status_t
00688 SBitstreamReader::SetBitPosition(size_t pos)
00689 {
00690 status_t result = SetBytePosition(pos >> 3);
00691 if (result < B_OK)
00692 {
00693 return result;
00694 }
00695 size_t bit = pos & 0x7;
00696 if (BitsAvailable() < bit)
00697 {
00698 return B_OUT_OF_RANGE;
00699 }
00700 SkipBits(bit);
00701 return B_OK;
00702 }
00703
00704 inline size_t
00705 SBitstreamReader::ByteLength() const
00706 {
00707 if (m_fragmentCount == 0)
00708 {
00709 return 0;
00710 }
00711 const SFragment& f = m_fragments[m_fragmentCount-1];
00712 return f.offset + f.size;
00713 }
00714
00715 #if _SUPPORTS_NAMESPACE
00716 } }
00717 #endif
00718
00719 #endif // _SUPPORT_BITSTREAM_READER_H_