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_