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(const RetainPtr<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   if (!IsInBounds())
     31     return -1;
     32 
     33   uint32_t dwBitPos = getBitPos();
     34   if (dwBitPos > LengthInBits())
     35     return -1;
     36 
     37   *dwResult = 0;
     38   if (dwBitPos + dwBits <= LengthInBits())
     39     dwBitPos = dwBits;
     40   else
     41     dwBitPos = LengthInBits() - dwBitPos;
     42 
     43   for (; dwBitPos > 0; --dwBitPos) {
     44     *dwResult =
     45         (*dwResult << 1) | ((m_pBuf[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01);
     46     AdvanceBit();
     47   }
     48   return 0;
     49 }
     50 
     51 int32_t CJBig2_BitStream::readNBits(uint32_t dwBits, int32_t* nResult) {
     52   if (!IsInBounds())
     53     return -1;
     54 
     55   uint32_t dwBitPos = getBitPos();
     56   if (dwBitPos > LengthInBits())
     57     return -1;
     58 
     59   *nResult = 0;
     60   if (dwBitPos + dwBits <= LengthInBits())
     61     dwBitPos = dwBits;
     62   else
     63     dwBitPos = LengthInBits() - dwBitPos;
     64 
     65   for (; dwBitPos > 0; --dwBitPos) {
     66     *nResult =
     67         (*nResult << 1) | ((m_pBuf[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01);
     68     AdvanceBit();
     69   }
     70   return 0;
     71 }
     72 
     73 int32_t CJBig2_BitStream::read1Bit(uint32_t* dwResult) {
     74   if (!IsInBounds())
     75     return -1;
     76 
     77   *dwResult = (m_pBuf[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01;
     78   AdvanceBit();
     79   return 0;
     80 }
     81 
     82 int32_t CJBig2_BitStream::read1Bit(bool* bResult) {
     83   if (!IsInBounds())
     84     return -1;
     85 
     86   *bResult = (m_pBuf[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01;
     87   AdvanceBit();
     88   return 0;
     89 }
     90 
     91 int32_t CJBig2_BitStream::read1Byte(uint8_t* cResult) {
     92   if (!IsInBounds())
     93     return -1;
     94 
     95   *cResult = m_pBuf[m_dwByteIdx];
     96   ++m_dwByteIdx;
     97   return 0;
     98 }
     99 
    100 int32_t CJBig2_BitStream::readInteger(uint32_t* dwResult) {
    101   if (m_dwByteIdx + 3 >= m_dwLength)
    102     return -1;
    103 
    104   *dwResult = (m_pBuf[m_dwByteIdx] << 24) | (m_pBuf[m_dwByteIdx + 1] << 16) |
    105               (m_pBuf[m_dwByteIdx + 2] << 8) | m_pBuf[m_dwByteIdx + 3];
    106   m_dwByteIdx += 4;
    107   return 0;
    108 }
    109 
    110 int32_t CJBig2_BitStream::readShortInteger(uint16_t* dwResult) {
    111   if (m_dwByteIdx + 1 >= m_dwLength)
    112     return -1;
    113 
    114   *dwResult = (m_pBuf[m_dwByteIdx] << 8) | m_pBuf[m_dwByteIdx + 1];
    115   m_dwByteIdx += 2;
    116   return 0;
    117 }
    118 
    119 void CJBig2_BitStream::alignByte() {
    120   if (m_dwBitIdx != 0) {
    121     ++m_dwByteIdx;
    122     m_dwBitIdx = 0;
    123   }
    124 }
    125 
    126 uint8_t CJBig2_BitStream::getCurByte() const {
    127   return IsInBounds() ? m_pBuf[m_dwByteIdx] : 0;
    128 }
    129 
    130 void CJBig2_BitStream::incByteIdx() {
    131   if (IsInBounds())
    132     ++m_dwByteIdx;
    133 }
    134 
    135 uint8_t CJBig2_BitStream::getCurByte_arith() const {
    136   return IsInBounds() ? m_pBuf[m_dwByteIdx] : 0xFF;
    137 }
    138 
    139 uint8_t CJBig2_BitStream::getNextByte_arith() const {
    140   return m_dwByteIdx + 1 < m_dwLength ? m_pBuf[m_dwByteIdx + 1] : 0xFF;
    141 }
    142 
    143 uint32_t CJBig2_BitStream::getOffset() const {
    144   return m_dwByteIdx;
    145 }
    146 
    147 void CJBig2_BitStream::setOffset(uint32_t dwOffset) {
    148   m_dwByteIdx = std::min(dwOffset, m_dwLength);
    149 }
    150 
    151 uint32_t CJBig2_BitStream::getBitPos() const {
    152   return (m_dwByteIdx << 3) + m_dwBitIdx;
    153 }
    154 
    155 void CJBig2_BitStream::setBitPos(uint32_t dwBitPos) {
    156   m_dwByteIdx = dwBitPos >> 3;
    157   m_dwBitIdx = dwBitPos & 7;
    158 }
    159 
    160 const uint8_t* CJBig2_BitStream::getBuf() const {
    161   return m_pBuf;
    162 }
    163 
    164 const uint8_t* CJBig2_BitStream::getPointer() const {
    165   return m_pBuf + m_dwByteIdx;
    166 }
    167 
    168 void CJBig2_BitStream::offset(uint32_t dwOffset) {
    169   m_dwByteIdx += dwOffset;
    170 }
    171 
    172 uint32_t CJBig2_BitStream::getByteLeft() const {
    173   return m_dwLength - m_dwByteIdx;
    174 }
    175 
    176 void CJBig2_BitStream::AdvanceBit() {
    177   if (m_dwBitIdx == 7) {
    178     ++m_dwByteIdx;
    179     m_dwBitIdx = 0;
    180   } else {
    181     ++m_dwBitIdx;
    182   }
    183 }
    184 
    185 bool CJBig2_BitStream::IsInBounds() const {
    186   return m_dwByteIdx < m_dwLength;
    187 }
    188 
    189 uint32_t CJBig2_BitStream::LengthInBits() const {
    190   return m_dwLength << 3;
    191 }
    192 
    193 uint32_t CJBig2_BitStream::getObjNum() const {
    194   return m_dwObjNum;
    195 }
    196