OLD | NEW |
1 // Copyright 2016 PDFium Authors. All rights reserved. | 1 // Copyright 2016 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "core/fpdfapi/fpdf_page/cpdf_meshstream.h" | 7 #include "core/fpdfapi/fpdf_page/cpdf_meshstream.h" |
8 | 8 |
9 #include "core/fpdfapi/fpdf_page/include/cpdf_colorspace.h" | 9 #include "core/fpdfapi/fpdf_page/include/cpdf_colorspace.h" |
10 #include "core/fpdfapi/fpdf_page/pageint.h" | 10 #include "core/fpdfapi/fpdf_page/pageint.h" |
(...skipping 26 matching lines...) Expand all Loading... |
37 case 12: | 37 case 12: |
38 case 16: | 38 case 16: |
39 case 24: | 39 case 24: |
40 case 32: | 40 case 32: |
41 return true; | 41 return true; |
42 default: | 42 default: |
43 return false; | 43 return false; |
44 } | 44 } |
45 } | 45 } |
46 | 46 |
| 47 // See PDF Reference 1.7, page 315, table 4.32. (Also table 4.34) |
| 48 bool ShouldCheckBitsPerFlag(ShadingType type) { |
| 49 switch (type) { |
| 50 case kFreeFormGouraudTriangleMeshShading: |
| 51 case kCoonsPatchMeshShading: |
| 52 case kTensorProductPatchMeshShading: |
| 53 return true; |
| 54 default: |
| 55 return false; |
| 56 } |
| 57 } |
| 58 |
| 59 // Same references as ShouldCheckBitsPerFlag() above. |
| 60 bool IsValidBitsPerFlag(uint32_t x) { |
| 61 switch (x) { |
| 62 case 2: |
| 63 case 4: |
| 64 case 8: |
| 65 return true; |
| 66 default: |
| 67 return false; |
| 68 } |
| 69 } |
| 70 |
47 } // namespace | 71 } // namespace |
48 | 72 |
49 CPDF_MeshStream::CPDF_MeshStream( | 73 CPDF_MeshStream::CPDF_MeshStream( |
| 74 ShadingType type, |
50 const std::vector<std::unique_ptr<CPDF_Function>>& funcs, | 75 const std::vector<std::unique_ptr<CPDF_Function>>& funcs, |
| 76 CPDF_Stream* pShadingStream, |
51 CPDF_ColorSpace* pCS) | 77 CPDF_ColorSpace* pCS) |
52 : m_funcs(funcs), m_pCS(pCS) {} | 78 : m_type(type), |
| 79 m_funcs(funcs), |
| 80 m_pShadingStream(pShadingStream), |
| 81 m_pCS(pCS) {} |
53 | 82 |
54 bool CPDF_MeshStream::Load(CPDF_Stream* pShadingStream) { | 83 bool CPDF_MeshStream::Load() { |
55 m_Stream.LoadAllData(pShadingStream); | 84 m_Stream.LoadAllData(m_pShadingStream); |
56 m_BitStream.Init(m_Stream.GetData(), m_Stream.GetSize()); | 85 m_BitStream.Init(m_Stream.GetData(), m_Stream.GetSize()); |
57 CPDF_Dictionary* pDict = pShadingStream->GetDict(); | 86 CPDF_Dictionary* pDict = m_pShadingStream->GetDict(); |
58 m_nCoordBits = pDict->GetIntegerBy("BitsPerCoordinate"); | 87 m_nCoordBits = pDict->GetIntegerBy("BitsPerCoordinate"); |
59 if (!IsValidBitsPerCoordinate(m_nCoordBits)) | 88 if (!IsValidBitsPerCoordinate(m_nCoordBits)) |
60 return false; | 89 return false; |
61 | 90 |
62 m_nCompBits = pDict->GetIntegerBy("BitsPerComponent"); | 91 m_nCompBits = pDict->GetIntegerBy("BitsPerComponent"); |
63 if (!IsValidBitsPerComponent(m_nCompBits)) | 92 if (!IsValidBitsPerComponent(m_nCompBits)) |
64 return false; | 93 return false; |
65 | 94 |
66 m_nFlagBits = pDict->GetIntegerBy("BitsPerFlag"); | 95 m_nFlagBits = pDict->GetIntegerBy("BitsPerFlag"); |
| 96 if (ShouldCheckBitsPerFlag(m_type) && !IsValidBitsPerFlag(m_nFlagBits)) |
| 97 return false; |
| 98 |
67 uint32_t nComps = m_pCS->CountComponents(); | 99 uint32_t nComps = m_pCS->CountComponents(); |
68 if (nComps > 8) | 100 if (nComps > 8) |
69 return false; | 101 return false; |
70 | 102 |
71 m_nComps = m_funcs.empty() ? nComps : 1; | 103 m_nComps = m_funcs.empty() ? nComps : 1; |
72 m_CoordMax = m_nCoordBits == 32 ? -1 : (1 << m_nCoordBits) - 1; | 104 m_CoordMax = m_nCoordBits == 32 ? -1 : (1 << m_nCoordBits) - 1; |
73 m_CompMax = (1 << m_nCompBits) - 1; | 105 m_CompMax = (1 << m_nCompBits) - 1; |
74 CPDF_Array* pDecode = pDict->GetArrayBy("Decode"); | 106 CPDF_Array* pDecode = pDict->GetArrayBy("Decode"); |
75 if (!pDecode || pDecode->GetCount() != 4 + m_nComps * 2) | 107 if (!pDecode || pDecode->GetCount() != 4 + m_nComps * 2) |
76 return false; | 108 return false; |
77 | 109 |
78 m_xmin = pDecode->GetNumberAt(0); | 110 m_xmin = pDecode->GetNumberAt(0); |
79 m_xmax = pDecode->GetNumberAt(1); | 111 m_xmax = pDecode->GetNumberAt(1); |
80 m_ymin = pDecode->GetNumberAt(2); | 112 m_ymin = pDecode->GetNumberAt(2); |
81 m_ymax = pDecode->GetNumberAt(3); | 113 m_ymax = pDecode->GetNumberAt(3); |
82 for (uint32_t i = 0; i < m_nComps; ++i) { | 114 for (uint32_t i = 0; i < m_nComps; ++i) { |
83 m_ColorMin[i] = pDecode->GetNumberAt(i * 2 + 4); | 115 m_ColorMin[i] = pDecode->GetNumberAt(i * 2 + 4); |
84 m_ColorMax[i] = pDecode->GetNumberAt(i * 2 + 5); | 116 m_ColorMax[i] = pDecode->GetNumberAt(i * 2 + 5); |
85 } | 117 } |
86 return true; | 118 return true; |
87 } | 119 } |
88 | 120 |
89 uint32_t CPDF_MeshStream::GetFlag() { | 121 uint32_t CPDF_MeshStream::GetFlag() { |
| 122 ASSERT(ShouldCheckBitsPerFlag(m_type)); |
90 return m_BitStream.GetBits(m_nFlagBits) & 0x03; | 123 return m_BitStream.GetBits(m_nFlagBits) & 0x03; |
91 } | 124 } |
92 | 125 |
93 void CPDF_MeshStream::GetCoords(FX_FLOAT& x, FX_FLOAT& y) { | 126 void CPDF_MeshStream::GetCoords(FX_FLOAT& x, FX_FLOAT& y) { |
94 if (m_nCoordBits == 32) { | 127 if (m_nCoordBits == 32) { |
95 x = m_xmin + (FX_FLOAT)(m_BitStream.GetBits(m_nCoordBits) * | 128 x = m_xmin + (FX_FLOAT)(m_BitStream.GetBits(m_nCoordBits) * |
96 (m_xmax - m_xmin) / (double)m_CoordMax); | 129 (m_xmax - m_xmin) / (double)m_CoordMax); |
97 y = m_ymin + (FX_FLOAT)(m_BitStream.GetBits(m_nCoordBits) * | 130 y = m_ymin + (FX_FLOAT)(m_BitStream.GetBits(m_nCoordBits) * |
98 (m_ymax - m_ymin) / (double)m_CoordMax); | 131 (m_ymax - m_ymin) / (double)m_CoordMax); |
99 } else { | 132 } else { |
100 x = m_xmin + | 133 x = m_xmin + |
101 m_BitStream.GetBits(m_nCoordBits) * (m_xmax - m_xmin) / m_CoordMax; | 134 m_BitStream.GetBits(m_nCoordBits) * (m_xmax - m_xmin) / m_CoordMax; |
102 y = m_ymin + | 135 y = m_ymin + |
103 m_BitStream.GetBits(m_nCoordBits) * (m_ymax - m_ymin) / m_CoordMax; | 136 m_BitStream.GetBits(m_nCoordBits) * (m_ymax - m_ymin) / m_CoordMax; |
104 } | 137 } |
105 } | 138 } |
106 | 139 |
107 void CPDF_MeshStream::GetColor(FX_FLOAT& r, FX_FLOAT& g, FX_FLOAT& b) { | 140 void CPDF_MeshStream::GetColor(FX_FLOAT& r, FX_FLOAT& g, FX_FLOAT& b) { |
108 static const int kMaxResults = 8; | |
109 FX_FLOAT color_value[kMaxResults]; | 141 FX_FLOAT color_value[kMaxResults]; |
110 for (uint32_t i = 0; i < m_nComps; ++i) { | 142 for (uint32_t i = 0; i < m_nComps; ++i) { |
111 color_value[i] = m_ColorMin[i] + | 143 color_value[i] = m_ColorMin[i] + |
112 m_BitStream.GetBits(m_nCompBits) * | 144 m_BitStream.GetBits(m_nCompBits) * |
113 (m_ColorMax[i] - m_ColorMin[i]) / m_CompMax; | 145 (m_ColorMax[i] - m_ColorMin[i]) / m_CompMax; |
114 } | 146 } |
115 if (m_funcs.empty()) { | 147 if (m_funcs.empty()) { |
116 m_pCS->GetRGB(color_value, r, g, b); | 148 m_pCS->GetRGB(color_value, r, g, b); |
117 return; | 149 return; |
118 } | 150 } |
(...skipping 25 matching lines...) Expand all Loading... |
144 if (m_BitStream.IsEOF()) | 176 if (m_BitStream.IsEOF()) |
145 return FALSE; | 177 return FALSE; |
146 | 178 |
147 GetCoords(vertex[i].x, vertex[i].y); | 179 GetCoords(vertex[i].x, vertex[i].y); |
148 pObject2Bitmap->Transform(vertex[i].x, vertex[i].y); | 180 pObject2Bitmap->Transform(vertex[i].x, vertex[i].y); |
149 GetColor(vertex[i].r, vertex[i].g, vertex[i].b); | 181 GetColor(vertex[i].r, vertex[i].g, vertex[i].b); |
150 m_BitStream.ByteAlign(); | 182 m_BitStream.ByteAlign(); |
151 } | 183 } |
152 return TRUE; | 184 return TRUE; |
153 } | 185 } |
OLD | NEW |