Remove GetBits32().

Replace it with CFX_BitStream.

Change-Id: Ib74657f888b8dec8b6fdad7b49e28d250991c590
Reviewed-on: https://pdfium-review.googlesource.com/32852
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: dsinclair <dsinclair@chromium.org>
diff --git a/core/fpdfapi/page/cpdf_sampledfunc.cpp b/core/fpdfapi/page/cpdf_sampledfunc.cpp
index 9f19c1c..8ac4bb5 100644
--- a/core/fpdfapi/page/cpdf_sampledfunc.cpp
+++ b/core/fpdfapi/page/cpdf_sampledfunc.cpp
@@ -7,8 +7,8 @@
 #include "core/fpdfapi/page/cpdf_sampledfunc.h"
 
 #include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fxcrt/cfx_bitstream.h"
 #include "core/fxcrt/cfx_fixedbufgrow.h"
-#include "core/fxcrt/fx_extension.h"
 #include "core/fxcrt/fx_safe_types.h"
 
 namespace {
@@ -119,45 +119,53 @@
   if (!bits_to_output.IsValid())
     return false;
 
-  FX_SAFE_INT32 bitpos = pos;
-  bitpos *= bits_to_output.ValueOrDie();
-  if (!bitpos.IsValid())
-    return false;
+  int bits_to_skip;
+  {
+    FX_SAFE_INT32 bitpos = pos;
+    bitpos *= bits_to_output.ValueOrDie();
+    bits_to_skip = bitpos.ValueOrDefault(-1);
+    if (bits_to_skip < 0)
+      return false;
 
-  FX_SAFE_INT32 range_check = bitpos;
-  range_check += bits_to_output.ValueOrDie();
-  if (!range_check.IsValid())
-    return false;
+    FX_SAFE_INT32 range_check = bitpos;
+    range_check += bits_to_output.ValueOrDie();
+    if (!range_check.IsValid())
+      return false;
+  }
 
   pdfium::span<const uint8_t> pSampleData = m_pSampleStream->GetSpan();
   if (pSampleData.empty())
     return false;
 
-  for (uint32_t j = 0; j < m_nOutputs; j++, bitpos += m_nBitsPerSample) {
-    uint32_t sample =
-        GetBits32(pSampleData, bitpos.ValueOrDie(), m_nBitsPerSample);
+  CFX_BitStream bitstream(pSampleData);
+  bitstream.SkipBits(bits_to_skip);
+  for (uint32_t i = 0; i < m_nOutputs; ++i) {
+    uint32_t sample = bitstream.GetBits(m_nBitsPerSample);
     float encoded = sample;
-    for (uint32_t i = 0; i < m_nInputs; i++) {
-      if (index[i] == m_EncodeInfo[i].sizes - 1) {
-        if (index[i] == 0)
-          encoded = encoded_input[i] * sample;
+    for (uint32_t j = 0; j < m_nInputs; ++j) {
+      if (index[j] == m_EncodeInfo[j].sizes - 1) {
+        if (index[j] == 0)
+          encoded = encoded_input[j] * sample;
       } else {
-        FX_SAFE_INT32 bitpos2 = blocksize[i];
+        FX_SAFE_INT32 bitpos2 = blocksize[j];
         bitpos2 += pos;
         bitpos2 *= m_nOutputs;
-        bitpos2 += j;
+        bitpos2 += i;
         bitpos2 *= m_nBitsPerSample;
-        if (!bitpos2.IsValid())
+        int bits_to_skip2 = bitpos2.ValueOrDefault(-1);
+        if (bits_to_skip2 < 0)
           return false;
-        uint32_t sample1 =
-            GetBits32(pSampleData, bitpos2.ValueOrDie(), m_nBitsPerSample);
-        encoded += (encoded_input[i] - index[i]) *
-                   (static_cast<float>(sample1) - sample);
+
+        CFX_BitStream bitstream2(pSampleData);
+        bitstream2.SkipBits(bits_to_skip2);
+        float sample2 =
+            static_cast<float>(bitstream2.GetBits(m_nBitsPerSample));
+        encoded += (encoded_input[j] - index[j]) * (sample2 - sample);
       }
     }
-    results[j] =
-        Interpolate(encoded, 0, m_SampleMax, m_DecodeInfo[j].decode_min,
-                    m_DecodeInfo[j].decode_max);
+    results[i] =
+        Interpolate(encoded, 0, m_SampleMax, m_DecodeInfo[i].decode_min,
+                    m_DecodeInfo[i].decode_max);
   }
   return true;
 }
diff --git a/core/fxcrt/cfx_bitstream_unittest.cpp b/core/fxcrt/cfx_bitstream_unittest.cpp
index 991cd43..e70455b 100644
--- a/core/fxcrt/cfx_bitstream_unittest.cpp
+++ b/core/fxcrt/cfx_bitstream_unittest.cpp
@@ -3,9 +3,21 @@
 // found in the LICENSE file.
 
 #include "core/fxcrt/cfx_bitstream.h"
-#include "core/fxcrt/fx_extension.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+namespace {
+
+uint32_t ReferenceGetBits32(const uint8_t* pData, int bitpos, int nbits) {
+  int result = 0;
+  for (int i = 0; i < nbits; i++) {
+    if (pData[(bitpos + i) / 8] & (1 << (7 - (bitpos + i) % 8)))
+      result |= 1 << (nbits - i - 1);
+  }
+  return result;
+}
+
+}  // namespace
+
 TEST(fxcrt, BitStream) {
   static const uint8_t kData[] = {0x00, 0x11, 0x22, 0x33,
                                   0x44, 0x55, 0x66, 0x77};
@@ -106,14 +118,15 @@
   EXPECT_EQ(0U, bitstream.BitsRemaining());
 }
 
-TEST(fxcrt, BitStreamSameAsGetBit32) {
+TEST(fxcrt, BitStreamSameAsReferenceGetBits32) {
   unsigned char kData[] = {0xDE, 0x3F, 0xB1, 0x7C, 0x12, 0x9A, 0x04, 0x56};
   CFX_BitStream bitstream(kData);
-  for (uint32_t nbits = 1; nbits <= 32; ++nbits) {
+  for (int nbits = 1; nbits <= 32; ++nbits) {
     for (size_t bitpos = 0; bitpos < sizeof(kData) * 8 - nbits; ++bitpos) {
       bitstream.Rewind();
       bitstream.SkipBits(bitpos);
-      EXPECT_EQ(bitstream.GetBits(nbits), GetBits32(kData, bitpos, nbits));
+      EXPECT_EQ(bitstream.GetBits(nbits),
+                ReferenceGetBits32(kData, bitpos, nbits));
     }
   }
 }
diff --git a/core/fxcrt/fx_extension.cpp b/core/fxcrt/fx_extension.cpp
index e27c78d..c754a85 100644
--- a/core/fxcrt/fx_extension.cpp
+++ b/core/fxcrt/fx_extension.cpp
@@ -167,34 +167,3 @@
   FXSYS_IntToFourHexChars(0xDC00 + unicode % 0x400, buf + 4);
   return 8;
 }
-
-uint32_t GetBits32(pdfium::span<const uint8_t> pData, int bitpos, int nbits) {
-  ASSERT(0 < nbits && nbits <= 32);
-  size_t bytepos = bitpos / 8;
-  int bitShift;
-  int bitMask;
-  int dstShift;
-  int bitCount = bitpos & 0x07;
-  if (nbits < 8 && nbits + bitCount <= 8) {
-    bitShift = 8 - nbits - bitCount;
-    bitMask = (1 << nbits) - 1;
-    dstShift = 0;
-  } else {
-    bitShift = 0;
-    int bitOffset = 8 - bitCount;
-    bitMask = (1 << std::min(bitOffset, nbits)) - 1;
-    dstShift = nbits - bitOffset;
-  }
-  uint32_t result = static_cast<uint32_t>(
-      (pData[bytepos++] >> bitShift & bitMask) << dstShift);
-  while (dstShift >= 8) {
-    dstShift -= 8;
-    result |= pData[bytepos++] << dstShift;
-  }
-  if (dstShift > 0) {
-    bitShift = 8 - dstShift;
-    bitMask = (1 << dstShift) - 1;
-    result |= pData[bytepos++] >> bitShift & bitMask;
-  }
-  return result;
-}
diff --git a/core/fxcrt/fx_extension.h b/core/fxcrt/fx_extension.h
index f5c0dad..cef943f 100644
--- a/core/fxcrt/fx_extension.h
+++ b/core/fxcrt/fx_extension.h
@@ -92,6 +92,4 @@
 
 size_t FXSYS_ToUTF16BE(uint32_t unicode, char* buf);
 
-uint32_t GetBits32(pdfium::span<const uint8_t> pData, int bitpos, int nbits);
-
 #endif  // CORE_FXCRT_FX_EXTENSION_H_
diff --git a/core/fxcrt/fx_extension_unittest.cpp b/core/fxcrt/fx_extension_unittest.cpp
index 155b701..39f26b5 100644
--- a/core/fxcrt/fx_extension_unittest.cpp
+++ b/core/fxcrt/fx_extension_unittest.cpp
@@ -5,19 +5,6 @@
 #include "core/fxcrt/fx_extension.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace {
-
-uint32_t ReferenceGetBits32(const uint8_t* pData, int bitpos, int nbits) {
-  int result = 0;
-  for (int i = 0; i < nbits; i++) {
-    if (pData[(bitpos + i) / 8] & (1 << (7 - (bitpos + i) % 8)))
-      result |= 1 << (nbits - i - 1);
-  }
-  return result;
-}
-
-}  // namespace
-
 TEST(fxcrt, FXSYS_HexCharToInt) {
   EXPECT_EQ(10, FXSYS_HexCharToInt('a'));
   EXPECT_EQ(10, FXSYS_HexCharToInt('A'));
@@ -103,16 +90,6 @@
   EXPECT_STREQ("D840DC3E", buf);
 }
 
-TEST(fxcrt, GetBits32) {
-  unsigned char data[] = {0xDE, 0x3F, 0xB1, 0x7C, 0x12, 0x9A, 0x04, 0x56};
-  for (int nbits = 1; nbits <= 32; ++nbits) {
-    for (int bitpos = 0; bitpos < (int)sizeof(data) * 8 - nbits; ++bitpos) {
-      EXPECT_EQ(ReferenceGetBits32(data, bitpos, nbits),
-                GetBits32(data, bitpos, nbits));
-    }
-  }
-}
-
 TEST(fxcrt, FXSYS_wcstof) {
   int32_t used_len = 0;
   EXPECT_FLOAT_EQ(-12.0f, FXSYS_wcstof(L"-12", 3, &used_len));
diff --git a/core/fxge/skia/fx_skia_device.cpp b/core/fxge/skia/fx_skia_device.cpp
index 6dd19ea..c0cc4e4 100644
--- a/core/fxge/skia/fx_skia_device.cpp
+++ b/core/fxge/skia/fx_skia_device.cpp
@@ -15,7 +15,7 @@
 #include "core/fpdfapi/parser/cpdf_array.h"
 #include "core/fpdfapi/parser/cpdf_dictionary.h"
 #include "core/fpdfapi/parser/cpdf_stream_acc.h"
-#include "core/fxcrt/fx_extension.h"
+#include "core/fxcrt/cfx_bitstream.h"
 #include "core/fxcrt/fx_memory.h"
 #include "core/fxge/cfx_defaultrenderdevice.h"
 #include "core/fxge/cfx_font.h"
@@ -407,11 +407,12 @@
     colorsMax[i] = pFunc->GetRange(i * 2 + 1);
   }
   pdfium::span<const uint8_t> pSampleData = pFunc->GetSampleStream()->GetSpan();
+  CFX_BitStream bitstream(pSampleData);
   for (uint32_t i = 0; i < sampleCount; ++i) {
     float floatColors[3];
     for (uint32_t j = 0; j < 3; ++j) {
-      int sample = GetBits32(pSampleData, (i * 3 + j) * sampleSize, sampleSize);
-      float interp = (float)sample / (sampleCount - 1);
+      float sample = static_cast<float>(bitstream.GetBits(sampleSize));
+      float interp = sample / (sampleCount - 1);
       floatColors[j] = colorsMin[j] + (colorsMax[j] - colorsMin[j]) * interp;
     }
     SkColor color =