Remove some unnecessary copies in CJBig2_SDDProc.

In 2 nearly identical spots, the code constructs a vector of pointers
and then only uses 1 element from the vector. Instead, do not construct
the vector, and just initialize a pointer. Since the 2 spots are very
similar, extract out the common logic into a helper function.

Change-Id: I79472f161e773e69c2989b23e19939e03154d66b
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/92873
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fxcodec/jbig2/JBig2_SddProc.cpp b/core/fxcodec/jbig2/JBig2_SddProc.cpp
index 97e0bc7..115feeb 100644
--- a/core/fxcodec/jbig2/JBig2_SddProc.cpp
+++ b/core/fxcodec/jbig2/JBig2_SddProc.cpp
@@ -165,27 +165,24 @@
         } else if (REFAGGNINST == 1) {
           uint8_t SBNUMSYMS = SDNUMINSYMS + NSYMSDECODED;
           uint32_t IDI;
-          int32_t RDXI;
-          int32_t RDYI;
           IAID->Decode(pArithDecoder, &IDI);
-          IARDX->Decode(pArithDecoder, &RDXI);
-          IARDY->Decode(pArithDecoder, &RDYI);
           if (IDI >= SBNUMSYMS)
             return nullptr;
 
-          std::vector<CJBig2_Image*> SBSYMS;  // Pointers are not owned
-          SBSYMS.resize(SBNUMSYMS);
-          std::copy(SDINSYMS, SDINSYMS + SDNUMINSYMS, SBSYMS.begin());
-          for (size_t i = 0; i < NSYMSDECODED; ++i)
-            SBSYMS[i + SDNUMINSYMS] = SDNEWSYMS[i].get();
-          if (!SBSYMS[IDI])
+          CJBig2_Image* sbsyms_idi = GetImage(IDI, SDNEWSYMS);
+          if (!sbsyms_idi)
             return nullptr;
 
+          int32_t RDXI;
+          int32_t RDYI;
+          IARDX->Decode(pArithDecoder, &RDXI);
+          IARDY->Decode(pArithDecoder, &RDYI);
+
           auto pGRRD = std::make_unique<CJBig2_GRRDProc>();
           pGRRD->GRW = SYMWIDTH;
           pGRRD->GRH = HCHEIGHT;
           pGRRD->GRTEMPLATE = SDRTEMPLATE;
-          pGRRD->GRREFERENCE = SBSYMS[IDI];
+          pGRRD->GRREFERENCE = sbsyms_idi;
           pGRRD->GRREFERENCEDX = RDXI;
           pGRRD->GRREFERENCEDY = RDYI;
           pGRRD->TPGRON = false;
@@ -366,6 +363,11 @@
             if (IDI < SBNUMSYMS)
               break;
           }
+
+          CJBig2_Image* sbsyms_idi = GetImage(IDI, SDNEWSYMS);
+          if (!sbsyms_idi)
+            return nullptr;
+
           auto SBHUFFRDX = std::make_unique<CJBig2_HuffmanTable>(15);
           auto SBHUFFRSIZE = std::make_unique<CJBig2_HuffmanTable>(1);
           int32_t RDXI;
@@ -375,18 +377,15 @@
               (pHuffmanDecoder->DecodeAValue(SBHUFFRSIZE.get(), &nVal) != 0)) {
             return nullptr;
           }
+
           pStream->alignByte();
           nTmp = pStream->getOffset();
-          std::vector<CJBig2_Image*> SBSYMS;  // Pointers are not owned
-          SBSYMS.resize(SBNUMSYMS);
-          std::copy(SDINSYMS, SDINSYMS + SDNUMINSYMS, SBSYMS.begin());
-          for (size_t i = 0; i < NSYMSDECODED; ++i)
-            SBSYMS[i + SDNUMINSYMS] = SDNEWSYMS[i].get();
+
           auto pGRRD = std::make_unique<CJBig2_GRRDProc>();
           pGRRD->GRW = SYMWIDTH;
           pGRRD->GRH = HCHEIGHT;
           pGRRD->GRTEMPLATE = SDRTEMPLATE;
-          pGRRD->GRREFERENCE = SBSYMS[IDI];
+          pGRRD->GRREFERENCE = sbsyms_idi;
           pGRRD->GRREFERENCEDX = RDXI;
           pGRRD->GRREFERENCEDY = RDYI;
           pGRRD->TPGRON = false;
@@ -495,3 +494,9 @@
   }
   return pDict;
 }
+
+CJBig2_Image* CJBig2_SDDProc::GetImage(
+    uint32_t i,
+    pdfium::span<const std::unique_ptr<CJBig2_Image>> new_syms) const {
+  return i < SDNUMINSYMS ? SDINSYMS[i] : new_syms[i - SDNUMINSYMS].get();
+}
diff --git a/core/fxcodec/jbig2/JBig2_SddProc.h b/core/fxcodec/jbig2/JBig2_SddProc.h
index f7312d2..0cca2d9 100644
--- a/core/fxcodec/jbig2/JBig2_SddProc.h
+++ b/core/fxcodec/jbig2/JBig2_SddProc.h
@@ -14,6 +14,7 @@
 
 #include "core/fxcodec/jbig2/JBig2_ArithDecoder.h"
 #include "core/fxcrt/unowned_ptr.h"
+#include "third_party/base/span.h"
 
 class CJBig2_BitStream;
 class CJBig2_HuffmanTable;
@@ -49,6 +50,13 @@
   UnownedPtr<const CJBig2_HuffmanTable> SDHUFFAGGINST;
   int8_t SDAT[8];
   int8_t SDRAT[4];
+
+ private:
+  // Reads from `SDINSYMS` if `i` is in-bounds. Otherwise, reduce `i` by
+  // `SDNUMINSYMS` and read from `new_syms` at the new index.
+  CJBig2_Image* GetImage(
+      uint32_t i,
+      pdfium::span<const std::unique_ptr<CJBig2_Image>> new_syms) const;
 };
 
 #endif  // CORE_FXCODEC_JBIG2_JBIG2_SDDPROC_H_