Cleanup JBig2_ArithIntDecoder.
authorLei Zhang <thestig@chromium.org>
Thu, 1 Oct 2015 20:16:29 +0000 (13:16 -0700)
committerLei Zhang <thestig@chromium.org>
Thu, 1 Oct 2015 20:16:29 +0000 (13:16 -0700)
R=tsepez@chromium.org

Review URL: https://codereview.chromium.org/1359013003 .

core/src/fxcodec/jbig2/JBig2_ArithDecoder.h
core/src/fxcodec/jbig2/JBig2_ArithIntDecoder.cpp
core/src/fxcodec/jbig2/JBig2_ArithIntDecoder.h
core/src/fxcodec/jbig2/JBig2_SddProc.cpp
core/src/fxcodec/jbig2/JBig2_TrdProc.cpp

index a1e8910..3cb95ac 100644 (file)
@@ -10,6 +10,8 @@
 class CJBig2_BitStream;
 
 struct JBig2ArithCtx {
+  JBig2ArithCtx() : MPS(0), I(0) {}
+
   unsigned int MPS;
   unsigned int I;
 };
index b194faf..49be941 100644 (file)
 
 #include "JBig2_ArithIntDecoder.h"
 
-#include "../../../include/fxcrt/fx_memory.h"
-#include "JBig2_Define.h"
+#include "../../../include/fxcrt/fx_basic.h"
+
+namespace {
+
+int ShiftOr(int val, int bitwise_or_val) {
+  return (val << 1) | bitwise_or_val;
+}
+
+const struct ArithIntDecodeData {
+  int nNeedBits;
+  int nValue;
+} g_ArithIntDecodeData[] = {
+    {2, 0},
+    {4, 4},
+    {6, 20},
+    {8, 84},
+    {12, 340},
+    {32, 4436},
+};
+
+size_t RecursiveDecode(CJBig2_ArithDecoder* decoder,
+                       std::vector<JBig2ArithCtx>* context,
+                       int* prev,
+                       size_t depth) {
+  static const size_t kDepthEnd = FX_ArraySize(g_ArithIntDecodeData) - 1;
+  if (depth == kDepthEnd)
+    return kDepthEnd;
+
+  JBig2ArithCtx* pCX = &(*context)[*prev];
+  int D = decoder->DECODE(pCX);
+  *prev = ShiftOr(*prev, D);
+  if (!D)
+    return depth;
+  return RecursiveDecode(decoder, context, prev, depth + 1);
+}
+
+}  // namespace
 
 CJBig2_ArithIntDecoder::CJBig2_ArithIntDecoder() {
-  IAx = FX_Alloc(JBig2ArithCtx, 512);
-  JBIG2_memset(IAx, 0, sizeof(JBig2ArithCtx) * 512);
+  m_IAx.resize(512);
 }
+
 CJBig2_ArithIntDecoder::~CJBig2_ArithIntDecoder() {
-  FX_Free(IAx);
 }
-int CJBig2_ArithIntDecoder::decode(CJBig2_ArithDecoder* pArithDecoder,
-                                   int* nResult) {
-  int PREV, V;
-  int S, D;
-  int nNeedBits, nTemp, i;
-  PREV = 1;
-  S = pArithDecoder->DECODE(IAx + PREV);
-  PREV = (PREV << 1) | S;
-  D = pArithDecoder->DECODE(IAx + PREV);
-  PREV = (PREV << 1) | D;
-  if (D) {
-    D = pArithDecoder->DECODE(IAx + PREV);
-    PREV = (PREV << 1) | D;
-    if (D) {
-      D = pArithDecoder->DECODE(IAx + PREV);
-      PREV = (PREV << 1) | D;
-      if (D) {
-        D = pArithDecoder->DECODE(IAx + PREV);
-        PREV = (PREV << 1) | D;
-        if (D) {
-          D = pArithDecoder->DECODE(IAx + PREV);
-          PREV = (PREV << 1) | D;
-          if (D) {
-            nNeedBits = 32;
-            V = 4436;
-          } else {
-            nNeedBits = 12;
-            V = 340;
-          }
-        } else {
-          nNeedBits = 8;
-          V = 84;
-        }
-      } else {
-        nNeedBits = 6;
-        V = 20;
-      }
-    } else {
-      nNeedBits = 4;
-      V = 4;
-    }
-  } else {
-    nNeedBits = 2;
-    V = 0;
-  }
-  nTemp = 0;
-  for (i = 0; i < nNeedBits; i++) {
-    D = pArithDecoder->DECODE(IAx + PREV);
-    if (PREV < 256) {
-      PREV = (PREV << 1) | D;
-    } else {
-      PREV = (((PREV << 1) | D) & 511) | 256;
-    }
-    nTemp = (nTemp << 1) | D;
-  }
-  V += nTemp;
-  if (S == 1 && V > 0) {
-    V = -V;
-  }
-  *nResult = V;
-  if (S == 1 && V == 0) {
-    return JBIG2_OOB;
+
+bool CJBig2_ArithIntDecoder::decode(CJBig2_ArithDecoder* pArithDecoder,
+                                    int* nResult) {
+  int PREV = 1;
+  const int S = pArithDecoder->DECODE(&m_IAx[PREV]);
+  PREV = ShiftOr(PREV, S);
+
+  const size_t nDecodeDataIndex =
+      RecursiveDecode(pArithDecoder, &m_IAx, &PREV, 0);
+
+  int nTemp = 0;
+  for (int i = 0; i < g_ArithIntDecodeData[nDecodeDataIndex].nNeedBits; ++i) {
+    int D = pArithDecoder->DECODE(&m_IAx[PREV]);
+    PREV = ShiftOr(PREV, D);
+    if (PREV >= 256)
+      PREV = (PREV & 511) | 256;
+    nTemp = ShiftOr(nTemp, D);
   }
-  return 0;
+  int nValue = g_ArithIntDecodeData[nDecodeDataIndex].nValue;
+  nValue += nTemp;
+  if (S == 1 && nValue > 0)
+    nValue = -nValue;
+
+  *nResult = nValue;
+  return S != 1 || nValue != 0;
 }
-CJBig2_ArithIaidDecoder::CJBig2_ArithIaidDecoder(unsigned char SBSYMCODELENA) {
-  SBSYMCODELEN = SBSYMCODELENA;
-  IAID = FX_Alloc(JBig2ArithCtx, 1 << SBSYMCODELEN);
-  JBIG2_memset(IAID, 0, sizeof(JBig2ArithCtx) * (int)(1 << SBSYMCODELEN));
+
+CJBig2_ArithIaidDecoder::CJBig2_ArithIaidDecoder(unsigned char SBSYMCODELENA)
+    : SBSYMCODELEN(SBSYMCODELENA) {
+  m_IAID.resize(1 << SBSYMCODELEN);
 }
+
 CJBig2_ArithIaidDecoder::~CJBig2_ArithIaidDecoder() {
-  FX_Free(IAID);
 }
-int CJBig2_ArithIaidDecoder::decode(CJBig2_ArithDecoder* pArithDecoder,
-                                    int* nResult) {
-  int PREV;
-  int D;
-  int i;
-  PREV = 1;
-  for (i = 0; i < SBSYMCODELEN; i++) {
-    D = pArithDecoder->DECODE(IAID + PREV);
-    PREV = (PREV << 1) | D;
+
+void CJBig2_ArithIaidDecoder::decode(CJBig2_ArithDecoder* pArithDecoder,
+                                     FX_DWORD* nResult) {
+  int PREV = 1;
+  for (unsigned char i = 0; i < SBSYMCODELEN; ++i) {
+    JBig2ArithCtx* pCX = &m_IAID[PREV];
+    int D = pArithDecoder->DECODE(pCX);
+    PREV = ShiftOr(PREV, D);
   }
-  PREV = PREV - (1 << SBSYMCODELEN);
-  *nResult = PREV;
-  return 0;
+  *nResult = PREV - (1 << SBSYMCODELEN);
 }
index ca8e181..f31636b 100644 (file)
@@ -4,33 +4,36 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#ifndef _JBIG2_ARITH_INT_DECODER_H_
-#define _JBIG2_ARITH_INT_DECODER_H_
+#ifndef CORE_SRC_FXCODEC_JBIG2_JBIG2_ARITHINTDECODER_H_
+#define CORE_SRC_FXCODEC_JBIG2_JBIG2_ARITHINTDECODER_H_
 
+#include <vector>
+
+#include "../../../include/fxcrt/fx_system.h"
 #include "JBig2_ArithDecoder.h"
 
 class CJBig2_ArithIntDecoder {
  public:
   CJBig2_ArithIntDecoder();
-
   ~CJBig2_ArithIntDecoder();
 
-  int decode(CJBig2_ArithDecoder* pArithDecoder, int* nResult);
+  bool decode(CJBig2_ArithDecoder* pArithDecoder, int* nResult);
 
  private:
-  JBig2ArithCtx* IAx;
+  std::vector<JBig2ArithCtx> m_IAx;
 };
+
 class CJBig2_ArithIaidDecoder {
  public:
-  CJBig2_ArithIaidDecoder(unsigned char SBSYMCODELENA);
-
+  explicit CJBig2_ArithIaidDecoder(unsigned char SBSYMCODELENA);
   ~CJBig2_ArithIaidDecoder();
 
-  int decode(CJBig2_ArithDecoder* pArithDecoder, int* nResult);
+  void decode(CJBig2_ArithDecoder* pArithDecoder, FX_DWORD* nResult);
 
  private:
-  JBig2ArithCtx* IAID;
+  std::vector<JBig2ArithCtx> m_IAID;
 
-  unsigned char SBSYMCODELEN;
+  const unsigned char SBSYMCODELEN;
 };
-#endif
+
+#endif  // CORE_SRC_FXCODEC_JBIG2_JBIG2_ARITHINTDECODER_H_
index ae5635b..afce6eb 100644 (file)
@@ -35,7 +35,6 @@ CJBig2_SymbolDict* CJBig2_SDDProc::decode_Arith(
   FX_DWORD nTmp;
   FX_DWORD SBNUMSYMS;
   uint8_t SBSYMCODELEN;
-  FX_DWORD IDI;
   int32_t RDXI, RDYI;
   CJBig2_Image** SBSYMS;
   nonstd::unique_ptr<CJBig2_ArithIaidDecoder> IAID;
@@ -65,7 +64,7 @@ CJBig2_SymbolDict* CJBig2_SDDProc::decode_Arith(
   NSYMSDECODED = 0;
   while (NSYMSDECODED < SDNUMNEWSYMS) {
     BS = nullptr;
-    if (IADH->decode(pArithDecoder, &HCDH) == -1) {
+    if (!IADH->decode(pArithDecoder, &HCDH)) {
       goto failed;
     }
     HCHEIGHT = HCHEIGHT + HCDH;
@@ -116,7 +115,7 @@ CJBig2_SymbolDict* CJBig2_SDDProc::decode_Arith(
           goto failed;
         }
       } else {
-        if (IAAI->decode(pArithDecoder, (int*)&REFAGGNINST) == -1) {
+        if (!IAAI->decode(pArithDecoder, (int*)&REFAGGNINST)) {
           goto failed;
         }
         if (REFAGGNINST > 1) {
@@ -209,11 +208,10 @@ CJBig2_SymbolDict* CJBig2_SDDProc::decode_Arith(
           FX_Free(SBSYMS);
         } else if (REFAGGNINST == 1) {
           SBNUMSYMS = SDNUMINSYMS + NSYMSDECODED;
-          if (IAID->decode(pArithDecoder, (int*)&IDI) == -1) {
-            goto failed;
-          }
-          if ((IARDX->decode(pArithDecoder, &RDXI) == -1) ||
-              (IARDY->decode(pArithDecoder, &RDYI) == -1)) {
+          FX_DWORD IDI;
+          IAID->decode(pArithDecoder, &IDI);
+          if (!IARDX->decode(pArithDecoder, &RDXI) ||
+              !IARDY->decode(pArithDecoder, &RDYI)) {
             goto failed;
           }
           if (IDI >= SBNUMSYMS) {
@@ -256,7 +254,7 @@ CJBig2_SymbolDict* CJBig2_SDDProc::decode_Arith(
   CUREXFLAG = 0;
   EXFLAGS = FX_Alloc(FX_BOOL, SDNUMINSYMS + SDNUMNEWSYMS);
   while (EXINDEX < SDNUMINSYMS + SDNUMNEWSYMS) {
-    if (IAEX->decode(pArithDecoder, (int*)&EXRUNLENGTH) == -1) {
+    if (!IAEX->decode(pArithDecoder, (int*)&EXRUNLENGTH)) {
       FX_Free(EXFLAGS);
       goto failed;
     }
index afa3dba..f26bdb6 100644 (file)
@@ -17,9 +17,7 @@ CJBig2_Image* CJBig2_TRDProc::decode_Huffman(CJBig2_BitStream* pStream,
   int32_t STRIPT, FIRSTS;
   FX_DWORD NINSTANCES;
   int32_t DT, DFS, CURS;
-  uint8_t CURT;
   int32_t SI, TI;
-  FX_DWORD IDI;
   CJBig2_Image* IBI;
   FX_DWORD WI, HI;
   int32_t IDS;
@@ -66,9 +64,8 @@ CJBig2_Image* CJBig2_TRDProc::decode_Huffman(CJBig2_BitStream* pStream,
           CURS = CURS + IDS + SBDSOFFSET;
         }
       }
-      if (SBSTRIPS == 1) {
-        CURT = 0;
-      } else {
+      uint8_t CURT = 0;
+      if (SBSTRIPS != 1) {
         nTmp = 1;
         while ((FX_DWORD)(1 << nTmp) < SBSTRIPS) {
           nTmp++;
@@ -81,6 +78,7 @@ CJBig2_Image* CJBig2_TRDProc::decode_Huffman(CJBig2_BitStream* pStream,
       TI = STRIPT + CURT;
       nVal = 0;
       nBits = 0;
+      FX_DWORD IDI;
       for (;;) {
         if (pStream->read1Bit(&nTmp) != 0)
           return nullptr;
@@ -219,9 +217,7 @@ CJBig2_Image* CJBig2_TRDProc::decode_Arith(CJBig2_ArithDecoder* pArithDecoder,
   int32_t STRIPT, FIRSTS;
   FX_DWORD NINSTANCES;
   int32_t DT, DFS, CURS;
-  int32_t CURT;
   int32_t SI, TI;
-  FX_DWORD IDI;
   CJBig2_Image* IBI;
   FX_DWORD WI, HI;
   int32_t IDS;
@@ -230,7 +226,7 @@ CJBig2_Image* CJBig2_TRDProc::decode_Arith(CJBig2_ArithDecoder* pArithDecoder,
   CJBig2_Image* IBOI;
   FX_DWORD WOI, HOI;
   FX_BOOL bFirst;
-  int32_t nRet, nVal;
+  int32_t nRet;
   int32_t bRetained;
   CJBig2_ArithIntDecoder* IADT, *IAFS, *IADS, *IAIT, *IARI, *IARDW, *IARDH,
       *IARDX, *IARDY;
@@ -262,7 +258,7 @@ CJBig2_Image* CJBig2_TRDProc::decode_Arith(CJBig2_ArithDecoder* pArithDecoder,
   }
   nonstd::unique_ptr<CJBig2_Image> SBREG(new CJBig2_Image(SBW, SBH));
   SBREG->fill(SBDEFPIXEL);
-  if (IADT->decode(pArithDecoder, &STRIPT) == -1) {
+  if (!IADT->decode(pArithDecoder, &STRIPT)) {
     goto failed;
   }
   STRIPT *= SBSTRIPS;
@@ -270,7 +266,7 @@ CJBig2_Image* CJBig2_TRDProc::decode_Arith(CJBig2_ArithDecoder* pArithDecoder,
   FIRSTS = 0;
   NINSTANCES = 0;
   while (NINSTANCES < SBNUMINSTANCES) {
-    if (IADT->decode(pArithDecoder, &DT) == -1) {
+    if (!IADT->decode(pArithDecoder, &DT)) {
       goto failed;
     }
     DT *= SBSTRIPS;
@@ -278,7 +274,7 @@ CJBig2_Image* CJBig2_TRDProc::decode_Arith(CJBig2_ArithDecoder* pArithDecoder,
     bFirst = TRUE;
     for (;;) {
       if (bFirst) {
-        if (IAFS->decode(pArithDecoder, &DFS) == -1) {
+        if (!IAFS->decode(pArithDecoder, &DFS)) {
           goto failed;
         }
         FIRSTS = FIRSTS + DFS;
@@ -297,26 +293,22 @@ CJBig2_Image* CJBig2_TRDProc::decode_Arith(CJBig2_ArithDecoder* pArithDecoder,
       if (NINSTANCES >= SBNUMINSTANCES) {
         break;
       }
-      if (SBSTRIPS == 1) {
-        CURT = 0;
-      } else {
-        if (IAIT->decode(pArithDecoder, &nVal) == -1) {
+      int CURT = 0;
+      if (SBSTRIPS != 1) {
+        if (!IAIT->decode(pArithDecoder, &CURT)) {
           goto failed;
         }
-        CURT = nVal;
       }
       TI = STRIPT + CURT;
-      if (IAID->decode(pArithDecoder, &nVal) == -1) {
-        goto failed;
-      }
-      IDI = nVal;
+      FX_DWORD IDI;
+      IAID->decode(pArithDecoder, &IDI);
       if (IDI >= SBNUMSYMS) {
         goto failed;
       }
       if (SBREFINE == 0) {
         RI = 0;
       } else {
-        if (IARI->decode(pArithDecoder, &RI) == -1) {
+        if (!IARI->decode(pArithDecoder, &RI)) {
           goto failed;
         }
       }
@@ -326,10 +318,10 @@ CJBig2_Image* CJBig2_TRDProc::decode_Arith(CJBig2_ArithDecoder* pArithDecoder,
       if (RI == 0) {
         IBI = SBSYMS[IDI];
       } else {
-        if ((IARDW->decode(pArithDecoder, &RDWI) == -1) ||
-            (IARDH->decode(pArithDecoder, &RDHI) == -1) ||
-            (IARDX->decode(pArithDecoder, &RDXI) == -1) ||
-            (IARDY->decode(pArithDecoder, &RDYI) == -1)) {
+        if (!IARDW->decode(pArithDecoder, &RDWI) ||
+            !IARDH->decode(pArithDecoder, &RDHI) ||
+            !IARDX->decode(pArithDecoder, &RDXI) ||
+            !IARDY->decode(pArithDecoder, &RDYI)) {
           goto failed;
         }
         IBOI = SBSYMS[IDI];