Index: core/fpdfapi/fpdf_page/cpdf_meshstream.cpp |
diff --git a/core/fpdfapi/fpdf_page/cpdf_meshstream.cpp b/core/fpdfapi/fpdf_page/cpdf_meshstream.cpp |
index d3649a1fdce6656521ab5b0375f7a1d137ed8e1b..1d9c56046a991cf9ca8f65f482857b853607c355 100644 |
--- a/core/fpdfapi/fpdf_page/cpdf_meshstream.cpp |
+++ b/core/fpdfapi/fpdf_page/cpdf_meshstream.cpp |
@@ -13,6 +13,19 @@ |
namespace { |
// See PDF Reference 1.7, page 315, table 4.32. (Also table 4.33 and 4.34) |
+bool ShouldCheckBPC(ShadingType type) { |
+ switch (type) { |
+ case kFreeFormGouraudTriangleMeshShading: |
+ case kLatticeFormGouraudTriangleMeshShading: |
+ case kCoonsPatchMeshShading: |
+ case kTensorProductPatchMeshShading: |
+ return true; |
+ default: |
+ return false; |
+ } |
+} |
+ |
+// Same references as ShouldCheckBPC() above. |
bool IsValidBitsPerComponent(uint32_t x) { |
switch (x) { |
case 1: |
@@ -27,7 +40,7 @@ bool IsValidBitsPerComponent(uint32_t x) { |
} |
} |
-// Same references as IsValidBitsPerComponent() above. |
+// Same references as ShouldCheckBPC() above. |
bool IsValidBitsPerCoordinate(uint32_t x) { |
switch (x) { |
case 1: |
@@ -78,43 +91,60 @@ CPDF_MeshStream::CPDF_MeshStream( |
: m_type(type), |
m_funcs(funcs), |
m_pShadingStream(pShadingStream), |
- m_pCS(pCS) {} |
+ m_pCS(pCS), |
+ m_nCoordBits(0), |
+ m_nComponentBits(0), |
+ m_nFlagBits(0), |
+ m_nComponents(0), |
+ m_CoordMax(0), |
+ m_ComponentMax(0), |
+ m_xmin(0), |
+ m_xmax(0), |
+ m_ymin(0), |
+ m_ymax(0) { |
+ memset(&m_ColorMin, 0, sizeof(m_ColorMin)); |
+ memset(&m_ColorMax, 0, sizeof(m_ColorMax)); |
+} |
bool CPDF_MeshStream::Load() { |
m_Stream.LoadAllData(m_pShadingStream); |
m_BitStream.Init(m_Stream.GetData(), m_Stream.GetSize()); |
CPDF_Dictionary* pDict = m_pShadingStream->GetDict(); |
m_nCoordBits = pDict->GetIntegerBy("BitsPerCoordinate"); |
- if (!IsValidBitsPerCoordinate(m_nCoordBits)) |
- return false; |
- |
- m_nCompBits = pDict->GetIntegerBy("BitsPerComponent"); |
- if (!IsValidBitsPerComponent(m_nCompBits)) |
- return false; |
+ m_nComponentBits = pDict->GetIntegerBy("BitsPerComponent"); |
+ if (ShouldCheckBPC(m_type)) { |
+ if (!IsValidBitsPerCoordinate(m_nCoordBits)) |
+ return false; |
+ if (!IsValidBitsPerComponent(m_nComponentBits)) |
+ return false; |
+ } |
m_nFlagBits = pDict->GetIntegerBy("BitsPerFlag"); |
if (ShouldCheckBitsPerFlag(m_type) && !IsValidBitsPerFlag(m_nFlagBits)) |
return false; |
- uint32_t nComps = m_pCS->CountComponents(); |
- if (nComps > 8) |
+ uint32_t nComponents = m_pCS->CountComponents(); |
+ if (nComponents > kMaxComponents) |
return false; |
- m_nComps = m_funcs.empty() ? nComps : 1; |
- m_CoordMax = m_nCoordBits == 32 ? -1 : (1 << m_nCoordBits) - 1; |
- m_CompMax = (1 << m_nCompBits) - 1; |
+ m_nComponents = m_funcs.empty() ? nComponents : 1; |
CPDF_Array* pDecode = pDict->GetArrayBy("Decode"); |
- if (!pDecode || pDecode->GetCount() != 4 + m_nComps * 2) |
+ if (!pDecode || pDecode->GetCount() != 4 + m_nComponents * 2) |
return false; |
m_xmin = pDecode->GetNumberAt(0); |
m_xmax = pDecode->GetNumberAt(1); |
m_ymin = pDecode->GetNumberAt(2); |
m_ymax = pDecode->GetNumberAt(3); |
- for (uint32_t i = 0; i < m_nComps; ++i) { |
+ for (uint32_t i = 0; i < m_nComponents; ++i) { |
m_ColorMin[i] = pDecode->GetNumberAt(i * 2 + 4); |
m_ColorMax[i] = pDecode->GetNumberAt(i * 2 + 5); |
} |
+ |
+ if (ShouldCheckBPC(m_type)) { |
+ m_CoordMax = m_nCoordBits == 32 ? -1 : (1 << m_nCoordBits) - 1; |
+ m_ComponentMax = (1 << m_nComponentBits) - 1; |
+ } |
return true; |
} |
@@ -124,6 +154,7 @@ uint32_t CPDF_MeshStream::GetFlag() { |
} |
void CPDF_MeshStream::GetCoords(FX_FLOAT& x, FX_FLOAT& y) { |
+ ASSERT(ShouldCheckBPC(m_type)); |
if (m_nCoordBits == 32) { |
x = m_xmin + (FX_FLOAT)(m_BitStream.GetBits(m_nCoordBits) * |
(m_xmax - m_xmin) / (double)m_CoordMax); |
@@ -138,22 +169,23 @@ void CPDF_MeshStream::GetCoords(FX_FLOAT& x, FX_FLOAT& y) { |
} |
void CPDF_MeshStream::GetColor(FX_FLOAT& r, FX_FLOAT& g, FX_FLOAT& b) { |
- FX_FLOAT color_value[kMaxResults]; |
- for (uint32_t i = 0; i < m_nComps; ++i) { |
+ ASSERT(ShouldCheckBPC(m_type)); |
+ FX_FLOAT color_value[kMaxComponents]; |
+ for (uint32_t i = 0; i < m_nComponents; ++i) { |
color_value[i] = m_ColorMin[i] + |
- m_BitStream.GetBits(m_nCompBits) * |
- (m_ColorMax[i] - m_ColorMin[i]) / m_CompMax; |
+ m_BitStream.GetBits(m_nComponentBits) * |
+ (m_ColorMax[i] - m_ColorMin[i]) / m_ComponentMax; |
} |
if (m_funcs.empty()) { |
m_pCS->GetRGB(color_value, r, g, b); |
return; |
} |
- FX_FLOAT result[kMaxResults]; |
+ FX_FLOAT result[kMaxComponents]; |
FXSYS_memset(result, 0, sizeof(result)); |
int nResults; |
for (const auto& func : m_funcs) { |
- if (func && func->CountOutputs() <= kMaxResults) |
+ if (func && func->CountOutputs() <= kMaxComponents) |
func->Call(color_value, 1, result, nResults); |
} |
m_pCS->GetRGB(result, r, g, b); |