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 <utility> |
12 #include <vector> | 12 #include <vector> |
13 | 13 |
14 #include "core/fpdfapi/cpdf_modulemgr.h" | 14 #include "core/fpdfapi/cpdf_modulemgr.h" |
15 #include "core/fpdfapi/page/cpdf_docpagedata.h" | 15 #include "core/fpdfapi/page/cpdf_docpagedata.h" |
16 #include "core/fpdfapi/page/cpdf_page.h" | 16 #include "core/fpdfapi/page/cpdf_page.h" |
17 #include "core/fpdfapi/parser/cpdf_array.h" | 17 #include "core/fpdfapi/parser/cpdf_array.h" |
18 #include "core/fpdfapi/parser/cpdf_boolean.h" | 18 #include "core/fpdfapi/parser/cpdf_boolean.h" |
19 #include "core/fpdfapi/parser/cpdf_dictionary.h" | 19 #include "core/fpdfapi/parser/cpdf_dictionary.h" |
20 #include "core/fpdfapi/parser/cpdf_document.h" | 20 #include "core/fpdfapi/parser/cpdf_document.h" |
21 #include "core/fpdfapi/parser/cpdf_name.h" | 21 #include "core/fpdfapi/parser/cpdf_name.h" |
22 #include "core/fpdfapi/parser/cpdf_number.h" | 22 #include "core/fpdfapi/parser/cpdf_number.h" |
23 #include "core/fpdfapi/parser/cpdf_reference.h" | 23 #include "core/fpdfapi/parser/cpdf_reference.h" |
24 #include "core/fpdfapi/parser/cpdf_stream.h" | |
24 #include "core/fpdfapi/parser/cpdf_string.h" | 25 #include "core/fpdfapi/parser/cpdf_string.h" |
25 #include "core/fpdfapi/render/cpdf_pagerendercache.h" | 26 #include "core/fpdfapi/render/cpdf_pagerendercache.h" |
26 #include "core/fpdfapi/render/render_int.h" | 27 #include "core/fpdfapi/render/render_int.h" |
27 #include "core/fxcodec/fx_codec.h" | 28 #include "core/fxcodec/fx_codec.h" |
28 #include "core/fxge/fx_dib.h" | 29 #include "core/fxge/fx_dib.h" |
30 #include "third_party/base/ptr_util.h" | |
29 | 31 |
30 CPDF_Image::CPDF_Image(CPDF_Document* pDoc) : m_pDocument(pDoc) {} | 32 CPDF_Image::CPDF_Image(CPDF_Document* pDoc) : m_pDocument(pDoc) {} |
31 | 33 |
32 CPDF_Image::CPDF_Image(CPDF_Document* pDoc, | 34 CPDF_Image::CPDF_Image(CPDF_Document* pDoc, |
33 std::unique_ptr<CPDF_Stream> pStream) | 35 std::unique_ptr<CPDF_Stream> pStream) |
34 : m_pDocument(pDoc), | 36 : m_pDocument(pDoc), |
35 m_pStream(pStream.get()), | 37 m_pStream(pStream.get()), |
36 m_pOwnedStream(std::move(pStream)) { | 38 m_pOwnedStream(std::move(pStream)) { |
37 m_pOwnedDict = | 39 m_pOwnedDict = |
38 ToDictionary(std::unique_ptr<CPDF_Object>(m_pStream->GetDict()->Clone())); | 40 ToDictionary(std::unique_ptr<CPDF_Object>(m_pStream->GetDict()->Clone())); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
142 pFile->ReadBlock(data.data(), 0, dwEstimateSize); | 144 pFile->ReadBlock(data.data(), 0, dwEstimateSize); |
143 CPDF_Dictionary* pDict = InitJPEG(data.data(), dwEstimateSize); | 145 CPDF_Dictionary* pDict = InitJPEG(data.data(), dwEstimateSize); |
144 if (!pDict && size > dwEstimateSize) { | 146 if (!pDict && size > dwEstimateSize) { |
145 data.resize(size); | 147 data.resize(size); |
146 pFile->ReadBlock(data.data(), 0, size); | 148 pFile->ReadBlock(data.data(), 0, size); |
147 pDict = InitJPEG(data.data(), size); | 149 pDict = InitJPEG(data.data(), size); |
148 } | 150 } |
149 if (!pDict) | 151 if (!pDict) |
150 return; | 152 return; |
151 | 153 |
152 m_pStream->InitStreamFromFile(pFile, pDict); | 154 m_pStream->InitStreamFromFile(pFile, pdfium::WrapUnique(pDict)); |
153 } | 155 } |
154 | 156 |
155 void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap, int32_t iCompress) { | 157 void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap, int32_t iCompress) { |
156 int32_t BitmapWidth = pBitmap->GetWidth(); | 158 int32_t BitmapWidth = pBitmap->GetWidth(); |
157 int32_t BitmapHeight = pBitmap->GetHeight(); | 159 int32_t BitmapHeight = pBitmap->GetHeight(); |
158 if (BitmapWidth < 1 || BitmapHeight < 1) { | 160 if (BitmapWidth < 1 || BitmapHeight < 1) { |
159 return; | 161 return; |
160 } | 162 } |
161 uint8_t* src_buf = pBitmap->GetBuffer(); | 163 uint8_t* src_buf = pBitmap->GetBuffer(); |
162 int32_t src_pitch = pBitmap->GetPitch(); | 164 int32_t src_pitch = pBitmap->GetPitch(); |
163 int32_t bpp = pBitmap->GetBPP(); | 165 int32_t bpp = pBitmap->GetBPP(); |
164 | 166 |
165 CPDF_Dictionary* pDict = | 167 auto pDict = |
166 new CPDF_Dictionary(m_pDocument->GetByteStringPool()); | 168 pdfium::MakeUnique<CPDF_Dictionary>(m_pDocument->GetByteStringPool()); |
167 pDict->SetNewFor<CPDF_Name>("Type", "XObject"); | 169 pDict->SetNewFor<CPDF_Name>("Type", "XObject"); |
168 pDict->SetNewFor<CPDF_Name>("Subtype", "Image"); | 170 pDict->SetNewFor<CPDF_Name>("Subtype", "Image"); |
169 pDict->SetNewFor<CPDF_Number>("Width", BitmapWidth); | 171 pDict->SetNewFor<CPDF_Number>("Width", BitmapWidth); |
170 pDict->SetNewFor<CPDF_Number>("Height", BitmapHeight); | 172 pDict->SetNewFor<CPDF_Number>("Height", BitmapHeight); |
171 uint8_t* dest_buf = nullptr; | 173 uint8_t* dest_buf = nullptr; |
172 FX_STRSIZE dest_pitch = 0, dest_size = 0, opType = -1; | 174 FX_STRSIZE dest_pitch = 0, dest_size = 0, opType = -1; |
173 if (bpp == 1) { | 175 if (bpp == 1) { |
174 int32_t reset_a = 0, reset_r = 0, reset_g = 0, reset_b = 0; | 176 int32_t reset_a = 0, reset_r = 0, reset_g = 0, reset_b = 0; |
175 int32_t set_a = 0, set_r = 0, set_g = 0, set_b = 0; | 177 int32_t set_a = 0, set_r = 0, set_g = 0, set_b = 0; |
176 if (!pBitmap->IsAlphaMask()) { | 178 if (!pBitmap->IsAlphaMask()) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
217 pCS->AddNew<CPDF_Number>(iPalette - 1); | 219 pCS->AddNew<CPDF_Number>(iPalette - 1); |
218 uint8_t* pColorTable = FX_Alloc2D(uint8_t, iPalette, 3); | 220 uint8_t* pColorTable = FX_Alloc2D(uint8_t, iPalette, 3); |
219 uint8_t* ptr = pColorTable; | 221 uint8_t* ptr = pColorTable; |
220 for (int32_t i = 0; i < iPalette; i++) { | 222 for (int32_t i = 0; i < iPalette; i++) { |
221 uint32_t argb = pBitmap->GetPaletteArgb(i); | 223 uint32_t argb = pBitmap->GetPaletteArgb(i); |
222 ptr[0] = (uint8_t)(argb >> 16); | 224 ptr[0] = (uint8_t)(argb >> 16); |
223 ptr[1] = (uint8_t)(argb >> 8); | 225 ptr[1] = (uint8_t)(argb >> 8); |
224 ptr[2] = (uint8_t)argb; | 226 ptr[2] = (uint8_t)argb; |
225 ptr += 3; | 227 ptr += 3; |
226 } | 228 } |
229 auto pNewDict = | |
230 pdfium::MakeUnique<CPDF_Dictionary>(m_pDocument->GetByteStringPool()); | |
227 CPDF_Stream* pCTS = m_pDocument->NewIndirect<CPDF_Stream>( | 231 CPDF_Stream* pCTS = m_pDocument->NewIndirect<CPDF_Stream>( |
228 pColorTable, iPalette * 3, | 232 pColorTable, iPalette * 3, std::move(pNewDict)); |
229 new CPDF_Dictionary(m_pDocument->GetByteStringPool())); | |
230 pCS->AddNew<CPDF_Reference>(m_pDocument, pCTS->GetObjNum()); | 233 pCS->AddNew<CPDF_Reference>(m_pDocument, pCTS->GetObjNum()); |
231 pDict->SetNewFor<CPDF_Reference>("ColorSpace", m_pDocument, | 234 pDict->SetNewFor<CPDF_Reference>("ColorSpace", m_pDocument, |
232 pCS->GetObjNum()); | 235 pCS->GetObjNum()); |
233 } else { | 236 } else { |
234 pDict->SetNewFor<CPDF_Name>("ColorSpace", "DeviceGray"); | 237 pDict->SetNewFor<CPDF_Name>("ColorSpace", "DeviceGray"); |
235 } | 238 } |
236 pDict->SetNewFor<CPDF_Number>("BitsPerComponent", 8); | 239 pDict->SetNewFor<CPDF_Number>("BitsPerComponent", 8); |
237 if ((iCompress & 0x03) == PDF_IMAGE_NO_COMPRESS) { | 240 if ((iCompress & 0x03) == PDF_IMAGE_NO_COMPRESS) { |
238 dest_pitch = BitmapWidth; | 241 dest_pitch = BitmapWidth; |
239 opType = 1; | 242 opType = 1; |
(...skipping 14 matching lines...) Expand all Loading... | |
254 bool bDeleteMask = false; | 257 bool bDeleteMask = false; |
255 if (pBitmap->HasAlpha()) { | 258 if (pBitmap->HasAlpha()) { |
256 pMaskBitmap = pBitmap->GetAlphaMask(); | 259 pMaskBitmap = pBitmap->GetAlphaMask(); |
257 bDeleteMask = true; | 260 bDeleteMask = true; |
258 } | 261 } |
259 if (pMaskBitmap) { | 262 if (pMaskBitmap) { |
260 int32_t maskWidth = pMaskBitmap->GetWidth(); | 263 int32_t maskWidth = pMaskBitmap->GetWidth(); |
261 int32_t maskHeight = pMaskBitmap->GetHeight(); | 264 int32_t maskHeight = pMaskBitmap->GetHeight(); |
262 uint8_t* mask_buf = nullptr; | 265 uint8_t* mask_buf = nullptr; |
263 FX_STRSIZE mask_size = 0; | 266 FX_STRSIZE mask_size = 0; |
264 CPDF_Dictionary* pMaskDict = | 267 auto pMaskDict = |
265 new CPDF_Dictionary(m_pDocument->GetByteStringPool()); | 268 pdfium::MakeUnique<CPDF_Dictionary>(m_pDocument->GetByteStringPool()); |
266 pMaskDict->SetNewFor<CPDF_Name>("Type", "XObject"); | 269 pMaskDict->SetNewFor<CPDF_Name>("Type", "XObject"); |
267 pMaskDict->SetNewFor<CPDF_Name>("Subtype", "Image"); | 270 pMaskDict->SetNewFor<CPDF_Name>("Subtype", "Image"); |
268 pMaskDict->SetNewFor<CPDF_Number>("Width", maskWidth); | 271 pMaskDict->SetNewFor<CPDF_Number>("Width", maskWidth); |
269 pMaskDict->SetNewFor<CPDF_Number>("Height", maskHeight); | 272 pMaskDict->SetNewFor<CPDF_Number>("Height", maskHeight); |
270 pMaskDict->SetNewFor<CPDF_Name>("ColorSpace", "DeviceGray"); | 273 pMaskDict->SetNewFor<CPDF_Name>("ColorSpace", "DeviceGray"); |
271 pMaskDict->SetNewFor<CPDF_Number>("BitsPerComponent", 8); | 274 pMaskDict->SetNewFor<CPDF_Number>("BitsPerComponent", 8); |
272 if (pMaskBitmap->GetBPP() == 8 && | 275 if (pMaskBitmap->GetBPP() == 8 && |
273 (iCompress & PDF_IMAGE_MASK_LOSSY_COMPRESS) != 0) { | 276 (iCompress & PDF_IMAGE_MASK_LOSSY_COMPRESS) != 0) { |
274 } else if (pMaskBitmap->GetFormat() == FXDIB_1bppMask) { | 277 } else if (pMaskBitmap->GetFormat() == FXDIB_1bppMask) { |
275 } else { | 278 } else { |
276 mask_buf = FX_Alloc2D(uint8_t, maskHeight, maskWidth); | 279 mask_buf = FX_Alloc2D(uint8_t, maskHeight, maskWidth); |
277 mask_size = maskHeight * maskWidth; // Safe since checked alloc returned. | 280 mask_size = maskHeight * maskWidth; // Safe since checked alloc returned. |
278 for (int32_t a = 0; a < maskHeight; a++) { | 281 for (int32_t a = 0; a < maskHeight; a++) { |
279 FXSYS_memcpy(mask_buf + a * maskWidth, pMaskBitmap->GetScanline(a), | 282 FXSYS_memcpy(mask_buf + a * maskWidth, pMaskBitmap->GetScanline(a), |
280 maskWidth); | 283 maskWidth); |
281 } | 284 } |
282 } | 285 } |
283 pMaskDict->SetNewFor<CPDF_Number>("Length", mask_size); | 286 pMaskDict->SetNewFor<CPDF_Number>("Length", mask_size); |
284 pDict->SetNewFor<CPDF_Reference>( | 287 pDict->SetNewFor<CPDF_Reference>( |
285 "SMask", m_pDocument, | 288 "SMask", m_pDocument, m_pDocument |
286 m_pDocument->NewIndirect<CPDF_Stream>(mask_buf, mask_size, pMaskDict) | 289 ->NewIndirect<CPDF_Stream>( |
Lei Zhang
2016/11/18 23:50:34
Can we do the NewIndirect() call separately?
Tom Sepez
2016/11/19 00:05:16
Done. That looks much better now.
| |
287 ->GetObjNum()); | 290 mask_buf, mask_size, std::move(pMaskDict)) |
291 ->GetObjNum()); | |
288 if (bDeleteMask) | 292 if (bDeleteMask) |
289 delete pMaskBitmap; | 293 delete pMaskBitmap; |
290 } | 294 } |
291 if (opType == 0) { | 295 if (opType == 0) { |
292 if (iCompress & PDF_IMAGE_LOSSLESS_COMPRESS) { | 296 if (iCompress & PDF_IMAGE_LOSSLESS_COMPRESS) { |
293 } else { | 297 } else { |
294 if (pBitmap->GetBPP() == 1) { | 298 if (pBitmap->GetBPP() == 1) { |
295 } else if (pBitmap->GetBPP() >= 8 && pBitmap->GetPalette()) { | 299 } else if (pBitmap->GetBPP() >= 8 && pBitmap->GetPalette()) { |
296 CFX_DIBitmap* pNewBitmap = new CFX_DIBitmap(); | 300 CFX_DIBitmap* pNewBitmap = new CFX_DIBitmap(); |
297 pNewBitmap->Copy(pBitmap); | 301 pNewBitmap->Copy(pBitmap); |
298 pNewBitmap->ConvertFormat(FXDIB_Rgb); | 302 pNewBitmap->ConvertFormat(FXDIB_Rgb); |
299 SetImage(pNewBitmap, iCompress); | 303 SetImage(pNewBitmap, iCompress); |
300 delete pDict; | |
301 pDict = nullptr; | |
302 FX_Free(dest_buf); | 304 FX_Free(dest_buf); |
303 dest_buf = nullptr; | 305 dest_buf = nullptr; |
304 dest_size = 0; | 306 dest_size = 0; |
305 delete pNewBitmap; | 307 delete pNewBitmap; |
306 return; | 308 return; |
307 } | 309 } |
308 } | 310 } |
309 } else if (opType == 1) { | 311 } else if (opType == 1) { |
310 dest_buf = FX_Alloc2D(uint8_t, dest_pitch, BitmapHeight); | 312 dest_buf = FX_Alloc2D(uint8_t, dest_pitch, BitmapHeight); |
311 dest_size = dest_pitch * BitmapHeight; // Safe as checked alloc returned. | 313 dest_size = dest_pitch * BitmapHeight; // Safe as checked alloc returned. |
(...skipping 23 matching lines...) Expand all Loading... | |
335 } | 337 } |
336 | 338 |
337 pDest += dest_pitch; | 339 pDest += dest_pitch; |
338 dest_offset = 0; | 340 dest_offset = 0; |
339 } | 341 } |
340 } | 342 } |
341 if (!m_pStream) { | 343 if (!m_pStream) { |
342 m_pOwnedStream = pdfium::MakeUnique<CPDF_Stream>(); | 344 m_pOwnedStream = pdfium::MakeUnique<CPDF_Stream>(); |
343 m_pStream = m_pOwnedStream.get(); | 345 m_pStream = m_pOwnedStream.get(); |
344 } | 346 } |
345 m_pStream->InitStream(dest_buf, dest_size, pDict); | 347 m_pStream->InitStream(dest_buf, dest_size, std::move(pDict)); |
346 m_bIsMask = pBitmap->IsAlphaMask(); | 348 m_bIsMask = pBitmap->IsAlphaMask(); |
347 m_Width = BitmapWidth; | 349 m_Width = BitmapWidth; |
348 m_Height = BitmapHeight; | 350 m_Height = BitmapHeight; |
349 FX_Free(dest_buf); | 351 FX_Free(dest_buf); |
350 } | 352 } |
351 | 353 |
352 void CPDF_Image::ResetCache(CPDF_Page* pPage, const CFX_DIBitmap* pBitmap) { | 354 void CPDF_Image::ResetCache(CPDF_Page* pPage, const CFX_DIBitmap* pBitmap) { |
353 pPage->GetRenderCache()->ResetBitmap(m_pStream, pBitmap); | 355 pPage->GetRenderCache()->ResetBitmap(m_pStream, pBitmap); |
354 } | 356 } |
355 | 357 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
410 } | 412 } |
411 if (!ret) { | 413 if (!ret) { |
412 delete m_pDIBSource; | 414 delete m_pDIBSource; |
413 m_pDIBSource = nullptr; | 415 m_pDIBSource = nullptr; |
414 return false; | 416 return false; |
415 } | 417 } |
416 m_pMask = pSource->DetachMask(); | 418 m_pMask = pSource->DetachMask(); |
417 m_MatteColor = pSource->GetMatteColor(); | 419 m_MatteColor = pSource->GetMatteColor(); |
418 return false; | 420 return false; |
419 } | 421 } |
OLD | NEW |