OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 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 "../../../../third_party/base/nonstd_unique_ptr.h" | 7 #include "../../../../third_party/base/nonstd_unique_ptr.h" |
8 #include "../../../include/fpdfapi/fpdf_module.h" | 8 #include "../../../include/fpdfapi/fpdf_module.h" |
9 #include "../../../include/fpdfapi/fpdf_pageobj.h" | 9 #include "../../../include/fpdfapi/fpdf_pageobj.h" |
10 #include "../../../include/fpdfapi/fpdf_render.h" | 10 #include "../../../include/fpdfapi/fpdf_render.h" |
11 #include "../../../include/fxcodec/fx_codec.h" | 11 #include "../../../include/fxcodec/fx_codec.h" |
12 #include "../../../include/fxcrt/fx_safe_types.h" | 12 #include "../../../include/fxcrt/fx_safe_types.h" |
13 #include "../../../include/fxge/fx_ge.h" | 13 #include "../../../include/fxge/fx_ge.h" |
14 #include "../fpdf_page/pageint.h" | 14 #include "../fpdf_page/pageint.h" |
15 #include "render_int.h" | 15 #include "render_int.h" |
16 | 16 |
17 namespace { | 17 namespace { |
18 | 18 |
19 unsigned int _GetBits8(const uint8_t* pData, int bitpos, int nbits) | 19 unsigned int _GetBits8(const uint8_t* pData, int bitpos, int nbits) { |
20 { | 20 unsigned int byte = pData[bitpos / 8]; |
21 unsigned int byte = pData[bitpos / 8]; | 21 if (nbits == 8) { |
22 if (nbits == 8) { | 22 return byte; |
23 return byte; | 23 } |
24 } | 24 if (nbits == 4) { |
25 if (nbits == 4) { | 25 return (bitpos % 8) ? (byte & 0x0f) : (byte >> 4); |
26 return (bitpos % 8) ? (byte & 0x0f) : (byte >> 4); | 26 } |
27 } | 27 if (nbits == 2) { |
28 if (nbits == 2) { | 28 return (byte >> (6 - bitpos % 8)) & 0x03; |
29 return (byte >> (6 - bitpos % 8)) & 0x03; | 29 } |
30 } | 30 if (nbits == 1) { |
31 if (nbits == 1) { | 31 return (byte >> (7 - bitpos % 8)) & 0x01; |
32 return (byte >> (7 - bitpos % 8)) & 0x01; | 32 } |
33 } | 33 if (nbits == 16) { |
34 if (nbits == 16) { | 34 return byte * 256 + pData[bitpos / 8 + 1]; |
35 return byte * 256 + pData[bitpos / 8 + 1]; | 35 } |
36 } | 36 return 0; |
37 return 0; | |
38 } | 37 } |
39 | 38 |
40 FX_SAFE_DWORD CalculatePitch8(FX_DWORD bpc, | 39 FX_SAFE_DWORD CalculatePitch8(FX_DWORD bpc, |
41 FX_DWORD components, | 40 FX_DWORD components, |
42 int width, | 41 int width, |
43 int height) | 42 int height) { |
44 { | 43 FX_SAFE_DWORD pitch = bpc; |
45 FX_SAFE_DWORD pitch = bpc; | 44 pitch *= components; |
46 pitch *= components; | 45 pitch *= width; |
47 pitch *= width; | 46 pitch += 7; |
48 pitch += 7; | 47 pitch /= 8; |
49 pitch /= 8; | 48 pitch *= height; |
50 pitch *= height; | 49 return pitch; |
51 return pitch; | 50 } |
52 } | 51 |
53 | 52 FX_SAFE_DWORD CalculatePitch32(int bpp, int width) { |
54 FX_SAFE_DWORD CalculatePitch32(int bpp, int width) | 53 FX_SAFE_DWORD pitch = bpp; |
55 { | 54 pitch *= width; |
56 FX_SAFE_DWORD pitch = bpp; | 55 pitch += 31; |
57 pitch *= width; | 56 pitch /= 8; |
58 pitch += 31; | 57 return pitch; |
59 pitch /= 8; | |
60 return pitch; | |
61 } | 58 } |
62 | 59 |
63 // Wrapper class to hold objects allocated in CPDF_DIBSource::LoadJpxBitmap(), | 60 // Wrapper class to hold objects allocated in CPDF_DIBSource::LoadJpxBitmap(), |
64 // because nonstd::unique_ptr does not support custom deleters yet. | 61 // because nonstd::unique_ptr does not support custom deleters yet. |
65 class JpxBitMapContext | 62 class JpxBitMapContext { |
66 { | 63 public: |
67 public: | 64 explicit JpxBitMapContext(ICodec_JpxModule* jpx_module) |
68 explicit JpxBitMapContext(ICodec_JpxModule* jpx_module) | 65 : jpx_module_(jpx_module), ctx_(nullptr), output_offsets_(nullptr) {} |
69 : jpx_module_(jpx_module), | 66 |
70 ctx_(nullptr), | 67 ~JpxBitMapContext() { |
71 output_offsets_(nullptr) {} | 68 FX_Free(output_offsets_); |
72 | 69 jpx_module_->DestroyDecoder(ctx_); |
73 ~JpxBitMapContext() { | 70 } |
74 FX_Free(output_offsets_); | 71 |
75 jpx_module_->DestroyDecoder(ctx_); | 72 // Takes ownership of |ctx|. |
76 } | 73 void set_context(void* ctx) { ctx_ = ctx; } |
77 | 74 |
78 // Takes ownership of |ctx|. | 75 void* context() { return ctx_; } |
79 void set_context(void* ctx) { | 76 |
80 ctx_ = ctx; | 77 // Takes ownership of |output_offsets|. |
81 } | 78 void set_output_offsets(unsigned char* output_offsets) { |
82 | 79 output_offsets_ = output_offsets; |
83 void* context() { | 80 } |
84 return ctx_; | 81 |
85 } | 82 unsigned char* output_offsets() { return output_offsets_; } |
86 | 83 |
87 // Takes ownership of |output_offsets|. | 84 private: |
88 void set_output_offsets(unsigned char* output_offsets) { | 85 ICodec_JpxModule* jpx_module_; // Weak pointer. |
89 output_offsets_ = output_offsets; | 86 void* ctx_; // Decoder context, owned. |
90 } | 87 unsigned char* output_offsets_; // Output offsets for decoding, owned. |
91 | 88 |
92 unsigned char* output_offsets() { | 89 // Disallow evil constructors |
93 return output_offsets_; | 90 JpxBitMapContext(const JpxBitMapContext&); |
94 } | 91 void operator=(const JpxBitMapContext&); |
95 | |
96 private: | |
97 ICodec_JpxModule* jpx_module_; // Weak pointer. | |
98 void* ctx_; // Decoder context, owned. | |
99 unsigned char* output_offsets_; // Output offsets for decoding, owned. | |
100 | |
101 // Disallow evil constructors | |
102 JpxBitMapContext(const JpxBitMapContext&); | |
103 void operator=(const JpxBitMapContext&); | |
104 }; | 92 }; |
105 | 93 |
106 } // namespace | 94 } // namespace |
107 | 95 |
108 CFX_DIBSource* CPDF_Image::LoadDIBSource(CFX_DIBSource** ppMask, FX_DWORD* pMatt
eColor, FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_BOOL bLoadMask) const | 96 CFX_DIBSource* CPDF_Image::LoadDIBSource(CFX_DIBSource** ppMask, |
109 { | 97 FX_DWORD* pMatteColor, |
110 CPDF_DIBSource* pSource = new CPDF_DIBSource; | 98 FX_BOOL bStdCS, |
111 if (pSource->Load(m_pDocument, m_pStream, (CPDF_DIBSource**)ppMask, pMatteCo
lor, NULL, NULL, bStdCS, GroupFamily, bLoadMask)) { | 99 FX_DWORD GroupFamily, |
112 return pSource; | 100 FX_BOOL bLoadMask) const { |
113 } | 101 CPDF_DIBSource* pSource = new CPDF_DIBSource; |
114 delete pSource; | 102 if (pSource->Load(m_pDocument, m_pStream, (CPDF_DIBSource**)ppMask, |
| 103 pMatteColor, NULL, NULL, bStdCS, GroupFamily, bLoadMask)) { |
| 104 return pSource; |
| 105 } |
| 106 delete pSource; |
| 107 return NULL; |
| 108 } |
| 109 CFX_DIBSource* CPDF_Image::DetachBitmap() { |
| 110 CFX_DIBSource* pBitmap = m_pDIBSource; |
| 111 m_pDIBSource = NULL; |
| 112 return pBitmap; |
| 113 } |
| 114 CFX_DIBSource* CPDF_Image::DetachMask() { |
| 115 CFX_DIBSource* pBitmap = m_pMask; |
| 116 m_pMask = NULL; |
| 117 return pBitmap; |
| 118 } |
| 119 FX_BOOL CPDF_Image::StartLoadDIBSource(CPDF_Dictionary* pFormResource, |
| 120 CPDF_Dictionary* pPageResource, |
| 121 FX_BOOL bStdCS, |
| 122 FX_DWORD GroupFamily, |
| 123 FX_BOOL bLoadMask) { |
| 124 m_pDIBSource = new CPDF_DIBSource; |
| 125 int ret = |
| 126 ((CPDF_DIBSource*)m_pDIBSource) |
| 127 ->StartLoadDIBSource(m_pDocument, m_pStream, TRUE, pFormResource, |
| 128 pPageResource, bStdCS, GroupFamily, bLoadMask); |
| 129 if (ret == 2) { |
| 130 return TRUE; |
| 131 } |
| 132 if (!ret) { |
| 133 delete m_pDIBSource; |
| 134 m_pDIBSource = NULL; |
| 135 return FALSE; |
| 136 } |
| 137 m_pMask = ((CPDF_DIBSource*)m_pDIBSource)->DetachMask(); |
| 138 m_MatteColor = ((CPDF_DIBSource*)m_pDIBSource)->m_MatteColor; |
| 139 return FALSE; |
| 140 } |
| 141 FX_BOOL CPDF_Image::Continue(IFX_Pause* pPause) { |
| 142 int ret = ((CPDF_DIBSource*)m_pDIBSource)->ContinueLoadDIBSource(pPause); |
| 143 if (ret == 2) { |
| 144 return TRUE; |
| 145 } |
| 146 if (!ret) { |
| 147 delete m_pDIBSource; |
| 148 m_pDIBSource = NULL; |
| 149 return FALSE; |
| 150 } |
| 151 m_pMask = ((CPDF_DIBSource*)m_pDIBSource)->DetachMask(); |
| 152 m_MatteColor = ((CPDF_DIBSource*)m_pDIBSource)->m_MatteColor; |
| 153 return FALSE; |
| 154 } |
| 155 CPDF_DIBSource::CPDF_DIBSource() { |
| 156 m_pDocument = NULL; |
| 157 m_pStreamAcc = NULL; |
| 158 m_pDict = NULL; |
| 159 m_bpp = 0; |
| 160 m_Width = m_Height = 0; |
| 161 m_pColorSpace = NULL; |
| 162 m_bDefaultDecode = TRUE; |
| 163 m_bImageMask = FALSE; |
| 164 m_bDoBpcCheck = TRUE; |
| 165 m_pPalette = NULL; |
| 166 m_pCompData = NULL; |
| 167 m_bColorKey = FALSE; |
| 168 m_pMaskedLine = m_pLineBuf = NULL; |
| 169 m_pDecoder = NULL; |
| 170 m_nComponents = 0; |
| 171 m_bpc = 0; |
| 172 m_bLoadMask = FALSE; |
| 173 m_Family = 0; |
| 174 m_pMask = NULL; |
| 175 m_MatteColor = 0; |
| 176 m_pJbig2Context = NULL; |
| 177 m_pGlobalStream = NULL; |
| 178 m_bStdCS = FALSE; |
| 179 m_pMaskStream = NULL; |
| 180 m_Status = 0; |
| 181 m_bHasMask = FALSE; |
| 182 } |
| 183 CPDF_DIBSource::~CPDF_DIBSource() { |
| 184 delete m_pStreamAcc; |
| 185 if (m_pMaskedLine) { |
| 186 FX_Free(m_pMaskedLine); |
| 187 } |
| 188 if (m_pLineBuf) { |
| 189 FX_Free(m_pLineBuf); |
| 190 } |
| 191 m_pCachedBitmap.reset(); |
| 192 delete m_pDecoder; |
| 193 if (m_pCompData) { |
| 194 FX_Free(m_pCompData); |
| 195 } |
| 196 CPDF_ColorSpace* pCS = m_pColorSpace; |
| 197 if (pCS && m_pDocument) { |
| 198 m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray()); |
| 199 } |
| 200 if (m_pJbig2Context) { |
| 201 ICodec_Jbig2Module* pJbig2Module = CPDF_ModuleMgr::Get()->GetJbig2Module(); |
| 202 pJbig2Module->DestroyJbig2Context(m_pJbig2Context); |
| 203 } |
| 204 delete m_pGlobalStream; |
| 205 } |
| 206 CFX_DIBitmap* CPDF_DIBSource::GetBitmap() const { |
| 207 return m_pCachedBitmap ? m_pCachedBitmap.get() : Clone(); |
| 208 } |
| 209 void CPDF_DIBSource::ReleaseBitmap(CFX_DIBitmap* pBitmap) const { |
| 210 if (pBitmap && pBitmap != m_pCachedBitmap) { |
| 211 delete pBitmap; |
| 212 } |
| 213 } |
| 214 FX_BOOL CPDF_DIBSource::Load(CPDF_Document* pDoc, |
| 215 const CPDF_Stream* pStream, |
| 216 CPDF_DIBSource** ppMask, |
| 217 FX_DWORD* pMatteColor, |
| 218 CPDF_Dictionary* pFormResources, |
| 219 CPDF_Dictionary* pPageResources, |
| 220 FX_BOOL bStdCS, |
| 221 FX_DWORD GroupFamily, |
| 222 FX_BOOL bLoadMask) { |
| 223 if (pStream == NULL) { |
| 224 return FALSE; |
| 225 } |
| 226 m_pDocument = pDoc; |
| 227 m_pDict = pStream->GetDict(); |
| 228 if (m_pDict == NULL) { |
| 229 return FALSE; |
| 230 } |
| 231 m_pStream = pStream; |
| 232 m_Width = m_pDict->GetInteger(FX_BSTRC("Width")); |
| 233 m_Height = m_pDict->GetInteger(FX_BSTRC("Height")); |
| 234 if (m_Width <= 0 || m_Height <= 0 || m_Width > 0x01ffff || |
| 235 m_Height > 0x01ffff) { |
| 236 return FALSE; |
| 237 } |
| 238 m_GroupFamily = GroupFamily; |
| 239 m_bLoadMask = bLoadMask; |
| 240 if (!LoadColorInfo(m_pStream->GetObjNum() != 0 ? NULL : pFormResources, |
| 241 pPageResources)) { |
| 242 return FALSE; |
| 243 } |
| 244 if (m_bDoBpcCheck && (m_bpc == 0 || m_nComponents == 0)) { |
| 245 return FALSE; |
| 246 } |
| 247 FX_SAFE_DWORD src_pitch = |
| 248 CalculatePitch8(m_bpc, m_nComponents, m_Width, m_Height); |
| 249 if (!src_pitch.IsValid()) { |
| 250 return FALSE; |
| 251 } |
| 252 m_pStreamAcc = new CPDF_StreamAcc; |
| 253 m_pStreamAcc->LoadAllData(pStream, FALSE, src_pitch.ValueOrDie(), TRUE); |
| 254 if (m_pStreamAcc->GetSize() == 0 || m_pStreamAcc->GetData() == NULL) { |
| 255 return FALSE; |
| 256 } |
| 257 if (!CreateDecoder()) { |
| 258 return FALSE; |
| 259 } |
| 260 if (m_bImageMask) { |
| 261 m_bpp = 1; |
| 262 m_bpc = 1; |
| 263 m_nComponents = 1; |
| 264 m_AlphaFlag = 1; |
| 265 } else if (m_bpc * m_nComponents == 1) { |
| 266 m_bpp = 1; |
| 267 } else if (m_bpc * m_nComponents <= 8) { |
| 268 m_bpp = 8; |
| 269 } else { |
| 270 m_bpp = 24; |
| 271 } |
| 272 FX_SAFE_DWORD pitch = CalculatePitch32(m_bpp, m_Width); |
| 273 if (!pitch.IsValid()) { |
| 274 return FALSE; |
| 275 } |
| 276 m_pLineBuf = FX_Alloc(uint8_t, pitch.ValueOrDie()); |
| 277 if (m_pColorSpace && bStdCS) { |
| 278 m_pColorSpace->EnableStdConversion(TRUE); |
| 279 } |
| 280 LoadPalette(); |
| 281 if (m_bColorKey) { |
| 282 m_bpp = 32; |
| 283 m_AlphaFlag = 2; |
| 284 pitch = CalculatePitch32(m_bpp, m_Width); |
| 285 if (!pitch.IsValid()) { |
| 286 return FALSE; |
| 287 } |
| 288 m_pMaskedLine = FX_Alloc(uint8_t, pitch.ValueOrDie()); |
| 289 } |
| 290 m_Pitch = pitch.ValueOrDie(); |
| 291 if (ppMask) { |
| 292 *ppMask = LoadMask(*pMatteColor); |
| 293 } |
| 294 if (m_pColorSpace && bStdCS) { |
| 295 m_pColorSpace->EnableStdConversion(FALSE); |
| 296 } |
| 297 return TRUE; |
| 298 } |
| 299 int CPDF_DIBSource::ContinueToLoadMask() { |
| 300 if (m_bImageMask) { |
| 301 m_bpp = 1; |
| 302 m_bpc = 1; |
| 303 m_nComponents = 1; |
| 304 m_AlphaFlag = 1; |
| 305 } else if (m_bpc * m_nComponents == 1) { |
| 306 m_bpp = 1; |
| 307 } else if (m_bpc * m_nComponents <= 8) { |
| 308 m_bpp = 8; |
| 309 } else { |
| 310 m_bpp = 24; |
| 311 } |
| 312 if (!m_bpc || !m_nComponents) { |
| 313 return 0; |
| 314 } |
| 315 FX_SAFE_DWORD pitch = CalculatePitch32(m_bpp, m_Width); |
| 316 if (!pitch.IsValid()) { |
| 317 return 0; |
| 318 } |
| 319 m_pLineBuf = FX_Alloc(uint8_t, pitch.ValueOrDie()); |
| 320 if (m_pColorSpace && m_bStdCS) { |
| 321 m_pColorSpace->EnableStdConversion(TRUE); |
| 322 } |
| 323 LoadPalette(); |
| 324 if (m_bColorKey) { |
| 325 m_bpp = 32; |
| 326 m_AlphaFlag = 2; |
| 327 pitch = CalculatePitch32(m_bpp, m_Width); |
| 328 if (!pitch.IsValid()) { |
| 329 return 0; |
| 330 } |
| 331 m_pMaskedLine = FX_Alloc(uint8_t, pitch.ValueOrDie()); |
| 332 } |
| 333 m_Pitch = pitch.ValueOrDie(); |
| 334 return 1; |
| 335 } |
| 336 int CPDF_DIBSource::StartLoadDIBSource(CPDF_Document* pDoc, |
| 337 const CPDF_Stream* pStream, |
| 338 FX_BOOL bHasMask, |
| 339 CPDF_Dictionary* pFormResources, |
| 340 CPDF_Dictionary* pPageResources, |
| 341 FX_BOOL bStdCS, |
| 342 FX_DWORD GroupFamily, |
| 343 FX_BOOL bLoadMask) { |
| 344 if (pStream == NULL) { |
| 345 return 0; |
| 346 } |
| 347 m_pDocument = pDoc; |
| 348 m_pDict = pStream->GetDict(); |
| 349 m_pStream = pStream; |
| 350 m_bStdCS = bStdCS; |
| 351 m_bHasMask = bHasMask; |
| 352 m_Width = m_pDict->GetInteger(FX_BSTRC("Width")); |
| 353 m_Height = m_pDict->GetInteger(FX_BSTRC("Height")); |
| 354 if (m_Width <= 0 || m_Height <= 0 || m_Width > 0x01ffff || |
| 355 m_Height > 0x01ffff) { |
| 356 return 0; |
| 357 } |
| 358 m_GroupFamily = GroupFamily; |
| 359 m_bLoadMask = bLoadMask; |
| 360 if (!LoadColorInfo(m_pStream->GetObjNum() != 0 ? NULL : pFormResources, |
| 361 pPageResources)) { |
| 362 return 0; |
| 363 } |
| 364 if (m_bDoBpcCheck && (m_bpc == 0 || m_nComponents == 0)) { |
| 365 return 0; |
| 366 } |
| 367 FX_SAFE_DWORD src_pitch = |
| 368 CalculatePitch8(m_bpc, m_nComponents, m_Width, m_Height); |
| 369 if (!src_pitch.IsValid()) { |
| 370 return 0; |
| 371 } |
| 372 m_pStreamAcc = new CPDF_StreamAcc; |
| 373 m_pStreamAcc->LoadAllData(pStream, FALSE, src_pitch.ValueOrDie(), TRUE); |
| 374 if (m_pStreamAcc->GetSize() == 0 || m_pStreamAcc->GetData() == NULL) { |
| 375 return 0; |
| 376 } |
| 377 int ret = CreateDecoder(); |
| 378 if (ret != 1) { |
| 379 if (!ret) { |
| 380 return ret; |
| 381 } |
| 382 if (!ContinueToLoadMask()) { |
| 383 return 0; |
| 384 } |
| 385 if (m_bHasMask) { |
| 386 StratLoadMask(); |
| 387 } |
| 388 return ret; |
| 389 } |
| 390 if (!ContinueToLoadMask()) { |
| 391 return 0; |
| 392 } |
| 393 if (m_bHasMask) { |
| 394 ret = StratLoadMask(); |
| 395 } |
| 396 if (ret == 2) { |
| 397 return ret; |
| 398 } |
| 399 if (m_pColorSpace && m_bStdCS) { |
| 400 m_pColorSpace->EnableStdConversion(FALSE); |
| 401 } |
| 402 return ret; |
| 403 } |
| 404 int CPDF_DIBSource::ContinueLoadDIBSource(IFX_Pause* pPause) { |
| 405 FXCODEC_STATUS ret; |
| 406 if (m_Status == 1) { |
| 407 const CFX_ByteString& decoder = m_pStreamAcc->GetImageDecoder(); |
| 408 if (decoder == FX_BSTRC("JPXDecode")) { |
| 409 return 0; |
| 410 } |
| 411 ICodec_Jbig2Module* pJbig2Module = CPDF_ModuleMgr::Get()->GetJbig2Module(); |
| 412 if (m_pJbig2Context == NULL) { |
| 413 m_pJbig2Context = pJbig2Module->CreateJbig2Context(); |
| 414 if (m_pStreamAcc->GetImageParam()) { |
| 415 CPDF_Stream* pGlobals = |
| 416 m_pStreamAcc->GetImageParam()->GetStream(FX_BSTRC("JBIG2Globals")); |
| 417 if (pGlobals) { |
| 418 m_pGlobalStream = new CPDF_StreamAcc; |
| 419 m_pGlobalStream->LoadAllData(pGlobals, FALSE); |
| 420 } |
| 421 } |
| 422 ret = pJbig2Module->StartDecode( |
| 423 m_pJbig2Context, m_Width, m_Height, m_pStreamAcc->GetData(), |
| 424 m_pStreamAcc->GetSize(), |
| 425 m_pGlobalStream ? m_pGlobalStream->GetData() : NULL, |
| 426 m_pGlobalStream ? m_pGlobalStream->GetSize() : 0, |
| 427 m_pCachedBitmap->GetBuffer(), m_pCachedBitmap->GetPitch(), pPause); |
| 428 if (ret < 0) { |
| 429 m_pCachedBitmap.reset(); |
| 430 delete m_pGlobalStream; |
| 431 m_pGlobalStream = NULL; |
| 432 pJbig2Module->DestroyJbig2Context(m_pJbig2Context); |
| 433 m_pJbig2Context = NULL; |
| 434 return 0; |
| 435 } |
| 436 if (ret == FXCODEC_STATUS_DECODE_TOBECONTINUE) { |
| 437 return 2; |
| 438 } |
| 439 int ret1 = 1; |
| 440 if (m_bHasMask) { |
| 441 ret1 = ContinueLoadMaskDIB(pPause); |
| 442 m_Status = 2; |
| 443 } |
| 444 if (ret1 == 2) { |
| 445 return ret1; |
| 446 } |
| 447 if (m_pColorSpace && m_bStdCS) { |
| 448 m_pColorSpace->EnableStdConversion(FALSE); |
| 449 } |
| 450 return ret1; |
| 451 } |
| 452 FXCODEC_STATUS ret = pJbig2Module->ContinueDecode(m_pJbig2Context, pPause); |
| 453 if (ret < 0) { |
| 454 m_pCachedBitmap.reset(); |
| 455 delete m_pGlobalStream; |
| 456 m_pGlobalStream = NULL; |
| 457 pJbig2Module->DestroyJbig2Context(m_pJbig2Context); |
| 458 m_pJbig2Context = NULL; |
| 459 return 0; |
| 460 } |
| 461 if (ret == FXCODEC_STATUS_DECODE_TOBECONTINUE) { |
| 462 return 2; |
| 463 } |
| 464 int ret1 = 1; |
| 465 if (m_bHasMask) { |
| 466 ret1 = ContinueLoadMaskDIB(pPause); |
| 467 m_Status = 2; |
| 468 } |
| 469 if (ret1 == 2) { |
| 470 return ret1; |
| 471 } |
| 472 if (m_pColorSpace && m_bStdCS) { |
| 473 m_pColorSpace->EnableStdConversion(FALSE); |
| 474 } |
| 475 return ret1; |
| 476 } |
| 477 if (m_Status == 2) { |
| 478 return ContinueLoadMaskDIB(pPause); |
| 479 } |
| 480 return 0; |
| 481 } |
| 482 FX_BOOL CPDF_DIBSource::LoadColorInfo(CPDF_Dictionary* pFormResources, |
| 483 CPDF_Dictionary* pPageResources) { |
| 484 m_bpc_orig = m_pDict->GetInteger(FX_BSTRC("BitsPerComponent")); |
| 485 if (m_pDict->GetInteger("ImageMask")) { |
| 486 m_bImageMask = TRUE; |
| 487 } |
| 488 if (m_bImageMask || !m_pDict->KeyExist(FX_BSTRC("ColorSpace"))) { |
| 489 if (!m_bImageMask) { |
| 490 CPDF_Object* pFilter = m_pDict->GetElementValue(FX_BSTRC("Filter")); |
| 491 if (pFilter) { |
| 492 CFX_ByteString filter; |
| 493 if (pFilter->GetType() == PDFOBJ_NAME) { |
| 494 filter = pFilter->GetString(); |
| 495 if (filter == FX_BSTRC("JPXDecode")) { |
| 496 m_bDoBpcCheck = FALSE; |
| 497 return TRUE; |
| 498 } |
| 499 } else if (pFilter->GetType() == PDFOBJ_ARRAY) { |
| 500 CPDF_Array* pArray = (CPDF_Array*)pFilter; |
| 501 if (pArray->GetString(pArray->GetCount() - 1) == |
| 502 FX_BSTRC("JPXDecode")) { |
| 503 m_bDoBpcCheck = FALSE; |
| 504 return TRUE; |
| 505 } |
| 506 } |
| 507 } |
| 508 } |
| 509 m_bImageMask = TRUE; |
| 510 m_bpc = m_nComponents = 1; |
| 511 CPDF_Array* pDecode = m_pDict->GetArray(FX_BSTRC("Decode")); |
| 512 m_bDefaultDecode = pDecode == NULL || pDecode->GetInteger(0) == 0; |
| 513 return TRUE; |
| 514 } |
| 515 CPDF_Object* pCSObj = m_pDict->GetElementValue(FX_BSTRC("ColorSpace")); |
| 516 if (pCSObj == NULL) { |
| 517 return FALSE; |
| 518 } |
| 519 CPDF_DocPageData* pDocPageData = m_pDocument->GetPageData(); |
| 520 if (pFormResources) { |
| 521 m_pColorSpace = pDocPageData->GetColorSpace(pCSObj, pFormResources); |
| 522 } |
| 523 if (m_pColorSpace == NULL) { |
| 524 m_pColorSpace = pDocPageData->GetColorSpace(pCSObj, pPageResources); |
| 525 } |
| 526 if (m_pColorSpace == NULL) { |
| 527 return FALSE; |
| 528 } |
| 529 m_Family = m_pColorSpace->GetFamily(); |
| 530 m_nComponents = m_pColorSpace->CountComponents(); |
| 531 if (m_Family == PDFCS_ICCBASED && pCSObj->GetType() == PDFOBJ_NAME) { |
| 532 CFX_ByteString cs = pCSObj->GetString(); |
| 533 if (cs == FX_BSTRC("DeviceGray")) { |
| 534 m_nComponents = 1; |
| 535 } else if (cs == FX_BSTRC("DeviceRGB")) { |
| 536 m_nComponents = 3; |
| 537 } else if (cs == FX_BSTRC("DeviceCMYK")) { |
| 538 m_nComponents = 4; |
| 539 } |
| 540 } |
| 541 ValidateDictParam(); |
| 542 m_pCompData = GetDecodeAndMaskArray(m_bDefaultDecode, m_bColorKey); |
| 543 if (m_pCompData == NULL) { |
| 544 return FALSE; |
| 545 } |
| 546 return TRUE; |
| 547 } |
| 548 DIB_COMP_DATA* CPDF_DIBSource::GetDecodeAndMaskArray(FX_BOOL& bDefaultDecode, |
| 549 FX_BOOL& bColorKey) { |
| 550 if (m_pColorSpace == NULL) { |
115 return NULL; | 551 return NULL; |
116 } | 552 } |
117 CFX_DIBSource* CPDF_Image::DetachBitmap() | 553 DIB_COMP_DATA* pCompData = FX_Alloc(DIB_COMP_DATA, m_nComponents); |
118 { | 554 int max_data = (1 << m_bpc) - 1; |
119 CFX_DIBSource* pBitmap = m_pDIBSource; | 555 CPDF_Array* pDecode = m_pDict->GetArray(FX_BSTRC("Decode")); |
120 m_pDIBSource = NULL; | 556 if (pDecode) { |
121 return pBitmap; | 557 for (FX_DWORD i = 0; i < m_nComponents; i++) { |
122 } | 558 pCompData[i].m_DecodeMin = pDecode->GetNumber(i * 2); |
123 CFX_DIBSource* CPDF_Image::DetachMask() | 559 FX_FLOAT max = pDecode->GetNumber(i * 2 + 1); |
124 { | 560 pCompData[i].m_DecodeStep = (max - pCompData[i].m_DecodeMin) / max_data; |
125 CFX_DIBSource* pBitmap = m_pMask; | 561 FX_FLOAT def_value, def_min, def_max; |
| 562 m_pColorSpace->GetDefaultValue(i, def_value, def_min, def_max); |
| 563 if (m_Family == PDFCS_INDEXED) { |
| 564 def_max = (FX_FLOAT)max_data; |
| 565 } |
| 566 if (def_min != pCompData[i].m_DecodeMin || def_max != max) { |
| 567 bDefaultDecode = FALSE; |
| 568 } |
| 569 } |
| 570 } else { |
| 571 for (FX_DWORD i = 0; i < m_nComponents; i++) { |
| 572 FX_FLOAT def_value; |
| 573 m_pColorSpace->GetDefaultValue(i, def_value, pCompData[i].m_DecodeMin, |
| 574 pCompData[i].m_DecodeStep); |
| 575 if (m_Family == PDFCS_INDEXED) { |
| 576 pCompData[i].m_DecodeStep = (FX_FLOAT)max_data; |
| 577 } |
| 578 pCompData[i].m_DecodeStep = |
| 579 (pCompData[i].m_DecodeStep - pCompData[i].m_DecodeMin) / max_data; |
| 580 } |
| 581 } |
| 582 if (!m_pDict->KeyExist(FX_BSTRC("SMask"))) { |
| 583 CPDF_Object* pMask = m_pDict->GetElementValue(FX_BSTRC("Mask")); |
| 584 if (pMask == NULL) { |
| 585 return pCompData; |
| 586 } |
| 587 if (pMask->GetType() == PDFOBJ_ARRAY) { |
| 588 CPDF_Array* pArray = (CPDF_Array*)pMask; |
| 589 if (pArray->GetCount() >= m_nComponents * 2) { |
| 590 for (FX_DWORD i = 0; i < m_nComponents; i++) { |
| 591 int min_num = pArray->GetInteger(i * 2); |
| 592 int max_num = pArray->GetInteger(i * 2 + 1); |
| 593 pCompData[i].m_ColorKeyMin = FX_MAX(min_num, 0); |
| 594 pCompData[i].m_ColorKeyMax = FX_MIN(max_num, max_data); |
| 595 } |
| 596 } |
| 597 bColorKey = TRUE; |
| 598 } |
| 599 } |
| 600 return pCompData; |
| 601 } |
| 602 ICodec_ScanlineDecoder* FPDFAPI_CreateFaxDecoder( |
| 603 const uint8_t* src_buf, |
| 604 FX_DWORD src_size, |
| 605 int width, |
| 606 int height, |
| 607 const CPDF_Dictionary* pParams); |
| 608 ICodec_ScanlineDecoder* FPDFAPI_CreateFlateDecoder( |
| 609 const uint8_t* src_buf, |
| 610 FX_DWORD src_size, |
| 611 int width, |
| 612 int height, |
| 613 int nComps, |
| 614 int bpc, |
| 615 const CPDF_Dictionary* pParams); |
| 616 int CPDF_DIBSource::CreateDecoder() { |
| 617 const CFX_ByteString& decoder = m_pStreamAcc->GetImageDecoder(); |
| 618 if (decoder.IsEmpty()) { |
| 619 return 1; |
| 620 } |
| 621 if (m_bDoBpcCheck && m_bpc == 0) { |
| 622 return 0; |
| 623 } |
| 624 const uint8_t* src_data = m_pStreamAcc->GetData(); |
| 625 FX_DWORD src_size = m_pStreamAcc->GetSize(); |
| 626 const CPDF_Dictionary* pParams = m_pStreamAcc->GetImageParam(); |
| 627 if (decoder == FX_BSTRC("CCITTFaxDecode")) { |
| 628 m_pDecoder = FPDFAPI_CreateFaxDecoder(src_data, src_size, m_Width, m_Height, |
| 629 pParams); |
| 630 } else if (decoder == FX_BSTRC("DCTDecode")) { |
| 631 m_pDecoder = CPDF_ModuleMgr::Get()->GetJpegModule()->CreateDecoder( |
| 632 src_data, src_size, m_Width, m_Height, m_nComponents, |
| 633 pParams ? pParams->GetInteger("ColorTransform", 1) : 1); |
| 634 if (!m_pDecoder) { |
| 635 FX_BOOL bTransform = FALSE; |
| 636 int comps, bpc; |
| 637 ICodec_JpegModule* pJpegModule = CPDF_ModuleMgr::Get()->GetJpegModule(); |
| 638 if (pJpegModule->LoadInfo(src_data, src_size, m_Width, m_Height, comps, |
| 639 bpc, bTransform)) { |
| 640 if (m_nComponents != comps) { |
| 641 FX_Free(m_pCompData); |
| 642 m_nComponents = comps; |
| 643 if (m_Family == PDFCS_LAB && m_nComponents != 3) { |
| 644 m_pCompData = NULL; |
| 645 return 0; |
| 646 } |
| 647 m_pCompData = GetDecodeAndMaskArray(m_bDefaultDecode, m_bColorKey); |
| 648 if (m_pCompData == NULL) { |
| 649 return 0; |
| 650 } |
| 651 } |
| 652 m_bpc = bpc; |
| 653 m_pDecoder = CPDF_ModuleMgr::Get()->GetJpegModule()->CreateDecoder( |
| 654 src_data, src_size, m_Width, m_Height, m_nComponents, bTransform); |
| 655 } |
| 656 } |
| 657 } else if (decoder == FX_BSTRC("FlateDecode")) { |
| 658 m_pDecoder = FPDFAPI_CreateFlateDecoder( |
| 659 src_data, src_size, m_Width, m_Height, m_nComponents, m_bpc, pParams); |
| 660 } else if (decoder == FX_BSTRC("JPXDecode")) { |
| 661 LoadJpxBitmap(); |
| 662 return m_pCachedBitmap ? 1 : 0; |
| 663 } else if (decoder == FX_BSTRC("JBIG2Decode")) { |
| 664 m_pCachedBitmap.reset(new CFX_DIBitmap); |
| 665 if (!m_pCachedBitmap->Create( |
| 666 m_Width, m_Height, m_bImageMask ? FXDIB_1bppMask : FXDIB_1bppRgb)) { |
| 667 m_pCachedBitmap.reset(); |
| 668 return 0; |
| 669 } |
| 670 m_Status = 1; |
| 671 return 2; |
| 672 } else if (decoder == FX_BSTRC("RunLengthDecode")) { |
| 673 m_pDecoder = CPDF_ModuleMgr::Get() |
| 674 ->GetCodecModule() |
| 675 ->GetBasicModule() |
| 676 ->CreateRunLengthDecoder(src_data, src_size, m_Width, |
| 677 m_Height, m_nComponents, m_bpc); |
| 678 } |
| 679 if (!m_pDecoder) |
| 680 return 0; |
| 681 |
| 682 FX_SAFE_DWORD requested_pitch = |
| 683 CalculatePitch8(m_bpc, m_nComponents, m_Width, 1); |
| 684 if (!requested_pitch.IsValid()) { |
| 685 return 0; |
| 686 } |
| 687 FX_SAFE_DWORD provided_pitch = |
| 688 CalculatePitch8(m_pDecoder->GetBPC(), m_pDecoder->CountComps(), |
| 689 m_pDecoder->GetWidth(), 1); |
| 690 if (!provided_pitch.IsValid()) { |
| 691 return 0; |
| 692 } |
| 693 if (provided_pitch.ValueOrDie() < requested_pitch.ValueOrDie()) { |
| 694 return 0; |
| 695 } |
| 696 return 1; |
| 697 } |
| 698 void CPDF_DIBSource::LoadJpxBitmap() { |
| 699 ICodec_JpxModule* pJpxModule = CPDF_ModuleMgr::Get()->GetJpxModule(); |
| 700 if (!pJpxModule) |
| 701 return; |
| 702 |
| 703 nonstd::unique_ptr<JpxBitMapContext> context( |
| 704 new JpxBitMapContext(pJpxModule)); |
| 705 context->set_context(pJpxModule->CreateDecoder(m_pStreamAcc->GetData(), |
| 706 m_pStreamAcc->GetSize(), |
| 707 m_pColorSpace != nullptr)); |
| 708 if (!context->context()) |
| 709 return; |
| 710 |
| 711 FX_DWORD width = 0; |
| 712 FX_DWORD height = 0; |
| 713 FX_DWORD codestream_nComps = 0; |
| 714 FX_DWORD image_nComps = 0; |
| 715 pJpxModule->GetImageInfo(context->context(), width, height, codestream_nComps, |
| 716 image_nComps); |
| 717 if ((int)width < m_Width || (int)height < m_Height) |
| 718 return; |
| 719 |
| 720 int output_nComps; |
| 721 FX_BOOL bTranslateColor; |
| 722 FX_BOOL bSwapRGB = FALSE; |
| 723 if (m_pColorSpace) { |
| 724 if (codestream_nComps != (FX_DWORD)m_pColorSpace->CountComponents()) |
| 725 return; |
| 726 output_nComps = codestream_nComps; |
| 727 bTranslateColor = FALSE; |
| 728 if (m_pColorSpace == CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB)) { |
| 729 bSwapRGB = TRUE; |
| 730 m_pColorSpace = nullptr; |
| 731 } |
| 732 } else { |
| 733 bTranslateColor = TRUE; |
| 734 if (image_nComps) { |
| 735 output_nComps = image_nComps; |
| 736 } else { |
| 737 output_nComps = codestream_nComps; |
| 738 } |
| 739 if (output_nComps == 3) { |
| 740 bSwapRGB = TRUE; |
| 741 } else if (output_nComps == 4) { |
| 742 m_pColorSpace = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK); |
| 743 bTranslateColor = FALSE; |
| 744 } |
| 745 m_nComponents = output_nComps; |
| 746 } |
| 747 FXDIB_Format format; |
| 748 if (output_nComps == 1) { |
| 749 format = FXDIB_8bppRgb; |
| 750 } else if (output_nComps <= 3) { |
| 751 format = FXDIB_Rgb; |
| 752 } else if (output_nComps == 4) { |
| 753 format = FXDIB_Rgb32; |
| 754 } else { |
| 755 width = (width * output_nComps + 2) / 3; |
| 756 format = FXDIB_Rgb; |
| 757 } |
| 758 m_pCachedBitmap.reset(new CFX_DIBitmap); |
| 759 if (!m_pCachedBitmap->Create(width, height, format)) { |
| 760 m_pCachedBitmap.reset(); |
| 761 return; |
| 762 } |
| 763 m_pCachedBitmap->Clear(0xFFFFFFFF); |
| 764 context->set_output_offsets(FX_Alloc(uint8_t, output_nComps)); |
| 765 for (int i = 0; i < output_nComps; ++i) |
| 766 context->output_offsets()[i] = i; |
| 767 if (bSwapRGB) { |
| 768 context->output_offsets()[0] = 2; |
| 769 context->output_offsets()[2] = 0; |
| 770 } |
| 771 if (!pJpxModule->Decode(context->context(), m_pCachedBitmap->GetBuffer(), |
| 772 m_pCachedBitmap->GetPitch(), bTranslateColor, |
| 773 context->output_offsets())) { |
| 774 m_pCachedBitmap.reset(); |
| 775 return; |
| 776 } |
| 777 if (m_pColorSpace && m_pColorSpace->GetFamily() == PDFCS_INDEXED && |
| 778 m_bpc < 8) { |
| 779 int scale = 8 - m_bpc; |
| 780 for (FX_DWORD row = 0; row < height; ++row) { |
| 781 uint8_t* scanline = (uint8_t*)m_pCachedBitmap->GetScanline(row); |
| 782 for (FX_DWORD col = 0; col < width; ++col) { |
| 783 *scanline = (*scanline) >> scale; |
| 784 ++scanline; |
| 785 } |
| 786 } |
| 787 } |
| 788 m_bpc = 8; |
| 789 } |
| 790 CPDF_DIBSource* CPDF_DIBSource::LoadMask(FX_DWORD& MatteColor) { |
| 791 MatteColor = 0xffffffff; |
| 792 CPDF_Stream* pSoftMask = m_pDict->GetStream(FX_BSTRC("SMask")); |
| 793 if (pSoftMask) { |
| 794 CPDF_Array* pMatte = pSoftMask->GetDict()->GetArray(FX_BSTRC("Matte")); |
| 795 if (pMatte != NULL && m_pColorSpace && |
| 796 (FX_DWORD)m_pColorSpace->CountComponents() <= m_nComponents) { |
| 797 FX_FLOAT* pColor = FX_Alloc(FX_FLOAT, m_nComponents); |
| 798 for (FX_DWORD i = 0; i < m_nComponents; i++) { |
| 799 pColor[i] = pMatte->GetFloat(i); |
| 800 } |
| 801 FX_FLOAT R, G, B; |
| 802 m_pColorSpace->GetRGB(pColor, R, G, B); |
| 803 FX_Free(pColor); |
| 804 MatteColor = FXARGB_MAKE(0, FXSYS_round(R * 255), FXSYS_round(G * 255), |
| 805 FXSYS_round(B * 255)); |
| 806 } |
| 807 return LoadMaskDIB(pSoftMask); |
| 808 } |
| 809 CPDF_Object* pMask = m_pDict->GetElementValue(FX_BSTRC("Mask")); |
| 810 if (pMask == NULL) { |
| 811 return NULL; |
| 812 } |
| 813 if (pMask->GetType() == PDFOBJ_STREAM) { |
| 814 return LoadMaskDIB((CPDF_Stream*)pMask); |
| 815 } |
| 816 return NULL; |
| 817 } |
| 818 int CPDF_DIBSource::StratLoadMask() { |
| 819 m_MatteColor = 0xffffffff; |
| 820 m_pMaskStream = m_pDict->GetStream(FX_BSTRC("SMask")); |
| 821 if (m_pMaskStream) { |
| 822 CPDF_Array* pMatte = m_pMaskStream->GetDict()->GetArray(FX_BSTRC("Matte")); |
| 823 if (pMatte != NULL && m_pColorSpace && |
| 824 (FX_DWORD)m_pColorSpace->CountComponents() <= m_nComponents) { |
| 825 FX_FLOAT R, G, B; |
| 826 FX_FLOAT* pColor = FX_Alloc(FX_FLOAT, m_nComponents); |
| 827 for (FX_DWORD i = 0; i < m_nComponents; i++) { |
| 828 pColor[i] = pMatte->GetFloat(i); |
| 829 } |
| 830 m_pColorSpace->GetRGB(pColor, R, G, B); |
| 831 FX_Free(pColor); |
| 832 m_MatteColor = FXARGB_MAKE(0, FXSYS_round(R * 255), FXSYS_round(G * 255), |
| 833 FXSYS_round(B * 255)); |
| 834 } |
| 835 return StartLoadMaskDIB(); |
| 836 } |
| 837 m_pMaskStream = m_pDict->GetElementValue(FX_BSTRC("Mask")); |
| 838 if (m_pMaskStream == NULL) { |
| 839 return 1; |
| 840 } |
| 841 if (m_pMaskStream->GetType() == PDFOBJ_STREAM) { |
| 842 return StartLoadMaskDIB(); |
| 843 } |
| 844 return 1; |
| 845 } |
| 846 int CPDF_DIBSource::ContinueLoadMaskDIB(IFX_Pause* pPause) { |
| 847 if (m_pMask == NULL) { |
| 848 return 1; |
| 849 } |
| 850 int ret = m_pMask->ContinueLoadDIBSource(pPause); |
| 851 if (ret == 2) { |
| 852 return ret; |
| 853 } |
| 854 if (m_pColorSpace && m_bStdCS) { |
| 855 m_pColorSpace->EnableStdConversion(FALSE); |
| 856 } |
| 857 if (!ret) { |
| 858 delete m_pMask; |
126 m_pMask = NULL; | 859 m_pMask = NULL; |
127 return pBitmap; | 860 return ret; |
128 } | 861 } |
129 FX_BOOL CPDF_Image::StartLoadDIBSource(CPDF_Dictionary* pFormResource, CPDF_Dict
ionary* pPageResource, FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_BOOL bLoadMask) | 862 return 1; |
130 { | 863 } |
131 m_pDIBSource = new CPDF_DIBSource; | 864 CPDF_DIBSource* CPDF_DIBSource::DetachMask() { |
132 int ret = ((CPDF_DIBSource*)m_pDIBSource)->StartLoadDIBSource(m_pDocument, m
_pStream, TRUE, pFormResource, pPageResource, bStdCS, GroupFamily, bLoadMask); | 865 CPDF_DIBSource* pDIBSource = m_pMask; |
133 if (ret == 2) { | 866 m_pMask = NULL; |
134 return TRUE; | 867 return pDIBSource; |
135 } | 868 } |
136 if (!ret) { | 869 CPDF_DIBSource* CPDF_DIBSource::LoadMaskDIB(CPDF_Stream* pMask) { |
137 delete m_pDIBSource; | 870 CPDF_DIBSource* pMaskSource = new CPDF_DIBSource; |
138 m_pDIBSource = NULL; | 871 if (!pMaskSource->Load(m_pDocument, pMask, NULL, NULL, NULL, NULL, TRUE)) { |
139 return FALSE; | 872 delete pMaskSource; |
140 } | 873 return NULL; |
141 m_pMask = ((CPDF_DIBSource*)m_pDIBSource)->DetachMask(); | 874 } |
142 m_MatteColor = ((CPDF_DIBSource*)m_pDIBSource)->m_MatteColor; | 875 return pMaskSource; |
143 return FALSE; | 876 } |
144 } | 877 int CPDF_DIBSource::StartLoadMaskDIB() { |
145 FX_BOOL CPDF_Image::Continue(IFX_Pause* pPause) | 878 m_pMask = new CPDF_DIBSource; |
146 { | 879 int ret = m_pMask->StartLoadDIBSource( |
147 int ret = ((CPDF_DIBSource*)m_pDIBSource)->ContinueLoadDIBSource(pPause); | 880 m_pDocument, (CPDF_Stream*)m_pMaskStream, FALSE, NULL, NULL, TRUE); |
148 if (ret == 2) { | 881 if (ret == 2) { |
149 return TRUE; | 882 if (m_Status == 0) { |
150 } | 883 m_Status = 2; |
151 if (!ret) { | 884 } |
152 delete m_pDIBSource; | 885 return 2; |
153 m_pDIBSource = NULL; | 886 } |
154 return FALSE; | 887 if (!ret) { |
155 } | 888 delete m_pMask; |
156 m_pMask = ((CPDF_DIBSource*)m_pDIBSource)->DetachMask(); | |
157 m_MatteColor = ((CPDF_DIBSource*)m_pDIBSource)->m_MatteColor; | |
158 return FALSE; | |
159 } | |
160 CPDF_DIBSource::CPDF_DIBSource() | |
161 { | |
162 m_pDocument = NULL; | |
163 m_pStreamAcc = NULL; | |
164 m_pDict = NULL; | |
165 m_bpp = 0; | |
166 m_Width = m_Height = 0; | |
167 m_pColorSpace = NULL; | |
168 m_bDefaultDecode = TRUE; | |
169 m_bImageMask = FALSE; | |
170 m_bDoBpcCheck = TRUE; | |
171 m_pPalette = NULL; | |
172 m_pCompData = NULL; | |
173 m_bColorKey = FALSE; | |
174 m_pMaskedLine = m_pLineBuf = NULL; | |
175 m_pDecoder = NULL; | |
176 m_nComponents = 0; | |
177 m_bpc = 0; | |
178 m_bLoadMask = FALSE; | |
179 m_Family = 0; | |
180 m_pMask = NULL; | 889 m_pMask = NULL; |
181 m_MatteColor = 0; | 890 return 1; |
182 m_pJbig2Context = NULL; | 891 } |
183 m_pGlobalStream = NULL; | 892 return 1; |
184 m_bStdCS = FALSE; | 893 } |
185 m_pMaskStream = NULL; | 894 void CPDF_DIBSource::LoadPalette() { |
186 m_Status = 0; | 895 if (m_bpc == 0) { |
187 m_bHasMask = FALSE; | 896 return; |
188 } | 897 } |
189 CPDF_DIBSource::~CPDF_DIBSource() | 898 if (m_bpc * m_nComponents > 8) { |
190 { | 899 return; |
191 delete m_pStreamAcc; | 900 } |
192 if (m_pMaskedLine) { | 901 if (m_pColorSpace == NULL) { |
193 FX_Free(m_pMaskedLine); | 902 return; |
194 } | 903 } |
195 if (m_pLineBuf) { | 904 if (m_bpc * m_nComponents == 1) { |
196 FX_Free(m_pLineBuf); | 905 if (m_bDefaultDecode && |
197 } | 906 (m_Family == PDFCS_DEVICEGRAY || m_Family == PDFCS_DEVICERGB)) { |
198 m_pCachedBitmap.reset(); | 907 return; |
199 delete m_pDecoder; | 908 } |
200 if (m_pCompData) { | 909 if (m_pColorSpace->CountComponents() > 3) { |
201 FX_Free(m_pCompData); | 910 return; |
202 } | 911 } |
203 CPDF_ColorSpace* pCS = m_pColorSpace; | 912 FX_FLOAT color_values[3]; |
204 if (pCS && m_pDocument) { | 913 color_values[0] = m_pCompData[0].m_DecodeMin; |
205 m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray()); | 914 color_values[1] = color_values[2] = color_values[0]; |
206 } | 915 FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f; |
207 if (m_pJbig2Context) { | 916 m_pColorSpace->GetRGB(color_values, R, G, B); |
208 ICodec_Jbig2Module* pJbig2Module = CPDF_ModuleMgr::Get()->GetJbig2Module
(); | 917 FX_ARGB argb0 = ArgbEncode(255, FXSYS_round(R * 255), FXSYS_round(G * 255), |
209 pJbig2Module->DestroyJbig2Context(m_pJbig2Context); | 918 FXSYS_round(B * 255)); |
210 } | 919 color_values[0] += m_pCompData[0].m_DecodeStep; |
211 delete m_pGlobalStream; | 920 color_values[1] += m_pCompData[0].m_DecodeStep; |
212 } | 921 color_values[2] += m_pCompData[0].m_DecodeStep; |
213 CFX_DIBitmap* CPDF_DIBSource::GetBitmap() const | 922 m_pColorSpace->GetRGB(color_values, R, G, B); |
214 { | 923 FX_ARGB argb1 = ArgbEncode(255, FXSYS_round(R * 255), FXSYS_round(G * 255), |
215 return m_pCachedBitmap ? m_pCachedBitmap.get() : Clone(); | 924 FXSYS_round(B * 255)); |
216 } | 925 if (argb0 != 0xFF000000 || argb1 != 0xFFFFFFFF) { |
217 void CPDF_DIBSource::ReleaseBitmap(CFX_DIBitmap* pBitmap) const | 926 SetPaletteArgb(0, argb0); |
218 { | 927 SetPaletteArgb(1, argb1); |
219 if (pBitmap && pBitmap != m_pCachedBitmap) { | 928 } |
220 delete pBitmap; | 929 return; |
221 } | 930 } |
222 } | 931 if (m_pColorSpace == CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY) && |
223 FX_BOOL CPDF_DIBSource::Load(CPDF_Document* pDoc, const CPDF_Stream* pStream, CP
DF_DIBSource** ppMask, | 932 m_bpc == 8 && m_bDefaultDecode) { |
224 FX_DWORD* pMatteColor, CPDF_Dictionary* pFormResour
ces, CPDF_Dictionary* pPageResources, FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_B
OOL bLoadMask) | 933 } else { |
225 { | 934 int palette_count = 1 << (m_bpc * m_nComponents); |
226 if (pStream == NULL) { | 935 CFX_FixedBufGrow<FX_FLOAT, 16> color_values(m_nComponents); |
227 return FALSE; | 936 FX_FLOAT* color_value = color_values; |
228 } | 937 for (int i = 0; i < palette_count; i++) { |
229 m_pDocument = pDoc; | 938 int color_data = i; |
230 m_pDict = pStream->GetDict(); | 939 for (FX_DWORD j = 0; j < m_nComponents; j++) { |
231 if (m_pDict == NULL) { | 940 int encoded_component = color_data % (1 << m_bpc); |
232 return FALSE; | 941 color_data /= 1 << m_bpc; |
233 } | 942 color_value[j] = m_pCompData[j].m_DecodeMin + |
234 m_pStream = pStream; | 943 m_pCompData[j].m_DecodeStep * encoded_component; |
235 m_Width = m_pDict->GetInteger(FX_BSTRC("Width")); | 944 } |
236 m_Height = m_pDict->GetInteger(FX_BSTRC("Height")); | 945 FX_FLOAT R = 0, G = 0, B = 0; |
237 if (m_Width <= 0 || m_Height <= 0 || m_Width > 0x01ffff || m_Height > 0x01ff
ff) { | 946 if (m_nComponents == 1 && m_Family == PDFCS_ICCBASED && |
238 return FALSE; | 947 m_pColorSpace->CountComponents() > 1) { |
239 } | 948 int nComponents = m_pColorSpace->CountComponents(); |
240 m_GroupFamily = GroupFamily; | 949 FX_FLOAT* temp_buf = FX_Alloc(FX_FLOAT, nComponents); |
241 m_bLoadMask = bLoadMask; | 950 for (int i = 0; i < nComponents; i++) { |
242 if (!LoadColorInfo(m_pStream->GetObjNum() != 0 ? NULL : pFormResources, pPag
eResources)) { | 951 temp_buf[i] = *color_value; |
243 return FALSE; | 952 } |
244 } | 953 m_pColorSpace->GetRGB(temp_buf, R, G, B); |
245 if (m_bDoBpcCheck && (m_bpc == 0 || m_nComponents == 0)) { | 954 FX_Free(temp_buf); |
246 return FALSE; | 955 } else { |
247 } | 956 m_pColorSpace->GetRGB(color_value, R, G, B); |
248 FX_SAFE_DWORD src_pitch = | 957 } |
249 CalculatePitch8(m_bpc, m_nComponents, m_Width, m_Height); | 958 SetPaletteArgb(i, ArgbEncode(255, FXSYS_round(R * 255), |
250 if (!src_pitch.IsValid()) { | 959 FXSYS_round(G * 255), FXSYS_round(B * 255))); |
251 return FALSE; | 960 } |
252 } | 961 } |
253 m_pStreamAcc = new CPDF_StreamAcc; | 962 } |
254 m_pStreamAcc->LoadAllData(pStream, FALSE, src_pitch.ValueOrDie(), TRUE); | 963 void CPDF_DIBSource::ValidateDictParam() { |
255 if (m_pStreamAcc->GetSize() == 0 || m_pStreamAcc->GetData() == NULL) { | 964 m_bpc = m_bpc_orig; |
256 return FALSE; | 965 CPDF_Object* pFilter = m_pDict->GetElementValue(FX_BSTRC("Filter")); |
257 } | 966 if (pFilter) { |
258 if (!CreateDecoder()) { | 967 if (pFilter->GetType() == PDFOBJ_NAME) { |
259 return FALSE; | 968 CFX_ByteString filter = pFilter->GetString(); |
260 } | 969 if (filter == FX_BSTRC("CCITTFaxDecode") || |
261 if (m_bImageMask) { | 970 filter == FX_BSTRC("JBIG2Decode")) { |
262 m_bpp = 1; | |
263 m_bpc = 1; | 971 m_bpc = 1; |
264 m_nComponents = 1; | 972 m_nComponents = 1; |
265 m_AlphaFlag = 1; | 973 } |
266 } else if (m_bpc * m_nComponents == 1) { | 974 if (filter == FX_BSTRC("RunLengthDecode") || |
267 m_bpp = 1; | 975 filter == FX_BSTRC("DCTDecode")) { |
268 } else if (m_bpc * m_nComponents <= 8) { | 976 m_bpc = 8; |
269 m_bpp = 8; | 977 } |
270 } else { | 978 } else if (pFilter->GetType() == PDFOBJ_ARRAY) { |
271 m_bpp = 24; | 979 CPDF_Array* pArray = (CPDF_Array*)pFilter; |
272 } | 980 if (pArray->GetString(pArray->GetCount() - 1) == |
273 FX_SAFE_DWORD pitch = CalculatePitch32(m_bpp, m_Width); | 981 FX_BSTRC("CCITTFaxDecode") || |
274 if (!pitch.IsValid()) { | 982 pArray->GetString(pArray->GetCount() - 1) == |
275 return FALSE; | 983 FX_BSTRC("JBIG2Decode")) { |
276 } | |
277 m_pLineBuf = FX_Alloc(uint8_t, pitch.ValueOrDie()); | |
278 if (m_pColorSpace && bStdCS) { | |
279 m_pColorSpace->EnableStdConversion(TRUE); | |
280 } | |
281 LoadPalette(); | |
282 if (m_bColorKey) { | |
283 m_bpp = 32; | |
284 m_AlphaFlag = 2; | |
285 pitch = CalculatePitch32(m_bpp, m_Width); | |
286 if (!pitch.IsValid()) { | |
287 return FALSE; | |
288 } | |
289 m_pMaskedLine = FX_Alloc(uint8_t, pitch.ValueOrDie()); | |
290 } | |
291 m_Pitch = pitch.ValueOrDie(); | |
292 if (ppMask) { | |
293 *ppMask = LoadMask(*pMatteColor); | |
294 } | |
295 if (m_pColorSpace && bStdCS) { | |
296 m_pColorSpace->EnableStdConversion(FALSE); | |
297 } | |
298 return TRUE; | |
299 } | |
300 int» CPDF_DIBSource::ContinueToLoadMask() | |
301 { | |
302 if (m_bImageMask) { | |
303 m_bpp = 1; | |
304 m_bpc = 1; | 984 m_bpc = 1; |
305 m_nComponents = 1; | 985 m_nComponents = 1; |
306 m_AlphaFlag = 1; | 986 } |
307 } else if (m_bpc * m_nComponents == 1) { | 987 if (pArray->GetString(pArray->GetCount() - 1) == FX_BSTRC("DCTDecode")) { |
308 m_bpp = 1; | 988 // Previously, pArray->GetString(pArray->GetCount() - 1) == |
309 } else if (m_bpc * m_nComponents <= 8) { | 989 // FX_BSTRC("RunLengthDecode") was checked in the "if" statement as |
310 m_bpp = 8; | 990 // well, |
| 991 // but too many documents don't conform to it. |
| 992 m_bpc = 8; |
| 993 } |
| 994 } |
| 995 } |
| 996 if (m_bpc != 1 && m_bpc != 2 && m_bpc != 4 && m_bpc != 8 && m_bpc != 16) { |
| 997 m_bpc = 0; |
| 998 } |
| 999 } |
| 1000 #define NORMALCOLOR_MAX(color, max) \ |
| 1001 (color) > (max) ? (max) : (color) < 0 ? 0 : (color); |
| 1002 void CPDF_DIBSource::TranslateScanline24bpp(uint8_t* dest_scan, |
| 1003 const uint8_t* src_scan) const { |
| 1004 if (m_bpc == 0) { |
| 1005 return; |
| 1006 } |
| 1007 int max_data = (1 << m_bpc) - 1; |
| 1008 if (m_bDefaultDecode) { |
| 1009 if (m_Family == PDFCS_DEVICERGB || m_Family == PDFCS_CALRGB) { |
| 1010 const uint8_t* src_pos = src_scan; |
| 1011 switch (m_bpc) { |
| 1012 case 16: |
| 1013 for (int col = 0; col < m_Width; col++) { |
| 1014 *dest_scan++ = src_pos[4]; |
| 1015 *dest_scan++ = src_pos[2]; |
| 1016 *dest_scan++ = *src_pos; |
| 1017 src_pos += 6; |
| 1018 } |
| 1019 break; |
| 1020 case 8: |
| 1021 for (int column = 0; column < m_Width; column++) { |
| 1022 *dest_scan++ = src_pos[2]; |
| 1023 *dest_scan++ = src_pos[1]; |
| 1024 *dest_scan++ = *src_pos; |
| 1025 src_pos += 3; |
| 1026 } |
| 1027 break; |
| 1028 default: |
| 1029 int src_bit_pos = 0; |
| 1030 int dest_byte_pos = 0; |
| 1031 for (int column = 0; column < m_Width; column++) { |
| 1032 int R = _GetBits8(src_scan, src_bit_pos, m_bpc); |
| 1033 src_bit_pos += m_bpc; |
| 1034 int G = _GetBits8(src_scan, src_bit_pos, m_bpc); |
| 1035 src_bit_pos += m_bpc; |
| 1036 int B = _GetBits8(src_scan, src_bit_pos, m_bpc); |
| 1037 src_bit_pos += m_bpc; |
| 1038 R = NORMALCOLOR_MAX(R, max_data); |
| 1039 G = NORMALCOLOR_MAX(G, max_data); |
| 1040 B = NORMALCOLOR_MAX(B, max_data); |
| 1041 dest_scan[dest_byte_pos] = B * 255 / max_data; |
| 1042 dest_scan[dest_byte_pos + 1] = G * 255 / max_data; |
| 1043 dest_scan[dest_byte_pos + 2] = R * 255 / max_data; |
| 1044 dest_byte_pos += 3; |
| 1045 } |
| 1046 break; |
| 1047 } |
| 1048 return; |
| 1049 } |
| 1050 if (m_bpc == 8) { |
| 1051 if (m_nComponents == m_pColorSpace->CountComponents()) |
| 1052 m_pColorSpace->TranslateImageLine( |
| 1053 dest_scan, src_scan, m_Width, m_Width, m_Height, |
| 1054 m_bLoadMask && m_GroupFamily == PDFCS_DEVICECMYK && |
| 1055 m_Family == PDFCS_DEVICECMYK); |
| 1056 return; |
| 1057 } |
| 1058 } |
| 1059 CFX_FixedBufGrow<FX_FLOAT, 16> color_values1(m_nComponents); |
| 1060 FX_FLOAT* color_values = color_values1; |
| 1061 FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f; |
| 1062 if (m_bpc == 8) { |
| 1063 int src_byte_pos = 0; |
| 1064 int dest_byte_pos = 0; |
| 1065 for (int column = 0; column < m_Width; column++) { |
| 1066 for (FX_DWORD color = 0; color < m_nComponents; color++) { |
| 1067 int data = src_scan[src_byte_pos++]; |
| 1068 color_values[color] = m_pCompData[color].m_DecodeMin + |
| 1069 m_pCompData[color].m_DecodeStep * data; |
| 1070 } |
| 1071 if (m_bLoadMask && m_GroupFamily == PDFCS_DEVICECMYK && |
| 1072 m_Family == PDFCS_DEVICECMYK) { |
| 1073 FX_FLOAT k = 1.0f - color_values[3]; |
| 1074 R = (1.0f - color_values[0]) * k; |
| 1075 G = (1.0f - color_values[1]) * k; |
| 1076 B = (1.0f - color_values[2]) * k; |
| 1077 } else { |
| 1078 m_pColorSpace->GetRGB(color_values, R, G, B); |
| 1079 } |
| 1080 R = NORMALCOLOR_MAX(R, 1); |
| 1081 G = NORMALCOLOR_MAX(G, 1); |
| 1082 B = NORMALCOLOR_MAX(B, 1); |
| 1083 dest_scan[dest_byte_pos] = (int32_t)(B * 255); |
| 1084 dest_scan[dest_byte_pos + 1] = (int32_t)(G * 255); |
| 1085 dest_scan[dest_byte_pos + 2] = (int32_t)(R * 255); |
| 1086 dest_byte_pos += 3; |
| 1087 } |
| 1088 } else { |
| 1089 int src_bit_pos = 0; |
| 1090 int dest_byte_pos = 0; |
| 1091 for (int column = 0; column < m_Width; column++) { |
| 1092 for (FX_DWORD color = 0; color < m_nComponents; color++) { |
| 1093 int data = _GetBits8(src_scan, src_bit_pos, m_bpc); |
| 1094 color_values[color] = m_pCompData[color].m_DecodeMin + |
| 1095 m_pCompData[color].m_DecodeStep * data; |
| 1096 src_bit_pos += m_bpc; |
| 1097 } |
| 1098 if (m_bLoadMask && m_GroupFamily == PDFCS_DEVICECMYK && |
| 1099 m_Family == PDFCS_DEVICECMYK) { |
| 1100 FX_FLOAT k = 1.0f - color_values[3]; |
| 1101 R = (1.0f - color_values[0]) * k; |
| 1102 G = (1.0f - color_values[1]) * k; |
| 1103 B = (1.0f - color_values[2]) * k; |
| 1104 } else { |
| 1105 m_pColorSpace->GetRGB(color_values, R, G, B); |
| 1106 } |
| 1107 R = NORMALCOLOR_MAX(R, 1); |
| 1108 G = NORMALCOLOR_MAX(G, 1); |
| 1109 B = NORMALCOLOR_MAX(B, 1); |
| 1110 dest_scan[dest_byte_pos] = (int32_t)(B * 255); |
| 1111 dest_scan[dest_byte_pos + 1] = (int32_t)(G * 255); |
| 1112 dest_scan[dest_byte_pos + 2] = (int32_t)(R * 255); |
| 1113 dest_byte_pos += 3; |
| 1114 } |
| 1115 } |
| 1116 } |
| 1117 uint8_t* CPDF_DIBSource::GetBuffer() const { |
| 1118 if (m_pCachedBitmap) { |
| 1119 return m_pCachedBitmap->GetBuffer(); |
| 1120 } |
| 1121 return NULL; |
| 1122 } |
| 1123 const uint8_t* CPDF_DIBSource::GetScanline(int line) const { |
| 1124 if (m_bpc == 0) { |
| 1125 return NULL; |
| 1126 } |
| 1127 FX_SAFE_DWORD src_pitch = CalculatePitch8(m_bpc, m_nComponents, m_Width, 1); |
| 1128 if (!src_pitch.IsValid()) |
| 1129 return NULL; |
| 1130 FX_DWORD src_pitch_value = src_pitch.ValueOrDie(); |
| 1131 const uint8_t* pSrcLine = NULL; |
| 1132 if (m_pCachedBitmap) { |
| 1133 if (line >= m_pCachedBitmap->GetHeight()) { |
| 1134 line = m_pCachedBitmap->GetHeight() - 1; |
| 1135 } |
| 1136 pSrcLine = m_pCachedBitmap->GetScanline(line); |
| 1137 } else if (m_pDecoder) { |
| 1138 pSrcLine = m_pDecoder->GetScanline(line); |
| 1139 } else { |
| 1140 if (m_pStreamAcc->GetSize() >= (line + 1) * src_pitch_value) { |
| 1141 pSrcLine = m_pStreamAcc->GetData() + line * src_pitch_value; |
| 1142 } |
| 1143 } |
| 1144 if (pSrcLine == NULL) { |
| 1145 uint8_t* pLineBuf = m_pMaskedLine ? m_pMaskedLine : m_pLineBuf; |
| 1146 FXSYS_memset(pLineBuf, 0xff, m_Pitch); |
| 1147 return pLineBuf; |
| 1148 } |
| 1149 if (m_bpc * m_nComponents == 1) { |
| 1150 if (m_bImageMask && m_bDefaultDecode) { |
| 1151 for (FX_DWORD i = 0; i < src_pitch_value; i++) { |
| 1152 m_pLineBuf[i] = ~pSrcLine[i]; |
| 1153 } |
| 1154 } else if (m_bColorKey) { |
| 1155 FX_DWORD reset_argb, set_argb; |
| 1156 reset_argb = m_pPalette ? m_pPalette[0] : 0xff000000; |
| 1157 set_argb = m_pPalette ? m_pPalette[1] : 0xffffffff; |
| 1158 if (m_pCompData[0].m_ColorKeyMin == 0) { |
| 1159 reset_argb = 0; |
| 1160 } |
| 1161 if (m_pCompData[0].m_ColorKeyMax == 1) { |
| 1162 set_argb = 0; |
| 1163 } |
| 1164 set_argb = FXARGB_TODIB(set_argb); |
| 1165 reset_argb = FXARGB_TODIB(reset_argb); |
| 1166 FX_DWORD* dest_scan = (FX_DWORD*)m_pMaskedLine; |
| 1167 for (int col = 0; col < m_Width; col++) { |
| 1168 if (pSrcLine[col / 8] & (1 << (7 - col % 8))) { |
| 1169 *dest_scan = set_argb; |
| 1170 } else { |
| 1171 *dest_scan = reset_argb; |
| 1172 } |
| 1173 dest_scan++; |
| 1174 } |
| 1175 return m_pMaskedLine; |
311 } else { | 1176 } else { |
312 m_bpp = 24; | 1177 FXSYS_memcpy(m_pLineBuf, pSrcLine, src_pitch_value); |
313 } | 1178 } |
314 if (!m_bpc || !m_nComponents) { | 1179 return m_pLineBuf; |
315 return 0; | 1180 } |
316 } | 1181 if (m_bpc * m_nComponents <= 8) { |
317 FX_SAFE_DWORD pitch = CalculatePitch32(m_bpp, m_Width); | 1182 if (m_bpc == 8) { |
| 1183 FXSYS_memcpy(m_pLineBuf, pSrcLine, src_pitch_value); |
| 1184 } else { |
| 1185 int src_bit_pos = 0; |
| 1186 for (int col = 0; col < m_Width; col++) { |
| 1187 int color_index = 0; |
| 1188 for (FX_DWORD color = 0; color < m_nComponents; color++) { |
| 1189 int data = _GetBits8(pSrcLine, src_bit_pos, m_bpc); |
| 1190 color_index |= data << (color * m_bpc); |
| 1191 src_bit_pos += m_bpc; |
| 1192 } |
| 1193 m_pLineBuf[col] = color_index; |
| 1194 } |
| 1195 } |
| 1196 if (m_bColorKey) { |
| 1197 uint8_t* pDestPixel = m_pMaskedLine; |
| 1198 const uint8_t* pSrcPixel = m_pLineBuf; |
| 1199 for (int col = 0; col < m_Width; col++) { |
| 1200 uint8_t index = *pSrcPixel++; |
| 1201 if (m_pPalette) { |
| 1202 *pDestPixel++ = FXARGB_B(m_pPalette[index]); |
| 1203 *pDestPixel++ = FXARGB_G(m_pPalette[index]); |
| 1204 *pDestPixel++ = FXARGB_R(m_pPalette[index]); |
| 1205 } else { |
| 1206 *pDestPixel++ = index; |
| 1207 *pDestPixel++ = index; |
| 1208 *pDestPixel++ = index; |
| 1209 } |
| 1210 *pDestPixel = (index < m_pCompData[0].m_ColorKeyMin || |
| 1211 index > m_pCompData[0].m_ColorKeyMax) |
| 1212 ? 0xff |
| 1213 : 0; |
| 1214 pDestPixel++; |
| 1215 } |
| 1216 return m_pMaskedLine; |
| 1217 } |
| 1218 return m_pLineBuf; |
| 1219 } |
| 1220 if (m_bColorKey) { |
| 1221 if (m_nComponents == 3 && m_bpc == 8) { |
| 1222 uint8_t* alpha_channel = m_pMaskedLine + 3; |
| 1223 for (int col = 0; col < m_Width; col++) { |
| 1224 const uint8_t* pPixel = pSrcLine + col * 3; |
| 1225 alpha_channel[col * 4] = (pPixel[0] < m_pCompData[0].m_ColorKeyMin || |
| 1226 pPixel[0] > m_pCompData[0].m_ColorKeyMax || |
| 1227 pPixel[1] < m_pCompData[1].m_ColorKeyMin || |
| 1228 pPixel[1] > m_pCompData[1].m_ColorKeyMax || |
| 1229 pPixel[2] < m_pCompData[2].m_ColorKeyMin || |
| 1230 pPixel[2] > m_pCompData[2].m_ColorKeyMax) |
| 1231 ? 0xff |
| 1232 : 0; |
| 1233 } |
| 1234 } else { |
| 1235 FXSYS_memset(m_pMaskedLine, 0xff, m_Pitch); |
| 1236 } |
| 1237 } |
| 1238 if (m_pColorSpace) { |
| 1239 TranslateScanline24bpp(m_pLineBuf, pSrcLine); |
| 1240 pSrcLine = m_pLineBuf; |
| 1241 } |
| 1242 if (m_bColorKey) { |
| 1243 const uint8_t* pSrcPixel = pSrcLine; |
| 1244 uint8_t* pDestPixel = m_pMaskedLine; |
| 1245 for (int col = 0; col < m_Width; col++) { |
| 1246 *pDestPixel++ = *pSrcPixel++; |
| 1247 *pDestPixel++ = *pSrcPixel++; |
| 1248 *pDestPixel++ = *pSrcPixel++; |
| 1249 pDestPixel++; |
| 1250 } |
| 1251 return m_pMaskedLine; |
| 1252 } |
| 1253 return pSrcLine; |
| 1254 } |
| 1255 FX_BOOL CPDF_DIBSource::SkipToScanline(int line, IFX_Pause* pPause) const { |
| 1256 if (m_pDecoder) { |
| 1257 return m_pDecoder->SkipToScanline(line, pPause); |
| 1258 } |
| 1259 return FALSE; |
| 1260 } |
| 1261 void CPDF_DIBSource::DownSampleScanline(int line, |
| 1262 uint8_t* dest_scan, |
| 1263 int dest_bpp, |
| 1264 int dest_width, |
| 1265 FX_BOOL bFlipX, |
| 1266 int clip_left, |
| 1267 int clip_width) const { |
| 1268 if (line < 0 || dest_scan == NULL || dest_bpp <= 0 || dest_width <= 0 || |
| 1269 clip_left < 0 || clip_width <= 0) { |
| 1270 return; |
| 1271 } |
| 1272 |
| 1273 FX_DWORD src_width = m_Width; |
| 1274 FX_SAFE_DWORD pitch = CalculatePitch8(m_bpc, m_nComponents, m_Width, 1); |
| 1275 if (!pitch.IsValid()) { |
| 1276 return; |
| 1277 } |
| 1278 |
| 1279 const uint8_t* pSrcLine = NULL; |
| 1280 if (m_pCachedBitmap) { |
| 1281 pSrcLine = m_pCachedBitmap->GetScanline(line); |
| 1282 } else if (m_pDecoder) { |
| 1283 pSrcLine = m_pDecoder->GetScanline(line); |
| 1284 } else { |
| 1285 FX_DWORD src_pitch = pitch.ValueOrDie(); |
| 1286 pitch *= (line + 1); |
318 if (!pitch.IsValid()) { | 1287 if (!pitch.IsValid()) { |
319 return 0; | 1288 return; |
320 } | 1289 } |
321 m_pLineBuf = FX_Alloc(uint8_t, pitch.ValueOrDie()); | 1290 |
322 if (m_pColorSpace && m_bStdCS) { | 1291 if (m_pStreamAcc->GetSize() >= pitch.ValueOrDie()) { |
323 m_pColorSpace->EnableStdConversion(TRUE); | 1292 pSrcLine = m_pStreamAcc->GetData() + line * src_pitch; |
324 } | 1293 } |
325 LoadPalette(); | 1294 } |
| 1295 int orig_Bpp = m_bpc * m_nComponents / 8; |
| 1296 int dest_Bpp = dest_bpp / 8; |
| 1297 if (pSrcLine == NULL) { |
| 1298 FXSYS_memset(dest_scan, 0xff, dest_Bpp * clip_width); |
| 1299 return; |
| 1300 } |
| 1301 |
| 1302 FX_SAFE_INT32 max_src_x = clip_left; |
| 1303 max_src_x += clip_width - 1; |
| 1304 max_src_x *= src_width; |
| 1305 max_src_x /= dest_width; |
| 1306 if (!max_src_x.IsValid()) { |
| 1307 return; |
| 1308 } |
| 1309 |
| 1310 CFX_FixedBufGrow<uint8_t, 128> temp(orig_Bpp); |
| 1311 if (m_bpc * m_nComponents == 1) { |
| 1312 FX_DWORD set_argb = (FX_DWORD)-1, reset_argb = 0; |
| 1313 if (m_bImageMask) { |
| 1314 if (m_bDefaultDecode) { |
| 1315 set_argb = 0; |
| 1316 reset_argb = (FX_DWORD)-1; |
| 1317 } |
| 1318 } else if (m_bColorKey) { |
| 1319 reset_argb = m_pPalette ? m_pPalette[0] : 0xff000000; |
| 1320 set_argb = m_pPalette ? m_pPalette[1] : 0xffffffff; |
| 1321 if (m_pCompData[0].m_ColorKeyMin == 0) { |
| 1322 reset_argb = 0; |
| 1323 } |
| 1324 if (m_pCompData[0].m_ColorKeyMax == 1) { |
| 1325 set_argb = 0; |
| 1326 } |
| 1327 set_argb = FXARGB_TODIB(set_argb); |
| 1328 reset_argb = FXARGB_TODIB(reset_argb); |
| 1329 for (int i = 0; i < clip_width; i++) { |
| 1330 FX_DWORD src_x = (clip_left + i) * src_width / dest_width; |
| 1331 if (bFlipX) { |
| 1332 src_x = src_width - src_x - 1; |
| 1333 } |
| 1334 src_x %= src_width; |
| 1335 if (pSrcLine[src_x / 8] & (1 << (7 - src_x % 8))) { |
| 1336 ((FX_DWORD*)dest_scan)[i] = set_argb; |
| 1337 } else { |
| 1338 ((FX_DWORD*)dest_scan)[i] = reset_argb; |
| 1339 } |
| 1340 } |
| 1341 return; |
| 1342 } else { |
| 1343 if (dest_Bpp == 1) { |
| 1344 } else if (m_pPalette) { |
| 1345 reset_argb = m_pPalette[0]; |
| 1346 set_argb = m_pPalette[1]; |
| 1347 } |
| 1348 } |
| 1349 for (int i = 0; i < clip_width; i++) { |
| 1350 FX_DWORD src_x = (clip_left + i) * src_width / dest_width; |
| 1351 if (bFlipX) { |
| 1352 src_x = src_width - src_x - 1; |
| 1353 } |
| 1354 src_x %= src_width; |
| 1355 int dest_pos = i * dest_Bpp; |
| 1356 if (pSrcLine[src_x / 8] & (1 << (7 - src_x % 8))) { |
| 1357 if (dest_Bpp == 1) { |
| 1358 dest_scan[dest_pos] = (uint8_t)set_argb; |
| 1359 } else if (dest_Bpp == 3) { |
| 1360 dest_scan[dest_pos] = FXARGB_B(set_argb); |
| 1361 dest_scan[dest_pos + 1] = FXARGB_G(set_argb); |
| 1362 dest_scan[dest_pos + 2] = FXARGB_R(set_argb); |
| 1363 } else { |
| 1364 *(FX_DWORD*)(dest_scan + dest_pos) = set_argb; |
| 1365 } |
| 1366 } else { |
| 1367 if (dest_Bpp == 1) { |
| 1368 dest_scan[dest_pos] = (uint8_t)reset_argb; |
| 1369 } else if (dest_Bpp == 3) { |
| 1370 dest_scan[dest_pos] = FXARGB_B(reset_argb); |
| 1371 dest_scan[dest_pos + 1] = FXARGB_G(reset_argb); |
| 1372 dest_scan[dest_pos + 2] = FXARGB_R(reset_argb); |
| 1373 } else { |
| 1374 *(FX_DWORD*)(dest_scan + dest_pos) = reset_argb; |
| 1375 } |
| 1376 } |
| 1377 } |
| 1378 return; |
| 1379 } else if (m_bpc * m_nComponents <= 8) { |
| 1380 if (m_bpc < 8) { |
| 1381 int src_bit_pos = 0; |
| 1382 for (FX_DWORD col = 0; col < src_width; col++) { |
| 1383 int color_index = 0; |
| 1384 for (FX_DWORD color = 0; color < m_nComponents; color++) { |
| 1385 int data = _GetBits8(pSrcLine, src_bit_pos, m_bpc); |
| 1386 color_index |= data << (color * m_bpc); |
| 1387 src_bit_pos += m_bpc; |
| 1388 } |
| 1389 m_pLineBuf[col] = color_index; |
| 1390 } |
| 1391 pSrcLine = m_pLineBuf; |
| 1392 } |
326 if (m_bColorKey) { | 1393 if (m_bColorKey) { |
327 m_bpp = 32; | 1394 for (int i = 0; i < clip_width; i++) { |
328 m_AlphaFlag = 2; | 1395 FX_DWORD src_x = (clip_left + i) * src_width / dest_width; |
329 pitch = CalculatePitch32(m_bpp, m_Width); | 1396 if (bFlipX) { |
330 if (!pitch.IsValid()) { | 1397 src_x = src_width - src_x - 1; |
331 return 0; | |
332 } | 1398 } |
333 m_pMaskedLine = FX_Alloc(uint8_t, pitch.ValueOrDie()); | 1399 src_x %= src_width; |
334 } | 1400 uint8_t* pDestPixel = dest_scan + i * 4; |
335 m_Pitch = pitch.ValueOrDie(); | 1401 uint8_t index = pSrcLine[src_x]; |
336 return 1; | 1402 if (m_pPalette) { |
337 } | 1403 *pDestPixel++ = FXARGB_B(m_pPalette[index]); |
338 int» CPDF_DIBSource::StartLoadDIBSource(CPDF_Document* pDoc, const CPDF_Strea
m* pStream, FX_BOOL bHasMask, | 1404 *pDestPixel++ = FXARGB_G(m_pPalette[index]); |
339 CPDF_Dictionary* pFormResources, CPDF_Dic
tionary* pPageResources, | 1405 *pDestPixel++ = FXARGB_R(m_pPalette[index]); |
340 FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_
BOOL bLoadMask) | 1406 } else { |
341 { | 1407 *pDestPixel++ = index; |
342 if (pStream == NULL) { | 1408 *pDestPixel++ = index; |
343 return 0; | 1409 *pDestPixel++ = index; |
344 } | |
345 m_pDocument = pDoc; | |
346 m_pDict = pStream->GetDict(); | |
347 m_pStream = pStream; | |
348 m_bStdCS = bStdCS; | |
349 m_bHasMask = bHasMask; | |
350 m_Width = m_pDict->GetInteger(FX_BSTRC("Width")); | |
351 m_Height = m_pDict->GetInteger(FX_BSTRC("Height")); | |
352 if (m_Width <= 0 || m_Height <= 0 || m_Width > 0x01ffff || m_Height > 0x01ff
ff) { | |
353 return 0; | |
354 } | |
355 m_GroupFamily = GroupFamily; | |
356 m_bLoadMask = bLoadMask; | |
357 if (!LoadColorInfo(m_pStream->GetObjNum() != 0 ? NULL : pFormResources, pPag
eResources)) { | |
358 return 0; | |
359 } | |
360 if (m_bDoBpcCheck && (m_bpc == 0 || m_nComponents == 0)) { | |
361 return 0; | |
362 } | |
363 FX_SAFE_DWORD src_pitch = | |
364 CalculatePitch8(m_bpc, m_nComponents, m_Width, m_Height); | |
365 if (!src_pitch.IsValid()) { | |
366 return 0; | |
367 } | |
368 m_pStreamAcc = new CPDF_StreamAcc; | |
369 m_pStreamAcc->LoadAllData(pStream, FALSE, src_pitch.ValueOrDie(), TRUE); | |
370 if (m_pStreamAcc->GetSize() == 0 || m_pStreamAcc->GetData() == NULL) { | |
371 return 0; | |
372 } | |
373 int ret = CreateDecoder(); | |
374 if (ret != 1) { | |
375 if (!ret) { | |
376 return ret; | |
377 } | 1410 } |
378 if (!ContinueToLoadMask()) { | 1411 *pDestPixel = (index < m_pCompData[0].m_ColorKeyMin || |
379 return 0; | 1412 index > m_pCompData[0].m_ColorKeyMax) |
380 } | 1413 ? 0xff |
381 if (m_bHasMask) { | 1414 : 0; |
382 StratLoadMask(); | 1415 } |
383 } | 1416 return; |
384 return ret; | 1417 } |
385 } | 1418 for (int i = 0; i < clip_width; i++) { |
386 if (!ContinueToLoadMask()) { | 1419 FX_DWORD src_x = (clip_left + i) * src_width / dest_width; |
387 return 0; | 1420 if (bFlipX) { |
388 } | 1421 src_x = src_width - src_x - 1; |
389 if (m_bHasMask) { | 1422 } |
390 ret = StratLoadMask(); | 1423 src_x %= src_width; |
391 } | 1424 uint8_t index = pSrcLine[src_x]; |
392 if (ret == 2) { | 1425 if (dest_Bpp == 1) { |
393 return ret; | 1426 dest_scan[i] = index; |
394 } | 1427 } else { |
395 if (m_pColorSpace && m_bStdCS) { | 1428 int dest_pos = i * dest_Bpp; |
396 m_pColorSpace->EnableStdConversion(FALSE); | 1429 FX_ARGB argb = m_pPalette[index]; |
397 } | 1430 dest_scan[dest_pos] = FXARGB_B(argb); |
398 return ret; | 1431 dest_scan[dest_pos + 1] = FXARGB_G(argb); |
399 } | 1432 dest_scan[dest_pos + 2] = FXARGB_R(argb); |
400 int» CPDF_DIBSource::ContinueLoadDIBSource(IFX_Pause* pPause) | 1433 } |
401 { | 1434 } |
402 FXCODEC_STATUS ret; | 1435 return; |
403 if (m_Status == 1) { | 1436 } else { |
404 const CFX_ByteString& decoder = m_pStreamAcc->GetImageDecoder(); | 1437 int last_src_x = -1; |
405 if (decoder == FX_BSTRC("JPXDecode")) { | 1438 FX_ARGB last_argb; |
406 return 0; | 1439 FX_FLOAT orig_Not8Bpp = (FX_FLOAT)m_bpc * (FX_FLOAT)m_nComponents / 8.0f; |
407 } | 1440 FX_FLOAT unit_To8Bpc = 255.0f / ((1 << m_bpc) - 1); |
408 ICodec_Jbig2Module* pJbig2Module = CPDF_ModuleMgr::Get()->GetJbig2Module
(); | 1441 for (int i = 0; i < clip_width; i++) { |
409 if (m_pJbig2Context == NULL) { | 1442 int dest_x = clip_left + i; |
410 m_pJbig2Context = pJbig2Module->CreateJbig2Context(); | 1443 FX_DWORD src_x = (bFlipX ? (dest_width - dest_x - 1) : dest_x) * |
411 if (m_pStreamAcc->GetImageParam()) { | 1444 (int64_t)src_width / dest_width; |
412 CPDF_Stream* pGlobals = m_pStreamAcc->GetImageParam()->GetStream
(FX_BSTRC("JBIG2Globals")); | 1445 src_x %= src_width; |
413 if (pGlobals) { | 1446 const uint8_t* pSrcPixel = NULL; |
414 m_pGlobalStream = new CPDF_StreamAcc; | 1447 if (m_bpc % 8 == 0) { |
415 m_pGlobalStream->LoadAllData(pGlobals, FALSE); | 1448 pSrcPixel = pSrcLine + src_x * orig_Bpp; |
416 } | 1449 } else { |
| 1450 pSrcPixel = pSrcLine + (int)(src_x * orig_Not8Bpp); |
| 1451 } |
| 1452 uint8_t* pDestPixel = dest_scan + i * dest_Bpp; |
| 1453 FX_ARGB argb; |
| 1454 if (src_x == last_src_x) { |
| 1455 argb = last_argb; |
| 1456 } else { |
| 1457 if (m_pColorSpace) { |
| 1458 uint8_t color[4]; |
| 1459 if (!m_bDefaultDecode) { |
| 1460 for (int i = 0; i < m_nComponents; i++) { |
| 1461 int color_value = |
| 1462 (int)((m_pCompData[i].m_DecodeMin + |
| 1463 m_pCompData[i].m_DecodeStep * (FX_FLOAT)pSrcPixel[i]) * |
| 1464 255.0f + |
| 1465 0.5f); |
| 1466 temp[i] = |
| 1467 color_value > 255 ? 255 : (color_value < 0 ? 0 : color_value); |
417 } | 1468 } |
418 ret = pJbig2Module->StartDecode(m_pJbig2Context, m_Width, m_Height,
m_pStreamAcc->GetData(), m_pStreamAcc->GetSize(), | 1469 m_pColorSpace->TranslateImageLine( |
419 m_pGlobalStream ? m_pGlobalStream->G
etData() : NULL, m_pGlobalStream ? m_pGlobalStream->GetSize() : 0, m_pCachedBitm
ap->GetBuffer(), | 1470 color, temp, 1, 0, 0, m_bLoadMask && |
420 m_pCachedBitmap->GetPitch(), pPause)
; | 1471 m_GroupFamily == PDFCS_DEVICECMYK && |
421 if (ret < 0) { | 1472 m_Family == PDFCS_DEVICECMYK); |
422 m_pCachedBitmap.reset(); | 1473 } else { |
423 delete m_pGlobalStream; | 1474 if (m_bpc < 8) { |
424 m_pGlobalStream = NULL; | 1475 int src_bit_pos = 0; |
425 pJbig2Module->DestroyJbig2Context(m_pJbig2Context); | 1476 if (src_x % 2) { |
426 m_pJbig2Context = NULL; | 1477 src_bit_pos = 4; |
427 return 0; | 1478 } |
| 1479 for (FX_DWORD i = 0; i < m_nComponents; i++) { |
| 1480 temp[i] = (uint8_t)(_GetBits8(pSrcPixel, src_bit_pos, m_bpc) * |
| 1481 unit_To8Bpc); |
| 1482 src_bit_pos += m_bpc; |
| 1483 } |
| 1484 m_pColorSpace->TranslateImageLine( |
| 1485 color, temp, 1, 0, 0, m_bLoadMask && |
| 1486 m_GroupFamily == PDFCS_DEVICECMYK && |
| 1487 m_Family == PDFCS_DEVICECMYK); |
| 1488 } else { |
| 1489 m_pColorSpace->TranslateImageLine( |
| 1490 color, pSrcPixel, 1, 0, 0, |
| 1491 m_bLoadMask && m_GroupFamily == PDFCS_DEVICECMYK && |
| 1492 m_Family == PDFCS_DEVICECMYK); |
428 } | 1493 } |
429 if (ret == FXCODEC_STATUS_DECODE_TOBECONTINUE) { | 1494 } |
430 return 2; | 1495 argb = FXARGB_MAKE(0xff, color[2], color[1], color[0]); |
431 } | |
432 int ret1 = 1; | |
433 if (m_bHasMask) { | |
434 ret1 = ContinueLoadMaskDIB(pPause); | |
435 m_Status = 2; | |
436 } | |
437 if (ret1 == 2) { | |
438 return ret1; | |
439 } | |
440 if (m_pColorSpace && m_bStdCS) { | |
441 m_pColorSpace->EnableStdConversion(FALSE); | |
442 } | |
443 return ret1; | |
444 } | |
445 FXCODEC_STATUS ret = pJbig2Module->ContinueDecode(m_pJbig2Context, pPaus
e); | |
446 if (ret < 0) { | |
447 m_pCachedBitmap.reset(); | |
448 delete m_pGlobalStream; | |
449 m_pGlobalStream = NULL; | |
450 pJbig2Module->DestroyJbig2Context(m_pJbig2Context); | |
451 m_pJbig2Context = NULL; | |
452 return 0; | |
453 } | |
454 if (ret == FXCODEC_STATUS_DECODE_TOBECONTINUE) { | |
455 return 2; | |
456 } | |
457 int ret1 = 1; | |
458 if (m_bHasMask) { | |
459 ret1 = ContinueLoadMaskDIB(pPause); | |
460 m_Status = 2; | |
461 } | |
462 if (ret1 == 2) { | |
463 return ret1; | |
464 } | |
465 if (m_pColorSpace && m_bStdCS) { | |
466 m_pColorSpace->EnableStdConversion(FALSE); | |
467 } | |
468 return ret1; | |
469 } | |
470 if (m_Status == 2) { | |
471 return ContinueLoadMaskDIB(pPause); | |
472 } | |
473 return 0; | |
474 } | |
475 FX_BOOL CPDF_DIBSource::LoadColorInfo(CPDF_Dictionary* pFormResources, CPDF_Dict
ionary* pPageResources) | |
476 { | |
477 m_bpc_orig = m_pDict->GetInteger(FX_BSTRC("BitsPerComponent")); | |
478 if (m_pDict->GetInteger("ImageMask")) { | |
479 m_bImageMask = TRUE; | |
480 } | |
481 if (m_bImageMask || !m_pDict->KeyExist(FX_BSTRC("ColorSpace"))) { | |
482 if (!m_bImageMask) { | |
483 CPDF_Object* pFilter = m_pDict->GetElementValue(FX_BSTRC("Filter")); | |
484 if (pFilter) { | |
485 CFX_ByteString filter; | |
486 if (pFilter->GetType() == PDFOBJ_NAME) { | |
487 filter = pFilter->GetString(); | |
488 if (filter == FX_BSTRC("JPXDecode")) { | |
489 m_bDoBpcCheck = FALSE; | |
490 return TRUE; | |
491 } | |
492 } else if (pFilter->GetType() == PDFOBJ_ARRAY) { | |
493 CPDF_Array* pArray = (CPDF_Array*)pFilter; | |
494 if (pArray->GetString(pArray->GetCount() - 1) == FX_BSTRC("J
PXDecode")) { | |
495 m_bDoBpcCheck = FALSE; | |
496 return TRUE; | |
497 } | |
498 } | |
499 } | |
500 } | |
501 m_bImageMask = TRUE; | |
502 m_bpc = m_nComponents = 1; | |
503 CPDF_Array* pDecode = m_pDict->GetArray(FX_BSTRC("Decode")); | |
504 m_bDefaultDecode = pDecode == NULL || pDecode->GetInteger(0) == 0; | |
505 return TRUE; | |
506 } | |
507 CPDF_Object* pCSObj = m_pDict->GetElementValue(FX_BSTRC("ColorSpace")); | |
508 if (pCSObj == NULL) { | |
509 return FALSE; | |
510 } | |
511 CPDF_DocPageData* pDocPageData = m_pDocument->GetPageData(); | |
512 if (pFormResources) { | |
513 m_pColorSpace = pDocPageData->GetColorSpace(pCSObj, pFormResources); | |
514 } | |
515 if (m_pColorSpace == NULL) { | |
516 m_pColorSpace = pDocPageData->GetColorSpace(pCSObj, pPageResources); | |
517 } | |
518 if (m_pColorSpace == NULL) { | |
519 return FALSE; | |
520 } | |
521 m_Family = m_pColorSpace->GetFamily(); | |
522 m_nComponents = m_pColorSpace->CountComponents(); | |
523 if (m_Family == PDFCS_ICCBASED && pCSObj->GetType() == PDFOBJ_NAME) { | |
524 CFX_ByteString cs = pCSObj->GetString(); | |
525 if (cs == FX_BSTRC("DeviceGray")) { | |
526 m_nComponents = 1; | |
527 } else if (cs == FX_BSTRC("DeviceRGB")) { | |
528 m_nComponents = 3; | |
529 } else if (cs == FX_BSTRC("DeviceCMYK")) { | |
530 m_nComponents = 4; | |
531 } | |
532 } | |
533 ValidateDictParam(); | |
534 m_pCompData = GetDecodeAndMaskArray(m_bDefaultDecode, m_bColorKey); | |
535 if (m_pCompData == NULL) { | |
536 return FALSE; | |
537 } | |
538 return TRUE; | |
539 } | |
540 DIB_COMP_DATA* CPDF_DIBSource::GetDecodeAndMaskArray(FX_BOOL& bDefaultDecode, FX
_BOOL& bColorKey) | |
541 { | |
542 if (m_pColorSpace == NULL) { | |
543 return NULL; | |
544 } | |
545 DIB_COMP_DATA* pCompData = FX_Alloc(DIB_COMP_DATA, m_nComponents); | |
546 int max_data = (1 << m_bpc) - 1; | |
547 CPDF_Array* pDecode = m_pDict->GetArray(FX_BSTRC("Decode")); | |
548 if (pDecode) { | |
549 for (FX_DWORD i = 0; i < m_nComponents; i ++) { | |
550 pCompData[i].m_DecodeMin = pDecode->GetNumber(i * 2); | |
551 FX_FLOAT max = pDecode->GetNumber(i * 2 + 1); | |
552 pCompData[i].m_DecodeStep = (max - pCompData[i].m_DecodeMin) / max_d
ata; | |
553 FX_FLOAT def_value, def_min, def_max; | |
554 m_pColorSpace->GetDefaultValue(i, def_value, def_min, def_max); | |
555 if (m_Family == PDFCS_INDEXED) { | |
556 def_max = (FX_FLOAT)max_data; | |
557 } | |
558 if (def_min != pCompData[i].m_DecodeMin || def_max != max) { | |
559 bDefaultDecode = FALSE; | |
560 } | |
561 } | |
562 } else { | |
563 for (FX_DWORD i = 0; i < m_nComponents; i ++) { | |
564 FX_FLOAT def_value; | |
565 m_pColorSpace->GetDefaultValue(i, def_value, pCompData[i].m_DecodeMi
n, pCompData[i].m_DecodeStep); | |
566 if (m_Family == PDFCS_INDEXED) { | |
567 pCompData[i].m_DecodeStep = (FX_FLOAT)max_data; | |
568 } | |
569 pCompData[i].m_DecodeStep = (pCompData[i].m_DecodeStep - pCompData[i
].m_DecodeMin) / max_data; | |
570 } | |
571 } | |
572 if (!m_pDict->KeyExist(FX_BSTRC("SMask"))) { | |
573 CPDF_Object* pMask = m_pDict->GetElementValue(FX_BSTRC("Mask")); | |
574 if (pMask == NULL) { | |
575 return pCompData; | |
576 } | |
577 if (pMask->GetType() == PDFOBJ_ARRAY) { | |
578 CPDF_Array* pArray = (CPDF_Array*)pMask; | |
579 if (pArray->GetCount() >= m_nComponents * 2) { | |
580 for (FX_DWORD i = 0; i < m_nComponents; i++) { | |
581 int min_num = pArray->GetInteger(i * 2); | |
582 int max_num = pArray->GetInteger(i * 2 + 1); | |
583 pCompData[i].m_ColorKeyMin = FX_MAX(min_num, 0); | |
584 pCompData[i].m_ColorKeyMax = FX_MIN(max_num, max_data); | |
585 } | |
586 } | |
587 bColorKey = TRUE; | |
588 } | |
589 } | |
590 return pCompData; | |
591 } | |
592 ICodec_ScanlineDecoder* FPDFAPI_CreateFaxDecoder(const uint8_t* src_buf, FX_DWOR
D src_size, int width, int height, | |
593 const CPDF_Dictionary* pParams); | |
594 ICodec_ScanlineDecoder* FPDFAPI_CreateFlateDecoder(const uint8_t* src_buf, FX_DW
ORD src_size, int width, int height, | |
595 int nComps, int bpc, const CPDF_Dictionary* pParams); | |
596 int CPDF_DIBSource::CreateDecoder() | |
597 { | |
598 const CFX_ByteString& decoder = m_pStreamAcc->GetImageDecoder(); | |
599 if (decoder.IsEmpty()) { | |
600 return 1; | |
601 } | |
602 if (m_bDoBpcCheck && m_bpc == 0) { | |
603 return 0; | |
604 } | |
605 const uint8_t* src_data = m_pStreamAcc->GetData(); | |
606 FX_DWORD src_size = m_pStreamAcc->GetSize(); | |
607 const CPDF_Dictionary* pParams = m_pStreamAcc->GetImageParam(); | |
608 if (decoder == FX_BSTRC("CCITTFaxDecode")) { | |
609 m_pDecoder = FPDFAPI_CreateFaxDecoder(src_data, src_size, m_Width, m_Hei
ght, pParams); | |
610 } else if (decoder == FX_BSTRC("DCTDecode")) { | |
611 m_pDecoder = CPDF_ModuleMgr::Get()->GetJpegModule()->CreateDecoder( | |
612 src_data, src_size, m_Width, m_Height, m_nComponents, | |
613 pParams ? pParams->GetInteger("ColorTransform", 1) : 1); | |
614 if (!m_pDecoder) { | |
615 FX_BOOL bTransform = FALSE; | |
616 int comps, bpc; | |
617 ICodec_JpegModule* pJpegModule = CPDF_ModuleMgr::Get()->GetJpegModul
e(); | |
618 if (pJpegModule->LoadInfo(src_data, src_size, m_Width, m_Height, com
ps, bpc, bTransform)) { | |
619 if (m_nComponents != comps) { | |
620 FX_Free(m_pCompData); | |
621 m_nComponents = comps; | |
622 if (m_Family == PDFCS_LAB && m_nComponents != 3) { | |
623 m_pCompData = NULL; | |
624 return 0; | |
625 } | |
626 m_pCompData = GetDecodeAndMaskArray(m_bDefaultDecode, m_bCol
orKey); | |
627 if (m_pCompData == NULL) { | |
628 return 0; | |
629 } | |
630 } | |
631 m_bpc = bpc; | |
632 m_pDecoder = CPDF_ModuleMgr::Get()->GetJpegModule()->CreateDecod
er(src_data, src_size, m_Width, m_Height, | |
633 m_nComponents, bTransform); | |
634 } | |
635 } | |
636 } else if (decoder == FX_BSTRC("FlateDecode")) { | |
637 m_pDecoder = FPDFAPI_CreateFlateDecoder(src_data, src_size, m_Width, m_H
eight, m_nComponents, m_bpc, pParams); | |
638 } else if (decoder == FX_BSTRC("JPXDecode")) { | |
639 LoadJpxBitmap(); | |
640 return m_pCachedBitmap ? 1 : 0; | |
641 } else if (decoder == FX_BSTRC("JBIG2Decode")) { | |
642 m_pCachedBitmap.reset(new CFX_DIBitmap); | |
643 if (!m_pCachedBitmap->Create(m_Width, m_Height, m_bImageMask ? FXDIB_1bp
pMask : FXDIB_1bppRgb)) { | |
644 m_pCachedBitmap.reset(); | |
645 return 0; | |
646 } | |
647 m_Status = 1; | |
648 return 2; | |
649 } else if (decoder == FX_BSTRC("RunLengthDecode")) { | |
650 m_pDecoder = CPDF_ModuleMgr::Get()->GetCodecModule()->GetBasicModule()->
CreateRunLengthDecoder(src_data, src_size, m_Width, m_Height, m_nComponents, m_b
pc); | |
651 } | |
652 if (!m_pDecoder) | |
653 return 0; | |
654 | |
655 FX_SAFE_DWORD requested_pitch = | |
656 CalculatePitch8(m_bpc, m_nComponents, m_Width, 1); | |
657 if (!requested_pitch.IsValid()) { | |
658 return 0; | |
659 } | |
660 FX_SAFE_DWORD provided_pitch = CalculatePitch8(m_pDecoder->GetBPC(), | |
661 m_pDecoder->CountComps(), | |
662 m_pDecoder->GetWidth(), | |
663 1); | |
664 if (!provided_pitch.IsValid()) { | |
665 return 0; | |
666 } | |
667 if (provided_pitch.ValueOrDie() < requested_pitch.ValueOrDie()) { | |
668 return 0; | |
669 } | |
670 return 1; | |
671 } | |
672 void CPDF_DIBSource::LoadJpxBitmap() | |
673 { | |
674 ICodec_JpxModule* pJpxModule = CPDF_ModuleMgr::Get()->GetJpxModule(); | |
675 if (!pJpxModule) | |
676 return; | |
677 | |
678 nonstd::unique_ptr<JpxBitMapContext> context( | |
679 new JpxBitMapContext(pJpxModule)); | |
680 context->set_context(pJpxModule->CreateDecoder(m_pStreamAcc->GetData(), | |
681 m_pStreamAcc->GetSize(), | |
682 m_pColorSpace != nullptr)); | |
683 if (!context->context()) | |
684 return; | |
685 | |
686 FX_DWORD width = 0; | |
687 FX_DWORD height = 0; | |
688 FX_DWORD codestream_nComps = 0; | |
689 FX_DWORD image_nComps = 0; | |
690 pJpxModule->GetImageInfo(context->context(), width, height, | |
691 codestream_nComps, image_nComps); | |
692 if ((int)width < m_Width || (int)height < m_Height) | |
693 return; | |
694 | |
695 int output_nComps; | |
696 FX_BOOL bTranslateColor; | |
697 FX_BOOL bSwapRGB = FALSE; | |
698 if (m_pColorSpace) { | |
699 if (codestream_nComps != (FX_DWORD)m_pColorSpace->CountComponents()) | |
700 return; | |
701 output_nComps = codestream_nComps; | |
702 bTranslateColor = FALSE; | |
703 if (m_pColorSpace == CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB)) { | |
704 bSwapRGB = TRUE; | |
705 m_pColorSpace = nullptr; | |
706 } | |
707 } else { | |
708 bTranslateColor = TRUE; | |
709 if (image_nComps) { | |
710 output_nComps = image_nComps; | |
711 } else { | 1496 } else { |
712 output_nComps = codestream_nComps; | 1497 argb = FXARGB_MAKE(0xff, pSrcPixel[2], pSrcPixel[1], pSrcPixel[0]); |
713 } | |
714 if (output_nComps == 3) { | |
715 bSwapRGB = TRUE; | |
716 } else if (output_nComps == 4) { | |
717 m_pColorSpace = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK); | |
718 bTranslateColor = FALSE; | |
719 } | |
720 m_nComponents = output_nComps; | |
721 } | |
722 FXDIB_Format format; | |
723 if (output_nComps == 1) { | |
724 format = FXDIB_8bppRgb; | |
725 } else if (output_nComps <= 3) { | |
726 format = FXDIB_Rgb; | |
727 } else if (output_nComps == 4) { | |
728 format = FXDIB_Rgb32; | |
729 } else { | |
730 width = (width * output_nComps + 2) / 3; | |
731 format = FXDIB_Rgb; | |
732 } | |
733 m_pCachedBitmap.reset(new CFX_DIBitmap); | |
734 if (!m_pCachedBitmap->Create(width, height, format)) { | |
735 m_pCachedBitmap.reset(); | |
736 return; | |
737 } | |
738 m_pCachedBitmap->Clear(0xFFFFFFFF); | |
739 context->set_output_offsets(FX_Alloc(uint8_t, output_nComps)); | |
740 for (int i = 0; i < output_nComps; ++i) | |
741 context->output_offsets()[i] = i; | |
742 if (bSwapRGB) { | |
743 context->output_offsets()[0] = 2; | |
744 context->output_offsets()[2] = 0; | |
745 } | |
746 if (!pJpxModule->Decode(context->context(), | |
747 m_pCachedBitmap->GetBuffer(), | |
748 m_pCachedBitmap->GetPitch(), | |
749 bTranslateColor, | |
750 context->output_offsets())) { | |
751 m_pCachedBitmap.reset(); | |
752 return; | |
753 } | |
754 if (m_pColorSpace && | |
755 m_pColorSpace->GetFamily() == PDFCS_INDEXED && | |
756 m_bpc < 8) { | |
757 int scale = 8 - m_bpc; | |
758 for (FX_DWORD row = 0; row < height; ++row) { | |
759 uint8_t* scanline = (uint8_t*)m_pCachedBitmap->GetScanline(row); | |
760 for (FX_DWORD col = 0; col < width; ++col) { | |
761 *scanline = (*scanline) >> scale; | |
762 ++scanline; | |
763 } | |
764 } | |
765 } | |
766 m_bpc = 8; | |
767 } | |
768 CPDF_DIBSource* CPDF_DIBSource::LoadMask(FX_DWORD& MatteColor) | |
769 { | |
770 MatteColor = 0xffffffff; | |
771 CPDF_Stream* pSoftMask = m_pDict->GetStream(FX_BSTRC("SMask")); | |
772 if (pSoftMask) { | |
773 CPDF_Array* pMatte = pSoftMask->GetDict()->GetArray(FX_BSTRC("Matte")); | |
774 if (pMatte != NULL && m_pColorSpace && (FX_DWORD)m_pColorSpace->CountCom
ponents() <= m_nComponents) { | |
775 FX_FLOAT* pColor = FX_Alloc(FX_FLOAT, m_nComponents); | |
776 for (FX_DWORD i = 0; i < m_nComponents; i ++) { | |
777 pColor[i] = pMatte->GetFloat(i); | |
778 } | |
779 FX_FLOAT R, G, B; | |
780 m_pColorSpace->GetRGB(pColor, R, G, B); | |
781 FX_Free(pColor); | |
782 MatteColor = FXARGB_MAKE(0, FXSYS_round(R * 255), FXSYS_round(G * 25
5), FXSYS_round(B * 255)); | |
783 } | |
784 return LoadMaskDIB(pSoftMask); | |
785 } | |
786 CPDF_Object* pMask = m_pDict->GetElementValue(FX_BSTRC("Mask")); | |
787 if (pMask == NULL) { | |
788 return NULL; | |
789 } | |
790 if (pMask->GetType() == PDFOBJ_STREAM) { | |
791 return LoadMaskDIB((CPDF_Stream*)pMask); | |
792 } | |
793 return NULL; | |
794 } | |
795 int CPDF_DIBSource::StratLoadMask() | |
796 { | |
797 m_MatteColor = 0xffffffff; | |
798 m_pMaskStream = m_pDict->GetStream(FX_BSTRC("SMask")); | |
799 if (m_pMaskStream) { | |
800 CPDF_Array* pMatte = m_pMaskStream->GetDict()->GetArray(FX_BSTRC("Matte"
)); | |
801 if (pMatte != NULL && m_pColorSpace && (FX_DWORD)m_pColorSpace->CountCom
ponents() <= m_nComponents) { | |
802 FX_FLOAT R, G, B; | |
803 FX_FLOAT* pColor = FX_Alloc(FX_FLOAT, m_nComponents); | |
804 for (FX_DWORD i = 0; i < m_nComponents; i ++) { | |
805 pColor[i] = pMatte->GetFloat(i); | |
806 } | |
807 m_pColorSpace->GetRGB(pColor, R, G, B); | |
808 FX_Free(pColor); | |
809 m_MatteColor = FXARGB_MAKE(0, FXSYS_round(R * 255), FXSYS_round(G *
255), FXSYS_round(B * 255)); | |
810 } | |
811 return StartLoadMaskDIB(); | |
812 } | |
813 m_pMaskStream = m_pDict->GetElementValue(FX_BSTRC("Mask")); | |
814 if (m_pMaskStream == NULL) { | |
815 return 1; | |
816 } | |
817 if (m_pMaskStream->GetType() == PDFOBJ_STREAM) { | |
818 return StartLoadMaskDIB(); | |
819 } | |
820 return 1; | |
821 } | |
822 int CPDF_DIBSource::ContinueLoadMaskDIB(IFX_Pause* pPause) | |
823 { | |
824 if (m_pMask == NULL) { | |
825 return 1; | |
826 } | |
827 int ret = m_pMask->ContinueLoadDIBSource(pPause); | |
828 if (ret == 2) { | |
829 return ret; | |
830 } | |
831 if (m_pColorSpace && m_bStdCS) { | |
832 m_pColorSpace->EnableStdConversion(FALSE); | |
833 } | |
834 if (!ret) { | |
835 delete m_pMask; | |
836 m_pMask = NULL; | |
837 return ret; | |
838 } | |
839 return 1; | |
840 } | |
841 CPDF_DIBSource* CPDF_DIBSource::DetachMask() | |
842 { | |
843 CPDF_DIBSource* pDIBSource = m_pMask; | |
844 m_pMask = NULL; | |
845 return pDIBSource; | |
846 } | |
847 CPDF_DIBSource* CPDF_DIBSource::LoadMaskDIB(CPDF_Stream* pMask) | |
848 { | |
849 CPDF_DIBSource* pMaskSource = new CPDF_DIBSource; | |
850 if (!pMaskSource->Load(m_pDocument, pMask, NULL, NULL, NULL, NULL, TRUE)) { | |
851 delete pMaskSource; | |
852 return NULL; | |
853 } | |
854 return pMaskSource; | |
855 } | |
856 int CPDF_DIBSource::StartLoadMaskDIB() | |
857 { | |
858 m_pMask = new CPDF_DIBSource; | |
859 int ret = m_pMask->StartLoadDIBSource(m_pDocument, (CPDF_Stream*)m_pMaskStre
am, FALSE, NULL, NULL, TRUE); | |
860 if (ret == 2) { | |
861 if (m_Status == 0) { | |
862 m_Status = 2; | |
863 } | |
864 return 2; | |
865 } | |
866 if (!ret) { | |
867 delete m_pMask; | |
868 m_pMask = NULL; | |
869 return 1; | |
870 } | |
871 return 1; | |
872 } | |
873 void CPDF_DIBSource::LoadPalette() | |
874 { | |
875 if (m_bpc == 0) { | |
876 return; | |
877 } | |
878 if (m_bpc * m_nComponents > 8) { | |
879 return; | |
880 } | |
881 if (m_pColorSpace == NULL) { | |
882 return; | |
883 } | |
884 if (m_bpc * m_nComponents == 1) { | |
885 if (m_bDefaultDecode && (m_Family == PDFCS_DEVICEGRAY || m_Family == PDF
CS_DEVICERGB)) { | |
886 return; | |
887 } | |
888 if (m_pColorSpace->CountComponents() > 3) { | |
889 return; | |
890 } | |
891 FX_FLOAT color_values[3]; | |
892 color_values[0] = m_pCompData[0].m_DecodeMin; | |
893 color_values[1] = color_values[2] = color_values[0]; | |
894 FX_FLOAT R=0.0f, G=0.0f, B=0.0f; | |
895 m_pColorSpace->GetRGB(color_values, R, G, B); | |
896 FX_ARGB argb0 = ArgbEncode(255, FXSYS_round(R * 255), FXSYS_round(G * 25
5), FXSYS_round(B * 255)); | |
897 color_values[0] += m_pCompData[0].m_DecodeStep; | |
898 color_values[1] += m_pCompData[0].m_DecodeStep; | |
899 color_values[2] += m_pCompData[0].m_DecodeStep; | |
900 m_pColorSpace->GetRGB(color_values, R, G, B); | |
901 FX_ARGB argb1 = ArgbEncode(255, FXSYS_round(R * 255), FXSYS_round(G * 25
5), FXSYS_round(B * 255)); | |
902 if (argb0 != 0xFF000000 || argb1 != 0xFFFFFFFF) { | |
903 SetPaletteArgb(0, argb0); | |
904 SetPaletteArgb(1, argb1); | |
905 } | |
906 return; | |
907 } | |
908 if (m_pColorSpace == CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY) && m_bpc
== 8 && m_bDefaultDecode) { | |
909 } else { | |
910 int palette_count = 1 << (m_bpc * m_nComponents); | |
911 CFX_FixedBufGrow<FX_FLOAT, 16> color_values(m_nComponents); | |
912 FX_FLOAT* color_value = color_values; | |
913 for (int i = 0; i < palette_count; i ++) { | |
914 int color_data = i; | |
915 for (FX_DWORD j = 0; j < m_nComponents; j ++) { | |
916 int encoded_component = color_data % (1 << m_bpc); | |
917 color_data /= 1 << m_bpc; | |
918 color_value[j] = m_pCompData[j].m_DecodeMin + m_pCompData[j].m_D
ecodeStep * encoded_component; | |
919 } | |
920 FX_FLOAT R = 0, G = 0, B = 0; | |
921 if (m_nComponents == 1 && m_Family == PDFCS_ICCBASED && m_pColorSpac
e->CountComponents() > 1) { | |
922 int nComponents = m_pColorSpace->CountComponents(); | |
923 FX_FLOAT* temp_buf = FX_Alloc(FX_FLOAT, nComponents); | |
924 for (int i = 0; i < nComponents; i++) { | |
925 temp_buf[i] = *color_value; | |
926 } | |
927 m_pColorSpace->GetRGB(temp_buf, R, G, B); | |
928 FX_Free(temp_buf); | |
929 } else { | |
930 m_pColorSpace->GetRGB(color_value, R, G, B); | |
931 } | |
932 SetPaletteArgb(i, ArgbEncode(255, FXSYS_round(R * 255), FXSYS_round(
G * 255), FXSYS_round(B * 255))); | |
933 } | |
934 } | |
935 } | |
936 void CPDF_DIBSource::ValidateDictParam() | |
937 { | |
938 m_bpc = m_bpc_orig; | |
939 CPDF_Object * pFilter = m_pDict->GetElementValue(FX_BSTRC("Filter")); | |
940 if (pFilter) { | |
941 if (pFilter->GetType() == PDFOBJ_NAME) { | |
942 CFX_ByteString filter = pFilter->GetString(); | |
943 if (filter == FX_BSTRC("CCITTFaxDecode") || filter == FX_BSTRC("JBIG
2Decode")) { | |
944 m_bpc = 1; | |
945 m_nComponents = 1; | |
946 } | |
947 if (filter == FX_BSTRC("RunLengthDecode") || filter == FX_BSTRC("DCT
Decode")) { | |
948 m_bpc = 8; | |
949 } | |
950 } else if (pFilter->GetType() == PDFOBJ_ARRAY) { | |
951 CPDF_Array *pArray = (CPDF_Array *)pFilter; | |
952 if (pArray->GetString(pArray->GetCount() - 1) == FX_BSTRC("CCITTFaxD
ecode") || | |
953 pArray->GetString(pArray->GetCount() - 1) == FX_BSTRC("JBIG2
Decode")) { | |
954 m_bpc = 1; | |
955 m_nComponents = 1; | |
956 } | |
957 if (pArray->GetString(pArray->GetCount() - 1) == FX_BSTRC("DCTDecode
")) { | |
958 // Previously, pArray->GetString(pArray->GetCount() - 1) == FX_B
STRC("RunLengthDecode") was checked in the "if" statement as well, | |
959 // but too many documents don't conform to it. | |
960 m_bpc = 8; | |
961 } | |
962 } | |
963 } | |
964 if (m_bpc != 1 && m_bpc != 2 && m_bpc != 4 && m_bpc != 8 && m_bpc != 16) { | |
965 m_bpc = 0; | |
966 } | |
967 } | |
968 #define NORMALCOLOR_MAX(color, max) (color) > (max) ? (max) : (color) < 0 ? 0 :
(color); | |
969 void CPDF_DIBSource::TranslateScanline24bpp(uint8_t* dest_scan, const uint8_t* s
rc_scan) const | |
970 { | |
971 if (m_bpc == 0) { | |
972 return; | |
973 } | |
974 int max_data = (1 << m_bpc) - 1; | |
975 if (m_bDefaultDecode) { | |
976 if (m_Family == PDFCS_DEVICERGB || m_Family == PDFCS_CALRGB) { | |
977 const uint8_t* src_pos = src_scan; | |
978 switch (m_bpc) { | |
979 case 16: | |
980 for (int col = 0; col < m_Width; col ++) { | |
981 *dest_scan++ = src_pos[4]; | |
982 *dest_scan++ = src_pos[2]; | |
983 *dest_scan++ = *src_pos; | |
984 src_pos += 6; | |
985 } | |
986 break; | |
987 case 8: | |
988 for (int column = 0; column < m_Width; column ++) { | |
989 *dest_scan++ = src_pos[2]; | |
990 *dest_scan++ = src_pos[1]; | |
991 *dest_scan++ = *src_pos; | |
992 src_pos += 3; | |
993 } | |
994 break; | |
995 default: | |
996 int src_bit_pos = 0; | |
997 int dest_byte_pos = 0; | |
998 for (int column = 0; column < m_Width; column ++) { | |
999 int R = _GetBits8(src_scan, src_bit_pos, m_bpc); | |
1000 src_bit_pos += m_bpc; | |
1001 int G = _GetBits8(src_scan, src_bit_pos, m_bpc); | |
1002 src_bit_pos += m_bpc; | |
1003 int B = _GetBits8(src_scan, src_bit_pos, m_bpc); | |
1004 src_bit_pos += m_bpc; | |
1005 R = NORMALCOLOR_MAX(R, max_data); | |
1006 G = NORMALCOLOR_MAX(G, max_data); | |
1007 B = NORMALCOLOR_MAX(B, max_data); | |
1008 dest_scan[dest_byte_pos] = B * 255 / max_data; | |
1009 dest_scan[dest_byte_pos + 1] = G * 255 / max_data; | |
1010 dest_scan[dest_byte_pos + 2] = R * 255 / max_data; | |
1011 dest_byte_pos += 3; | |
1012 } | |
1013 break; | |
1014 } | |
1015 return; | |
1016 } | |
1017 if (m_bpc == 8) { | |
1018 if (m_nComponents == m_pColorSpace->CountComponents()) | |
1019 m_pColorSpace->TranslateImageLine(dest_scan, src_scan, m_Width,
m_Width, m_Height, | |
1020 m_bLoadMask && m_GroupFamily =
= PDFCS_DEVICECMYK && m_Family == PDFCS_DEVICECMYK); | |
1021 return; | |
1022 } | |
1023 } | |
1024 CFX_FixedBufGrow<FX_FLOAT, 16> color_values1(m_nComponents); | |
1025 FX_FLOAT* color_values = color_values1; | |
1026 FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f; | |
1027 if (m_bpc == 8) { | |
1028 int src_byte_pos = 0; | |
1029 int dest_byte_pos = 0; | |
1030 for (int column = 0; column < m_Width; column ++) { | |
1031 for (FX_DWORD color = 0; color < m_nComponents; color ++) { | |
1032 int data = src_scan[src_byte_pos ++]; | |
1033 color_values[color] = m_pCompData[color].m_DecodeMin + | |
1034 m_pCompData[color].m_DecodeStep * data; | |
1035 } | |
1036 if (m_bLoadMask && m_GroupFamily == PDFCS_DEVICECMYK && m_Family ==
PDFCS_DEVICECMYK) { | |
1037 FX_FLOAT k = 1.0f - color_values[3]; | |
1038 R = (1.0f - color_values[0]) * k; | |
1039 G = (1.0f - color_values[1]) * k; | |
1040 B = (1.0f - color_values[2]) * k; | |
1041 } else { | |
1042 m_pColorSpace->GetRGB(color_values, R, G, B); | |
1043 } | |
1044 R = NORMALCOLOR_MAX(R, 1); | |
1045 G = NORMALCOLOR_MAX(G, 1); | |
1046 B = NORMALCOLOR_MAX(B, 1); | |
1047 dest_scan[dest_byte_pos] = (int32_t)(B * 255); | |
1048 dest_scan[dest_byte_pos + 1] = (int32_t)(G * 255); | |
1049 dest_scan[dest_byte_pos + 2] = (int32_t)(R * 255); | |
1050 dest_byte_pos += 3; | |
1051 } | |
1052 } else { | |
1053 int src_bit_pos = 0; | |
1054 int dest_byte_pos = 0; | |
1055 for (int column = 0; column < m_Width; column ++) { | |
1056 for (FX_DWORD color = 0; color < m_nComponents; color ++) { | |
1057 int data = _GetBits8(src_scan, src_bit_pos, m_bpc); | |
1058 color_values[color] = m_pCompData[color].m_DecodeMin + | |
1059 m_pCompData[color].m_DecodeStep * data; | |
1060 src_bit_pos += m_bpc; | |
1061 } | |
1062 if (m_bLoadMask && m_GroupFamily == PDFCS_DEVICECMYK && m_Family ==
PDFCS_DEVICECMYK) { | |
1063 FX_FLOAT k = 1.0f - color_values[3]; | |
1064 R = (1.0f - color_values[0]) * k; | |
1065 G = (1.0f - color_values[1]) * k; | |
1066 B = (1.0f - color_values[2]) * k; | |
1067 } else { | |
1068 m_pColorSpace->GetRGB(color_values, R, G, B); | |
1069 } | |
1070 R = NORMALCOLOR_MAX(R, 1); | |
1071 G = NORMALCOLOR_MAX(G, 1); | |
1072 B = NORMALCOLOR_MAX(B, 1); | |
1073 dest_scan[dest_byte_pos] = (int32_t)(B * 255); | |
1074 dest_scan[dest_byte_pos + 1] = (int32_t)(G * 255); | |
1075 dest_scan[dest_byte_pos + 2] = (int32_t)(R * 255); | |
1076 dest_byte_pos += 3; | |
1077 } | |
1078 } | |
1079 } | |
1080 uint8_t* CPDF_DIBSource::GetBuffer() const | |
1081 { | |
1082 if (m_pCachedBitmap) { | |
1083 return m_pCachedBitmap->GetBuffer(); | |
1084 } | |
1085 return NULL; | |
1086 } | |
1087 const uint8_t* CPDF_DIBSource::GetScanline(int line) const | |
1088 { | |
1089 if (m_bpc == 0) { | |
1090 return NULL; | |
1091 } | |
1092 FX_SAFE_DWORD src_pitch = CalculatePitch8(m_bpc, m_nComponents, m_Width, 1); | |
1093 if (!src_pitch.IsValid()) | |
1094 return NULL; | |
1095 FX_DWORD src_pitch_value = src_pitch.ValueOrDie(); | |
1096 const uint8_t* pSrcLine = NULL; | |
1097 if (m_pCachedBitmap) { | |
1098 if (line >= m_pCachedBitmap->GetHeight()) { | |
1099 line = m_pCachedBitmap->GetHeight() - 1; | |
1100 } | |
1101 pSrcLine = m_pCachedBitmap->GetScanline(line); | |
1102 } else if (m_pDecoder) { | |
1103 pSrcLine = m_pDecoder->GetScanline(line); | |
1104 } else { | |
1105 if (m_pStreamAcc->GetSize() >= (line + 1) * src_pitch_value) { | |
1106 pSrcLine = m_pStreamAcc->GetData() + line * src_pitch_value; | |
1107 } | |
1108 } | |
1109 if (pSrcLine == NULL) { | |
1110 uint8_t* pLineBuf = m_pMaskedLine ? m_pMaskedLine : m_pLineBuf; | |
1111 FXSYS_memset(pLineBuf, 0xff, m_Pitch); | |
1112 return pLineBuf; | |
1113 } | |
1114 if (m_bpc * m_nComponents == 1) { | |
1115 if (m_bImageMask && m_bDefaultDecode) { | |
1116 for (FX_DWORD i = 0; i < src_pitch_value; i++) { | |
1117 m_pLineBuf[i] = ~pSrcLine[i]; | |
1118 } | |
1119 } else if (m_bColorKey) { | |
1120 FX_DWORD reset_argb, set_argb; | |
1121 reset_argb = m_pPalette ? m_pPalette[0] : 0xff000000; | |
1122 set_argb = m_pPalette ? m_pPalette[1] : 0xffffffff; | |
1123 if (m_pCompData[0].m_ColorKeyMin == 0) { | |
1124 reset_argb = 0; | |
1125 } | |
1126 if (m_pCompData[0].m_ColorKeyMax == 1) { | |
1127 set_argb = 0; | |
1128 } | |
1129 set_argb = FXARGB_TODIB(set_argb); | |
1130 reset_argb = FXARGB_TODIB(reset_argb); | |
1131 FX_DWORD* dest_scan = (FX_DWORD*)m_pMaskedLine; | |
1132 for (int col = 0; col < m_Width; col ++) { | |
1133 if (pSrcLine[col / 8] & (1 << (7 - col % 8))) { | |
1134 *dest_scan = set_argb; | |
1135 } else { | |
1136 *dest_scan = reset_argb; | |
1137 } | |
1138 dest_scan ++; | |
1139 } | |
1140 return m_pMaskedLine; | |
1141 } else { | |
1142 FXSYS_memcpy(m_pLineBuf, pSrcLine, src_pitch_value); | |
1143 } | |
1144 return m_pLineBuf; | |
1145 } | |
1146 if (m_bpc * m_nComponents <= 8) { | |
1147 if (m_bpc == 8) { | |
1148 FXSYS_memcpy(m_pLineBuf, pSrcLine, src_pitch_value); | |
1149 } else { | |
1150 int src_bit_pos = 0; | |
1151 for (int col = 0; col < m_Width; col ++) { | |
1152 int color_index = 0; | |
1153 for (FX_DWORD color = 0; color < m_nComponents; color ++) { | |
1154 int data = _GetBits8(pSrcLine, src_bit_pos, m_bpc); | |
1155 color_index |= data << (color * m_bpc); | |
1156 src_bit_pos += m_bpc; | |
1157 } | |
1158 m_pLineBuf[col] = color_index; | |
1159 } | |
1160 } | 1498 } |
1161 if (m_bColorKey) { | 1499 if (m_bColorKey) { |
1162 uint8_t* pDestPixel = m_pMaskedLine; | 1500 int alpha = 0xff; |
1163 const uint8_t* pSrcPixel = m_pLineBuf; | 1501 if (m_nComponents == 3 && m_bpc == 8) { |
1164 for (int col = 0; col < m_Width; col ++) { | 1502 alpha = (pSrcPixel[0] < m_pCompData[0].m_ColorKeyMin || |
1165 uint8_t index = *pSrcPixel++; | 1503 pSrcPixel[0] > m_pCompData[0].m_ColorKeyMax || |
1166 if (m_pPalette) { | 1504 pSrcPixel[1] < m_pCompData[1].m_ColorKeyMin || |
1167 *pDestPixel++ = FXARGB_B(m_pPalette[index]); | 1505 pSrcPixel[1] > m_pCompData[1].m_ColorKeyMax || |
1168 *pDestPixel++ = FXARGB_G(m_pPalette[index]); | 1506 pSrcPixel[2] < m_pCompData[2].m_ColorKeyMin || |
1169 *pDestPixel++ = FXARGB_R(m_pPalette[index]); | 1507 pSrcPixel[2] > m_pCompData[2].m_ColorKeyMax) |
1170 } else { | 1508 ? 0xff |
1171 *pDestPixel++ = index; | 1509 : 0; |
1172 *pDestPixel++ = index; | 1510 } |
1173 *pDestPixel++ = index; | 1511 argb &= 0xffffff; |
1174 } | 1512 argb |= alpha << 24; |
1175 *pDestPixel = (index < m_pCompData[0].m_ColorKeyMin || index > m
_pCompData[0].m_ColorKeyMax) ? 0xff : 0; | |
1176 pDestPixel ++ ; | |
1177 } | |
1178 return m_pMaskedLine; | |
1179 } | 1513 } |
1180 return m_pLineBuf; | 1514 last_src_x = src_x; |
1181 } | 1515 last_argb = argb; |
1182 if (m_bColorKey) { | 1516 } |
1183 if (m_nComponents == 3 && m_bpc == 8) { | 1517 if (dest_Bpp == 4) { |
1184 uint8_t* alpha_channel = m_pMaskedLine + 3; | 1518 *(FX_DWORD*)pDestPixel = FXARGB_TODIB(argb); |
1185 for (int col = 0; col < m_Width; col ++) { | 1519 } else { |
1186 const uint8_t* pPixel = pSrcLine + col * 3; | 1520 *pDestPixel++ = FXARGB_B(argb); |
1187 alpha_channel[col * 4] = (pPixel[0] < m_pCompData[0].m_ColorKeyM
in || pPixel[0] > m_pCompData[0].m_ColorKeyMax || | 1521 *pDestPixel++ = FXARGB_G(argb); |
1188 pPixel[1] < m_pCompData[1].m_ColorKeyM
in || pPixel[1] > m_pCompData[1].m_ColorKeyMax || | 1522 *pDestPixel = FXARGB_R(argb); |
1189 pPixel[2] < m_pCompData[2].m_ColorKeyM
in || pPixel[2] > m_pCompData[2].m_ColorKeyMax) ? 0xff : 0; | 1523 } |
1190 } | 1524 } |
1191 } else { | 1525 } |
1192 FXSYS_memset(m_pMaskedLine, 0xff, m_Pitch); | 1526 } |
1193 } | 1527 void CPDF_DIBSource::SetDownSampleSize(int dest_width, int dest_height) const { |
1194 } | 1528 if (m_pDecoder) { |
1195 if (m_pColorSpace) { | 1529 m_pDecoder->DownScale(dest_width, dest_height); |
1196 TranslateScanline24bpp(m_pLineBuf, pSrcLine); | 1530 ((CPDF_DIBSource*)this)->m_Width = m_pDecoder->GetWidth(); |
1197 pSrcLine = m_pLineBuf; | 1531 ((CPDF_DIBSource*)this)->m_Height = m_pDecoder->GetHeight(); |
1198 } | 1532 } |
1199 if (m_bColorKey) { | 1533 } |
1200 const uint8_t* pSrcPixel = pSrcLine; | 1534 void CPDF_DIBSource::ClearImageData() { |
1201 uint8_t* pDestPixel = m_pMaskedLine; | 1535 if (m_pDecoder) { |
1202 for (int col = 0; col < m_Width; col ++) { | 1536 m_pDecoder->ClearImageData(); |
1203 *pDestPixel++ = *pSrcPixel++; | 1537 } |
1204 *pDestPixel++ = *pSrcPixel++; | 1538 } |
1205 *pDestPixel++ = *pSrcPixel++; | 1539 CPDF_ProgressiveImageLoaderHandle::CPDF_ProgressiveImageLoaderHandle() { |
1206 pDestPixel ++; | 1540 m_pImageLoader = NULL; |
1207 } | 1541 m_pCache = NULL; |
1208 return m_pMaskedLine; | 1542 m_pImage = NULL; |
1209 } | 1543 } |
1210 return pSrcLine; | 1544 CPDF_ProgressiveImageLoaderHandle::~CPDF_ProgressiveImageLoaderHandle() {} |
1211 } | 1545 FX_BOOL CPDF_ProgressiveImageLoaderHandle::Start( |
1212 FX_BOOL CPDF_DIBSource::SkipToScanline(int line, IFX_Pause* pPause) const | 1546 CPDF_ImageLoader* pImageLoader, |
1213 { | 1547 const CPDF_ImageObject* pImage, |
1214 if (m_pDecoder) { | 1548 CPDF_PageRenderCache* pCache, |
1215 return m_pDecoder->SkipToScanline(line, pPause); | 1549 FX_BOOL bStdCS, |
1216 } | 1550 FX_DWORD GroupFamily, |
| 1551 FX_BOOL bLoadMask, |
| 1552 CPDF_RenderStatus* pRenderStatus, |
| 1553 int32_t nDownsampleWidth, |
| 1554 int32_t nDownsampleHeight) { |
| 1555 m_pImageLoader = pImageLoader; |
| 1556 m_pCache = pCache; |
| 1557 m_pImage = (CPDF_ImageObject*)pImage; |
| 1558 m_nDownsampleWidth = nDownsampleWidth; |
| 1559 m_nDownsampleHeight = nDownsampleHeight; |
| 1560 FX_BOOL ret; |
| 1561 if (pCache) { |
| 1562 ret = pCache->StartGetCachedBitmap(pImage->m_pImage->GetStream(), bStdCS, |
| 1563 GroupFamily, bLoadMask, pRenderStatus, |
| 1564 m_nDownsampleWidth, m_nDownsampleHeight); |
| 1565 if (ret == FALSE) { |
| 1566 m_pImageLoader->m_bCached = TRUE; |
| 1567 m_pImageLoader->m_pBitmap = pCache->m_pCurImageCache->DetachBitmap(); |
| 1568 m_pImageLoader->m_pMask = pCache->m_pCurImageCache->DetachMask(); |
| 1569 m_pImageLoader->m_MatteColor = pCache->m_pCurImageCache->m_MatteColor; |
| 1570 } |
| 1571 } else { |
| 1572 ret = pImage->m_pImage->StartLoadDIBSource(pRenderStatus->m_pFormResource, |
| 1573 pRenderStatus->m_pPageResource, |
| 1574 bStdCS, GroupFamily, bLoadMask); |
| 1575 if (ret == FALSE) { |
| 1576 m_pImageLoader->m_bCached = FALSE; |
| 1577 m_pImageLoader->m_pBitmap = m_pImage->m_pImage->DetachBitmap(); |
| 1578 m_pImageLoader->m_pMask = m_pImage->m_pImage->DetachMask(); |
| 1579 m_pImageLoader->m_MatteColor = m_pImage->m_pImage->m_MatteColor; |
| 1580 } |
| 1581 } |
| 1582 return ret; |
| 1583 } |
| 1584 FX_BOOL CPDF_ProgressiveImageLoaderHandle::Continue(IFX_Pause* pPause) { |
| 1585 FX_BOOL ret; |
| 1586 if (m_pCache) { |
| 1587 ret = m_pCache->Continue(pPause); |
| 1588 if (ret == FALSE) { |
| 1589 m_pImageLoader->m_bCached = TRUE; |
| 1590 m_pImageLoader->m_pBitmap = m_pCache->m_pCurImageCache->DetachBitmap(); |
| 1591 m_pImageLoader->m_pMask = m_pCache->m_pCurImageCache->DetachMask(); |
| 1592 m_pImageLoader->m_MatteColor = m_pCache->m_pCurImageCache->m_MatteColor; |
| 1593 } |
| 1594 } else { |
| 1595 ret = m_pImage->m_pImage->Continue(pPause); |
| 1596 if (ret == FALSE) { |
| 1597 m_pImageLoader->m_bCached = FALSE; |
| 1598 m_pImageLoader->m_pBitmap = m_pImage->m_pImage->DetachBitmap(); |
| 1599 m_pImageLoader->m_pMask = m_pImage->m_pImage->DetachMask(); |
| 1600 m_pImageLoader->m_MatteColor = m_pImage->m_pImage->m_MatteColor; |
| 1601 } |
| 1602 } |
| 1603 return ret; |
| 1604 } |
| 1605 FX_BOOL CPDF_ImageLoader::Load(const CPDF_ImageObject* pImage, |
| 1606 CPDF_PageRenderCache* pCache, |
| 1607 FX_BOOL bStdCS, |
| 1608 FX_DWORD GroupFamily, |
| 1609 FX_BOOL bLoadMask, |
| 1610 CPDF_RenderStatus* pRenderStatus) { |
| 1611 if (pImage == NULL) { |
1217 return FALSE; | 1612 return FALSE; |
1218 } | 1613 } |
1219 void CPDF_DIBSource::DownSampleScanline(int line, uint8_t* dest_scan, int dest_b
pp, | 1614 if (pCache) { |
1220 int dest_width, FX_BOOL bFlipX, int clip
_left, int clip_width) const | 1615 pCache->GetCachedBitmap(pImage->m_pImage->GetStream(), m_pBitmap, m_pMask, |
1221 { | 1616 m_MatteColor, bStdCS, GroupFamily, bLoadMask, |
1222 if (line < 0 || dest_scan == NULL || dest_bpp <= 0 || | 1617 pRenderStatus, m_nDownsampleWidth, |
1223 dest_width <= 0 || clip_left < 0 || clip_width <= 0) { | 1618 m_nDownsampleHeight); |
1224 return; | 1619 m_bCached = TRUE; |
1225 } | 1620 } else { |
1226 | 1621 m_pBitmap = pImage->m_pImage->LoadDIBSource(&m_pMask, &m_MatteColor, bStdCS, |
1227 FX_DWORD src_width = m_Width; | 1622 GroupFamily, bLoadMask); |
1228 FX_SAFE_DWORD pitch = CalculatePitch8(m_bpc, m_nComponents, m_Width, 1); | 1623 m_bCached = FALSE; |
1229 if (!pitch.IsValid()) { | 1624 } |
1230 return; | 1625 return FALSE; |
1231 } | 1626 } |
1232 | 1627 FX_BOOL CPDF_ImageLoader::StartLoadImage(const CPDF_ImageObject* pImage, |
1233 const uint8_t* pSrcLine = NULL; | 1628 CPDF_PageRenderCache* pCache, |
1234 if (m_pCachedBitmap) { | 1629 void*& LoadHandle, |
1235 pSrcLine = m_pCachedBitmap->GetScanline(line); | 1630 FX_BOOL bStdCS, |
1236 } else if (m_pDecoder) { | 1631 FX_DWORD GroupFamily, |
1237 pSrcLine = m_pDecoder->GetScanline(line); | 1632 FX_BOOL bLoadMask, |
1238 } else { | 1633 CPDF_RenderStatus* pRenderStatus, |
1239 FX_DWORD src_pitch = pitch.ValueOrDie(); | 1634 int32_t nDownsampleWidth, |
1240 pitch *= (line+1); | 1635 int32_t nDownsampleHeight) { |
1241 if (!pitch.IsValid()) { | 1636 m_nDownsampleWidth = nDownsampleWidth; |
1242 return; | 1637 m_nDownsampleHeight = nDownsampleHeight; |
1243 } | 1638 CPDF_ProgressiveImageLoaderHandle* pLoaderHandle = |
1244 | 1639 new CPDF_ProgressiveImageLoaderHandle; |
1245 if (m_pStreamAcc->GetSize() >= pitch.ValueOrDie()) { | 1640 FX_BOOL ret = pLoaderHandle->Start(this, pImage, pCache, bStdCS, GroupFamily, |
1246 pSrcLine = m_pStreamAcc->GetData() + line * src_pitch; | 1641 bLoadMask, pRenderStatus, |
1247 } | 1642 m_nDownsampleWidth, m_nDownsampleHeight); |
1248 } | 1643 LoadHandle = pLoaderHandle; |
1249 int orig_Bpp = m_bpc * m_nComponents / 8; | 1644 return ret; |
1250 int dest_Bpp = dest_bpp / 8; | 1645 } |
1251 if (pSrcLine == NULL) { | 1646 FX_BOOL CPDF_ImageLoader::Continue(void* LoadHandle, IFX_Pause* pPause) { |
1252 FXSYS_memset(dest_scan, 0xff, dest_Bpp * clip_width); | 1647 return ((CPDF_ProgressiveImageLoaderHandle*)LoadHandle)->Continue(pPause); |
1253 return; | 1648 } |
1254 } | 1649 CPDF_ImageLoader::~CPDF_ImageLoader() { |
1255 | 1650 if (!m_bCached) { |
1256 FX_SAFE_INT32 max_src_x = clip_left; | 1651 delete m_pBitmap; |
1257 max_src_x += clip_width - 1; | 1652 delete m_pMask; |
1258 max_src_x *= src_width; | 1653 } |
1259 max_src_x /= dest_width; | 1654 } |
1260 if (!max_src_x.IsValid()) { | |
1261 return; | |
1262 } | |
1263 | |
1264 CFX_FixedBufGrow<uint8_t, 128> temp(orig_Bpp); | |
1265 if (m_bpc * m_nComponents == 1) { | |
1266 FX_DWORD set_argb = (FX_DWORD) - 1, reset_argb = 0; | |
1267 if (m_bImageMask) { | |
1268 if (m_bDefaultDecode) { | |
1269 set_argb = 0; | |
1270 reset_argb = (FX_DWORD) - 1; | |
1271 } | |
1272 } else if (m_bColorKey) { | |
1273 reset_argb = m_pPalette ? m_pPalette[0] : 0xff000000; | |
1274 set_argb = m_pPalette ? m_pPalette[1] : 0xffffffff; | |
1275 if (m_pCompData[0].m_ColorKeyMin == 0) { | |
1276 reset_argb = 0; | |
1277 } | |
1278 if (m_pCompData[0].m_ColorKeyMax == 1) { | |
1279 set_argb = 0; | |
1280 } | |
1281 set_argb = FXARGB_TODIB(set_argb); | |
1282 reset_argb = FXARGB_TODIB(reset_argb); | |
1283 for (int i = 0; i < clip_width; i ++) { | |
1284 FX_DWORD src_x = (clip_left + i) * src_width / dest_width; | |
1285 if (bFlipX) { | |
1286 src_x = src_width - src_x - 1; | |
1287 } | |
1288 src_x %= src_width; | |
1289 if (pSrcLine[src_x / 8] & (1 << (7 - src_x % 8))) { | |
1290 ((FX_DWORD*)dest_scan)[i] = set_argb; | |
1291 } else { | |
1292 ((FX_DWORD*)dest_scan)[i] = reset_argb; | |
1293 } | |
1294 } | |
1295 return; | |
1296 } else { | |
1297 if (dest_Bpp == 1) { | |
1298 } else if (m_pPalette) { | |
1299 reset_argb = m_pPalette[0]; | |
1300 set_argb = m_pPalette[1]; | |
1301 } | |
1302 } | |
1303 for (int i = 0; i < clip_width; i ++) { | |
1304 FX_DWORD src_x = (clip_left + i) * src_width / dest_width; | |
1305 if (bFlipX) { | |
1306 src_x = src_width - src_x - 1; | |
1307 } | |
1308 src_x %= src_width; | |
1309 int dest_pos = i * dest_Bpp; | |
1310 if (pSrcLine[src_x / 8] & (1 << (7 - src_x % 8))) { | |
1311 if (dest_Bpp == 1) { | |
1312 dest_scan[dest_pos] = (uint8_t)set_argb; | |
1313 } else if (dest_Bpp == 3) { | |
1314 dest_scan[dest_pos] = FXARGB_B(set_argb); | |
1315 dest_scan[dest_pos + 1] = FXARGB_G(set_argb); | |
1316 dest_scan[dest_pos + 2] = FXARGB_R(set_argb); | |
1317 } else { | |
1318 *(FX_DWORD*)(dest_scan + dest_pos) = set_argb; | |
1319 } | |
1320 } else { | |
1321 if (dest_Bpp == 1) { | |
1322 dest_scan[dest_pos] = (uint8_t)reset_argb; | |
1323 } else if (dest_Bpp == 3) { | |
1324 dest_scan[dest_pos] = FXARGB_B(reset_argb); | |
1325 dest_scan[dest_pos + 1] = FXARGB_G(reset_argb); | |
1326 dest_scan[dest_pos + 2] = FXARGB_R(reset_argb); | |
1327 } else { | |
1328 *(FX_DWORD*)(dest_scan + dest_pos) = reset_argb; | |
1329 } | |
1330 } | |
1331 } | |
1332 return; | |
1333 } else if (m_bpc * m_nComponents <= 8) { | |
1334 if (m_bpc < 8) { | |
1335 int src_bit_pos = 0; | |
1336 for (FX_DWORD col = 0; col < src_width; col ++) { | |
1337 int color_index = 0; | |
1338 for (FX_DWORD color = 0; color < m_nComponents; color ++) { | |
1339 int data = _GetBits8(pSrcLine, src_bit_pos, m_bpc); | |
1340 color_index |= data << (color * m_bpc); | |
1341 src_bit_pos += m_bpc; | |
1342 } | |
1343 m_pLineBuf[col] = color_index; | |
1344 } | |
1345 pSrcLine = m_pLineBuf; | |
1346 } | |
1347 if (m_bColorKey) { | |
1348 for (int i = 0; i < clip_width; i ++) { | |
1349 FX_DWORD src_x = (clip_left + i) * src_width / dest_width; | |
1350 if (bFlipX) { | |
1351 src_x = src_width - src_x - 1; | |
1352 } | |
1353 src_x %= src_width; | |
1354 uint8_t* pDestPixel = dest_scan + i * 4; | |
1355 uint8_t index = pSrcLine[src_x]; | |
1356 if (m_pPalette) { | |
1357 *pDestPixel++ = FXARGB_B(m_pPalette[index]); | |
1358 *pDestPixel++ = FXARGB_G(m_pPalette[index]); | |
1359 *pDestPixel++ = FXARGB_R(m_pPalette[index]); | |
1360 } else { | |
1361 *pDestPixel++ = index; | |
1362 *pDestPixel++ = index; | |
1363 *pDestPixel++ = index; | |
1364 } | |
1365 *pDestPixel = (index < m_pCompData[0].m_ColorKeyMin || index > m
_pCompData[0].m_ColorKeyMax) ? 0xff : 0; | |
1366 } | |
1367 return; | |
1368 } | |
1369 for (int i = 0; i < clip_width; i ++) { | |
1370 FX_DWORD src_x = (clip_left + i) * src_width / dest_width; | |
1371 if (bFlipX) { | |
1372 src_x = src_width - src_x - 1; | |
1373 } | |
1374 src_x %= src_width; | |
1375 uint8_t index = pSrcLine[src_x]; | |
1376 if (dest_Bpp == 1) { | |
1377 dest_scan[i] = index; | |
1378 } else { | |
1379 int dest_pos = i * dest_Bpp; | |
1380 FX_ARGB argb = m_pPalette[index]; | |
1381 dest_scan[dest_pos] = FXARGB_B(argb); | |
1382 dest_scan[dest_pos + 1] = FXARGB_G(argb); | |
1383 dest_scan[dest_pos + 2] = FXARGB_R(argb); | |
1384 } | |
1385 } | |
1386 return; | |
1387 } else { | |
1388 int last_src_x = -1; | |
1389 FX_ARGB last_argb; | |
1390 FX_FLOAT orig_Not8Bpp = (FX_FLOAT)m_bpc * (FX_FLOAT)m_nComponents / 8.0f
; | |
1391 FX_FLOAT unit_To8Bpc = 255.0f / ((1 << m_bpc) - 1); | |
1392 for (int i = 0; i < clip_width; i ++) { | |
1393 int dest_x = clip_left + i; | |
1394 FX_DWORD src_x = (bFlipX ? (dest_width - dest_x - 1) : dest_x) * (in
t64_t)src_width / dest_width; | |
1395 src_x %= src_width; | |
1396 const uint8_t* pSrcPixel = NULL; | |
1397 if (m_bpc % 8 == 0) { | |
1398 pSrcPixel = pSrcLine + src_x * orig_Bpp; | |
1399 } else { | |
1400 pSrcPixel = pSrcLine + (int)(src_x * orig_Not8Bpp); | |
1401 } | |
1402 uint8_t* pDestPixel = dest_scan + i * dest_Bpp; | |
1403 FX_ARGB argb; | |
1404 if (src_x == last_src_x) { | |
1405 argb = last_argb; | |
1406 } else { | |
1407 if (m_pColorSpace) { | |
1408 uint8_t color[4]; | |
1409 if (!m_bDefaultDecode) { | |
1410 for (int i = 0; i < m_nComponents; i ++) { | |
1411 int color_value = (int)((m_pCompData[i].m_DecodeMin
+ m_pCompData[i].m_DecodeStep * (FX_FLOAT)pSrcPixel[i]) * 255.0f + 0.5f); | |
1412 temp[i] = color_value > 255 ? 255 : (color_value < 0
? 0 : color_value); | |
1413 } | |
1414 m_pColorSpace->TranslateImageLine(color, temp, 1, 0, 0,
m_bLoadMask && m_GroupFamily == PDFCS_DEVICECMYK && m_Family == PDFCS_DEVICECMYK
); | |
1415 } else { | |
1416 if (m_bpc < 8) { | |
1417 int src_bit_pos = 0; | |
1418 if (src_x % 2) { | |
1419 src_bit_pos = 4; | |
1420 } | |
1421 for (FX_DWORD i = 0; i < m_nComponents; i ++) { | |
1422 temp[i] = (uint8_t)(_GetBits8(pSrcPixel, src_bit
_pos, m_bpc) * unit_To8Bpc); | |
1423 src_bit_pos += m_bpc; | |
1424 } | |
1425 m_pColorSpace->TranslateImageLine(color, temp, 1, 0,
0, m_bLoadMask && m_GroupFamily == PDFCS_DEVICECMYK && m_Family == PDFCS_DEVICE
CMYK); | |
1426 } else { | |
1427 m_pColorSpace->TranslateImageLine(color, pSrcPixel,
1, 0, 0, m_bLoadMask && m_GroupFamily == PDFCS_DEVICECMYK && m_Family == PDFCS_D
EVICECMYK); | |
1428 } | |
1429 } | |
1430 argb = FXARGB_MAKE(0xff, color[2], color[1], color[0]); | |
1431 } else { | |
1432 argb = FXARGB_MAKE(0xff, pSrcPixel[2], pSrcPixel[1], pSrcPix
el[0]); | |
1433 } | |
1434 if (m_bColorKey) { | |
1435 int alpha = 0xff; | |
1436 if (m_nComponents == 3 && m_bpc == 8) { | |
1437 alpha = (pSrcPixel[0] < m_pCompData[0].m_ColorKeyMin || | |
1438 pSrcPixel[0] > m_pCompData[0].m_ColorKeyMax || | |
1439 pSrcPixel[1] < m_pCompData[1].m_ColorKeyMin || | |
1440 pSrcPixel[1] > m_pCompData[1].m_ColorKeyMax || | |
1441 pSrcPixel[2] < m_pCompData[2].m_ColorKeyMin || | |
1442 pSrcPixel[2] > m_pCompData[2].m_ColorKeyMax) ?
0xff : 0; | |
1443 } | |
1444 argb &= 0xffffff; | |
1445 argb |= alpha << 24; | |
1446 } | |
1447 last_src_x = src_x; | |
1448 last_argb = argb; | |
1449 } | |
1450 if (dest_Bpp == 4) { | |
1451 *(FX_DWORD*)pDestPixel = FXARGB_TODIB(argb); | |
1452 } else { | |
1453 *pDestPixel++ = FXARGB_B(argb); | |
1454 *pDestPixel++ = FXARGB_G(argb); | |
1455 *pDestPixel = FXARGB_R(argb); | |
1456 } | |
1457 } | |
1458 } | |
1459 } | |
1460 void CPDF_DIBSource::SetDownSampleSize(int dest_width, int dest_height) const | |
1461 { | |
1462 if (m_pDecoder) { | |
1463 m_pDecoder->DownScale(dest_width, dest_height); | |
1464 ((CPDF_DIBSource*)this)->m_Width = m_pDecoder->GetWidth(); | |
1465 ((CPDF_DIBSource*)this)->m_Height = m_pDecoder->GetHeight(); | |
1466 } | |
1467 } | |
1468 void CPDF_DIBSource::ClearImageData() | |
1469 { | |
1470 if (m_pDecoder) { | |
1471 m_pDecoder->ClearImageData(); | |
1472 } | |
1473 } | |
1474 CPDF_ProgressiveImageLoaderHandle::CPDF_ProgressiveImageLoaderHandle() | |
1475 { | |
1476 m_pImageLoader = NULL; | |
1477 m_pCache = NULL; | |
1478 m_pImage = NULL; | |
1479 } | |
1480 CPDF_ProgressiveImageLoaderHandle::~CPDF_ProgressiveImageLoaderHandle() | |
1481 { | |
1482 } | |
1483 FX_BOOL CPDF_ProgressiveImageLoaderHandle::Start(CPDF_ImageLoader* pImageLoader,
const CPDF_ImageObject* pImage, CPDF_PageRenderCache* pCache, FX_BOOL bStdCS, F
X_DWORD GroupFamily, FX_BOOL bLoadMask, CPDF_RenderStatus* pRenderStatus, int32_
t nDownsampleWidth, int32_t nDownsampleHeight) | |
1484 { | |
1485 m_pImageLoader = pImageLoader; | |
1486 m_pCache = pCache; | |
1487 m_pImage = (CPDF_ImageObject*)pImage; | |
1488 m_nDownsampleWidth = nDownsampleWidth; | |
1489 m_nDownsampleHeight = nDownsampleHeight; | |
1490 FX_BOOL ret; | |
1491 if (pCache) { | |
1492 ret = pCache->StartGetCachedBitmap(pImage->m_pImage->GetStream(), bStdCS
, GroupFamily, bLoadMask, pRenderStatus, m_nDownsampleWidth, m_nDownsampleHeight
); | |
1493 if (ret == FALSE) { | |
1494 m_pImageLoader->m_bCached = TRUE; | |
1495 m_pImageLoader->m_pBitmap = pCache->m_pCurImageCache->DetachBitmap()
; | |
1496 m_pImageLoader->m_pMask = pCache->m_pCurImageCache->DetachMask(); | |
1497 m_pImageLoader->m_MatteColor = pCache->m_pCurImageCache->m_MatteColo
r; | |
1498 } | |
1499 } else { | |
1500 ret = pImage->m_pImage->StartLoadDIBSource(pRenderStatus->m_pFormResourc
e, pRenderStatus->m_pPageResource, bStdCS, GroupFamily, bLoadMask); | |
1501 if (ret == FALSE) { | |
1502 m_pImageLoader->m_bCached = FALSE; | |
1503 m_pImageLoader->m_pBitmap = m_pImage->m_pImage->DetachBitmap(); | |
1504 m_pImageLoader->m_pMask = m_pImage->m_pImage->DetachMask(); | |
1505 m_pImageLoader->m_MatteColor = m_pImage->m_pImage->m_MatteColor; | |
1506 } | |
1507 } | |
1508 return ret; | |
1509 } | |
1510 FX_BOOL CPDF_ProgressiveImageLoaderHandle::Continue(IFX_Pause* pPause) | |
1511 { | |
1512 FX_BOOL ret; | |
1513 if (m_pCache) { | |
1514 ret = m_pCache->Continue(pPause); | |
1515 if (ret == FALSE) { | |
1516 m_pImageLoader->m_bCached = TRUE; | |
1517 m_pImageLoader->m_pBitmap = m_pCache->m_pCurImageCache->DetachBitmap
(); | |
1518 m_pImageLoader->m_pMask = m_pCache->m_pCurImageCache->DetachMask(); | |
1519 m_pImageLoader->m_MatteColor = m_pCache->m_pCurImageCache->m_MatteCo
lor; | |
1520 } | |
1521 } else { | |
1522 ret = m_pImage->m_pImage->Continue(pPause); | |
1523 if (ret == FALSE) { | |
1524 m_pImageLoader->m_bCached = FALSE; | |
1525 m_pImageLoader->m_pBitmap = m_pImage->m_pImage->DetachBitmap(); | |
1526 m_pImageLoader->m_pMask = m_pImage->m_pImage->DetachMask(); | |
1527 m_pImageLoader->m_MatteColor = m_pImage->m_pImage->m_MatteColor; | |
1528 } | |
1529 } | |
1530 return ret; | |
1531 } | |
1532 FX_BOOL CPDF_ImageLoader::Load(const CPDF_ImageObject* pImage, CPDF_PageRenderCa
che* pCache, FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_BOOL bLoadMask, CPDF_Rende
rStatus* pRenderStatus) | |
1533 { | |
1534 if (pImage == NULL) { | |
1535 return FALSE; | |
1536 } | |
1537 if (pCache) { | |
1538 pCache->GetCachedBitmap(pImage->m_pImage->GetStream(), m_pBitmap, m_pMas
k, m_MatteColor, bStdCS, GroupFamily, bLoadMask, pRenderStatus, m_nDownsampleWid
th, m_nDownsampleHeight); | |
1539 m_bCached = TRUE; | |
1540 } else { | |
1541 m_pBitmap = pImage->m_pImage->LoadDIBSource(&m_pMask, &m_MatteColor, bSt
dCS, GroupFamily, bLoadMask); | |
1542 m_bCached = FALSE; | |
1543 } | |
1544 return FALSE; | |
1545 } | |
1546 FX_BOOL CPDF_ImageLoader::StartLoadImage(const CPDF_ImageObject* pImage, CPDF_Pa
geRenderCache* pCache, void*& LoadHandle, FX_BOOL bStdCS, FX_DWORD GroupFamily,
FX_BOOL bLoadMask, CPDF_RenderStatus* pRenderStatus, int32_t nDownsampleWidth, i
nt32_t nDownsampleHeight) | |
1547 { | |
1548 m_nDownsampleWidth = nDownsampleWidth; | |
1549 m_nDownsampleHeight = nDownsampleHeight; | |
1550 CPDF_ProgressiveImageLoaderHandle* pLoaderHandle = new CPDF_ProgressiveImage
LoaderHandle; | |
1551 FX_BOOL ret = pLoaderHandle->Start(this, pImage, pCache, bStdCS, GroupFamily
, bLoadMask, pRenderStatus, m_nDownsampleWidth, m_nDownsampleHeight); | |
1552 LoadHandle = pLoaderHandle; | |
1553 return ret; | |
1554 } | |
1555 FX_BOOL CPDF_ImageLoader::Continue(void* LoadHandle, IFX_Pause* pPause) | |
1556 { | |
1557 return ((CPDF_ProgressiveImageLoaderHandle*)LoadHandle)->Continue(pPause); | |
1558 } | |
1559 CPDF_ImageLoader::~CPDF_ImageLoader() | |
1560 { | |
1561 if (!m_bCached) { | |
1562 delete m_pBitmap; | |
1563 delete m_pMask; | |
1564 } | |
1565 } | |
OLD | NEW |