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/page/cpdf_image.h" | 7 #include "core/fpdfapi/page/cpdf_image.h" |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <memory> | 10 #include <memory> |
| 11 #include <utility> |
11 #include <vector> | 12 #include <vector> |
12 | 13 |
13 #include "core/fpdfapi/cpdf_modulemgr.h" | 14 #include "core/fpdfapi/cpdf_modulemgr.h" |
14 #include "core/fpdfapi/page/cpdf_docpagedata.h" | 15 #include "core/fpdfapi/page/cpdf_docpagedata.h" |
15 #include "core/fpdfapi/page/cpdf_page.h" | 16 #include "core/fpdfapi/page/cpdf_page.h" |
16 #include "core/fpdfapi/parser/cpdf_array.h" | 17 #include "core/fpdfapi/parser/cpdf_array.h" |
17 #include "core/fpdfapi/parser/cpdf_boolean.h" | 18 #include "core/fpdfapi/parser/cpdf_boolean.h" |
18 #include "core/fpdfapi/parser/cpdf_dictionary.h" | 19 #include "core/fpdfapi/parser/cpdf_dictionary.h" |
19 #include "core/fpdfapi/parser/cpdf_document.h" | 20 #include "core/fpdfapi/parser/cpdf_document.h" |
20 #include "core/fpdfapi/parser/cpdf_name.h" | 21 #include "core/fpdfapi/parser/cpdf_name.h" |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 int32_t num_comps; | 91 int32_t num_comps; |
91 int32_t bits; | 92 int32_t bits; |
92 bool color_trans; | 93 bool color_trans; |
93 if (!CPDF_ModuleMgr::Get()->GetJpegModule()->LoadInfo( | 94 if (!CPDF_ModuleMgr::Get()->GetJpegModule()->LoadInfo( |
94 pData, size, &width, &height, &num_comps, &bits, &color_trans)) { | 95 pData, size, &width, &height, &num_comps, &bits, &color_trans)) { |
95 return nullptr; | 96 return nullptr; |
96 } | 97 } |
97 | 98 |
98 CPDF_Dictionary* pDict = | 99 CPDF_Dictionary* pDict = |
99 new CPDF_Dictionary(m_pDocument->GetByteStringPool()); | 100 new CPDF_Dictionary(m_pDocument->GetByteStringPool()); |
100 pDict->SetNameFor("Type", "XObject"); | 101 pDict->SetNewFor<CPDF_Name>("Type", "XObject"); |
101 pDict->SetNameFor("Subtype", "Image"); | 102 pDict->SetNewFor<CPDF_Name>("Subtype", "Image"); |
102 pDict->SetIntegerFor("Width", width); | 103 pDict->SetNewFor<CPDF_Number>("Width", width); |
103 pDict->SetIntegerFor("Height", height); | 104 pDict->SetNewFor<CPDF_Number>("Height", height); |
104 const FX_CHAR* csname = nullptr; | 105 const FX_CHAR* csname = nullptr; |
105 if (num_comps == 1) { | 106 if (num_comps == 1) { |
106 csname = "DeviceGray"; | 107 csname = "DeviceGray"; |
107 } else if (num_comps == 3) { | 108 } else if (num_comps == 3) { |
108 csname = "DeviceRGB"; | 109 csname = "DeviceRGB"; |
109 } else if (num_comps == 4) { | 110 } else if (num_comps == 4) { |
110 csname = "DeviceCMYK"; | 111 csname = "DeviceCMYK"; |
111 CPDF_Array* pDecode = new CPDF_Array; | 112 CPDF_Array* pDecode = pDict->SetNewFor<CPDF_Array>("Decode"); |
112 for (int n = 0; n < 4; n++) { | 113 for (int n = 0; n < 4; n++) { |
113 pDecode->AddNew<CPDF_Number>(1); | 114 pDecode->AddNew<CPDF_Number>(1); |
114 pDecode->AddNew<CPDF_Number>(0); | 115 pDecode->AddNew<CPDF_Number>(0); |
115 } | 116 } |
116 pDict->SetFor("Decode", pDecode); | |
117 } | 117 } |
118 pDict->SetNameFor("ColorSpace", csname); | 118 pDict->SetNewFor<CPDF_Name>("ColorSpace", csname); |
119 pDict->SetIntegerFor("BitsPerComponent", bits); | 119 pDict->SetNewFor<CPDF_Number>("BitsPerComponent", bits); |
120 pDict->SetNameFor("Filter", "DCTDecode"); | 120 pDict->SetNewFor<CPDF_Name>("Filter", "DCTDecode"); |
121 if (!color_trans) { | 121 if (!color_trans) { |
122 CPDF_Dictionary* pParms = | 122 CPDF_Dictionary* pParms = pDict->SetNewFor<CPDF_Dictionary>("DecodeParms"); |
123 new CPDF_Dictionary(m_pDocument->GetByteStringPool()); | 123 pParms->SetNewFor<CPDF_Number>("ColorTransform", 0); |
124 pDict->SetFor("DecodeParms", pParms); | |
125 pParms->SetIntegerFor("ColorTransform", 0); | |
126 } | 124 } |
127 m_bIsMask = false; | 125 m_bIsMask = false; |
128 m_Width = width; | 126 m_Width = width; |
129 m_Height = height; | 127 m_Height = height; |
130 if (!m_pStream) { | 128 if (!m_pStream) { |
131 m_pOwnedStream = pdfium::MakeUnique<CPDF_Stream>(); | 129 m_pOwnedStream = pdfium::MakeUnique<CPDF_Stream>(); |
132 m_pStream = m_pOwnedStream.get(); | 130 m_pStream = m_pOwnedStream.get(); |
133 } | 131 } |
134 return pDict; | 132 return pDict; |
135 } | 133 } |
(...skipping 23 matching lines...) Expand all Loading... |
159 int32_t BitmapHeight = pBitmap->GetHeight(); | 157 int32_t BitmapHeight = pBitmap->GetHeight(); |
160 if (BitmapWidth < 1 || BitmapHeight < 1) { | 158 if (BitmapWidth < 1 || BitmapHeight < 1) { |
161 return; | 159 return; |
162 } | 160 } |
163 uint8_t* src_buf = pBitmap->GetBuffer(); | 161 uint8_t* src_buf = pBitmap->GetBuffer(); |
164 int32_t src_pitch = pBitmap->GetPitch(); | 162 int32_t src_pitch = pBitmap->GetPitch(); |
165 int32_t bpp = pBitmap->GetBPP(); | 163 int32_t bpp = pBitmap->GetBPP(); |
166 | 164 |
167 CPDF_Dictionary* pDict = | 165 CPDF_Dictionary* pDict = |
168 new CPDF_Dictionary(m_pDocument->GetByteStringPool()); | 166 new CPDF_Dictionary(m_pDocument->GetByteStringPool()); |
169 pDict->SetNameFor("Type", "XObject"); | 167 pDict->SetNewFor<CPDF_Name>("Type", "XObject"); |
170 pDict->SetNameFor("Subtype", "Image"); | 168 pDict->SetNewFor<CPDF_Name>("Subtype", "Image"); |
171 pDict->SetIntegerFor("Width", BitmapWidth); | 169 pDict->SetNewFor<CPDF_Number>("Width", BitmapWidth); |
172 pDict->SetIntegerFor("Height", BitmapHeight); | 170 pDict->SetNewFor<CPDF_Number>("Height", BitmapHeight); |
173 uint8_t* dest_buf = nullptr; | 171 uint8_t* dest_buf = nullptr; |
174 FX_STRSIZE dest_pitch = 0, dest_size = 0, opType = -1; | 172 FX_STRSIZE dest_pitch = 0, dest_size = 0, opType = -1; |
175 if (bpp == 1) { | 173 if (bpp == 1) { |
176 int32_t reset_a = 0, reset_r = 0, reset_g = 0, reset_b = 0; | 174 int32_t reset_a = 0, reset_r = 0, reset_g = 0, reset_b = 0; |
177 int32_t set_a = 0, set_r = 0, set_g = 0, set_b = 0; | 175 int32_t set_a = 0, set_r = 0, set_g = 0, set_b = 0; |
178 if (!pBitmap->IsAlphaMask()) { | 176 if (!pBitmap->IsAlphaMask()) { |
179 ArgbDecode(pBitmap->GetPaletteArgb(0), reset_a, reset_r, reset_g, | 177 ArgbDecode(pBitmap->GetPaletteArgb(0), reset_a, reset_r, reset_g, |
180 reset_b); | 178 reset_b); |
181 ArgbDecode(pBitmap->GetPaletteArgb(1), set_a, set_r, set_g, set_b); | 179 ArgbDecode(pBitmap->GetPaletteArgb(1), set_a, set_r, set_g, set_b); |
182 } | 180 } |
183 if (set_a == 0 || reset_a == 0) { | 181 if (set_a == 0 || reset_a == 0) { |
184 pDict->SetFor("ImageMask", new CPDF_Boolean(true)); | 182 pDict->SetNewFor<CPDF_Boolean>("ImageMask", true); |
185 if (reset_a == 0) { | 183 if (reset_a == 0) { |
186 CPDF_Array* pArray = new CPDF_Array; | 184 CPDF_Array* pArray = pDict->SetNewFor<CPDF_Array>("Decode"); |
187 pArray->AddNew<CPDF_Number>(1); | 185 pArray->AddNew<CPDF_Number>(1); |
188 pArray->AddNew<CPDF_Number>(0); | 186 pArray->AddNew<CPDF_Number>(0); |
189 pDict->SetFor("Decode", pArray); | |
190 } | 187 } |
191 } else { | 188 } else { |
192 CPDF_Array* pCS = new CPDF_Array; | 189 CPDF_Array* pCS = pDict->SetNewFor<CPDF_Array>("ColorSpace"); |
193 pCS->AddNew<CPDF_Name>("Indexed"); | 190 pCS->AddNew<CPDF_Name>("Indexed"); |
194 pCS->AddNew<CPDF_Name>("DeviceRGB"); | 191 pCS->AddNew<CPDF_Name>("DeviceRGB"); |
195 pCS->AddNew<CPDF_Number>(1); | 192 pCS->AddNew<CPDF_Number>(1); |
196 CFX_ByteString ct; | 193 CFX_ByteString ct; |
197 FX_CHAR* pBuf = ct.GetBuffer(6); | 194 FX_CHAR* pBuf = ct.GetBuffer(6); |
198 pBuf[0] = (FX_CHAR)reset_r; | 195 pBuf[0] = (FX_CHAR)reset_r; |
199 pBuf[1] = (FX_CHAR)reset_g; | 196 pBuf[1] = (FX_CHAR)reset_g; |
200 pBuf[2] = (FX_CHAR)reset_b; | 197 pBuf[2] = (FX_CHAR)reset_b; |
201 pBuf[3] = (FX_CHAR)set_r; | 198 pBuf[3] = (FX_CHAR)set_r; |
202 pBuf[4] = (FX_CHAR)set_g; | 199 pBuf[4] = (FX_CHAR)set_g; |
203 pBuf[5] = (FX_CHAR)set_b; | 200 pBuf[5] = (FX_CHAR)set_b; |
204 ct.ReleaseBuffer(6); | 201 ct.ReleaseBuffer(6); |
205 pCS->AddNew<CPDF_String>(ct, true); | 202 pCS->AddNew<CPDF_String>(ct, true); |
206 pDict->SetFor("ColorSpace", pCS); | |
207 } | 203 } |
208 pDict->SetIntegerFor("BitsPerComponent", 1); | 204 pDict->SetNewFor<CPDF_Number>("BitsPerComponent", 1); |
209 dest_pitch = (BitmapWidth + 7) / 8; | 205 dest_pitch = (BitmapWidth + 7) / 8; |
210 if ((iCompress & 0x03) == PDF_IMAGE_NO_COMPRESS) { | 206 if ((iCompress & 0x03) == PDF_IMAGE_NO_COMPRESS) { |
211 opType = 1; | 207 opType = 1; |
212 } else { | 208 } else { |
213 opType = 0; | 209 opType = 0; |
214 } | 210 } |
215 } else if (bpp == 8) { | 211 } else if (bpp == 8) { |
216 int32_t iPalette = pBitmap->GetPaletteSize(); | 212 int32_t iPalette = pBitmap->GetPaletteSize(); |
217 if (iPalette > 0) { | 213 if (iPalette > 0) { |
218 CPDF_Array* pCS = m_pDocument->NewIndirect<CPDF_Array>(); | 214 CPDF_Array* pCS = m_pDocument->NewIndirect<CPDF_Array>(); |
219 pCS->AddNew<CPDF_Name>("Indexed"); | 215 pCS->AddNew<CPDF_Name>("Indexed"); |
220 pCS->AddNew<CPDF_Name>("DeviceRGB"); | 216 pCS->AddNew<CPDF_Name>("DeviceRGB"); |
221 pCS->AddNew<CPDF_Number>(iPalette - 1); | 217 pCS->AddNew<CPDF_Number>(iPalette - 1); |
222 uint8_t* pColorTable = FX_Alloc2D(uint8_t, iPalette, 3); | 218 uint8_t* pColorTable = FX_Alloc2D(uint8_t, iPalette, 3); |
223 uint8_t* ptr = pColorTable; | 219 uint8_t* ptr = pColorTable; |
224 for (int32_t i = 0; i < iPalette; i++) { | 220 for (int32_t i = 0; i < iPalette; i++) { |
225 uint32_t argb = pBitmap->GetPaletteArgb(i); | 221 uint32_t argb = pBitmap->GetPaletteArgb(i); |
226 ptr[0] = (uint8_t)(argb >> 16); | 222 ptr[0] = (uint8_t)(argb >> 16); |
227 ptr[1] = (uint8_t)(argb >> 8); | 223 ptr[1] = (uint8_t)(argb >> 8); |
228 ptr[2] = (uint8_t)argb; | 224 ptr[2] = (uint8_t)argb; |
229 ptr += 3; | 225 ptr += 3; |
230 } | 226 } |
231 CPDF_Stream* pCTS = m_pDocument->NewIndirect<CPDF_Stream>( | 227 CPDF_Stream* pCTS = m_pDocument->NewIndirect<CPDF_Stream>( |
232 pColorTable, iPalette * 3, | 228 pColorTable, iPalette * 3, |
233 new CPDF_Dictionary(m_pDocument->GetByteStringPool())); | 229 new CPDF_Dictionary(m_pDocument->GetByteStringPool())); |
234 pCS->AddNew<CPDF_Reference>(m_pDocument, pCTS->GetObjNum()); | 230 pCS->AddNew<CPDF_Reference>(m_pDocument, pCTS->GetObjNum()); |
235 pDict->SetReferenceFor("ColorSpace", m_pDocument, pCS); | 231 pDict->SetNewFor<CPDF_Reference>("ColorSpace", m_pDocument, |
| 232 pCS->GetObjNum()); |
236 } else { | 233 } else { |
237 pDict->SetNameFor("ColorSpace", "DeviceGray"); | 234 pDict->SetNewFor<CPDF_Name>("ColorSpace", "DeviceGray"); |
238 } | 235 } |
239 pDict->SetIntegerFor("BitsPerComponent", 8); | 236 pDict->SetNewFor<CPDF_Number>("BitsPerComponent", 8); |
240 if ((iCompress & 0x03) == PDF_IMAGE_NO_COMPRESS) { | 237 if ((iCompress & 0x03) == PDF_IMAGE_NO_COMPRESS) { |
241 dest_pitch = BitmapWidth; | 238 dest_pitch = BitmapWidth; |
242 opType = 1; | 239 opType = 1; |
243 } else { | 240 } else { |
244 opType = 0; | 241 opType = 0; |
245 } | 242 } |
246 } else { | 243 } else { |
247 pDict->SetNameFor("ColorSpace", "DeviceRGB"); | 244 pDict->SetNewFor<CPDF_Name>("ColorSpace", "DeviceRGB"); |
248 pDict->SetIntegerFor("BitsPerComponent", 8); | 245 pDict->SetNewFor<CPDF_Number>("BitsPerComponent", 8); |
249 if ((iCompress & 0x03) == PDF_IMAGE_NO_COMPRESS) { | 246 if ((iCompress & 0x03) == PDF_IMAGE_NO_COMPRESS) { |
250 dest_pitch = BitmapWidth * 3; | 247 dest_pitch = BitmapWidth * 3; |
251 opType = 2; | 248 opType = 2; |
252 } else { | 249 } else { |
253 opType = 0; | 250 opType = 0; |
254 } | 251 } |
255 } | 252 } |
256 const CFX_DIBitmap* pMaskBitmap = nullptr; | 253 const CFX_DIBitmap* pMaskBitmap = nullptr; |
257 bool bDeleteMask = false; | 254 bool bDeleteMask = false; |
258 if (pBitmap->HasAlpha()) { | 255 if (pBitmap->HasAlpha()) { |
259 pMaskBitmap = pBitmap->GetAlphaMask(); | 256 pMaskBitmap = pBitmap->GetAlphaMask(); |
260 bDeleteMask = true; | 257 bDeleteMask = true; |
261 } | 258 } |
262 if (pMaskBitmap) { | 259 if (pMaskBitmap) { |
263 int32_t maskWidth = pMaskBitmap->GetWidth(); | 260 int32_t maskWidth = pMaskBitmap->GetWidth(); |
264 int32_t maskHeight = pMaskBitmap->GetHeight(); | 261 int32_t maskHeight = pMaskBitmap->GetHeight(); |
265 uint8_t* mask_buf = nullptr; | 262 uint8_t* mask_buf = nullptr; |
266 FX_STRSIZE mask_size = 0; | 263 FX_STRSIZE mask_size = 0; |
267 CPDF_Dictionary* pMaskDict = | 264 CPDF_Dictionary* pMaskDict = |
268 new CPDF_Dictionary(m_pDocument->GetByteStringPool()); | 265 new CPDF_Dictionary(m_pDocument->GetByteStringPool()); |
269 pMaskDict->SetNameFor("Type", "XObject"); | 266 pMaskDict->SetNewFor<CPDF_Name>("Type", "XObject"); |
270 pMaskDict->SetNameFor("Subtype", "Image"); | 267 pMaskDict->SetNewFor<CPDF_Name>("Subtype", "Image"); |
271 pMaskDict->SetIntegerFor("Width", maskWidth); | 268 pMaskDict->SetNewFor<CPDF_Number>("Width", maskWidth); |
272 pMaskDict->SetIntegerFor("Height", maskHeight); | 269 pMaskDict->SetNewFor<CPDF_Number>("Height", maskHeight); |
273 pMaskDict->SetNameFor("ColorSpace", "DeviceGray"); | 270 pMaskDict->SetNewFor<CPDF_Name>("ColorSpace", "DeviceGray"); |
274 pMaskDict->SetIntegerFor("BitsPerComponent", 8); | 271 pMaskDict->SetNewFor<CPDF_Number>("BitsPerComponent", 8); |
275 if (pMaskBitmap->GetBPP() == 8 && | 272 if (pMaskBitmap->GetBPP() == 8 && |
276 (iCompress & PDF_IMAGE_MASK_LOSSY_COMPRESS) != 0) { | 273 (iCompress & PDF_IMAGE_MASK_LOSSY_COMPRESS) != 0) { |
277 } else if (pMaskBitmap->GetFormat() == FXDIB_1bppMask) { | 274 } else if (pMaskBitmap->GetFormat() == FXDIB_1bppMask) { |
278 } else { | 275 } else { |
279 mask_buf = FX_Alloc2D(uint8_t, maskHeight, maskWidth); | 276 mask_buf = FX_Alloc2D(uint8_t, maskHeight, maskWidth); |
280 mask_size = maskHeight * maskWidth; // Safe since checked alloc returned. | 277 mask_size = maskHeight * maskWidth; // Safe since checked alloc returned. |
281 for (int32_t a = 0; a < maskHeight; a++) { | 278 for (int32_t a = 0; a < maskHeight; a++) { |
282 FXSYS_memcpy(mask_buf + a * maskWidth, pMaskBitmap->GetScanline(a), | 279 FXSYS_memcpy(mask_buf + a * maskWidth, pMaskBitmap->GetScanline(a), |
283 maskWidth); | 280 maskWidth); |
284 } | 281 } |
285 } | 282 } |
286 pMaskDict->SetIntegerFor("Length", mask_size); | 283 pMaskDict->SetNewFor<CPDF_Number>("Length", mask_size); |
287 pDict->SetReferenceFor( | 284 pDict->SetNewFor<CPDF_Reference>( |
288 "SMask", m_pDocument, | 285 "SMask", m_pDocument, |
289 m_pDocument->NewIndirect<CPDF_Stream>(mask_buf, mask_size, pMaskDict)); | 286 m_pDocument->NewIndirect<CPDF_Stream>(mask_buf, mask_size, pMaskDict) |
| 287 ->GetObjNum()); |
290 if (bDeleteMask) | 288 if (bDeleteMask) |
291 delete pMaskBitmap; | 289 delete pMaskBitmap; |
292 } | 290 } |
293 if (opType == 0) { | 291 if (opType == 0) { |
294 if (iCompress & PDF_IMAGE_LOSSLESS_COMPRESS) { | 292 if (iCompress & PDF_IMAGE_LOSSLESS_COMPRESS) { |
295 } else { | 293 } else { |
296 if (pBitmap->GetBPP() == 1) { | 294 if (pBitmap->GetBPP() == 1) { |
297 } else if (pBitmap->GetBPP() >= 8 && pBitmap->GetPalette()) { | 295 } else if (pBitmap->GetBPP() >= 8 && pBitmap->GetPalette()) { |
298 CFX_DIBitmap* pNewBitmap = new CFX_DIBitmap(); | 296 CFX_DIBitmap* pNewBitmap = new CFX_DIBitmap(); |
299 pNewBitmap->Copy(pBitmap); | 297 pNewBitmap->Copy(pBitmap); |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
412 } | 410 } |
413 if (!ret) { | 411 if (!ret) { |
414 delete m_pDIBSource; | 412 delete m_pDIBSource; |
415 m_pDIBSource = nullptr; | 413 m_pDIBSource = nullptr; |
416 return false; | 414 return false; |
417 } | 415 } |
418 m_pMask = pSource->DetachMask(); | 416 m_pMask = pSource->DetachMask(); |
419 m_MatteColor = pSource->GetMatteColor(); | 417 m_MatteColor = pSource->GetMatteColor(); |
420 return false; | 418 return false; |
421 } | 419 } |
OLD | NEW |