Add a ReadArrayElementsToVector() helper function.
For filling in std::vector<float> from CPDF_Array.
Change-Id: I4227f7e21d02976aa20c2806cb568ce661c01e6a
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/54870
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/page/cpdf_allstates.cpp b/core/fpdfapi/page/cpdf_allstates.cpp
index fd5eaa3..2485a06 100644
--- a/core/fpdfapi/page/cpdf_allstates.cpp
+++ b/core/fpdfapi/page/cpdf_allstates.cpp
@@ -14,6 +14,7 @@
#include "core/fpdfapi/page/cpdf_streamcontentparser.h"
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
+#include "core/fpdfapi/parser/fpdf_parser_utility.h"
#include "core/fxge/cfx_graphstatedata.h"
#include "third_party/base/compiler_specific.h"
#include "third_party/base/stl_util.h"
@@ -37,9 +38,7 @@
void CPDF_AllStates::SetLineDash(const CPDF_Array* pArray,
float phase,
float scale) {
- std::vector<float> dashes(pArray->size());
- for (size_t i = 0; i < pArray->size(); ++i)
- dashes[i] = pArray->GetNumberAt(i);
+ std::vector<float> dashes = ReadArrayElementsToVector(pArray, pArray->size());
m_GraphState.SetLineDash(std::move(dashes), phase, scale);
}
diff --git a/core/fpdfapi/page/cpdf_colorspace.cpp b/core/fpdfapi/page/cpdf_colorspace.cpp
index 9d054ca..a52a0a8 100644
--- a/core/fpdfapi/page/cpdf_colorspace.cpp
+++ b/core/fpdfapi/page/cpdf_colorspace.cpp
@@ -28,6 +28,7 @@
#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fpdfapi/parser/cpdf_stream_acc.h"
#include "core/fpdfapi/parser/cpdf_string.h"
+#include "core/fpdfapi/parser/fpdf_parser_utility.h"
#include "core/fxcodec/codec/ccodec_iccmodule.h"
#include "core/fxcodec/fx_codec.h"
#include "core/fxcrt/fx_memory.h"
@@ -1062,13 +1063,11 @@
ASSERT(IsValidComponents(nComponents));
std::vector<float> ranges;
- ranges.reserve(nComponents * 2);
const CPDF_Array* pRanges = pDict->GetArrayFor("Range");
if (pRanges) {
- for (uint32_t i = 0; i < nComponents * 2; i++) {
- ranges.push_back(pRanges->GetNumberAt(i));
- }
+ ranges = ReadArrayElementsToVector(pRanges, nComponents * 2);
} else {
+ ranges.reserve(nComponents * 2);
for (uint32_t i = 0; i < nComponents; i++) {
ranges.push_back(0.0f);
ranges.push_back(1.0f);
diff --git a/core/fpdfapi/page/cpdf_function.cpp b/core/fpdfapi/page/cpdf_function.cpp
index d6bde12..688c48e 100644
--- a/core/fpdfapi/page/cpdf_function.cpp
+++ b/core/fpdfapi/page/cpdf_function.cpp
@@ -15,6 +15,7 @@
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_stream.h"
+#include "core/fpdfapi/parser/fpdf_parser_utility.h"
#include "core/fxcrt/fx_safe_types.h"
#include "third_party/base/ptr_util.h"
#include "third_party/base/stl_util.h"
@@ -92,9 +93,7 @@
return false;
size_t nInputs = m_nInputs * 2;
- m_Domains = std::vector<float>(nInputs);
- for (size_t i = 0; i < nInputs; ++i)
- m_Domains[i] = pDomains->GetNumberAt(i);
+ m_Domains = ReadArrayElementsToVector(pDomains, nInputs);
const CPDF_Array* pRanges = pDict->GetArrayFor("Range");
m_nOutputs = pRanges ? pRanges->size() / 2 : 0;
@@ -108,9 +107,7 @@
if (m_nOutputs > 0) {
size_t nOutputs = m_nOutputs * 2;
- m_Ranges = std::vector<float>(nOutputs);
- for (size_t i = 0; i < nOutputs; ++i)
- m_Ranges[i] = pRanges->GetNumberAt(i);
+ m_Ranges = ReadArrayElementsToVector(pRanges, nOutputs);
}
uint32_t old_outputs = m_nOutputs;
diff --git a/core/fpdfapi/page/cpdf_stitchfunc.cpp b/core/fpdfapi/page/cpdf_stitchfunc.cpp
index 95d920e..1ec48ac 100644
--- a/core/fpdfapi/page/cpdf_stitchfunc.cpp
+++ b/core/fpdfapi/page/cpdf_stitchfunc.cpp
@@ -10,6 +10,7 @@
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
+#include "core/fpdfapi/parser/fpdf_parser_utility.h"
#include "core/fxcrt/fx_safe_types.h"
namespace {
@@ -101,9 +102,7 @@
m_bounds.push_back(pBoundsArray->GetNumberAt(i));
m_bounds.push_back(m_Domains[1]);
- m_encode.reserve(nSubs * 2);
- for (uint32_t i = 0; i < nSubs * 2; i++)
- m_encode.push_back(pEncodeArray->GetNumberAt(i));
+ m_encode = ReadArrayElementsToVector(pEncodeArray, nSubs * 2);
return true;
}
diff --git a/core/fpdfapi/parser/fpdf_parser_utility.cpp b/core/fpdfapi/parser/fpdf_parser_utility.cpp
index ec42087..540aabd 100644
--- a/core/fpdfapi/parser/fpdf_parser_utility.cpp
+++ b/core/fpdfapi/parser/fpdf_parser_utility.cpp
@@ -152,6 +152,16 @@
return res;
}
+std::vector<float> ReadArrayElementsToVector(const CPDF_Array* pArray,
+ size_t nCount) {
+ ASSERT(pArray);
+ ASSERT(pArray->size() >= nCount);
+ std::vector<float> ret(nCount);
+ for (size_t i = 0; i < nCount; ++i)
+ ret[i] = pArray->GetNumberAt(i);
+ return ret;
+}
+
std::ostream& operator<<(std::ostream& buf, const CPDF_Object* pObj) {
if (!pObj) {
buf << " null";
diff --git a/core/fpdfapi/parser/fpdf_parser_utility.h b/core/fpdfapi/parser/fpdf_parser_utility.h
index 93a991c..29dd246 100644
--- a/core/fpdfapi/parser/fpdf_parser_utility.h
+++ b/core/fpdfapi/parser/fpdf_parser_utility.h
@@ -8,11 +8,13 @@
#define CORE_FPDFAPI_PARSER_FPDF_PARSER_UTILITY_H_
#include <ostream>
+#include <vector>
#include "core/fxcrt/fx_string.h"
#include "core/fxcrt/retain_ptr.h"
#include "third_party/base/optional.h"
+class CPDF_Array;
class CPDF_Dictionary;
class CPDF_Object;
class IFX_SeekableReadStream;
@@ -48,6 +50,11 @@
ByteString PDF_NameDecode(ByteStringView orig);
ByteString PDF_NameEncode(const ByteString& orig);
+// Return |nCount| elements from |pArray| as a vector of floats. |pArray| must
+// have at least |nCount| elements.
+std::vector<float> ReadArrayElementsToVector(const CPDF_Array* pArray,
+ size_t nCount);
+
std::ostream& operator<<(std::ostream& buf, const CPDF_Object* pObj);
#endif // CORE_FPDFAPI_PARSER_FPDF_PARSER_UTILITY_H_
diff --git a/core/fpdfapi/render/cpdf_dibbase.cpp b/core/fpdfapi/render/cpdf_dibbase.cpp
index 696cad5..4f1d7e5 100644
--- a/core/fpdfapi/render/cpdf_dibbase.cpp
+++ b/core/fpdfapi/render/cpdf_dibbase.cpp
@@ -21,6 +21,7 @@
#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fpdfapi/parser/cpdf_stream_acc.h"
#include "core/fpdfapi/parser/fpdf_parser_decode.h"
+#include "core/fpdfapi/parser/fpdf_parser_utility.h"
#include "core/fpdfapi/render/cpdf_pagerendercache.h"
#include "core/fpdfapi/render/cpdf_renderstatus.h"
#include "core/fxcodec/codec/ccodec_basicmodule.h"
@@ -649,9 +650,8 @@
const CPDF_Array* pMatte = m_pMaskStream->GetDict()->GetArrayFor("Matte");
if (pMatte && m_pColorSpace && m_Family != PDFCS_PATTERN &&
m_pColorSpace->CountComponents() <= m_nComponents) {
- std::vector<float> colors(m_nComponents);
- for (uint32_t i = 0; i < m_nComponents; i++)
- colors[i] = pMatte->GetNumberAt(i);
+ std::vector<float> colors =
+ ReadArrayElementsToVector(pMatte, m_nComponents);
float R;
float G;
diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp
index 1c28227..dce3828 100644
--- a/core/fpdfapi/render/cpdf_renderstatus.cpp
+++ b/core/fpdfapi/render/cpdf_renderstatus.cpp
@@ -37,6 +37,7 @@
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_document.h"
#include "core/fpdfapi/parser/cpdf_stream.h"
+#include "core/fpdfapi/parser/fpdf_parser_utility.h"
#include "core/fpdfapi/render/cpdf_charposlist.h"
#include "core/fpdfapi/render/cpdf_devicebuffer.h"
#include "core/fpdfapi/render/cpdf_dibbase.h"
@@ -2019,9 +2020,9 @@
if (!pPattern->IsShadingObject() && pDict->KeyExist("Background")) {
const CPDF_Array* pBackColor = pDict->GetArrayFor("Background");
if (pBackColor && pBackColor->size() >= pColorSpace->CountComponents()) {
- std::vector<float> comps(pColorSpace->CountComponents());
- for (uint32_t i = 0; i < pColorSpace->CountComponents(); i++)
- comps[i] = pBackColor->GetNumberAt(i);
+ std::vector<float> comps =
+ ReadArrayElementsToVector(pBackColor, pColorSpace->CountComponents());
+
float R = 0.0f;
float G = 0.0f;
float B = 0.0f;
@@ -2626,10 +2627,9 @@
*pCSFamily = family;
uint32_t comps = std::max(8u, pCS->CountComponents());
- std::vector<float> floats(comps);
size_t count = std::min<size_t>(8, pBC->size());
- for (size_t i = 0; i < count; i++)
- floats[i] = pBC->GetNumberAt(i);
+ std::vector<float> floats = ReadArrayElementsToVector(pBC, count);
+ floats.resize(comps);
float R;
float G;
diff --git a/core/fpdfdoc/cpdf_annot.cpp b/core/fpdfdoc/cpdf_annot.cpp
index adc6f53..a4381f9 100644
--- a/core/fpdfdoc/cpdf_annot.cpp
+++ b/core/fpdfdoc/cpdf_annot.cpp
@@ -17,6 +17,7 @@
#include "core/fpdfapi/parser/cpdf_boolean.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/fpdf_parser_utility.h"
#include "core/fpdfapi/render/cpdf_rendercontext.h"
#include "core/fpdfapi/render/cpdf_renderoptions.h"
#include "core/fpdfdoc/cpvt_generateap.h"
@@ -497,18 +498,10 @@
graph_state.m_LineWidth = width;
if (style_char == 'D') {
if (pDashArray) {
- size_t dash_count = pDashArray->size();
- if (dash_count % 2) {
- dash_count++;
- }
- graph_state.m_DashArray.resize(dash_count);
- size_t i;
- for (i = 0; i < pDashArray->size(); ++i) {
- graph_state.m_DashArray[i] = pDashArray->GetNumberAt(i);
- }
- if (i < dash_count) {
- graph_state.m_DashArray[i] = graph_state.m_DashArray[i - 1];
- }
+ graph_state.m_DashArray =
+ ReadArrayElementsToVector(pDashArray, pDashArray->size());
+ if (graph_state.m_DashArray.size() % 2)
+ graph_state.m_DashArray.push_back(graph_state.m_DashArray.back());
} else {
graph_state.m_DashArray = {3.0f, 3.0f};
}