Move CalculatePitch code from fxcodec to fxge.

Move the utility functions to the lower layer, so it can be used there.

Remove unnecessary fx_codec.h includes along the way.

Change-Id: I30a5771cb12187ed36cf8b2a8195e3eba707b47f
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/90851
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/page/cpdf_dib.cpp b/core/fpdfapi/page/cpdf_dib.cpp
index 971ede0..304a280 100644
--- a/core/fpdfapi/page/cpdf_dib.cpp
+++ b/core/fpdfapi/page/cpdf_dib.cpp
@@ -26,7 +26,6 @@
 #include "core/fpdfapi/parser/fpdf_parser_decode.h"
 #include "core/fpdfapi/parser/fpdf_parser_utility.h"
 #include "core/fxcodec/basic/basicmodule.h"
-#include "core/fxcodec/fx_codec.h"
 #include "core/fxcodec/jbig2/jbig2_decoder.h"
 #include "core/fxcodec/jpeg/jpegmodule.h"
 #include "core/fxcodec/jpx/cjpx_decoder.h"
@@ -34,6 +33,7 @@
 #include "core/fxcrt/cfx_fixedbufgrow.h"
 #include "core/fxcrt/fx_safe_types.h"
 #include "core/fxcrt/span_util.h"
+#include "core/fxge/calculate_pitch.h"
 #include "core/fxge/dib/cfx_dibitmap.h"
 #include "third_party/base/check.h"
 #include "third_party/base/check_op.h"
@@ -184,7 +184,7 @@
     return false;
 
   const absl::optional<uint32_t> maybe_size =
-      fxcodec::CalculatePitch8(m_bpc, m_nComponents, m_Width);
+      fxge::CalculatePitch8(m_bpc, m_nComponents, m_Width);
   if (!maybe_size.has_value())
     return false;
 
@@ -207,7 +207,7 @@
     m_Format = MakeRGBFormat(CalculateBitsPerPixel(m_bpc, m_nComponents));
 
   absl::optional<uint32_t> pitch =
-      fxcodec::CalculatePitch32(GetBppFromFormat(m_Format), m_Width);
+      fxge::CalculatePitch32(GetBppFromFormat(m_Format), m_Width);
   if (!pitch.has_value())
     return false;
 
@@ -215,7 +215,7 @@
   LoadPalette();
   if (m_bColorKey) {
     m_Format = FXDIB_Format::kArgb;
-    pitch = fxcodec::CalculatePitch32(GetBppFromFormat(m_Format), m_Width);
+    pitch = fxge::CalculatePitch32(GetBppFromFormat(m_Format), m_Width);
     if (!pitch.has_value())
       return false;
 
@@ -236,7 +236,7 @@
   }
 
   absl::optional<uint32_t> pitch =
-      fxcodec::CalculatePitch32(GetBppFromFormat(m_Format), m_Width);
+      fxge::CalculatePitch32(GetBppFromFormat(m_Format), m_Width);
   if (!pitch.has_value())
     return false;
 
@@ -247,7 +247,7 @@
   LoadPalette();
   if (m_bColorKey) {
     m_Format = FXDIB_Format::kArgb;
-    pitch = fxcodec::CalculatePitch32(GetBppFromFormat(m_Format), m_Width);
+    pitch = fxge::CalculatePitch32(GetBppFromFormat(m_Format), m_Width);
     if (!pitch.has_value())
       return false;
     m_MaskBuf = std::vector<uint8_t, FxAllocAllocator<uint8_t>>(pitch.value());
@@ -288,7 +288,7 @@
     return LoadState::kFail;
 
   const absl::optional<uint32_t> maybe_size =
-      fxcodec::CalculatePitch8(m_bpc, m_nComponents, m_Width);
+      fxge::CalculatePitch8(m_bpc, m_nComponents, m_Width);
   if (!maybe_size.has_value())
     return LoadState::kFail;
 
@@ -553,10 +553,10 @@
     return LoadState::kFail;
 
   const absl::optional<uint32_t> requested_pitch =
-      fxcodec::CalculatePitch8(m_bpc, m_nComponents, m_Width);
+      fxge::CalculatePitch8(m_bpc, m_nComponents, m_Width);
   if (!requested_pitch.has_value())
     return LoadState::kFail;
-  const absl::optional<uint32_t> provided_pitch = fxcodec::CalculatePitch8(
+  const absl::optional<uint32_t> provided_pitch = fxge::CalculatePitch8(
       m_pDecoder->GetBPC(), m_pDecoder->CountComps(), m_pDecoder->GetWidth());
   if (!provided_pitch.has_value())
     return LoadState::kFail;
@@ -1091,7 +1091,7 @@
     return pdfium::span<const uint8_t>();
 
   const absl::optional<uint32_t> src_pitch =
-      fxcodec::CalculatePitch8(m_bpc, m_nComponents, m_Width);
+      fxge::CalculatePitch8(m_bpc, m_nComponents, m_Width);
   if (!src_pitch.has_value())
     return pdfium::span<const uint8_t>();
 
diff --git a/core/fpdfapi/page/cpdf_streamparser.cpp b/core/fpdfapi/page/cpdf_streamparser.cpp
index b134e50..333108b 100644
--- a/core/fpdfapi/page/cpdf_streamparser.cpp
+++ b/core/fpdfapi/page/cpdf_streamparser.cpp
@@ -24,13 +24,13 @@
 #include "core/fpdfapi/parser/cpdf_string.h"
 #include "core/fpdfapi/parser/fpdf_parser_decode.h"
 #include "core/fpdfapi/parser/fpdf_parser_utility.h"
-#include "core/fxcodec/fx_codec.h"
 #include "core/fxcodec/jpeg/jpegmodule.h"
 #include "core/fxcodec/scanlinedecoder.h"
 #include "core/fxcrt/fx_extension.h"
 #include "core/fxcrt/fx_memory_wrappers.h"
 #include "core/fxcrt/fx_safe_types.h"
 #include "core/fxcrt/span_util.h"
+#include "core/fxge/calculate_pitch.h"
 #include "third_party/base/check.h"
 
 namespace {
@@ -54,7 +54,7 @@
     return FX_INVALID_OFFSET;
 
   absl::optional<uint32_t> maybe_size =
-      fxcodec::CalculatePitch8(bpc, ncomps, width);
+      fxge::CalculatePitch8(bpc, ncomps, width);
   if (!maybe_size.has_value())
     return FX_INVALID_OFFSET;
 
@@ -165,7 +165,7 @@
     bpc = pDict->GetIntegerFor("BitsPerComponent");
   }
   absl::optional<uint32_t> maybe_size =
-      fxcodec::CalculatePitch8(bpc, nComponents, width);
+      fxge::CalculatePitch8(bpc, nComponents, width);
   if (!maybe_size.has_value())
     return nullptr;
 
diff --git a/core/fpdfapi/page/cpdf_transferfuncdib.cpp b/core/fpdfapi/page/cpdf_transferfuncdib.cpp
index 96ddbf0..cba7de1 100644
--- a/core/fpdfapi/page/cpdf_transferfuncdib.cpp
+++ b/core/fpdfapi/page/cpdf_transferfuncdib.cpp
@@ -9,6 +9,7 @@
 #include "build/build_config.h"
 #include "core/fpdfapi/page/cpdf_transferfunc.h"
 #include "core/fpdfapi/parser/cpdf_dictionary.h"
+#include "core/fxge/calculate_pitch.h"
 #include "third_party/base/check.h"
 #include "third_party/base/compiler_specific.h"
 
@@ -23,7 +24,7 @@
   m_Width = pSrc->GetWidth();
   m_Height = pSrc->GetHeight();
   m_Format = GetDestFormat();
-  m_Pitch = (m_Width * GetBppFromFormat(m_Format) + 31) / 32 * 4;
+  m_Pitch = fxge::CalculatePitch32OrDie(GetBppFromFormat(m_Format), m_Width);
   m_Scanline.resize(m_Pitch);
   DCHECK(m_palette.empty());
 }
diff --git a/core/fpdfapi/parser/fpdf_parser_decode.cpp b/core/fpdfapi/parser/fpdf_parser_decode.cpp
index 9a5a8eb..f6e3c8c 100644
--- a/core/fpdfapi/parser/fpdf_parser_decode.cpp
+++ b/core/fpdfapi/parser/fpdf_parser_decode.cpp
@@ -19,7 +19,6 @@
 #include "core/fpdfapi/parser/fpdf_parser_utility.h"
 #include "core/fxcodec/fax/faxmodule.h"
 #include "core/fxcodec/flate/flatemodule.h"
-#include "core/fxcodec/fx_codec.h"
 #include "core/fxcodec/scanlinedecoder.h"
 #include "core/fxcrt/fx_extension.h"
 #include "core/fxcrt/fx_safe_types.h"
diff --git a/core/fxcodec/bmp/cfx_bmpdecompressor.cpp b/core/fxcodec/bmp/cfx_bmpdecompressor.cpp
index cf4b180..b37c70d 100644
--- a/core/fxcodec/bmp/cfx_bmpdecompressor.cpp
+++ b/core/fxcodec/bmp/cfx_bmpdecompressor.cpp
@@ -12,10 +12,10 @@
 
 #include "core/fxcodec/bmp/cfx_bmpcontext.h"
 #include "core/fxcodec/cfx_codec_memory.h"
-#include "core/fxcodec/fx_codec.h"
 #include "core/fxcrt/fx_memory_wrappers.h"
 #include "core/fxcrt/fx_safe_types.h"
 #include "core/fxcrt/fx_system.h"
+#include "core/fxge/calculate_pitch.h"
 #include "third_party/base/numerics/safe_math.h"
 
 namespace fxcodec {
@@ -224,7 +224,7 @@
     default:
       return BmpDecoder::Status::kFail;
   }
-  absl::optional<uint32_t> stride = CalculatePitch32(bit_counts_, width_);
+  absl::optional<uint32_t> stride = fxge::CalculatePitch32(bit_counts_, width_);
   if (!stride.has_value())
     return BmpDecoder::Status::kFail;
 
@@ -233,7 +233,7 @@
     case 1:
     case 4:
     case 8:
-      stride = CalculatePitch32(8, width_);
+      stride = fxge::CalculatePitch32(8, width_);
       if (!stride.has_value())
         return BmpDecoder::Status::kFail;
       out_row_bytes_ = stride.value();
@@ -241,7 +241,7 @@
       break;
     case 16:
     case 24:
-      stride = CalculatePitch32(24, width_);
+      stride = fxge::CalculatePitch32(24, width_);
       if (!stride.has_value())
         return BmpDecoder::Status::kFail;
       out_row_bytes_ = stride.value();
diff --git a/core/fxcodec/fax/faxmodule.cpp b/core/fxcodec/fax/faxmodule.cpp
index 9386f82..753cd6e 100644
--- a/core/fxcodec/fax/faxmodule.cpp
+++ b/core/fxcodec/fax/faxmodule.cpp
@@ -12,11 +12,11 @@
 #include <vector>
 
 #include "build/build_config.h"
-#include "core/fxcodec/fx_codec.h"
 #include "core/fxcodec/scanlinedecoder.h"
 #include "core/fxcrt/cfx_binarybuf.h"
 #include "core/fxcrt/fx_memory_wrappers.h"
 #include "core/fxcrt/stl_util.h"
+#include "core/fxge/calculate_pitch.h"
 #include "third_party/base/check.h"
 #include "third_party/base/check_op.h"
 #include "third_party/base/cxx17_backports.h"
@@ -498,7 +498,7 @@
                       height,
                       kFaxComps,
                       kFaxBpc,
-                      CalculatePitch32OrDie(kFaxBpc, width)),
+                      fxge::CalculatePitch32OrDie(kFaxBpc, width)),
       m_Encoding(K),
       m_bByteAlign(EncodedByteAlign),
       m_bEndOfLine(EndOfLine),
diff --git a/core/fxcodec/flate/flatemodule.cpp b/core/fxcodec/flate/flatemodule.cpp
index 9dd3603..1c5f4de 100644
--- a/core/fxcodec/flate/flatemodule.cpp
+++ b/core/fxcodec/flate/flatemodule.cpp
@@ -14,11 +14,11 @@
 #include <utility>
 #include <vector>
 
-#include "core/fxcodec/fx_codec.h"
 #include "core/fxcodec/scanlinedecoder.h"
 #include "core/fxcrt/fx_extension.h"
 #include "core/fxcrt/fx_memory_wrappers.h"
 #include "core/fxcrt/fx_safe_types.h"
+#include "core/fxge/calculate_pitch.h"
 #include "third_party/base/check.h"
 #include "third_party/base/notreached.h"
 #include "third_party/base/numerics/safe_conversions.h"
@@ -302,7 +302,7 @@
   uint8_t* pDestData = dest_span.data();
   const uint8_t* pSrcData = src_span.data();
   const uint8_t* pLastLine = last_span.data();
-  const uint32_t row_size = CalculatePitch8OrDie(bpc, nColors, nPixels);
+  const uint32_t row_size = fxge::CalculatePitch8OrDie(bpc, nColors, nPixels);
   const uint32_t BytesPerPixel = (bpc * nColors + 7) / 8;
   uint8_t tag = pSrcData[0];
   if (tag == 0) {
@@ -630,7 +630,7 @@
                       height,
                       nComps,
                       bpc,
-                      CalculatePitch8OrDie(bpc, nComps, width)),
+                      fxge::CalculatePitch8OrDie(bpc, nComps, width)),
       m_SrcBuf(src_span),
       m_Scanline(m_Pitch) {}
 
@@ -711,7 +711,7 @@
   m_BitsPerComponent = BitsPerComponent;
   m_Columns = Columns;
   m_PredictPitch =
-      CalculatePitch8OrDie(m_BitsPerComponent, m_Colors, m_Columns);
+      fxge::CalculatePitch8OrDie(m_BitsPerComponent, m_Colors, m_Columns);
   m_LastLine.resize(m_PredictPitch);
   m_PredictBuffer.resize(m_PredictPitch);
   m_PredictRaw.resize(m_PredictPitch + 1);
diff --git a/core/fxcodec/fx_codec.cpp b/core/fxcodec/fx_codec.cpp
index dd7d3e8..4c92024 100644
--- a/core/fxcodec/fx_codec.cpp
+++ b/core/fxcodec/fx_codec.cpp
@@ -6,37 +6,11 @@
 
 #include "core/fxcodec/fx_codec.h"
 
-#include <algorithm>
 #include <utility>
 
-#include "core/fxcrt/fx_memory.h"
-#include "core/fxcrt/fx_safe_types.h"
 #include "core/fxge/dib/fx_dib.h"
 
 namespace fxcodec {
-namespace {
-
-FX_SAFE_UINT32 CalculatePitch8Safely(uint32_t bpc,
-                                     uint32_t components,
-                                     int width) {
-  FX_SAFE_UINT32 pitch = bpc;
-  pitch *= components;
-  pitch *= width;
-  pitch += 7;
-  pitch /= 8;
-  return pitch;
-}
-
-FX_SAFE_UINT32 CalculatePitch32Safely(int bpp, int width) {
-  FX_SAFE_UINT32 pitch = bpp;
-  pitch *= width;
-  pitch += 31;
-  pitch /= 32;  // quantized to number of 32-bit words.
-  pitch *= 4;   // and then back to bytes, (not just /8 in one step).
-  return pitch;
-}
-
-}  // namespace
 
 #ifdef PDF_ENABLE_XFA
 CFX_DIBAttribute::CFX_DIBAttribute() = default;
@@ -59,28 +33,4 @@
   }
 }
 
-uint32_t CalculatePitch8OrDie(uint32_t bpc, uint32_t components, int width) {
-  return CalculatePitch8Safely(bpc, components, width).ValueOrDie();
-}
-
-uint32_t CalculatePitch32OrDie(int bpp, int width) {
-  return CalculatePitch32Safely(bpp, width).ValueOrDie();
-}
-
-absl::optional<uint32_t> CalculatePitch8(uint32_t bpc,
-                                         uint32_t components,
-                                         int width) {
-  FX_SAFE_UINT32 pitch = CalculatePitch8Safely(bpc, components, width);
-  if (!pitch.IsValid())
-    return absl::nullopt;
-  return pitch.ValueOrDie();
-}
-
-absl::optional<uint32_t> CalculatePitch32(int bpp, int width) {
-  FX_SAFE_UINT32 pitch = CalculatePitch32Safely(bpp, width);
-  if (!pitch.IsValid())
-    return absl::nullopt;
-  return pitch.ValueOrDie();
-}
-
 }  // namespace fxcodec
diff --git a/core/fxcodec/fx_codec.h b/core/fxcodec/fx_codec.h
index c0724cf..df99bd9 100644
--- a/core/fxcodec/fx_codec.h
+++ b/core/fxcodec/fx_codec.h
@@ -9,8 +9,6 @@
 
 #include <stdint.h>
 
-#include "third_party/abseil-cpp/absl/types/optional.h"
-
 namespace fxcodec {
 
 #ifdef PDF_ENABLE_XFA
@@ -36,13 +34,6 @@
 
 void ReverseRGB(uint8_t* pDestBuf, const uint8_t* pSrcBuf, int pixels);
 
-uint32_t CalculatePitch8OrDie(uint32_t bpc, uint32_t components, int width);
-uint32_t CalculatePitch32OrDie(int bpp, int width);
-absl::optional<uint32_t> CalculatePitch8(uint32_t bpc,
-                                         uint32_t components,
-                                         int width);
-absl::optional<uint32_t> CalculatePitch32(int bpp, int width);
-
 }  // namespace fxcodec
 
 #ifdef PDF_ENABLE_XFA
diff --git a/core/fxcodec/gif/gif_decoder.cpp b/core/fxcodec/gif/gif_decoder.cpp
index 57f5432..c753449 100644
--- a/core/fxcodec/gif/gif_decoder.cpp
+++ b/core/fxcodec/gif/gif_decoder.cpp
@@ -7,7 +7,6 @@
 #include "core/fxcodec/gif/gif_decoder.h"
 
 #include "core/fxcodec/cfx_codec_memory.h"
-#include "core/fxcodec/fx_codec.h"
 #include "core/fxcodec/gif/cfx_gifcontext.h"
 #include "core/fxge/dib/fx_dib.h"
 
diff --git a/core/fxcodec/jpeg/jpegmodule.cpp b/core/fxcodec/jpeg/jpegmodule.cpp
index 1d00698..fe2ee09 100644
--- a/core/fxcodec/jpeg/jpegmodule.cpp
+++ b/core/fxcodec/jpeg/jpegmodule.cpp
@@ -15,7 +15,6 @@
 
 #include "build/build_config.h"
 #include "core/fxcodec/cfx_codec_memory.h"
-#include "core/fxcodec/fx_codec.h"
 #include "core/fxcodec/jpeg/jpeg_common.h"
 #include "core/fxcodec/scanlinedecoder.h"
 #include "core/fxcrt/fx_memory_wrappers.h"
diff --git a/core/fxge/BUILD.gn b/core/fxge/BUILD.gn
index 23f80e1..260913a 100644
--- a/core/fxge/BUILD.gn
+++ b/core/fxge/BUILD.gn
@@ -18,6 +18,8 @@
 
 source_set("fxge") {
   sources = [
+    "calculate_pitch.cpp",
+    "calculate_pitch.h",
     "cfx_cliprgn.cpp",
     "cfx_cliprgn.h",
     "cfx_color.cpp",
diff --git a/core/fxge/calculate_pitch.cpp b/core/fxge/calculate_pitch.cpp
new file mode 100644
index 0000000..9a9801a
--- /dev/null
+++ b/core/fxge/calculate_pitch.cpp
@@ -0,0 +1,59 @@
+// Copyright 2022 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/fxge/calculate_pitch.h"
+
+#include "core/fxcrt/fx_safe_types.h"
+#include "core/fxge/dib/fx_dib.h"
+
+namespace fxge {
+namespace {
+
+FX_SAFE_UINT32 CalculatePitch8Safely(uint32_t bpc,
+                                     uint32_t components,
+                                     int width) {
+  FX_SAFE_UINT32 pitch = bpc;
+  pitch *= components;
+  pitch *= width;
+  pitch += 7;
+  pitch /= 8;
+  return pitch;
+}
+
+FX_SAFE_UINT32 CalculatePitch32Safely(int bpp, int width) {
+  FX_SAFE_UINT32 pitch = bpp;
+  pitch *= width;
+  pitch += 31;
+  pitch /= 32;  // quantized to number of 32-bit words.
+  pitch *= 4;   // and then back to bytes, (not just /8 in one step).
+  return pitch;
+}
+
+}  // namespace
+
+uint32_t CalculatePitch8OrDie(uint32_t bpc, uint32_t components, int width) {
+  return CalculatePitch8Safely(bpc, components, width).ValueOrDie();
+}
+
+uint32_t CalculatePitch32OrDie(int bpp, int width) {
+  return CalculatePitch32Safely(bpp, width).ValueOrDie();
+}
+
+absl::optional<uint32_t> CalculatePitch8(uint32_t bpc,
+                                         uint32_t components,
+                                         int width) {
+  FX_SAFE_UINT32 pitch = CalculatePitch8Safely(bpc, components, width);
+  if (!pitch.IsValid())
+    return absl::nullopt;
+  return pitch.ValueOrDie();
+}
+
+absl::optional<uint32_t> CalculatePitch32(int bpp, int width) {
+  FX_SAFE_UINT32 pitch = CalculatePitch32Safely(bpp, width);
+  if (!pitch.IsValid())
+    return absl::nullopt;
+  return pitch.ValueOrDie();
+}
+
+}  // namespace fxge
diff --git a/core/fxge/calculate_pitch.h b/core/fxge/calculate_pitch.h
new file mode 100644
index 0000000..09b35d6
--- /dev/null
+++ b/core/fxge/calculate_pitch.h
@@ -0,0 +1,23 @@
+// Copyright 2022 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CORE_FXGE_CALCULATE_PITCH_H_
+#define CORE_FXGE_CALCULATE_PITCH_H_
+
+#include <stdint.h>
+
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace fxge {
+
+uint32_t CalculatePitch8OrDie(uint32_t bpc, uint32_t components, int width);
+uint32_t CalculatePitch32OrDie(int bpp, int width);
+absl::optional<uint32_t> CalculatePitch8(uint32_t bpc,
+                                         uint32_t components,
+                                         int width);
+absl::optional<uint32_t> CalculatePitch32(int bpp, int width);
+
+}  // namespace fxge
+
+#endif  // CORE_FXGE_CALCULATE_PITCH_H_
diff --git a/core/fxge/dib/cfx_dibitmap.cpp b/core/fxge/dib/cfx_dibitmap.cpp
index 7dc8cae..2141fba 100644
--- a/core/fxge/dib/cfx_dibitmap.cpp
+++ b/core/fxge/dib/cfx_dibitmap.cpp
@@ -16,6 +16,7 @@
 #include "build/build_config.h"
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/fx_safe_types.h"
+#include "core/fxge/calculate_pitch.h"
 #include "core/fxge/cfx_cliprgn.h"
 #include "core/fxge/dib/cfx_scanlinecompositor.h"
 #include "third_party/base/check.h"
@@ -1068,7 +1069,7 @@
     return true;
   }
   int dest_bpp = GetBppFromFormat(dest_format);
-  int dest_pitch = (dest_bpp * m_Width + 31) / 32 * 4;
+  int dest_pitch = fxge::CalculatePitch32OrDie(dest_bpp, m_Width);
   std::unique_ptr<uint8_t, FxFreeDeleter> dest_buf(
       FX_TryAlloc(uint8_t, dest_pitch * m_Height + 4));
   if (!dest_buf)
diff --git a/core/fxge/dib/cstretchengine.cpp b/core/fxge/dib/cstretchengine.cpp
index 8fbd0c8..5c96dcb 100644
--- a/core/fxge/dib/cstretchengine.cpp
+++ b/core/fxge/dib/cstretchengine.cpp
@@ -6,7 +6,6 @@
 
 #include "core/fxge/dib/cstretchengine.h"
 
-#include <limits.h>
 #include <math.h>
 
 #include <algorithm>
@@ -16,6 +15,7 @@
 #include "core/fxcrt/fx_safe_types.h"
 #include "core/fxcrt/fx_system.h"
 #include "core/fxcrt/pauseindicator_iface.h"
+#include "core/fxge/calculate_pitch.h"
 #include "core/fxge/dib/cfx_dibbase.h"
 #include "core/fxge/dib/cfx_dibitmap.h"
 #include "core/fxge/dib/fx_dib.h"
@@ -27,14 +27,6 @@
     std::is_trivially_destructible<CStretchEngine::PixelWeight>::value,
     "PixelWeight storage may be re-used without invoking its destructor");
 
-namespace {
-
-int GetPitchRoundUpTo4Bytes(int bits_per_pixel) {
-  return (bits_per_pixel + 31) / 32 * 4;
-}
-
-}  // namespace
-
 // static
 size_t CStretchEngine::PixelWeight::TotalBytesForWeightCount(
     size_t weight_count) {
@@ -187,20 +179,16 @@
       m_DestWidth(dest_width),
       m_DestHeight(dest_height),
       m_DestClip(clip_rect) {
-  uint32_t size = clip_rect.Width();
-  if (size && m_DestBpp > static_cast<int>(INT_MAX / size))
+  absl::optional<uint32_t> maybe_size =
+      fxge::CalculatePitch32(m_DestBpp, clip_rect.Width());
+  if (!maybe_size.has_value())
     return;
 
-  size *= m_DestBpp;
-  if (size > INT_MAX - 31)
-    return;
-
-  size = GetPitchRoundUpTo4Bytes(size);
-  m_DestScanline.resize(size);
+  m_DestScanline.resize(maybe_size.value());
   if (dest_format == FXDIB_Format::kRgb32)
     std::fill(m_DestScanline.begin(), m_DestScanline.end(), 255);
-  m_InterPitch = GetPitchRoundUpTo4Bytes(m_DestClip.Width() * m_DestBpp);
-  m_ExtraMaskPitch = GetPitchRoundUpTo4Bytes(m_DestClip.Width() * 8);
+  m_InterPitch = fxge::CalculatePitch32OrDie(m_DestBpp, m_DestClip.Width());
+  m_ExtraMaskPitch = fxge::CalculatePitch32OrDie(8, m_DestClip.Width());
   if (options.bNoSmoothing) {
     m_ResampleOptions.bNoSmoothing = true;
   } else {