Home | History | Annotate | Download | only in jbig2
      1 // Copyright 2015 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #include "core/fxcodec/jbig2/JBig2_BitStream.h"
      8 
      9 #include <algorithm>
     10 
     11 #include "core/fpdfapi/parser/cpdf_stream.h"
     12 #include "core/fpdfapi/parser/cpdf_stream_acc.h"
     13 
     14 CJBig2_BitStream::CJBig2_BitStream(CPDF_StreamAcc* pSrcStream)
     15     : m_pBuf(pSrcStream->GetData()),
     16       m_dwLength(pSrcStream->GetSize()),
     17       m_dwByteIdx(0),
     18       m_dwBitIdx(0),
     19       m_dwObjNum(pSrcStream->GetStream() ? pSrcStream->GetStream()->GetObjNum()
     20                                          : 0) {
     21   if (m_dwLength > 256 * 1024 * 1024) {
     22     m_dwLength = 0;
     23     m_pBuf = nullptr;
     24   }
     25 }
     26 
     27 CJBig2_BitStream::~CJBig2_BitStream() {}
     28 
     29 int32_t CJBig2_BitStream::readNBits(uint32_t dwBits, uint32_t* dwResult) {
     30   uint32_t dwBitPos = getBitPos();
     31   if (dwBitPos > LengthInBits())
     32     return -1;
     33 
     34   *dwResult = 0;
     35   if (dwBitPos + dwBits <= LengthInBits())
     36     dwBitPos = dwBits;
     37   else
     38     dwBitPos = LengthInBits() - dwBitPos;
     39 
     40   for (; dwBitPos > 0; --dwBitPos) {
     41     *dwResult =
     42         (*dwResult << 1) | ((m_pBuf[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01);
     43     AdvanceBit();
     44   }
     45   return 0;
     46 }
     47 
     48 int32_t CJBig2_BitStream::readNBits(uint32_t dwBits, int32_t* nResult) {
     49   uint32_t dwBitPos = getBitPos();
     50   if (dwBitPos > LengthInBits())
     51     return -1;
     52 
     53   *nResult = 0;
     54   if (dwBitPos + dwBits <= LengthInBits())
     55     dwBitPos = dwBits;
     56   else
     57     dwBitPos = LengthInBits() - dwBitPos;
     58 
     59   for (; dwBitPos > 0; --dwBitPos) {
     60     *nResult =
     61         (*nResult << 1) | ((m_pBuf[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01);
     62     AdvanceBit();
     63   }
     64   return 0;
     65 }
     66 
     67 int32_t CJBig2_BitStream::read1Bit(uint32_t* dwResult) {
     68   if (!IsInBound())
     69     return -1;
     70 
     71   *dwResult = (m_pBuf[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01;
     72   AdvanceBit();
     73   return 0;
     74 }
     75 
     76 int32_t CJBig2_BitStream::read1Bit(bool* bResult) {
     77   if (!IsInBound())
     78     return -1;
     79 
     80   *bResult = (m_pBuf[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01;
     81   AdvanceBit();
     82   return 0;
     83 }
     84 
     85 int32_t CJBig2_BitStream::read1Byte(uint8_t* cResult) {
     86   if (!IsInBound())
     87     return -1;
     88 
     89   *cResult = m_pBuf[m_dwByteIdx];
     90   ++m_dwByteIdx;
     91   return 0;
     92 }
     93 
     94 int32_t CJBig2_BitStream::readInteger(uint32_t* dwResult) {
     95   if (m_dwByteIdx + 3 >= m_dwLength)
     96     return -1;
     97 
     98   *dwResult = (m_pBuf[m_dwByteIdx] << 24) | (m_pBuf[m_dwByteIdx + 1] << 16) |
     99               (m_pBuf[m_dwByteIdx + 2] << 8) | m_pBuf[m_dwByteIdx + 3];
    100   m_dwByteIdx += 4;
    101   return 0;
    102 }
    103 
    104 int32_t CJBig2_BitStream::readShortInteger(uint16_t* dwResult) {
    105   if (m_dwByteIdx + 1 >= m_dwLength)
    106     return -1;
    107 
    108   *dwResult = (m_pBuf[m_dwByteIdx] << 8) | m_pBuf[m_dwByteIdx + 1];
    109   m_dwByteIdx += 2;
    110   return 0;
    111 }
    112 
    113 void CJBig2_BitStream::alignByte() {
    114   if (m_dwBitIdx != 0) {
    115     ++m_dwByteIdx;
    116     m_dwBitIdx = 0;
    117   }
    118 }
    119 
    120 uint8_t CJBig2_BitStream::getCurByte() const {
    121   return IsInBound() ? m_pBuf[m_dwByteIdx] : 0;
    122 }
    123 
    124 void CJBig2_BitStream::incByteIdx() {
    125   if (IsInBound())
    126     ++m_dwByteIdx;
    127 }
    128 
    129 uint8_t CJBig2_BitStream::getCurByte_arith() const {
    130   return IsInBound() ? m_pBuf[m_dwByteIdx] : 0xFF;
    131 }
    132 
    133 uint8_t CJBig2_BitStream::getNextByte_arith() const {
    134   return m_dwByteIdx + 1 < m_dwLength ? m_pBuf[m_dwByteIdx + 1] : 0xFF;
    135 }
    136 
    137 uint32_t CJBig2_BitStream::getOffset() const {
    138   return m_dwByteIdx;
    139 }
    140 
    141 void CJBig2_BitStream::setOffset(uint32_t dwOffset) {
    142   m_dwByteIdx = std::min(dwOffset, m_dwLength);
    143 }
    144 
    145 uint32_t CJBig2_BitStream::getBitPos() const {
    146   return (m_dwByteIdx << 3) + m_dwBitIdx;
    147 }
    148 
    149 void CJBig2_BitStream::setBitPos(uint32_t dwBitPos) {
    150   m_dwByteIdx = dwBitPos >> 3;
    151   m_dwBitIdx = dwBitPos & 7;
    152 }
    153 
    154 const uint8_t* CJBig2_BitStream::getBuf() const {
    155   return m_pBuf;
    156 }
    157 
    158 const uint8_t* CJBig2_BitStream::getPointer() const {
    159   return m_pBuf + m_dwByteIdx;
    160 }
    161 
    162 void CJBig2_BitStream::offset(uint32_t dwOffset) {
    163   m_dwByteIdx += dwOffset;
    164 }
    165 
    166 uint32_t CJBig2_BitStream::getByteLeft() const {
    167   return m_dwLength - m_dwByteIdx;
    168 }
    169 
    170 void CJBig2_BitStream::AdvanceBit() {
    171   if (m_dwBitIdx == 7) {
    172     ++m_dwByteIdx;
    173     m_dwBitIdx = 0;
    174   } else {
    175     ++m_dwBitIdx;
    176   }
    177 }
    178 
    179 bool CJBig2_BitStream::IsInBound() const {
    180   return m_dwByteIdx < m_dwLength;
    181 }
    182 
    183 uint32_t CJBig2_BitStream::LengthInBits() const {
    184   return m_dwLength << 3;
    185 }
    186 
    187 uint32_t CJBig2_BitStream::getObjNum() const {
    188   return m_dwObjNum;
    189 }
    190