Fix include paths for fx_system.h
[pdfium.git] / core / src / fxcodec / jbig2 / JBig2_ArithIntDecoder.cpp
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);
 }