Cleanup in CCodec_FaxModule

This CL moves FaxG4Decode to the class where it's implemented. It should
remain there because it calls FaxG4GetRow, declared and used in the cpp
file. Do some ++ cleanup while at it.

This CL also makes CCodec_FaxModule own some methods that were
namespaced since doing so allows removing a bunch of parameters.

Change-Id: I24787f5668c7273b9bdb4009c3d0b29590c5552f
Reviewed-on: https://pdfium-review.googlesource.com/42950
Commit-Queue: Nicolás Peña Moreno <npm@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fxcodec/codec/ccodec_faxmodule.cpp b/core/fxcodec/codec/ccodec_faxmodule.cpp
index faa40da..423dfe6 100644
--- a/core/fxcodec/codec/ccodec_faxmodule.cpp
+++ b/core/fxcodec/codec/ccodec_faxmodule.cpp
@@ -555,25 +555,26 @@
   return std::min(static_cast<size_t>((m_bitpos + 7) / 8), m_SrcSpan.size());
 }
 
-void FaxG4Decode(const uint8_t* src_buf,
-                 uint32_t src_size,
-                 int* pbitpos,
-                 uint8_t* dest_buf,
-                 int width,
-                 int height,
-                 int pitch) {
+// static
+int CCodec_FaxModule::FaxG4Decode(const uint8_t* src_buf,
+                                  uint32_t src_size,
+                                  int starting_bitpos,
+                                  int width,
+                                  int height,
+                                  int pitch,
+                                  uint8_t* dest_buf) {
   if (pitch == 0)
     pitch = (width + 7) / 8;
 
   std::vector<uint8_t> ref_buf(pitch, 0xff);
-  int bitpos = *pbitpos;
-  for (int iRow = 0; iRow < height; iRow++) {
+  int bitpos = starting_bitpos;
+  for (int iRow = 0; iRow < height; ++iRow) {
     uint8_t* line_buf = dest_buf + iRow * pitch;
     memset(line_buf, 0xff, pitch);
     FaxG4GetRow(src_buf, src_size << 3, &bitpos, line_buf, ref_buf, width);
     memcpy(ref_buf.data(), line_buf, pitch);
   }
-  *pbitpos = bitpos;
+  return bitpos;
 }
 
 std::unique_ptr<CCodec_ScanlineDecoder> CCodec_FaxModule::CreateDecoder(
@@ -647,90 +648,6 @@
     0x17, 12, 0x1c, 12, 0x1d, 12, 0x1e, 12, 0x1f, 12,
 };
 
-void AddBitStream(uint8_t* dest_buf, int* dest_bitpos, int data, int bitlen) {
-  for (int i = bitlen - 1; i >= 0; i--) {
-    if (data & (1 << i))
-      dest_buf[*dest_bitpos / 8] |= 1 << (7 - *dest_bitpos % 8);
-    (*dest_bitpos)++;
-  }
-}
-
-void FaxEncodeRun(uint8_t* dest_buf, int* dest_bitpos, int run, bool bWhite) {
-  while (run >= 2560) {
-    AddBitStream(dest_buf, dest_bitpos, 0x1f, 12);
-    run -= 2560;
-  }
-  if (run >= 64) {
-    int markup = run - run % 64;
-    const uint8_t* p = bWhite ? WhiteRunMarkup : BlackRunMarkup;
-    p += (markup / 64 - 1) * 2;
-    AddBitStream(dest_buf, dest_bitpos, *p, p[1]);
-  }
-  run %= 64;
-  const uint8_t* p = bWhite ? WhiteRunTerminator : BlackRunTerminator;
-  p += run * 2;
-  AddBitStream(dest_buf, dest_bitpos, *p, p[1]);
-}
-
-void FaxEncode2DLine(uint8_t* dest_buf,
-                     int* dest_bitpos,
-                     const uint8_t* src_buf,
-                     const std::vector<uint8_t>& ref_buf,
-                     int cols) {
-  int a0 = -1;
-  bool a0color = true;
-  while (1) {
-    int a1 = FindBit(src_buf, cols, a0 + 1, !a0color);
-    int b1;
-    int b2;
-    FaxG4FindB1B2(ref_buf, cols, a0, a0color, &b1, &b2);
-    if (b2 < a1) {
-      *dest_bitpos += 3;
-      dest_buf[*dest_bitpos / 8] |= 1 << (7 - *dest_bitpos % 8);
-      (*dest_bitpos)++;
-      a0 = b2;
-    } else if (a1 - b1 <= 3 && b1 - a1 <= 3) {
-      int delta = a1 - b1;
-      switch (delta) {
-        case 0:
-          dest_buf[*dest_bitpos / 8] |= 1 << (7 - *dest_bitpos % 8);
-          break;
-        case 1:
-        case 2:
-        case 3:
-          *dest_bitpos += delta == 1 ? 1 : delta + 2;
-          dest_buf[*dest_bitpos / 8] |= 1 << (7 - *dest_bitpos % 8);
-          (*dest_bitpos)++;
-          dest_buf[*dest_bitpos / 8] |= 1 << (7 - *dest_bitpos % 8);
-          break;
-        case -1:
-        case -2:
-        case -3:
-          *dest_bitpos += delta == -1 ? 1 : -delta + 2;
-          dest_buf[*dest_bitpos / 8] |= 1 << (7 - *dest_bitpos % 8);
-          (*dest_bitpos)++;
-          break;
-      }
-      (*dest_bitpos)++;
-      a0 = a1;
-      a0color = !a0color;
-    } else {
-      int a2 = FindBit(src_buf, cols, a1 + 1, a0color);
-      (*dest_bitpos)++;
-      (*dest_bitpos)++;
-      dest_buf[*dest_bitpos / 8] |= 1 << (7 - *dest_bitpos % 8);
-      (*dest_bitpos)++;
-      if (a0 < 0)
-        a0 = 0;
-      FaxEncodeRun(dest_buf, dest_bitpos, a1 - a0, a0color);
-      FaxEncodeRun(dest_buf, dest_bitpos, a2 - a1, !a0color);
-      a0 = a2;
-    }
-    if (a0 >= cols)
-      return;
-  }
-}
-
 class CCodec_FaxEncoder {
  public:
   CCodec_FaxEncoder(const uint8_t* src_buf, int width, int height, int pitch);
@@ -739,9 +656,14 @@
               uint32_t* dest_size);
 
  private:
+  void FaxEncode2DLine(const uint8_t* src_buf);
+  void FaxEncodeRun(int run, bool bWhite);
+  void AddBitStream(int data, int bitlen);
+
   CFX_BinaryBuf m_DestBuf;
   std::vector<uint8_t> m_RefLine;
   uint8_t* m_pLineBuf;
+  int m_DestBitpos;
   const int m_Cols;
   const int m_Rows;
   const int m_Pitch;
@@ -763,22 +685,101 @@
   FX_Free(m_pLineBuf);
 }
 
+void CCodec_FaxEncoder::AddBitStream(int data, int bitlen) {
+  for (int i = bitlen - 1; i >= 0; --i, ++m_DestBitpos) {
+    if (data & (1 << i))
+      m_pLineBuf[m_DestBitpos / 8] |= 1 << (7 - m_DestBitpos % 8);
+  }
+}
+
+void CCodec_FaxEncoder::FaxEncodeRun(int run, bool bWhite) {
+  while (run >= 2560) {
+    AddBitStream(0x1f, 12);
+    run -= 2560;
+  }
+  if (run >= 64) {
+    int markup = run - run % 64;
+    const uint8_t* p = bWhite ? WhiteRunMarkup : BlackRunMarkup;
+    p += (markup / 64 - 1) * 2;
+    AddBitStream(*p, p[1]);
+  }
+  run %= 64;
+  const uint8_t* p = bWhite ? WhiteRunTerminator : BlackRunTerminator;
+  p += run * 2;
+  AddBitStream(*p, p[1]);
+}
+
+void CCodec_FaxEncoder::FaxEncode2DLine(const uint8_t* src_buf) {
+  int a0 = -1;
+  bool a0color = true;
+  while (1) {
+    int a1 = FindBit(src_buf, m_Cols, a0 + 1, !a0color);
+    int b1;
+    int b2;
+    FaxG4FindB1B2(m_RefLine, m_Cols, a0, a0color, &b1, &b2);
+    if (b2 < a1) {
+      m_DestBitpos += 3;
+      m_pLineBuf[m_DestBitpos / 8] |= 1 << (7 - m_DestBitpos % 8);
+      ++m_DestBitpos;
+      a0 = b2;
+    } else if (a1 - b1 <= 3 && b1 - a1 <= 3) {
+      int delta = a1 - b1;
+      switch (delta) {
+        case 0:
+          m_pLineBuf[m_DestBitpos / 8] |= 1 << (7 - m_DestBitpos % 8);
+          break;
+        case 1:
+        case 2:
+        case 3:
+          m_DestBitpos += delta == 1 ? 1 : delta + 2;
+          m_pLineBuf[m_DestBitpos / 8] |= 1 << (7 - m_DestBitpos % 8);
+          ++m_DestBitpos;
+          m_pLineBuf[m_DestBitpos / 8] |= 1 << (7 - m_DestBitpos % 8);
+          break;
+        case -1:
+        case -2:
+        case -3:
+          m_DestBitpos += delta == -1 ? 1 : -delta + 2;
+          m_pLineBuf[m_DestBitpos / 8] |= 1 << (7 - m_DestBitpos % 8);
+          ++m_DestBitpos;
+          break;
+      }
+      ++m_DestBitpos;
+      a0 = a1;
+      a0color = !a0color;
+    } else {
+      int a2 = FindBit(src_buf, m_Cols, a1 + 1, a0color);
+      ++m_DestBitpos;
+      ++m_DestBitpos;
+      m_pLineBuf[m_DestBitpos / 8] |= 1 << (7 - m_DestBitpos % 8);
+      ++m_DestBitpos;
+      if (a0 < 0)
+        a0 = 0;
+      FaxEncodeRun(a1 - a0, a0color);
+      FaxEncodeRun(a2 - a1, !a0color);
+      a0 = a2;
+    }
+    if (a0 >= m_Cols)
+      return;
+  }
+}
+
 void CCodec_FaxEncoder::Encode(
     std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
     uint32_t* dest_size) {
-  int dest_bitpos = 0;
+  m_DestBitpos = 0;
   uint8_t last_byte = 0;
-  for (int i = 0; i < m_Rows; i++) {
+  for (int i = 0; i < m_Rows; ++i) {
     const uint8_t* scan_line = m_pSrcBuf + i * m_Pitch;
     memset(m_pLineBuf, 0, m_Pitch * 8);
     m_pLineBuf[0] = last_byte;
-    FaxEncode2DLine(m_pLineBuf, &dest_bitpos, scan_line, m_RefLine, m_Cols);
-    m_DestBuf.AppendBlock(m_pLineBuf, dest_bitpos / 8);
-    last_byte = m_pLineBuf[dest_bitpos / 8];
-    dest_bitpos %= 8;
+    FaxEncode2DLine(scan_line);
+    m_DestBuf.AppendBlock(m_pLineBuf, m_DestBitpos / 8);
+    last_byte = m_pLineBuf[m_DestBitpos / 8];
+    m_DestBitpos %= 8;
     memcpy(m_RefLine.data(), scan_line, m_Pitch);
   }
-  if (dest_bitpos)
+  if (m_DestBitpos)
     m_DestBuf.AppendByte(last_byte);
   *dest_size = m_DestBuf.GetSize();
   *dest_buf = m_DestBuf.DetachBuffer();
diff --git a/core/fxcodec/codec/ccodec_faxmodule.h b/core/fxcodec/codec/ccodec_faxmodule.h
index 3d546d7..e43aea3 100644
--- a/core/fxcodec/codec/ccodec_faxmodule.h
+++ b/core/fxcodec/codec/ccodec_faxmodule.h
@@ -36,6 +36,15 @@
                         std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
                         uint32_t* dest_size);
 #endif  // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
+
+  // Return the ending bit position.
+  static int FaxG4Decode(const uint8_t* src_buf,
+                         uint32_t src_size,
+                         int starting_bitpos,
+                         int width,
+                         int height,
+                         int pitch,
+                         uint8_t* dest_buf);
 };
 
 #endif  // CORE_FXCODEC_CODEC_CCODEC_FAXMODULE_H_
diff --git a/core/fxcodec/fx_codec.h b/core/fxcodec/fx_codec.h
index 8e96676..3b15fd7 100644
--- a/core/fxcodec/fx_codec.h
+++ b/core/fxcodec/fx_codec.h
@@ -151,13 +151,6 @@
                                                          uint8_t m,
                                                          uint8_t y,
                                                          uint8_t k);
-void FaxG4Decode(const uint8_t* src_buf,
-                 uint32_t src_size,
-                 int* pbitpos,
-                 uint8_t* dest_buf,
-                 int width,
-                 int height,
-                 int pitch);
 
 FX_SAFE_UINT32 CalculatePitch8(uint32_t bpc, uint32_t components, int width);
 FX_SAFE_UINT32 CalculatePitch32(int bpp, int width);
diff --git a/core/fxcodec/jbig2/JBig2_GrdProc.cpp b/core/fxcodec/jbig2/JBig2_GrdProc.cpp
index d0fe440..278b5c0 100644
--- a/core/fxcodec/jbig2/JBig2_GrdProc.cpp
+++ b/core/fxcodec/jbig2/JBig2_GrdProc.cpp
@@ -10,6 +10,7 @@
 #include <memory>
 #include <utility>
 
+#include "core/fxcodec/codec/ccodec_faxmodule.h"
 #include "core/fxcodec/fx_codec.h"
 #include "core/fxcodec/jbig2/JBig2_ArithDecoder.h"
 #include "core/fxcodec/jbig2/JBig2_BitStream.h"
@@ -451,18 +452,18 @@
 FXCODEC_STATUS CJBig2_GRDProc::StartDecodeMMR(
     std::unique_ptr<CJBig2_Image>* pImage,
     CJBig2_BitStream* pStream) {
-  int bitpos, i;
   auto image = pdfium::MakeUnique<CJBig2_Image>(GBW, GBH);
   if (!image->data()) {
     *pImage = nullptr;
     m_ProssiveStatus = FXCODEC_STATUS_ERROR;
     return m_ProssiveStatus;
   }
-  bitpos = static_cast<int>(pStream->getBitPos());
-  FaxG4Decode(pStream->getBuf(), pStream->getLength(), &bitpos, image->data(),
-              GBW, GBH, image->stride());
+  int bitpos = static_cast<int>(pStream->getBitPos());
+  bitpos = CCodec_FaxModule::FaxG4Decode(pStream->getBuf(),
+                                         pStream->getLength(), bitpos, GBW, GBH,
+                                         image->stride(), image->data());
   pStream->setBitPos(bitpos);
-  for (i = 0; (uint32_t)i < image->stride() * GBH; ++i)
+  for (uint32_t i = 0; i < image->stride() * GBH; ++i)
     image->data()[i] = ~image->data()[i];
   m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
   *pImage = std::move(image);