Make CJBig2_GRDProc::DecodeArithOpt3() templated

DecodeArithOpt3() is a hotspot when decoding some JBIG2 images. Make it
templated so the compiler can see the `OPT` value is always 0/1/2 and
optimize for that. Do the same for DecodeArithTemplateUnopt().

Change-Id: Ia568ab386bc0f7d5d5b8311c00a52712d321212e
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/147771
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fxcodec/jbig2/jbig2_grd_proc.cpp b/core/fxcodec/jbig2/jbig2_grd_proc.cpp
index ea0bd10..14fb21d 100644
--- a/core/fxcodec/jbig2/jbig2_grd_proc.cpp
+++ b/core/fxcodec/jbig2/jbig2_grd_proc.cpp
@@ -97,16 +97,16 @@
   switch (GBTEMPLATE) {
     case 0:
       return UseTemplate0Opt3()
-                 ? DecodeArithOpt3(pArithDecoder, gbContexts, 0)
-                 : DecodeArithTemplateUnopt(pArithDecoder, gbContexts, 0);
+                 ? DecodeArithOpt3<0>(pArithDecoder, gbContexts)
+                 : DecodeArithTemplateUnopt<0>(pArithDecoder, gbContexts);
     case 1:
       return UseTemplate1Opt3()
-                 ? DecodeArithOpt3(pArithDecoder, gbContexts, 1)
-                 : DecodeArithTemplateUnopt(pArithDecoder, gbContexts, 1);
+                 ? DecodeArithOpt3<1>(pArithDecoder, gbContexts)
+                 : DecodeArithTemplateUnopt<1>(pArithDecoder, gbContexts);
     case 2:
       return UseTemplate23Opt3()
-                 ? DecodeArithOpt3(pArithDecoder, gbContexts, 2)
-                 : DecodeArithTemplateUnopt(pArithDecoder, gbContexts, 2);
+                 ? DecodeArithOpt3<2>(pArithDecoder, gbContexts)
+                 : DecodeArithTemplateUnopt<2>(pArithDecoder, gbContexts);
     default:
       return UseTemplate23Opt3()
                  ? DecodeArithTemplate3Opt3(pArithDecoder, gbContexts)
@@ -114,10 +114,10 @@
   }
 }
 
+template <int OPT>
 std::unique_ptr<CJBig2_Image> CJBig2_GRDProc::DecodeArithOpt3(
     CJBig2_ArithDecoder* pArithDecoder,
-    pdfium::span<JBig2ArithCtx> gbContexts,
-    int OPT) {
+    pdfium::span<JBig2ArithCtx> gbContexts) {
   auto GBREG = std::make_unique<CJBig2_Image>(GBW, GBH);
   if (!GBREG->has_data()) {
     return nullptr;
@@ -235,10 +235,10 @@
   return GBREG;
 }
 
+template <int UNOPT>
 std::unique_ptr<CJBig2_Image> CJBig2_GRDProc::DecodeArithTemplateUnopt(
     CJBig2_ArithDecoder* pArithDecoder,
-    pdfium::span<JBig2ArithCtx> gbContexts,
-    int UNOPT) {
+    pdfium::span<JBig2ArithCtx> gbContexts) {
   auto GBREG = std::make_unique<CJBig2_Image>(GBW, GBH);
   if (!GBREG->has_data()) {
     return nullptr;
diff --git a/core/fxcodec/jbig2/jbig2_grd_proc.h b/core/fxcodec/jbig2/jbig2_grd_proc.h
index 0b2cced..48be463 100644
--- a/core/fxcodec/jbig2/jbig2_grd_proc.h
+++ b/core/fxcodec/jbig2/jbig2_grd_proc.h
@@ -104,14 +104,14 @@
   void AdvanceLine(const CJBig2_Image* image);
   void CopyPrevLine(CJBig2_Image* image);
 
+  template <int OPT>
   std::unique_ptr<CJBig2_Image> DecodeArithOpt3(
       CJBig2_ArithDecoder* pArithDecoder,
-      pdfium::span<JBig2ArithCtx> gbContexts,
-      int OPT);
+      pdfium::span<JBig2ArithCtx> gbContexts);
+  template <int UNOPT>
   std::unique_ptr<CJBig2_Image> DecodeArithTemplateUnopt(
       CJBig2_ArithDecoder* pArithDecoder,
-      pdfium::span<JBig2ArithCtx> gbContexts,
-      int UNOPT);
+      pdfium::span<JBig2ArithCtx> gbContexts);
   std::unique_ptr<CJBig2_Image> DecodeArithTemplate3Opt3(
       CJBig2_ArithDecoder* pArithDecoder,
       pdfium::span<JBig2ArithCtx> gbContexts);