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 "../../../include/fxge/fx_dib.h" | 7 #include "../../../include/fxge/fx_dib.h" |
8 #include "../../../include/fxge/fx_ge.h" | 8 #include "../../../include/fxge/fx_ge.h" |
9 #include "../../../include/fxcodec/fx_codec.h" | 9 #include "../../../include/fxcodec/fx_codec.h" |
10 #include "dib_int.h" | 10 #include "dib_int.h" |
11 #include <limits.h> | 11 #include <limits.h> |
12 FX_BOOL ConvertBuffer(FXDIB_Format dest_format, FX_LPBYTE dest_buf, int dest_pit
ch, int width, int height, | 12 FX_BOOL ConvertBuffer(FXDIB_Format dest_format, |
13 const CFX_DIBSource* pSrcBitmap, int src_left, int src_top
, FX_DWORD*& pal, void* pIccTransform); | 13 FX_LPBYTE dest_buf, |
14 void CmykDecode(FX_DWORD cmyk, int& c, int& m, int& y, int& k) | 14 int dest_pitch, |
15 { | 15 int width, |
16 c = FXSYS_GetCValue(cmyk); | 16 int height, |
17 m = FXSYS_GetMValue(cmyk); | 17 const CFX_DIBSource* pSrcBitmap, |
18 y = FXSYS_GetYValue(cmyk); | 18 int src_left, |
19 k = FXSYS_GetKValue(cmyk); | 19 int src_top, |
20 } | 20 FX_DWORD*& pal, |
21 void ArgbDecode(FX_DWORD argb, int& a, int& r, int& g, int& b) | 21 void* pIccTransform); |
22 { | 22 void CmykDecode(FX_DWORD cmyk, int& c, int& m, int& y, int& k) { |
23 a = FXARGB_A(argb); | 23 c = FXSYS_GetCValue(cmyk); |
24 r = FXARGB_R(argb); | 24 m = FXSYS_GetMValue(cmyk); |
25 g = FXARGB_G(argb); | 25 y = FXSYS_GetYValue(cmyk); |
26 b = FXARGB_B(argb); | 26 k = FXSYS_GetKValue(cmyk); |
27 } | 27 } |
28 void ArgbDecode(FX_DWORD argb, int& a, FX_COLORREF& rgb) | 28 void ArgbDecode(FX_DWORD argb, int& a, int& r, int& g, int& b) { |
29 { | 29 a = FXARGB_A(argb); |
30 a = FXARGB_A(argb); | 30 r = FXARGB_R(argb); |
31 rgb = FXSYS_RGB(FXARGB_R(argb), FXARGB_G(argb), FXARGB_B(argb)); | 31 g = FXARGB_G(argb); |
32 } | 32 b = FXARGB_B(argb); |
33 FX_DWORD ArgbEncode(int a, FX_COLORREF rgb) | 33 } |
34 { | 34 void ArgbDecode(FX_DWORD argb, int& a, FX_COLORREF& rgb) { |
35 return FXARGB_MAKE(a, FXSYS_GetRValue(rgb), FXSYS_GetGValue(rgb), FXSYS_GetB
Value(rgb)); | 35 a = FXARGB_A(argb); |
36 } | 36 rgb = FXSYS_RGB(FXARGB_R(argb), FXARGB_G(argb), FXARGB_B(argb)); |
37 CFX_DIBSource::CFX_DIBSource() | 37 } |
38 { | 38 FX_DWORD ArgbEncode(int a, FX_COLORREF rgb) { |
39 m_bpp = 0; | 39 return FXARGB_MAKE( |
40 m_AlphaFlag = 0; | 40 a, FXSYS_GetRValue(rgb), FXSYS_GetGValue(rgb), FXSYS_GetBValue(rgb)); |
41 m_Width = m_Height = 0; | 41 } |
42 m_Pitch = 0; | 42 CFX_DIBSource::CFX_DIBSource() { |
| 43 m_bpp = 0; |
| 44 m_AlphaFlag = 0; |
| 45 m_Width = m_Height = 0; |
| 46 m_Pitch = 0; |
| 47 m_pPalette = NULL; |
| 48 m_pAlphaMask = NULL; |
| 49 } |
| 50 CFX_DIBSource::~CFX_DIBSource() { |
| 51 if (m_pPalette) { |
| 52 FX_Free(m_pPalette); |
| 53 } |
| 54 if (m_pAlphaMask) { |
| 55 delete m_pAlphaMask; |
| 56 } |
| 57 } |
| 58 CFX_DIBitmap::CFX_DIBitmap() { |
| 59 m_bExtBuf = FALSE; |
| 60 m_pBuffer = NULL; |
| 61 m_pPalette = NULL; |
| 62 } |
| 63 #define _MAX_OOM_LIMIT_ 12000000 |
| 64 FX_BOOL CFX_DIBitmap::Create(int width, |
| 65 int height, |
| 66 FXDIB_Format format, |
| 67 FX_LPBYTE pBuffer, |
| 68 int pitch) { |
| 69 m_pBuffer = NULL; |
| 70 m_bpp = (FX_BYTE)format; |
| 71 m_AlphaFlag = (FX_BYTE)(format >> 8); |
| 72 m_Width = m_Height = m_Pitch = 0; |
| 73 if (width <= 0 || height <= 0 || pitch < 0) { |
| 74 return FALSE; |
| 75 } |
| 76 if ((INT_MAX - 31) / width < (format & 0xff)) { |
| 77 return FALSE; |
| 78 } |
| 79 if (!pitch) { |
| 80 pitch = (width * (format & 0xff) + 31) / 32 * 4; |
| 81 } |
| 82 if ((1 << 30) / pitch < height) { |
| 83 return FALSE; |
| 84 } |
| 85 if (pBuffer) { |
| 86 m_pBuffer = pBuffer; |
| 87 m_bExtBuf = TRUE; |
| 88 } else { |
| 89 int size = pitch * height + 4; |
| 90 int oomlimit = _MAX_OOM_LIMIT_; |
| 91 if (oomlimit >= 0 && size >= oomlimit) { |
| 92 m_pBuffer = FX_AllocNL(FX_BYTE, size); |
| 93 } else { |
| 94 m_pBuffer = FX_Alloc(FX_BYTE, size); |
| 95 } |
| 96 if (m_pBuffer == NULL) { |
| 97 return FALSE; |
| 98 } |
| 99 } |
| 100 m_Width = width; |
| 101 m_Height = height; |
| 102 m_Pitch = pitch; |
| 103 if (HasAlpha() && format != FXDIB_Argb) { |
| 104 FX_BOOL ret = TRUE; |
| 105 ret = BuildAlphaMask(); |
| 106 if (!ret) { |
| 107 if (!m_bExtBuf && m_pBuffer) { |
| 108 FX_Free(m_pBuffer); |
| 109 m_pBuffer = NULL; |
| 110 m_Width = m_Height = m_Pitch = 0; |
| 111 return FALSE; |
| 112 } |
| 113 } |
| 114 } |
| 115 return TRUE; |
| 116 } |
| 117 FX_BOOL CFX_DIBitmap::Copy(const CFX_DIBSource* pSrc) { |
| 118 if (m_pBuffer) { |
| 119 return FALSE; |
| 120 } |
| 121 if (!Create(pSrc->GetWidth(), pSrc->GetHeight(), pSrc->GetFormat())) { |
| 122 return FALSE; |
| 123 } |
| 124 CopyPalette(pSrc->GetPalette()); |
| 125 CopyAlphaMask(pSrc->m_pAlphaMask); |
| 126 for (int row = 0; row < pSrc->GetHeight(); row++) { |
| 127 FXSYS_memcpy32(m_pBuffer + row * m_Pitch, pSrc->GetScanline(row), m_Pitch); |
| 128 } |
| 129 return TRUE; |
| 130 } |
| 131 CFX_DIBitmap::~CFX_DIBitmap() { |
| 132 if (m_pBuffer && !m_bExtBuf) { |
| 133 FX_Free(m_pBuffer); |
| 134 } |
| 135 m_pBuffer = NULL; |
| 136 } |
| 137 void CFX_DIBitmap::TakeOver(CFX_DIBitmap* pSrcBitmap) { |
| 138 if (m_pBuffer && !m_bExtBuf) { |
| 139 FX_Free(m_pBuffer); |
| 140 } |
| 141 if (m_pPalette) { |
| 142 FX_Free(m_pPalette); |
| 143 } |
| 144 if (m_pAlphaMask) { |
| 145 delete m_pAlphaMask; |
| 146 } |
| 147 m_pBuffer = pSrcBitmap->m_pBuffer; |
| 148 m_pPalette = pSrcBitmap->m_pPalette; |
| 149 m_pAlphaMask = pSrcBitmap->m_pAlphaMask; |
| 150 pSrcBitmap->m_pBuffer = NULL; |
| 151 pSrcBitmap->m_pPalette = NULL; |
| 152 pSrcBitmap->m_pAlphaMask = NULL; |
| 153 m_bpp = pSrcBitmap->m_bpp; |
| 154 m_bExtBuf = pSrcBitmap->m_bExtBuf; |
| 155 m_AlphaFlag = pSrcBitmap->m_AlphaFlag; |
| 156 m_Width = pSrcBitmap->m_Width; |
| 157 m_Height = pSrcBitmap->m_Height; |
| 158 m_Pitch = pSrcBitmap->m_Pitch; |
| 159 } |
| 160 CFX_DIBitmap* CFX_DIBSource::Clone(const FX_RECT* pClip) const { |
| 161 FX_RECT rect(0, 0, m_Width, m_Height); |
| 162 if (pClip) { |
| 163 rect.Intersect(*pClip); |
| 164 if (rect.IsEmpty()) { |
| 165 return NULL; |
| 166 } |
| 167 } |
| 168 CFX_DIBitmap* pNewBitmap = FX_NEW CFX_DIBitmap; |
| 169 if (!pNewBitmap) { |
| 170 return NULL; |
| 171 } |
| 172 if (!pNewBitmap->Create(rect.Width(), rect.Height(), GetFormat())) { |
| 173 delete pNewBitmap; |
| 174 return NULL; |
| 175 } |
| 176 pNewBitmap->CopyPalette(m_pPalette); |
| 177 pNewBitmap->CopyAlphaMask(m_pAlphaMask, pClip); |
| 178 if (GetBPP() == 1 && rect.left % 8 != 0) { |
| 179 int left_shift = rect.left % 32; |
| 180 int right_shift = 32 - left_shift; |
| 181 int dword_count = pNewBitmap->m_Pitch / 4; |
| 182 for (int row = rect.top; row < rect.bottom; row++) { |
| 183 FX_DWORD* src_scan = (FX_DWORD*)GetScanline(row) + rect.left / 32; |
| 184 FX_DWORD* dest_scan = (FX_DWORD*)pNewBitmap->GetScanline(row - rect.top); |
| 185 for (int i = 0; i < dword_count; i++) { |
| 186 dest_scan[i] = |
| 187 (src_scan[i] << left_shift) | (src_scan[i + 1] >> right_shift); |
| 188 } |
| 189 } |
| 190 } else { |
| 191 int copy_len = (pNewBitmap->GetWidth() * pNewBitmap->GetBPP() + 7) / 8; |
| 192 if (m_Pitch < (FX_DWORD)copy_len) { |
| 193 copy_len = m_Pitch; |
| 194 } |
| 195 for (int row = rect.top; row < rect.bottom; row++) { |
| 196 FX_LPCBYTE src_scan = GetScanline(row) + rect.left * m_bpp / 8; |
| 197 FX_LPBYTE dest_scan = (FX_LPBYTE)pNewBitmap->GetScanline(row - rect.top); |
| 198 FXSYS_memcpy32(dest_scan, src_scan, copy_len); |
| 199 } |
| 200 } |
| 201 return pNewBitmap; |
| 202 } |
| 203 void CFX_DIBSource::BuildPalette() { |
| 204 if (m_pPalette) { |
| 205 return; |
| 206 } |
| 207 if (GetBPP() == 1) { |
| 208 m_pPalette = FX_Alloc(FX_DWORD, 2); |
| 209 if (!m_pPalette) { |
| 210 return; |
| 211 } |
| 212 if (IsCmykImage()) { |
| 213 m_pPalette[0] = 0xff; |
| 214 m_pPalette[1] = 0; |
| 215 } else { |
| 216 m_pPalette[0] = 0xff000000; |
| 217 m_pPalette[1] = 0xffffffff; |
| 218 } |
| 219 } else if (GetBPP() == 8) { |
| 220 m_pPalette = FX_Alloc(FX_DWORD, 256); |
| 221 if (!m_pPalette) { |
| 222 return; |
| 223 } |
| 224 if (IsCmykImage()) { |
| 225 for (int i = 0; i < 256; i++) { |
| 226 m_pPalette[i] = 0xff - i; |
| 227 } |
| 228 } else { |
| 229 for (int i = 0; i < 256; i++) { |
| 230 m_pPalette[i] = 0xff000000 | (i * 0x10101); |
| 231 } |
| 232 } |
| 233 } |
| 234 } |
| 235 FX_BOOL CFX_DIBSource::BuildAlphaMask() { |
| 236 if (m_pAlphaMask) { |
| 237 return TRUE; |
| 238 } |
| 239 m_pAlphaMask = FX_NEW CFX_DIBitmap; |
| 240 if (!m_pAlphaMask) { |
| 241 return FALSE; |
| 242 } |
| 243 if (!m_pAlphaMask->Create(m_Width, m_Height, FXDIB_8bppMask)) { |
| 244 delete m_pAlphaMask; |
| 245 m_pAlphaMask = NULL; |
| 246 return FALSE; |
| 247 } |
| 248 FXSYS_memset8(m_pAlphaMask->GetBuffer(), |
| 249 0xff, |
| 250 m_pAlphaMask->GetHeight() * m_pAlphaMask->GetPitch()); |
| 251 return TRUE; |
| 252 } |
| 253 FX_DWORD CFX_DIBSource::GetPaletteEntry(int index) const { |
| 254 ASSERT((GetBPP() == 1 || GetBPP() == 8) && !IsAlphaMask()); |
| 255 if (m_pPalette) { |
| 256 return m_pPalette[index]; |
| 257 } |
| 258 if (IsCmykImage()) { |
| 259 if (GetBPP() == 1) { |
| 260 return index ? 0 : 0xff; |
| 261 } |
| 262 return 0xff - index; |
| 263 } |
| 264 if (GetBPP() == 1) { |
| 265 return index ? 0xffffffff : 0xff000000; |
| 266 } |
| 267 return index * 0x10101 | 0xff000000; |
| 268 } |
| 269 void CFX_DIBSource::SetPaletteEntry(int index, FX_DWORD color) { |
| 270 ASSERT((GetBPP() == 1 || GetBPP() == 8) && !IsAlphaMask()); |
| 271 if (m_pPalette == NULL) { |
| 272 BuildPalette(); |
| 273 } |
| 274 m_pPalette[index] = color; |
| 275 } |
| 276 int CFX_DIBSource::FindPalette(FX_DWORD color) const { |
| 277 ASSERT((GetBPP() == 1 || GetBPP() == 8) && !IsAlphaMask()); |
| 278 if (m_pPalette == NULL) { |
| 279 if (IsCmykImage()) { |
| 280 if (GetBPP() == 1) { |
| 281 return ((FX_BYTE)color == 0xff) ? 0 : 1; |
| 282 } |
| 283 return 0xff - (FX_BYTE)color; |
| 284 } |
| 285 if (GetBPP() == 1) { |
| 286 return ((FX_BYTE)color == 0xff) ? 1 : 0; |
| 287 } |
| 288 return (FX_BYTE)color; |
| 289 } |
| 290 int palsize = (1 << GetBPP()); |
| 291 for (int i = 0; i < palsize; i++) |
| 292 if (m_pPalette[i] == color) { |
| 293 return i; |
| 294 } |
| 295 return -1; |
| 296 } |
| 297 void CFX_DIBitmap::Clear(FX_DWORD color) { |
| 298 if (m_pBuffer == NULL) { |
| 299 return; |
| 300 } |
| 301 switch (GetFormat()) { |
| 302 case FXDIB_1bppMask: |
| 303 FXSYS_memset8( |
| 304 m_pBuffer, (color & 0xff000000) ? 0xff : 0, m_Pitch * m_Height); |
| 305 break; |
| 306 case FXDIB_1bppRgb: { |
| 307 int index = FindPalette(color); |
| 308 FXSYS_memset8(m_pBuffer, index ? 0xff : 0, m_Pitch * m_Height); |
| 309 break; |
| 310 } |
| 311 case FXDIB_8bppMask: |
| 312 FXSYS_memset8(m_pBuffer, color >> 24, m_Pitch * m_Height); |
| 313 break; |
| 314 case FXDIB_8bppRgb: { |
| 315 int index = FindPalette(color); |
| 316 FXSYS_memset8(m_pBuffer, index, m_Pitch * m_Height); |
| 317 break; |
| 318 } |
| 319 case FXDIB_Rgb: |
| 320 case FXDIB_Rgba: { |
| 321 int a, r, g, b; |
| 322 ArgbDecode(color, a, r, g, b); |
| 323 if (r == g && g == b) { |
| 324 FXSYS_memset8(m_pBuffer, r, m_Pitch * m_Height); |
| 325 } else { |
| 326 int byte_pos = 0; |
| 327 for (int col = 0; col < m_Width; col++) { |
| 328 m_pBuffer[byte_pos++] = b; |
| 329 m_pBuffer[byte_pos++] = g; |
| 330 m_pBuffer[byte_pos++] = r; |
| 331 } |
| 332 for (int row = 1; row < m_Height; row++) { |
| 333 FXSYS_memcpy32(m_pBuffer + row * m_Pitch, m_pBuffer, m_Pitch); |
| 334 } |
| 335 } |
| 336 break; |
| 337 } |
| 338 case FXDIB_Rgb32: |
| 339 case FXDIB_Argb: { |
| 340 color = IsCmykImage() ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); |
| 341 for (int i = 0; i < m_Width; i++) { |
| 342 ((FX_DWORD*)m_pBuffer)[i] = color; |
| 343 } |
| 344 for (int row = 1; row < m_Height; row++) { |
| 345 FXSYS_memcpy32(m_pBuffer + row * m_Pitch, m_pBuffer, m_Pitch); |
| 346 } |
| 347 break; |
| 348 } |
| 349 default: |
| 350 break; |
| 351 } |
| 352 } |
| 353 void CFX_DIBSource::GetOverlapRect(int& dest_left, |
| 354 int& dest_top, |
| 355 int& width, |
| 356 int& height, |
| 357 int src_width, |
| 358 int src_height, |
| 359 int& src_left, |
| 360 int& src_top, |
| 361 const CFX_ClipRgn* pClipRgn) { |
| 362 if (width == 0 || height == 0) { |
| 363 return; |
| 364 } |
| 365 ASSERT(width > 0 && height > 0); |
| 366 if (dest_left > m_Width || dest_top > m_Height) { |
| 367 width = 0; |
| 368 height = 0; |
| 369 return; |
| 370 } |
| 371 int x_offset = dest_left - src_left; |
| 372 int y_offset = dest_top - src_top; |
| 373 FX_RECT src_rect(src_left, src_top, src_left + width, src_top + height); |
| 374 FX_RECT src_bound(0, 0, src_width, src_height); |
| 375 src_rect.Intersect(src_bound); |
| 376 FX_RECT dest_rect(src_rect.left + x_offset, |
| 377 src_rect.top + y_offset, |
| 378 src_rect.right + x_offset, |
| 379 src_rect.bottom + y_offset); |
| 380 FX_RECT dest_bound(0, 0, m_Width, m_Height); |
| 381 dest_rect.Intersect(dest_bound); |
| 382 if (pClipRgn) { |
| 383 dest_rect.Intersect(pClipRgn->GetBox()); |
| 384 } |
| 385 dest_left = dest_rect.left; |
| 386 dest_top = dest_rect.top; |
| 387 src_left = dest_left - x_offset; |
| 388 src_top = dest_top - y_offset; |
| 389 width = dest_rect.right - dest_rect.left; |
| 390 height = dest_rect.bottom - dest_rect.top; |
| 391 } |
| 392 FX_BOOL CFX_DIBitmap::TransferBitmap(int dest_left, |
| 393 int dest_top, |
| 394 int width, |
| 395 int height, |
| 396 const CFX_DIBSource* pSrcBitmap, |
| 397 int src_left, |
| 398 int src_top, |
| 399 void* pIccTransform) { |
| 400 if (m_pBuffer == NULL) { |
| 401 return FALSE; |
| 402 } |
| 403 GetOverlapRect(dest_left, |
| 404 dest_top, |
| 405 width, |
| 406 height, |
| 407 pSrcBitmap->GetWidth(), |
| 408 pSrcBitmap->GetHeight(), |
| 409 src_left, |
| 410 src_top, |
| 411 NULL); |
| 412 if (width == 0 || height == 0) { |
| 413 return TRUE; |
| 414 } |
| 415 FXDIB_Format dest_format = GetFormat(); |
| 416 FXDIB_Format src_format = pSrcBitmap->GetFormat(); |
| 417 if (dest_format == src_format && pIccTransform == NULL) { |
| 418 if (GetBPP() == 1) { |
| 419 for (int row = 0; row < height; row++) { |
| 420 FX_LPBYTE dest_scan = m_pBuffer + (dest_top + row) * m_Pitch; |
| 421 FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row); |
| 422 for (int col = 0; col < width; col++) { |
| 423 if (src_scan[(src_left + col) / 8] & |
| 424 (1 << (7 - (src_left + col) % 8))) { |
| 425 dest_scan[(dest_left + col) / 8] |= 1 |
| 426 << (7 - (dest_left + col) % 8); |
| 427 } else { |
| 428 dest_scan[(dest_left + col) / 8] &= |
| 429 ~(1 << (7 - (dest_left + col) % 8)); |
| 430 } |
| 431 } |
| 432 } |
| 433 } else { |
| 434 int Bpp = GetBPP() / 8; |
| 435 for (int row = 0; row < height; row++) { |
| 436 FX_LPBYTE dest_scan = |
| 437 m_pBuffer + (dest_top + row) * m_Pitch + dest_left * Bpp; |
| 438 FX_LPCBYTE src_scan = |
| 439 pSrcBitmap->GetScanline(src_top + row) + src_left * Bpp; |
| 440 FXSYS_memcpy32(dest_scan, src_scan, width * Bpp); |
| 441 } |
| 442 } |
| 443 } else { |
| 444 if (m_pPalette) { |
| 445 return FALSE; |
| 446 } |
| 447 if (m_bpp == 8) { |
| 448 dest_format = FXDIB_8bppMask; |
| 449 } |
| 450 FX_LPBYTE dest_buf = |
| 451 m_pBuffer + dest_top * m_Pitch + dest_left * GetBPP() / 8; |
| 452 FX_DWORD* d_plt = NULL; |
| 453 if (!ConvertBuffer(dest_format, |
| 454 dest_buf, |
| 455 m_Pitch, |
| 456 width, |
| 457 height, |
| 458 pSrcBitmap, |
| 459 src_left, |
| 460 src_top, |
| 461 d_plt, |
| 462 pIccTransform)) { |
| 463 return FALSE; |
| 464 } |
| 465 } |
| 466 return TRUE; |
| 467 } |
| 468 #ifndef _FPDFAPI_MINI_ |
| 469 FX_BOOL CFX_DIBitmap::TransferMask(int dest_left, |
| 470 int dest_top, |
| 471 int width, |
| 472 int height, |
| 473 const CFX_DIBSource* pMask, |
| 474 FX_DWORD color, |
| 475 int src_left, |
| 476 int src_top, |
| 477 int alpha_flag, |
| 478 void* pIccTransform) { |
| 479 if (m_pBuffer == NULL) { |
| 480 return FALSE; |
| 481 } |
| 482 ASSERT(HasAlpha() && (m_bpp >= 24)); |
| 483 ASSERT(pMask->IsAlphaMask()); |
| 484 if (!HasAlpha() || !pMask->IsAlphaMask() || m_bpp < 24) { |
| 485 return FALSE; |
| 486 } |
| 487 GetOverlapRect(dest_left, |
| 488 dest_top, |
| 489 width, |
| 490 height, |
| 491 pMask->GetWidth(), |
| 492 pMask->GetHeight(), |
| 493 src_left, |
| 494 src_top, |
| 495 NULL); |
| 496 if (width == 0 || height == 0) { |
| 497 return TRUE; |
| 498 } |
| 499 int src_bpp = pMask->GetBPP(); |
| 500 int alpha; |
| 501 FX_DWORD dst_color; |
| 502 if (alpha_flag >> 8) { |
| 503 alpha = alpha_flag & 0xff; |
| 504 dst_color = FXCMYK_TODIB(color); |
| 505 } else { |
| 506 alpha = FXARGB_A(color); |
| 507 dst_color = FXARGB_TODIB(color); |
| 508 } |
| 509 FX_LPBYTE color_p = (FX_LPBYTE)&dst_color; |
| 510 if (pIccTransform && CFX_GEModule::Get()->GetCodecModule() && |
| 511 CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) { |
| 512 ICodec_IccModule* pIccModule = |
| 513 CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); |
| 514 pIccModule->TranslateScanline(pIccTransform, color_p, color_p, 1); |
| 515 } else { |
| 516 if (alpha_flag >> 8 && !IsCmykImage()) |
| 517 AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), |
| 518 FXSYS_GetMValue(color), |
| 519 FXSYS_GetYValue(color), |
| 520 FXSYS_GetKValue(color), |
| 521 color_p[2], |
| 522 color_p[1], |
| 523 color_p[0]); |
| 524 else if (!(alpha_flag >> 8) && IsCmykImage()) { |
| 525 return FALSE; |
| 526 } |
| 527 } |
| 528 if (!IsCmykImage()) { |
| 529 color_p[3] = (FX_BYTE)alpha; |
| 530 } |
| 531 if (GetFormat() == FXDIB_Argb) { |
| 532 for (int row = 0; row < height; row++) { |
| 533 FX_DWORD* dest_pos = |
| 534 (FX_DWORD*)(m_pBuffer + (dest_top + row) * m_Pitch + dest_left * 4); |
| 535 FX_LPCBYTE src_scan = pMask->GetScanline(src_top + row); |
| 536 if (src_bpp == 1) { |
| 537 for (int col = 0; col < width; col++) { |
| 538 int src_bitpos = src_left + col; |
| 539 if (src_scan[src_bitpos / 8] & (1 << (7 - src_bitpos % 8))) { |
| 540 *dest_pos = dst_color; |
| 541 } else { |
| 542 *dest_pos = 0; |
| 543 } |
| 544 dest_pos++; |
| 545 } |
| 546 } else { |
| 547 src_scan += src_left; |
| 548 dst_color = FXARGB_TODIB(dst_color); |
| 549 dst_color &= 0xffffff; |
| 550 for (int col = 0; col < width; col++) { |
| 551 FXARGB_SETDIB(dest_pos++, |
| 552 dst_color | ((alpha * (*src_scan++) / 255) << 24)); |
| 553 } |
| 554 } |
| 555 } |
| 556 } else { |
| 557 int comps = m_bpp / 8; |
| 558 for (int row = 0; row < height; row++) { |
| 559 FX_LPBYTE dest_color_pos = |
| 560 m_pBuffer + (dest_top + row) * m_Pitch + dest_left * comps; |
| 561 FX_LPBYTE dest_alpha_pos = |
| 562 (FX_LPBYTE)m_pAlphaMask->GetScanline(dest_top + row) + dest_left; |
| 563 FX_LPCBYTE src_scan = pMask->GetScanline(src_top + row); |
| 564 if (src_bpp == 1) { |
| 565 for (int col = 0; col < width; col++) { |
| 566 int src_bitpos = src_left + col; |
| 567 if (src_scan[src_bitpos / 8] & (1 << (7 - src_bitpos % 8))) { |
| 568 FXSYS_memcpy32(dest_color_pos, color_p, comps); |
| 569 *dest_alpha_pos = 0xff; |
| 570 } else { |
| 571 FXSYS_memset32(dest_color_pos, 0, comps); |
| 572 *dest_alpha_pos = 0; |
| 573 } |
| 574 dest_color_pos += comps; |
| 575 dest_alpha_pos++; |
| 576 } |
| 577 } else { |
| 578 src_scan += src_left; |
| 579 for (int col = 0; col < width; col++) { |
| 580 FXSYS_memcpy32(dest_color_pos, color_p, comps); |
| 581 dest_color_pos += comps; |
| 582 *dest_alpha_pos++ = (alpha * (*src_scan++) / 255); |
| 583 } |
| 584 } |
| 585 } |
| 586 } |
| 587 return TRUE; |
| 588 } |
| 589 #endif |
| 590 void CFX_DIBSource::CopyPalette(const FX_DWORD* pSrc, FX_DWORD size) { |
| 591 if (pSrc == NULL || GetBPP() > 8) { |
| 592 if (m_pPalette) { |
| 593 FX_Free(m_pPalette); |
| 594 } |
43 m_pPalette = NULL; | 595 m_pPalette = NULL; |
44 m_pAlphaMask = NULL; | 596 } else { |
45 } | 597 FX_DWORD pal_size = 1 << GetBPP(); |
46 CFX_DIBSource::~CFX_DIBSource() | 598 if (m_pPalette == NULL) { |
47 { | 599 m_pPalette = FX_Alloc(FX_DWORD, pal_size); |
48 if (m_pPalette) { | 600 } |
49 FX_Free(m_pPalette); | 601 if (!m_pPalette) { |
50 } | 602 return; |
51 if (m_pAlphaMask) { | 603 } |
52 delete m_pAlphaMask; | 604 if (pal_size > size) { |
53 } | 605 pal_size = size; |
54 } | 606 } |
55 CFX_DIBitmap::CFX_DIBitmap() | 607 FXSYS_memcpy32(m_pPalette, pSrc, pal_size * sizeof(FX_DWORD)); |
56 { | 608 } |
57 m_bExtBuf = FALSE; | 609 } |
58 m_pBuffer = NULL; | 610 void CFX_DIBSource::GetPalette(FX_DWORD* pal, int alpha) const { |
59 m_pPalette = NULL; | 611 ASSERT(GetBPP() <= 8 && !IsCmykImage()); |
60 } | 612 if (GetBPP() == 1) { |
61 #define _MAX_OOM_LIMIT_»12000000 | 613 pal[0] = |
62 FX_BOOL CFX_DIBitmap::Create(int width, int height, FXDIB_Format format, FX_LPBY
TE pBuffer, int pitch) | 614 ((m_pPalette ? m_pPalette[0] : 0xff000000) & 0xffffff) | (alpha << 24); |
63 { | 615 pal[1] = |
64 m_pBuffer = NULL; | 616 ((m_pPalette ? m_pPalette[1] : 0xffffffff) & 0xffffff) | (alpha << 24); |
65 m_bpp = (FX_BYTE)format; | 617 return; |
66 m_AlphaFlag = (FX_BYTE)(format >> 8); | 618 } |
67 m_Width = m_Height = m_Pitch = 0; | 619 if (m_pPalette) { |
68 if (width <= 0 || height <= 0 || pitch < 0) { | 620 for (int i = 0; i < 256; i++) { |
69 return FALSE; | 621 pal[i] = (m_pPalette[i] & 0x00ffffff) | (alpha << 24); |
70 } | 622 } |
71 if ((INT_MAX - 31) / width < (format & 0xff)) { | 623 } else { |
72 return FALSE; | 624 for (int i = 0; i < 256; i++) { |
73 } | 625 pal[i] = (i * 0x10101) | (alpha << 24); |
74 if (!pitch) { | 626 } |
75 pitch = (width * (format & 0xff) + 31) / 32 * 4; | 627 } |
76 } | 628 } |
77 if ((1 << 30) / pitch < height) { | 629 CFX_DIBitmap* CFX_DIBSource::GetAlphaMask(const FX_RECT* pClip) const { |
78 return FALSE; | 630 ASSERT(GetFormat() == FXDIB_Argb); |
79 } | 631 FX_RECT rect(0, 0, m_Width, m_Height); |
80 if (pBuffer) { | 632 if (pClip) { |
81 m_pBuffer = pBuffer; | 633 rect.Intersect(*pClip); |
82 m_bExtBuf = TRUE; | 634 if (rect.IsEmpty()) { |
| 635 return NULL; |
| 636 } |
| 637 } |
| 638 CFX_DIBitmap* pMask = FX_NEW CFX_DIBitmap; |
| 639 if (!pMask) { |
| 640 return NULL; |
| 641 } |
| 642 if (!pMask->Create(rect.Width(), rect.Height(), FXDIB_8bppMask)) { |
| 643 delete pMask; |
| 644 return NULL; |
| 645 } |
| 646 for (int row = rect.top; row < rect.bottom; row++) { |
| 647 FX_LPCBYTE src_scan = GetScanline(row) + rect.left * 4 + 3; |
| 648 FX_LPBYTE dest_scan = (FX_LPBYTE)pMask->GetScanline(row - rect.top); |
| 649 for (int col = rect.left; col < rect.right; col++) { |
| 650 *dest_scan++ = *src_scan; |
| 651 src_scan += 4; |
| 652 } |
| 653 } |
| 654 return pMask; |
| 655 } |
| 656 FX_BOOL CFX_DIBSource::CopyAlphaMask(const CFX_DIBSource* pAlphaMask, |
| 657 const FX_RECT* pClip) { |
| 658 if (!HasAlpha() || GetFormat() == FXDIB_Argb) { |
| 659 return FALSE; |
| 660 } |
| 661 if (pAlphaMask) { |
| 662 FX_RECT rect(0, 0, pAlphaMask->m_Width, pAlphaMask->m_Height); |
| 663 if (pClip) { |
| 664 rect.Intersect(*pClip); |
| 665 if (rect.IsEmpty() || rect.Width() != m_Width || |
| 666 rect.Height() != m_Height) { |
| 667 return FALSE; |
| 668 } |
83 } else { | 669 } else { |
84 int size = pitch * height + 4; | 670 if (pAlphaMask->m_Width != m_Width || pAlphaMask->m_Height != m_Height) { |
85 int oomlimit = _MAX_OOM_LIMIT_; | 671 return FALSE; |
86 if (oomlimit >= 0 && size >= oomlimit) { | 672 } |
87 m_pBuffer = FX_AllocNL(FX_BYTE, size); | 673 } |
| 674 for (int row = 0; row < m_Height; row++) |
| 675 FXSYS_memcpy32((void*)m_pAlphaMask->GetScanline(row), |
| 676 pAlphaMask->GetScanline(row + rect.top) + rect.left, |
| 677 m_pAlphaMask->m_Pitch); |
| 678 } else { |
| 679 m_pAlphaMask->Clear(0xff000000); |
| 680 } |
| 681 return TRUE; |
| 682 } |
| 683 const int g_ChannelOffset[] = { 0, 2, 1, 0, 0, 1, 2, 3, 3 }; |
| 684 FX_BOOL CFX_DIBitmap::LoadChannel(FXDIB_Channel destChannel, |
| 685 const CFX_DIBSource* pSrcBitmap, |
| 686 FXDIB_Channel srcChannel) { |
| 687 if (m_pBuffer == NULL) { |
| 688 return FALSE; |
| 689 } |
| 690 CFX_DIBSource* pSrcClone = (CFX_DIBSource*)pSrcBitmap; |
| 691 CFX_DIBitmap* pDst = this; |
| 692 int destOffset, srcOffset; |
| 693 if (srcChannel == FXDIB_Alpha) { |
| 694 if (!pSrcBitmap->HasAlpha() && !pSrcBitmap->IsAlphaMask()) { |
| 695 return FALSE; |
| 696 } |
| 697 if (pSrcBitmap->GetBPP() == 1) { |
| 698 pSrcClone = pSrcBitmap->CloneConvert(FXDIB_8bppMask); |
| 699 if (pSrcClone == NULL) { |
| 700 return FALSE; |
| 701 } |
| 702 } |
| 703 if (pSrcBitmap->GetFormat() == FXDIB_Argb) { |
| 704 srcOffset = 3; |
| 705 } else { |
| 706 srcOffset = 0; |
| 707 } |
| 708 } else { |
| 709 if (pSrcBitmap->IsAlphaMask()) { |
| 710 return FALSE; |
| 711 } |
| 712 if (pSrcBitmap->GetBPP() < 24) { |
| 713 if (pSrcBitmap->IsCmykImage()) { |
| 714 pSrcClone = pSrcBitmap->CloneConvert( |
| 715 (FXDIB_Format)((pSrcBitmap->GetFormat() & 0xff00) | 0x20)); |
| 716 } else { |
| 717 pSrcClone = pSrcBitmap->CloneConvert( |
| 718 (FXDIB_Format)((pSrcBitmap->GetFormat() & 0xff00) | 0x18)); |
| 719 } |
| 720 if (pSrcClone == NULL) { |
| 721 return FALSE; |
| 722 } |
| 723 } |
| 724 srcOffset = g_ChannelOffset[srcChannel]; |
| 725 } |
| 726 if (destChannel == FXDIB_Alpha) { |
| 727 if (IsAlphaMask()) { |
| 728 if (!ConvertFormat(FXDIB_8bppMask)) { |
| 729 if (pSrcClone != pSrcBitmap) { |
| 730 delete pSrcClone; |
| 731 } |
| 732 return FALSE; |
| 733 } |
| 734 destOffset = 0; |
| 735 } else { |
| 736 destOffset = 0; |
| 737 if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyka : FXDIB_Argb)) { |
| 738 if (pSrcClone != pSrcBitmap) { |
| 739 delete pSrcClone; |
| 740 } |
| 741 return FALSE; |
| 742 } |
| 743 if (GetFormat() == FXDIB_Argb) { |
| 744 destOffset = 3; |
| 745 } |
| 746 } |
| 747 } else { |
| 748 if (IsAlphaMask()) { |
| 749 if (pSrcClone != pSrcBitmap) { |
| 750 delete pSrcClone; |
| 751 } |
| 752 return FALSE; |
| 753 } |
| 754 if (GetBPP() < 24) { |
| 755 if (HasAlpha()) { |
| 756 if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyka : FXDIB_Argb)) { |
| 757 if (pSrcClone != pSrcBitmap) { |
| 758 delete pSrcClone; |
| 759 } |
| 760 return FALSE; |
| 761 } |
| 762 } else |
| 763 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |
| 764 if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyk : FXDIB_Rgb32)) { |
| 765 #else |
| 766 if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyk : FXDIB_Rgb)) { |
| 767 #endif |
| 768 if (pSrcClone != pSrcBitmap) { |
| 769 delete pSrcClone; |
| 770 } |
| 771 return FALSE; |
| 772 } |
| 773 } |
| 774 destOffset = g_ChannelOffset[destChannel]; |
| 775 } |
| 776 if (srcChannel == FXDIB_Alpha && pSrcClone->m_pAlphaMask) { |
| 777 CFX_DIBitmap* pAlphaMask = pSrcClone->m_pAlphaMask; |
| 778 if (pSrcClone->GetWidth() != m_Width || |
| 779 pSrcClone->GetHeight() != m_Height) { |
| 780 if (pAlphaMask) { |
| 781 pAlphaMask = pAlphaMask->StretchTo(m_Width, m_Height); |
| 782 if (pAlphaMask == NULL) { |
| 783 if (pSrcClone != pSrcBitmap) { |
| 784 delete pSrcClone; |
| 785 } |
| 786 return FALSE; |
| 787 } |
| 788 } |
| 789 } |
| 790 if (pSrcClone != pSrcBitmap) { |
| 791 pSrcClone->m_pAlphaMask = NULL; |
| 792 delete pSrcClone; |
| 793 } |
| 794 pSrcClone = pAlphaMask; |
| 795 srcOffset = 0; |
| 796 } else if (pSrcClone->GetWidth() != m_Width || |
| 797 pSrcClone->GetHeight() != m_Height) { |
| 798 CFX_DIBitmap* pSrcMatched = pSrcClone->StretchTo(m_Width, m_Height); |
| 799 if (pSrcClone != pSrcBitmap) { |
| 800 delete pSrcClone; |
| 801 } |
| 802 if (pSrcMatched == NULL) { |
| 803 return FALSE; |
| 804 } |
| 805 pSrcClone = pSrcMatched; |
| 806 } |
| 807 if (destChannel == FXDIB_Alpha && m_pAlphaMask) { |
| 808 pDst = m_pAlphaMask; |
| 809 destOffset = 0; |
| 810 } |
| 811 int srcBytes = pSrcClone->GetBPP() / 8; |
| 812 int destBytes = pDst->GetBPP() / 8; |
| 813 for (int row = 0; row < m_Height; row++) { |
| 814 FX_LPBYTE dest_pos = (FX_LPBYTE)pDst->GetScanline(row) + destOffset; |
| 815 FX_LPCBYTE src_pos = pSrcClone->GetScanline(row) + srcOffset; |
| 816 for (int col = 0; col < m_Width; col++) { |
| 817 *dest_pos = *src_pos; |
| 818 dest_pos += destBytes; |
| 819 src_pos += srcBytes; |
| 820 } |
| 821 } |
| 822 if (pSrcClone != pSrcBitmap && pSrcClone != pSrcBitmap->m_pAlphaMask) { |
| 823 delete pSrcClone; |
| 824 } |
| 825 return TRUE; |
| 826 } |
| 827 FX_BOOL CFX_DIBitmap::LoadChannel(FXDIB_Channel destChannel, int value) { |
| 828 if (m_pBuffer == NULL) { |
| 829 return FALSE; |
| 830 } |
| 831 int destOffset; |
| 832 if (destChannel == FXDIB_Alpha) { |
| 833 if (IsAlphaMask()) { |
| 834 if (!ConvertFormat(FXDIB_8bppMask)) { |
| 835 return FALSE; |
| 836 } |
| 837 destOffset = 0; |
| 838 } else { |
| 839 destOffset = 0; |
| 840 if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyka : FXDIB_Argb)) { |
| 841 return FALSE; |
| 842 } |
| 843 if (GetFormat() == FXDIB_Argb) { |
| 844 destOffset = 3; |
| 845 } |
| 846 } |
| 847 } else { |
| 848 if (IsAlphaMask()) { |
| 849 return FALSE; |
| 850 } |
| 851 if (GetBPP() < 24) { |
| 852 if (HasAlpha()) { |
| 853 if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyka : FXDIB_Argb)) { |
| 854 return FALSE; |
| 855 } |
| 856 } else |
| 857 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |
| 858 if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyk : FXDIB_Rgb)) { |
| 859 return FALSE; |
| 860 } |
| 861 #else |
| 862 if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyk : FXDIB_Rgb32)) { |
| 863 return FALSE; |
| 864 } |
| 865 #endif |
| 866 } |
| 867 destOffset = g_ChannelOffset[destChannel]; |
| 868 } |
| 869 int Bpp = GetBPP() / 8; |
| 870 if (Bpp == 1) { |
| 871 FXSYS_memset8(m_pBuffer, value, m_Height * m_Pitch); |
| 872 return TRUE; |
| 873 } |
| 874 if (destChannel == FXDIB_Alpha && m_pAlphaMask) { |
| 875 FXSYS_memset8(m_pAlphaMask->GetBuffer(), |
| 876 value, |
| 877 m_pAlphaMask->GetHeight() * m_pAlphaMask->GetPitch()); |
| 878 return TRUE; |
| 879 } |
| 880 for (int row = 0; row < m_Height; row++) { |
| 881 FX_LPBYTE scan_line = m_pBuffer + row * m_Pitch + destOffset; |
| 882 for (int col = 0; col < m_Width; col++) { |
| 883 *scan_line = value; |
| 884 scan_line += Bpp; |
| 885 } |
| 886 } |
| 887 return TRUE; |
| 888 } |
| 889 FX_BOOL CFX_DIBitmap::MultiplyAlpha(const CFX_DIBSource* pSrcBitmap) { |
| 890 if (m_pBuffer == NULL) { |
| 891 return FALSE; |
| 892 } |
| 893 ASSERT(pSrcBitmap->IsAlphaMask()); |
| 894 if (!pSrcBitmap->IsAlphaMask()) { |
| 895 return FALSE; |
| 896 } |
| 897 if (!IsAlphaMask() && !HasAlpha()) { |
| 898 return LoadChannel(FXDIB_Alpha, pSrcBitmap, FXDIB_Alpha); |
| 899 } |
| 900 CFX_DIBitmap* pSrcClone = (CFX_DIBitmap*)pSrcBitmap; |
| 901 if (pSrcBitmap->GetWidth() != m_Width || |
| 902 pSrcBitmap->GetHeight() != m_Height) { |
| 903 pSrcClone = pSrcBitmap->StretchTo(m_Width, m_Height); |
| 904 ASSERT(pSrcClone != NULL); |
| 905 if (pSrcClone == NULL) { |
| 906 return FALSE; |
| 907 } |
| 908 } |
| 909 if (IsAlphaMask()) { |
| 910 if (!ConvertFormat(FXDIB_8bppMask)) { |
| 911 if (pSrcClone != pSrcBitmap) { |
| 912 delete pSrcClone; |
| 913 } |
| 914 return FALSE; |
| 915 } |
| 916 for (int row = 0; row < m_Height; row++) { |
| 917 FX_LPBYTE dest_scan = m_pBuffer + m_Pitch * row; |
| 918 FX_LPBYTE src_scan = pSrcClone->m_pBuffer + pSrcClone->m_Pitch * row; |
| 919 if (pSrcClone->GetBPP() == 1) { |
| 920 for (int col = 0; col < m_Width; col++) { |
| 921 if (!((1 << (7 - col % 8)) & src_scan[col / 8])) { |
| 922 dest_scan[col] = 0; |
| 923 } |
| 924 } |
| 925 } else { |
| 926 for (int col = 0; col < m_Width; col++) { |
| 927 *dest_scan = (*dest_scan) * src_scan[col] / 255; |
| 928 dest_scan++; |
| 929 } |
| 930 } |
| 931 } |
| 932 } else { |
| 933 if (GetFormat() == FXDIB_Argb) { |
| 934 if (pSrcClone->GetBPP() == 1) { |
| 935 if (pSrcClone != pSrcBitmap) { |
| 936 delete pSrcClone; |
| 937 } |
| 938 return FALSE; |
| 939 } |
| 940 for (int row = 0; row < m_Height; row++) { |
| 941 FX_LPBYTE dest_scan = m_pBuffer + m_Pitch * row + 3; |
| 942 FX_LPBYTE src_scan = pSrcClone->m_pBuffer + pSrcClone->m_Pitch * row; |
| 943 for (int col = 0; col < m_Width; col++) { |
| 944 *dest_scan = (*dest_scan) * src_scan[col] / 255; |
| 945 dest_scan += 4; |
| 946 } |
| 947 } |
| 948 } else { |
| 949 m_pAlphaMask->MultiplyAlpha(pSrcClone); |
| 950 } |
| 951 } |
| 952 if (pSrcClone != pSrcBitmap) { |
| 953 delete pSrcClone; |
| 954 } |
| 955 return TRUE; |
| 956 } |
| 957 FX_BOOL CFX_DIBitmap::GetGrayData(void* pIccTransform) { |
| 958 if (m_pBuffer == NULL) { |
| 959 return FALSE; |
| 960 } |
| 961 switch (GetFormat()) { |
| 962 case FXDIB_1bppRgb: { |
| 963 if (m_pPalette == NULL) { |
| 964 return FALSE; |
| 965 } |
| 966 FX_BYTE gray[2]; |
| 967 for (int i = 0; i < 2; i++) { |
| 968 int r = (FX_BYTE)(m_pPalette[i] >> 16); |
| 969 int g = (FX_BYTE)(m_pPalette[i] >> 8); |
| 970 int b = (FX_BYTE)m_pPalette[i]; |
| 971 gray[i] = (FX_BYTE)FXRGB2GRAY(r, g, b); |
| 972 } |
| 973 CFX_DIBitmap* pMask = FX_NEW CFX_DIBitmap; |
| 974 if (!pMask) { |
| 975 return FALSE; |
| 976 } |
| 977 if (!pMask->Create(m_Width, m_Height, FXDIB_8bppMask)) { |
| 978 delete pMask; |
| 979 return FALSE; |
| 980 } |
| 981 FXSYS_memset8(pMask->GetBuffer(), gray[0], pMask->GetPitch() * m_Height); |
| 982 for (int row = 0; row < m_Height; row++) { |
| 983 FX_LPBYTE src_pos = m_pBuffer + row * m_Pitch; |
| 984 FX_LPBYTE dest_pos = (FX_LPBYTE)pMask->GetScanline(row); |
| 985 for (int col = 0; col < m_Width; col++) { |
| 986 if (src_pos[col / 8] & (1 << (7 - col % 8))) { |
| 987 *dest_pos = gray[1]; |
| 988 } |
| 989 dest_pos++; |
| 990 } |
| 991 } |
| 992 TakeOver(pMask); |
| 993 delete pMask; |
| 994 break; |
| 995 } |
| 996 case FXDIB_8bppRgb: { |
| 997 if (m_pPalette == NULL) { |
| 998 return FALSE; |
| 999 } |
| 1000 FX_BYTE gray[256]; |
| 1001 for (int i = 0; i < 256; i++) { |
| 1002 int r = (FX_BYTE)(m_pPalette[i] >> 16); |
| 1003 int g = (FX_BYTE)(m_pPalette[i] >> 8); |
| 1004 int b = (FX_BYTE)m_pPalette[i]; |
| 1005 gray[i] = (FX_BYTE)FXRGB2GRAY(r, g, b); |
| 1006 } |
| 1007 CFX_DIBitmap* pMask = FX_NEW CFX_DIBitmap; |
| 1008 if (!pMask) { |
| 1009 return FALSE; |
| 1010 } |
| 1011 if (!pMask->Create(m_Width, m_Height, FXDIB_8bppMask)) { |
| 1012 delete pMask; |
| 1013 return FALSE; |
| 1014 } |
| 1015 for (int row = 0; row < m_Height; row++) { |
| 1016 FX_LPBYTE dest_pos = pMask->GetBuffer() + row * pMask->GetPitch(); |
| 1017 FX_LPBYTE src_pos = m_pBuffer + row * m_Pitch; |
| 1018 for (int col = 0; col < m_Width; col++) { |
| 1019 *dest_pos++ = gray[*src_pos++]; |
| 1020 } |
| 1021 } |
| 1022 TakeOver(pMask); |
| 1023 delete pMask; |
| 1024 break; |
| 1025 } |
| 1026 case FXDIB_Rgb: { |
| 1027 CFX_DIBitmap* pMask = FX_NEW CFX_DIBitmap; |
| 1028 if (!pMask) { |
| 1029 return FALSE; |
| 1030 } |
| 1031 if (!pMask->Create(m_Width, m_Height, FXDIB_8bppMask)) { |
| 1032 delete pMask; |
| 1033 return FALSE; |
| 1034 } |
| 1035 for (int row = 0; row < m_Height; row++) { |
| 1036 FX_LPBYTE src_pos = m_pBuffer + row * m_Pitch; |
| 1037 FX_LPBYTE dest_pos = pMask->GetBuffer() + row * pMask->GetPitch(); |
| 1038 for (int col = 0; col < m_Width; col++) { |
| 1039 *dest_pos++ = FXRGB2GRAY(src_pos[2], src_pos[1], *src_pos); |
| 1040 src_pos += 3; |
| 1041 } |
| 1042 } |
| 1043 TakeOver(pMask); |
| 1044 delete pMask; |
| 1045 break; |
| 1046 } |
| 1047 case FXDIB_Rgb32: { |
| 1048 CFX_DIBitmap* pMask = FX_NEW CFX_DIBitmap; |
| 1049 if (!pMask) { |
| 1050 return FALSE; |
| 1051 } |
| 1052 if (!pMask->Create(m_Width, m_Height, FXDIB_8bppMask)) { |
| 1053 delete pMask; |
| 1054 return FALSE; |
| 1055 } |
| 1056 for (int row = 0; row < m_Height; row++) { |
| 1057 FX_LPBYTE src_pos = m_pBuffer + row * m_Pitch; |
| 1058 FX_LPBYTE dest_pos = pMask->GetBuffer() + row * pMask->GetPitch(); |
| 1059 for (int col = 0; col < m_Width; col++) { |
| 1060 *dest_pos++ = FXRGB2GRAY(src_pos[2], src_pos[1], *src_pos); |
| 1061 src_pos += 4; |
| 1062 } |
| 1063 } |
| 1064 TakeOver(pMask); |
| 1065 delete pMask; |
| 1066 break; |
| 1067 } |
| 1068 default: |
| 1069 return FALSE; |
| 1070 } |
| 1071 return TRUE; |
| 1072 } |
| 1073 FX_BOOL CFX_DIBitmap::MultiplyAlpha(int alpha) { |
| 1074 if (m_pBuffer == NULL) { |
| 1075 return FALSE; |
| 1076 } |
| 1077 switch (GetFormat()) { |
| 1078 case FXDIB_1bppMask: |
| 1079 if (!ConvertFormat(FXDIB_8bppMask)) { |
| 1080 return FALSE; |
| 1081 } |
| 1082 MultiplyAlpha(alpha); |
| 1083 break; |
| 1084 case FXDIB_8bppMask: { |
| 1085 for (int row = 0; row < m_Height; row++) { |
| 1086 FX_LPBYTE scan_line = m_pBuffer + row * m_Pitch; |
| 1087 for (int col = 0; col < m_Width; col++) { |
| 1088 scan_line[col] = scan_line[col] * alpha / 255; |
| 1089 } |
| 1090 } |
| 1091 break; |
| 1092 } |
| 1093 case FXDIB_Argb: { |
| 1094 for (int row = 0; row < m_Height; row++) { |
| 1095 FX_LPBYTE scan_line = m_pBuffer + row * m_Pitch + 3; |
| 1096 for (int col = 0; col < m_Width; col++) { |
| 1097 *scan_line = (*scan_line) * alpha / 255; |
| 1098 scan_line += 4; |
| 1099 } |
| 1100 } |
| 1101 break; |
| 1102 } |
| 1103 default: |
| 1104 if (HasAlpha()) { |
| 1105 m_pAlphaMask->MultiplyAlpha(alpha); |
| 1106 } else if (IsCmykImage()) { |
| 1107 if (!ConvertFormat((FXDIB_Format)(GetFormat() | 0x0200))) { |
| 1108 return FALSE; |
| 1109 } |
| 1110 m_pAlphaMask->MultiplyAlpha(alpha); |
| 1111 } else { |
| 1112 if (!ConvertFormat(FXDIB_Argb)) { |
| 1113 return FALSE; |
| 1114 } |
| 1115 MultiplyAlpha(alpha); |
| 1116 } |
| 1117 break; |
| 1118 } |
| 1119 return TRUE; |
| 1120 } |
| 1121 #if !defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_) |
| 1122 FX_DWORD CFX_DIBitmap::GetPixel(int x, int y) const { |
| 1123 if (m_pBuffer == NULL) { |
| 1124 return 0; |
| 1125 } |
| 1126 FX_LPBYTE pos = m_pBuffer + y * m_Pitch + x * GetBPP() / 8; |
| 1127 switch (GetFormat()) { |
| 1128 case FXDIB_1bppMask: { |
| 1129 if ((*pos) & (1 << (7 - x % 8))) { |
| 1130 return 0xff000000; |
| 1131 } |
| 1132 return 0; |
| 1133 } |
| 1134 case FXDIB_1bppRgb: { |
| 1135 if ((*pos) & (1 << (7 - x % 8))) { |
| 1136 return m_pPalette ? m_pPalette[1] : 0xffffffff; |
| 1137 } else { |
| 1138 return m_pPalette ? m_pPalette[0] : 0xff000000; |
| 1139 } |
| 1140 break; |
| 1141 } |
| 1142 case FXDIB_8bppMask: |
| 1143 return (*pos) << 24; |
| 1144 case FXDIB_8bppRgb: |
| 1145 return m_pPalette ? m_pPalette[*pos] : (0xff000000 | ((*pos) * 0x10101)); |
| 1146 case FXDIB_Rgb: |
| 1147 case FXDIB_Rgba: |
| 1148 case FXDIB_Rgb32: |
| 1149 return FXARGB_GETDIB(pos) | 0xff000000; |
| 1150 case FXDIB_Argb: |
| 1151 return FXARGB_GETDIB(pos); |
| 1152 default: |
| 1153 break; |
| 1154 } |
| 1155 return 0; |
| 1156 } |
| 1157 #endif |
| 1158 void CFX_DIBitmap::SetPixel(int x, int y, FX_DWORD color) { |
| 1159 if (m_pBuffer == NULL) { |
| 1160 return; |
| 1161 } |
| 1162 if (x < 0 || x >= m_Width || y < 0 || y >= m_Height) { |
| 1163 return; |
| 1164 } |
| 1165 FX_LPBYTE pos = m_pBuffer + y * m_Pitch + x * GetBPP() / 8; |
| 1166 switch (GetFormat()) { |
| 1167 case FXDIB_1bppMask: |
| 1168 if (color >> 24) { |
| 1169 *pos |= 1 << (7 - x % 8); |
| 1170 } else { |
| 1171 *pos &= ~(1 << (7 - x % 8)); |
| 1172 } |
| 1173 break; |
| 1174 case FXDIB_1bppRgb: |
| 1175 if (m_pPalette) { |
| 1176 if (color == m_pPalette[1]) { |
| 1177 *pos |= 1 << (7 - x % 8); |
88 } else { | 1178 } else { |
89 m_pBuffer = FX_Alloc(FX_BYTE, size); | 1179 *pos &= ~(1 << (7 - x % 8)); |
90 } | 1180 } |
91 if (m_pBuffer == NULL) { | 1181 } else { |
92 return FALSE; | 1182 if (color == 0xffffffff) { |
93 } | 1183 *pos |= 1 << (7 - x % 8); |
94 } | 1184 } else { |
95 m_Width = width; | 1185 *pos &= ~(1 << (7 - x % 8)); |
96 m_Height = height; | 1186 } |
97 m_Pitch = pitch; | 1187 } |
98 if (HasAlpha() && format != FXDIB_Argb) { | 1188 break; |
99 FX_BOOL ret = TRUE; | 1189 case FXDIB_8bppMask: |
100 ret = BuildAlphaMask(); | 1190 *pos = (FX_BYTE)(color >> 24); |
101 if (!ret) { | 1191 break; |
102 if (!m_bExtBuf && m_pBuffer) { | 1192 case FXDIB_8bppRgb: { |
103 FX_Free(m_pBuffer); | 1193 if (m_pPalette) { |
104 m_pBuffer = NULL; | 1194 for (int i = 0; i < 256; i++) { |
105 m_Width = m_Height = m_Pitch = 0; | 1195 if (m_pPalette[i] == color) { |
106 return FALSE; | 1196 *pos = (FX_BYTE)i; |
107 } | 1197 return; |
108 } | 1198 } |
109 } | 1199 } |
| 1200 *pos = 0; |
| 1201 } else { |
| 1202 *pos = FXRGB2GRAY(FXARGB_R(color), FXARGB_G(color), FXARGB_B(color)); |
| 1203 } |
| 1204 break; |
| 1205 } |
| 1206 case FXDIB_Rgb: |
| 1207 case FXDIB_Rgb32: { |
| 1208 int alpha = FXARGB_A(color); |
| 1209 pos[0] = (FXARGB_B(color) * alpha + pos[0] * (255 - alpha)) / 255; |
| 1210 pos[1] = (FXARGB_G(color) * alpha + pos[1] * (255 - alpha)) / 255; |
| 1211 pos[2] = (FXARGB_R(color) * alpha + pos[2] * (255 - alpha)) / 255; |
| 1212 break; |
| 1213 } |
| 1214 case FXDIB_Rgba: { |
| 1215 pos[0] = FXARGB_B(color); |
| 1216 pos[1] = FXARGB_G(color); |
| 1217 pos[2] = FXARGB_R(color); |
| 1218 break; |
| 1219 } |
| 1220 case FXDIB_Argb: |
| 1221 FXARGB_SETDIB(pos, color); |
| 1222 break; |
| 1223 default: |
| 1224 break; |
| 1225 } |
| 1226 } |
| 1227 void CFX_DIBitmap::DownSampleScanline(int line, |
| 1228 FX_LPBYTE dest_scan, |
| 1229 int dest_bpp, |
| 1230 int dest_width, |
| 1231 FX_BOOL bFlipX, |
| 1232 int clip_left, |
| 1233 int clip_width) const { |
| 1234 if (m_pBuffer == NULL) { |
| 1235 return; |
| 1236 } |
| 1237 int src_Bpp = m_bpp / 8; |
| 1238 FX_LPBYTE scanline = m_pBuffer + line * m_Pitch; |
| 1239 if (src_Bpp == 0) { |
| 1240 for (int i = 0; i < clip_width; i++) { |
| 1241 FX_DWORD dest_x = clip_left + i; |
| 1242 FX_DWORD src_x = dest_x * m_Width / dest_width; |
| 1243 if (bFlipX) { |
| 1244 src_x = m_Width - src_x - 1; |
| 1245 } |
| 1246 #ifdef FOXIT_CHROME_BUILD |
| 1247 src_x %= m_Width; |
| 1248 #endif |
| 1249 dest_scan[i] = (scanline[src_x / 8] & (1 << (7 - src_x % 8))) ? 255 : 0; |
| 1250 } |
| 1251 } else if (src_Bpp == 1) { |
| 1252 for (int i = 0; i < clip_width; i++) { |
| 1253 FX_DWORD dest_x = clip_left + i; |
| 1254 FX_DWORD src_x = dest_x * m_Width / dest_width; |
| 1255 if (bFlipX) { |
| 1256 src_x = m_Width - src_x - 1; |
| 1257 } |
| 1258 #ifdef FOXIT_CHROME_BUILD |
| 1259 src_x %= m_Width; |
| 1260 #endif |
| 1261 int dest_pos = i; |
| 1262 if (m_pPalette) { |
| 1263 if (!IsCmykImage()) { |
| 1264 dest_pos *= 3; |
| 1265 FX_ARGB argb = m_pPalette[scanline[src_x]]; |
| 1266 dest_scan[dest_pos] = FXARGB_B(argb); |
| 1267 dest_scan[dest_pos + 1] = FXARGB_G(argb); |
| 1268 dest_scan[dest_pos + 2] = FXARGB_R(argb); |
| 1269 } else { |
| 1270 dest_pos *= 4; |
| 1271 FX_CMYK cmyk = m_pPalette[scanline[src_x]]; |
| 1272 dest_scan[dest_pos] = FXSYS_GetCValue(cmyk); |
| 1273 dest_scan[dest_pos + 1] = FXSYS_GetMValue(cmyk); |
| 1274 dest_scan[dest_pos + 2] = FXSYS_GetYValue(cmyk); |
| 1275 dest_scan[dest_pos + 3] = FXSYS_GetKValue(cmyk); |
| 1276 } |
| 1277 } else { |
| 1278 dest_scan[dest_pos] = scanline[src_x]; |
| 1279 } |
| 1280 } |
| 1281 } else { |
| 1282 for (int i = 0; i < clip_width; i++) { |
| 1283 FX_DWORD dest_x = clip_left + i; |
| 1284 FX_DWORD src_x = |
| 1285 bFlipX ? (m_Width - dest_x * m_Width / dest_width - 1) * src_Bpp |
| 1286 : (dest_x * m_Width / dest_width) * src_Bpp; |
| 1287 #ifdef FOXIT_CHROME_BUILD |
| 1288 src_x %= m_Width * src_Bpp; |
| 1289 #endif |
| 1290 int dest_pos = i * src_Bpp; |
| 1291 for (int b = 0; b < src_Bpp; b++) { |
| 1292 dest_scan[dest_pos + b] = scanline[src_x + b]; |
| 1293 } |
| 1294 } |
| 1295 } |
| 1296 } |
| 1297 FX_BOOL CFX_DIBitmap::ConvertColorScale(FX_DWORD forecolor, |
| 1298 FX_DWORD backcolor) { |
| 1299 ASSERT(!IsAlphaMask()); |
| 1300 if (m_pBuffer == NULL || IsAlphaMask()) { |
| 1301 return FALSE; |
| 1302 } |
| 1303 int fc, fm, fy, fk, bc, bm, by, bk; |
| 1304 int fr, fg, fb, br, bg, bb; |
| 1305 FX_BOOL isCmykImage = IsCmykImage(); |
| 1306 if (isCmykImage) { |
| 1307 fc = FXSYS_GetCValue(forecolor); |
| 1308 fm = FXSYS_GetMValue(forecolor); |
| 1309 fy = FXSYS_GetYValue(forecolor); |
| 1310 fk = FXSYS_GetKValue(forecolor); |
| 1311 bc = FXSYS_GetCValue(backcolor); |
| 1312 bm = FXSYS_GetMValue(backcolor); |
| 1313 by = FXSYS_GetYValue(backcolor); |
| 1314 bk = FXSYS_GetKValue(backcolor); |
| 1315 } else { |
| 1316 fr = FXSYS_GetRValue(forecolor); |
| 1317 fg = FXSYS_GetGValue(forecolor); |
| 1318 fb = FXSYS_GetBValue(forecolor); |
| 1319 br = FXSYS_GetRValue(backcolor); |
| 1320 bg = FXSYS_GetGValue(backcolor); |
| 1321 bb = FXSYS_GetBValue(backcolor); |
| 1322 } |
| 1323 if (m_bpp <= 8) { |
| 1324 if (isCmykImage) { |
| 1325 if (forecolor == 0xff && backcolor == 0 && m_pPalette == NULL) { |
| 1326 return TRUE; |
| 1327 } |
| 1328 } else if (forecolor == 0 && backcolor == 0xffffff && m_pPalette == NULL) { |
| 1329 return TRUE; |
| 1330 } |
| 1331 if (m_pPalette == NULL) { |
| 1332 BuildPalette(); |
| 1333 } |
| 1334 int size = 1 << m_bpp; |
| 1335 if (isCmykImage) { |
| 1336 for (int i = 0; i < size; i++) { |
| 1337 FX_BYTE b, g, r; |
| 1338 AdobeCMYK_to_sRGB1(FXSYS_GetCValue(m_pPalette[i]), |
| 1339 FXSYS_GetMValue(m_pPalette[i]), |
| 1340 FXSYS_GetYValue(m_pPalette[i]), |
| 1341 FXSYS_GetKValue(m_pPalette[i]), |
| 1342 r, |
| 1343 g, |
| 1344 b); |
| 1345 int gray = 255 - FXRGB2GRAY(r, g, b); |
| 1346 m_pPalette[i] = CmykEncode(bc + (fc - bc) * gray / 255, |
| 1347 bm + (fm - bm) * gray / 255, |
| 1348 by + (fy - by) * gray / 255, |
| 1349 bk + (fk - bk) * gray / 255); |
| 1350 } |
| 1351 } else |
| 1352 for (int i = 0; i < size; i++) { |
| 1353 int gray = FXRGB2GRAY(FXARGB_R(m_pPalette[i]), |
| 1354 FXARGB_G(m_pPalette[i]), |
| 1355 FXARGB_B(m_pPalette[i])); |
| 1356 m_pPalette[i] = FXARGB_MAKE(0xff, |
| 1357 br + (fr - br) * gray / 255, |
| 1358 bg + (fg - bg) * gray / 255, |
| 1359 bb + (fb - bb) * gray / 255); |
| 1360 } |
110 return TRUE; | 1361 return TRUE; |
111 } | 1362 } |
112 FX_BOOL CFX_DIBitmap::Copy(const CFX_DIBSource* pSrc) | 1363 if (isCmykImage) { |
113 { | 1364 if (forecolor == 0xff && backcolor == 0x00) { |
114 if (m_pBuffer) { | 1365 for (int row = 0; row < m_Height; row++) { |
115 return FALSE; | 1366 FX_LPBYTE scanline = m_pBuffer + row * m_Pitch; |
116 } | 1367 for (int col = 0; col < m_Width; col++) { |
117 if (!Create(pSrc->GetWidth(), pSrc->GetHeight(), pSrc->GetFormat())) { | 1368 FX_BYTE b, g, r; |
118 return FALSE; | 1369 AdobeCMYK_to_sRGB1( |
119 } | 1370 scanline[0], scanline[1], scanline[2], scanline[3], r, g, b); |
120 CopyPalette(pSrc->GetPalette()); | 1371 *scanline++ = 0; |
121 CopyAlphaMask(pSrc->m_pAlphaMask); | 1372 *scanline++ = 0; |
122 for (int row = 0; row < pSrc->GetHeight(); row ++) { | 1373 *scanline++ = 0; |
123 FXSYS_memcpy32(m_pBuffer + row * m_Pitch, pSrc->GetScanline(row), m_Pitc
h); | 1374 *scanline++ = 255 - FXRGB2GRAY(r, g, b); |
| 1375 } |
| 1376 } |
| 1377 return TRUE; |
| 1378 } |
| 1379 } else if (forecolor == 0 && backcolor == 0xffffff) { |
| 1380 for (int row = 0; row < m_Height; row++) { |
| 1381 FX_LPBYTE scanline = m_pBuffer + row * m_Pitch; |
| 1382 int gap = m_bpp / 8 - 2; |
| 1383 for (int col = 0; col < m_Width; col++) { |
| 1384 int gray = FXRGB2GRAY(scanline[2], scanline[1], scanline[0]); |
| 1385 *scanline++ = gray; |
| 1386 *scanline++ = gray; |
| 1387 *scanline = gray; |
| 1388 scanline += gap; |
| 1389 } |
124 } | 1390 } |
125 return TRUE; | 1391 return TRUE; |
126 } | 1392 } |
127 CFX_DIBitmap::~CFX_DIBitmap() | 1393 if (isCmykImage) { |
128 { | 1394 for (int row = 0; row < m_Height; row++) { |
129 if (m_pBuffer && !m_bExtBuf) { | 1395 FX_LPBYTE scanline = m_pBuffer + row * m_Pitch; |
130 FX_Free(m_pBuffer); | 1396 for (int col = 0; col < m_Width; col++) { |
131 } | 1397 FX_BYTE b, g, r; |
132 m_pBuffer = NULL; | 1398 AdobeCMYK_to_sRGB1( |
133 } | 1399 scanline[0], scanline[1], scanline[2], scanline[3], r, g, b); |
134 void CFX_DIBitmap::TakeOver(CFX_DIBitmap* pSrcBitmap) | 1400 int gray = 255 - FXRGB2GRAY(r, g, b); |
135 { | 1401 *scanline++ = bc + (fc - bc) * gray / 255; |
136 if (m_pBuffer && !m_bExtBuf) { | 1402 *scanline++ = bm + (fm - bm) * gray / 255; |
137 FX_Free(m_pBuffer); | 1403 *scanline++ = by + (fy - by) * gray / 255; |
138 } | 1404 *scanline++ = bk + (fk - bk) * gray / 255; |
139 if (m_pPalette) { | 1405 } |
140 FX_Free(m_pPalette); | 1406 } |
141 } | 1407 } else { |
142 if (m_pAlphaMask) { | 1408 for (int row = 0; row < m_Height; row++) { |
143 delete m_pAlphaMask; | 1409 FX_LPBYTE scanline = m_pBuffer + row * m_Pitch; |
144 } | 1410 int gap = m_bpp / 8 - 2; |
145 m_pBuffer = pSrcBitmap->m_pBuffer; | 1411 for (int col = 0; col < m_Width; col++) { |
146 m_pPalette = pSrcBitmap->m_pPalette; | 1412 int gray = FXRGB2GRAY(scanline[2], scanline[1], scanline[0]); |
147 m_pAlphaMask = pSrcBitmap->m_pAlphaMask; | 1413 *scanline++ = bb + (fb - bb) * gray / 255; |
148 pSrcBitmap->m_pBuffer = NULL; | 1414 *scanline++ = bg + (fg - bg) * gray / 255; |
149 pSrcBitmap->m_pPalette = NULL; | 1415 *scanline = br + (fr - br) * gray / 255; |
150 pSrcBitmap->m_pAlphaMask = NULL; | 1416 scanline += gap; |
151 m_bpp = pSrcBitmap->m_bpp; | 1417 } |
152 m_bExtBuf = pSrcBitmap->m_bExtBuf; | 1418 } |
153 m_AlphaFlag = pSrcBitmap->m_AlphaFlag; | 1419 } |
154 m_Width = pSrcBitmap->m_Width; | 1420 return TRUE; |
155 m_Height = pSrcBitmap->m_Height; | 1421 } |
156 m_Pitch = pSrcBitmap->m_Pitch; | 1422 FX_BOOL CFX_DIBitmap::DitherFS(const FX_DWORD* pPalette, |
157 } | 1423 int pal_size, |
158 CFX_DIBitmap* CFX_DIBSource::Clone(const FX_RECT* pClip) const | 1424 const FX_RECT* pRect) { |
159 { | 1425 if (m_pBuffer == NULL) { |
160 FX_RECT rect(0, 0, m_Width, m_Height); | 1426 return FALSE; |
161 if (pClip) { | 1427 } |
162 rect.Intersect(*pClip); | 1428 if (m_bpp != 8 && m_pPalette != NULL && m_AlphaFlag != 0) { |
163 if (rect.IsEmpty()) { | 1429 return FALSE; |
164 return NULL; | 1430 } |
165 } | 1431 if (m_Width < 4 && m_Height < 4) { |
166 } | 1432 return FALSE; |
167 CFX_DIBitmap* pNewBitmap = FX_NEW CFX_DIBitmap; | 1433 } |
168 if (!pNewBitmap) { | 1434 FX_RECT rect(0, 0, m_Width, m_Height); |
169 return NULL; | 1435 if (pRect) { |
170 } | 1436 rect.Intersect(*pRect); |
171 if (!pNewBitmap->Create(rect.Width(), rect.Height(), GetFormat())) { | 1437 } |
172 delete pNewBitmap; | 1438 FX_BYTE translate[256]; |
173 return NULL; | 1439 for (int i = 0; i < 256; i++) { |
174 } | 1440 int err2 = 65536; |
175 pNewBitmap->CopyPalette(m_pPalette); | 1441 for (int j = 0; j < pal_size; j++) { |
176 pNewBitmap->CopyAlphaMask(m_pAlphaMask, pClip); | 1442 FX_BYTE entry = (FX_BYTE)pPalette[j]; |
177 if (GetBPP() == 1 && rect.left % 8 != 0) { | 1443 int err = (int)entry - i; |
178 int left_shift = rect.left % 32; | 1444 if (err * err < err2) { |
179 int right_shift = 32 - left_shift; | 1445 err2 = err * err; |
180 int dword_count = pNewBitmap->m_Pitch / 4; | 1446 translate[i] = entry; |
181 for (int row = rect.top; row < rect.bottom; row ++) { | 1447 } |
182 FX_DWORD* src_scan = (FX_DWORD*)GetScanline(row) + rect.left / 32; | 1448 } |
183 FX_DWORD* dest_scan = (FX_DWORD*)pNewBitmap->GetScanline(row - rect.
top); | 1449 } |
184 for (int i = 0; i < dword_count; i ++) { | 1450 for (int row = rect.top; row < rect.bottom; row++) { |
185 dest_scan[i] = (src_scan[i] << left_shift) | (src_scan[i + 1] >>
right_shift); | 1451 FX_LPBYTE scan = m_pBuffer + row * m_Pitch; |
186 } | 1452 FX_LPBYTE next_scan = m_pBuffer + (row + 1) * m_Pitch; |
| 1453 for (int col = rect.left; col < rect.right; col++) { |
| 1454 int src_pixel = scan[col]; |
| 1455 int dest_pixel = translate[src_pixel]; |
| 1456 scan[col] = (FX_BYTE)dest_pixel; |
| 1457 int error = -dest_pixel + src_pixel; |
| 1458 if (col < rect.right - 1) { |
| 1459 int src = scan[col + 1]; |
| 1460 src += error * 7 / 16; |
| 1461 if (src > 255) { |
| 1462 scan[col + 1] = 255; |
| 1463 } else if (src < 0) { |
| 1464 scan[col + 1] = 0; |
| 1465 } else { |
| 1466 scan[col + 1] = src; |
| 1467 } |
| 1468 } |
| 1469 if (col < rect.right - 1 && row < rect.bottom - 1) { |
| 1470 int src = next_scan[col + 1]; |
| 1471 src += error * 1 / 16; |
| 1472 if (src > 255) { |
| 1473 next_scan[col + 1] = 255; |
| 1474 } else if (src < 0) { |
| 1475 next_scan[col + 1] = 0; |
| 1476 } else { |
| 1477 next_scan[col + 1] = src; |
| 1478 } |
| 1479 } |
| 1480 if (row < rect.bottom - 1) { |
| 1481 int src = next_scan[col]; |
| 1482 src += error * 5 / 16; |
| 1483 if (src > 255) { |
| 1484 next_scan[col] = 255; |
| 1485 } else if (src < 0) { |
| 1486 next_scan[col] = 0; |
| 1487 } else { |
| 1488 next_scan[col] = src; |
| 1489 } |
| 1490 } |
| 1491 if (col > rect.left && row < rect.bottom - 1) { |
| 1492 int src = next_scan[col - 1]; |
| 1493 src += error * 3 / 16; |
| 1494 if (src > 255) { |
| 1495 next_scan[col - 1] = 255; |
| 1496 } else if (src < 0) { |
| 1497 next_scan[col - 1] = 0; |
| 1498 } else { |
| 1499 next_scan[col - 1] = src; |
| 1500 } |
| 1501 } |
| 1502 } |
| 1503 } |
| 1504 return TRUE; |
| 1505 } |
| 1506 CFX_DIBitmap* CFX_DIBSource::FlipImage(FX_BOOL bXFlip, FX_BOOL bYFlip) const { |
| 1507 CFX_DIBitmap* pFlipped = FX_NEW CFX_DIBitmap; |
| 1508 if (!pFlipped) { |
| 1509 return NULL; |
| 1510 } |
| 1511 if (!pFlipped->Create(m_Width, m_Height, GetFormat())) { |
| 1512 delete pFlipped; |
| 1513 return NULL; |
| 1514 } |
| 1515 pFlipped->CopyPalette(m_pPalette); |
| 1516 FX_LPBYTE pDestBuffer = pFlipped->GetBuffer(); |
| 1517 int Bpp = m_bpp / 8; |
| 1518 for (int row = 0; row < m_Height; row++) { |
| 1519 FX_LPCBYTE src_scan = GetScanline(row); |
| 1520 FX_LPBYTE dest_scan = |
| 1521 pDestBuffer + m_Pitch * (bYFlip ? (m_Height - row - 1) : row); |
| 1522 if (!bXFlip) { |
| 1523 FXSYS_memcpy32(dest_scan, src_scan, m_Pitch); |
| 1524 continue; |
| 1525 } |
| 1526 if (m_bpp == 1) { |
| 1527 FXSYS_memset32(dest_scan, 0, m_Pitch); |
| 1528 for (int col = 0; col < m_Width; col++) |
| 1529 if (src_scan[col / 8] & (1 << (7 - col % 8))) { |
| 1530 int dest_col = m_Width - col - 1; |
| 1531 dest_scan[dest_col / 8] |= (1 << (7 - dest_col % 8)); |
187 } | 1532 } |
188 } else { | 1533 } else { |
189 int copy_len = (pNewBitmap->GetWidth() * pNewBitmap->GetBPP() + 7) / 8; | 1534 dest_scan += (m_Width - 1) * Bpp; |
190 if (m_Pitch < (FX_DWORD)copy_len) { | 1535 if (Bpp == 1) { |
191 copy_len = m_Pitch; | 1536 for (int col = 0; col < m_Width; col++) { |
192 } | 1537 *dest_scan = *src_scan; |
193 for (int row = rect.top; row < rect.bottom; row ++) { | 1538 dest_scan--; |
194 FX_LPCBYTE src_scan = GetScanline(row) + rect.left * m_bpp / 8; | 1539 src_scan++; |
195 FX_LPBYTE dest_scan = (FX_LPBYTE)pNewBitmap->GetScanline(row - rect.
top); | 1540 } |
196 FXSYS_memcpy32(dest_scan, src_scan, copy_len); | 1541 } else if (Bpp == 3) { |
197 } | 1542 for (int col = 0; col < m_Width; col++) { |
198 } | 1543 dest_scan[0] = src_scan[0]; |
199 return pNewBitmap; | 1544 dest_scan[1] = src_scan[1]; |
200 } | 1545 dest_scan[2] = src_scan[2]; |
201 void CFX_DIBSource::BuildPalette() | 1546 dest_scan -= 3; |
202 { | 1547 src_scan += 3; |
203 if (m_pPalette) { | 1548 } |
204 return; | 1549 } else { |
205 } | 1550 ASSERT(Bpp == 4); |
206 if (GetBPP() == 1) { | 1551 for (int col = 0; col < m_Width; col++) { |
207 m_pPalette = FX_Alloc(FX_DWORD, 2); | 1552 *(FX_DWORD*)dest_scan = *(FX_DWORD*)src_scan; |
208 if (!m_pPalette) { | 1553 dest_scan -= 4; |
209 return; | 1554 src_scan += 4; |
210 } | 1555 } |
211 if(IsCmykImage()) { | 1556 } |
212 m_pPalette[0] = 0xff; | 1557 } |
213 m_pPalette[1] = 0; | 1558 } |
214 } else { | 1559 if (m_pAlphaMask) { |
215 m_pPalette[0] = 0xff000000; | 1560 pDestBuffer = pFlipped->m_pAlphaMask->GetBuffer(); |
216 m_pPalette[1] = 0xffffffff; | 1561 FX_DWORD dest_pitch = pFlipped->m_pAlphaMask->GetPitch(); |
217 } | 1562 for (int row = 0; row < m_Height; row++) { |
218 } else if (GetBPP() == 8) { | 1563 FX_LPCBYTE src_scan = m_pAlphaMask->GetScanline(row); |
219 m_pPalette = FX_Alloc(FX_DWORD, 256); | 1564 FX_LPBYTE dest_scan = |
220 if (!m_pPalette) { | 1565 pDestBuffer + dest_pitch * (bYFlip ? (m_Height - row - 1) : row); |
221 return; | 1566 if (!bXFlip) { |
222 } | 1567 FXSYS_memcpy32(dest_scan, src_scan, dest_pitch); |
223 if(IsCmykImage()) { | 1568 continue; |
224 for (int i = 0; i < 256; i ++) { | 1569 } |
225 m_pPalette[i] = 0xff - i; | 1570 dest_scan += (m_Width - 1); |
226 } | 1571 for (int col = 0; col < m_Width; col++) { |
227 } else { | 1572 *dest_scan = *src_scan; |
228 for (int i = 0; i < 256; i ++) { | 1573 dest_scan--; |
229 m_pPalette[i] = 0xff000000 | (i * 0x10101); | 1574 src_scan++; |
230 } | 1575 } |
231 } | 1576 } |
232 } | 1577 } |
233 } | 1578 return pFlipped; |
234 FX_BOOL CFX_DIBSource::BuildAlphaMask() | 1579 } |
235 { | 1580 CFX_DIBExtractor::CFX_DIBExtractor(const CFX_DIBSource* pSrc) { |
236 if (m_pAlphaMask) { | 1581 m_pBitmap = NULL; |
237 return TRUE; | 1582 if (pSrc->GetBuffer() == NULL) { |
238 } | 1583 m_pBitmap = pSrc->Clone(); |
239 m_pAlphaMask = FX_NEW CFX_DIBitmap; | 1584 } else { |
240 if (!m_pAlphaMask) { | |
241 return FALSE; | |
242 } | |
243 if (!m_pAlphaMask->Create(m_Width, m_Height, FXDIB_8bppMask)) { | |
244 delete m_pAlphaMask; | |
245 m_pAlphaMask = NULL; | |
246 return FALSE; | |
247 } | |
248 FXSYS_memset8(m_pAlphaMask->GetBuffer(), 0xff, m_pAlphaMask->GetHeight()*m_p
AlphaMask->GetPitch()); | |
249 return TRUE; | |
250 } | |
251 FX_DWORD CFX_DIBSource::GetPaletteEntry(int index) const | |
252 { | |
253 ASSERT((GetBPP() == 1 || GetBPP() == 8) && !IsAlphaMask()); | |
254 if (m_pPalette) { | |
255 return m_pPalette[index]; | |
256 } | |
257 if (IsCmykImage()) { | |
258 if (GetBPP() == 1) { | |
259 return index ? 0 : 0xff; | |
260 } | |
261 return 0xff - index; | |
262 } | |
263 if (GetBPP() == 1) { | |
264 return index ? 0xffffffff : 0xff000000; | |
265 } | |
266 return index * 0x10101 | 0xff000000; | |
267 } | |
268 void CFX_DIBSource::SetPaletteEntry(int index, FX_DWORD color) | |
269 { | |
270 ASSERT((GetBPP() == 1 || GetBPP() == 8) && !IsAlphaMask()); | |
271 if (m_pPalette == NULL) { | |
272 BuildPalette(); | |
273 } | |
274 m_pPalette[index] = color; | |
275 } | |
276 int CFX_DIBSource::FindPalette(FX_DWORD color) const | |
277 { | |
278 ASSERT((GetBPP() == 1 || GetBPP() == 8) && !IsAlphaMask()); | |
279 if (m_pPalette == NULL) { | |
280 if (IsCmykImage()) { | |
281 if (GetBPP() == 1) { | |
282 return ((FX_BYTE)color == 0xff) ? 0 : 1; | |
283 } | |
284 return 0xff - (FX_BYTE)color; | |
285 } | |
286 if (GetBPP() == 1) { | |
287 return ((FX_BYTE)color == 0xff) ? 1 : 0; | |
288 } | |
289 return (FX_BYTE)color; | |
290 } | |
291 int palsize = (1 << GetBPP()); | |
292 for (int i = 0; i < palsize; i ++) | |
293 if (m_pPalette[i] == color) { | |
294 return i; | |
295 } | |
296 return -1; | |
297 } | |
298 void CFX_DIBitmap::Clear(FX_DWORD color) | |
299 { | |
300 if (m_pBuffer == NULL) { | |
301 return; | |
302 } | |
303 switch (GetFormat()) { | |
304 case FXDIB_1bppMask: | |
305 FXSYS_memset8(m_pBuffer, (color & 0xff000000) ? 0xff : 0, m_Pitch *
m_Height); | |
306 break; | |
307 case FXDIB_1bppRgb: { | |
308 int index = FindPalette(color); | |
309 FXSYS_memset8(m_pBuffer, index ? 0xff : 0, m_Pitch * m_Height); | |
310 break; | |
311 } | |
312 case FXDIB_8bppMask: | |
313 FXSYS_memset8(m_pBuffer, color >> 24, m_Pitch * m_Height); | |
314 break; | |
315 case FXDIB_8bppRgb: { | |
316 int index = FindPalette(color); | |
317 FXSYS_memset8(m_pBuffer, index, m_Pitch * m_Height); | |
318 break; | |
319 } | |
320 case FXDIB_Rgb: | |
321 case FXDIB_Rgba: { | |
322 int a, r, g, b; | |
323 ArgbDecode(color, a, r, g, b); | |
324 if (r == g && g == b) { | |
325 FXSYS_memset8(m_pBuffer, r, m_Pitch * m_Height); | |
326 } else { | |
327 int byte_pos = 0; | |
328 for (int col = 0; col < m_Width; col ++) { | |
329 m_pBuffer[byte_pos++] = b; | |
330 m_pBuffer[byte_pos++] = g; | |
331 m_pBuffer[byte_pos++] = r; | |
332 } | |
333 for (int row = 1; row < m_Height; row ++) { | |
334 FXSYS_memcpy32(m_pBuffer + row * m_Pitch, m_pBuffer, m_P
itch); | |
335 } | |
336 } | |
337 break; | |
338 } | |
339 case FXDIB_Rgb32: | |
340 case FXDIB_Argb: { | |
341 color = IsCmykImage() ? FXCMYK_TODIB(color) : FXARGB_TODIB(color
); | |
342 for (int i = 0; i < m_Width; i ++) { | |
343 ((FX_DWORD*)m_pBuffer)[i] = color; | |
344 } | |
345 for (int row = 1; row < m_Height; row ++) { | |
346 FXSYS_memcpy32(m_pBuffer + row * m_Pitch, m_pBuffer, m_Pitch
); | |
347 } | |
348 break; | |
349 } | |
350 default: | |
351 break; | |
352 } | |
353 } | |
354 void CFX_DIBSource::GetOverlapRect(int& dest_left, int& dest_top, int& width, in
t& height, | |
355 int src_width, int src_height, int& src_left,
int& src_top, | |
356 const CFX_ClipRgn* pClipRgn) | |
357 { | |
358 if (width == 0 || height == 0) { | |
359 return; | |
360 } | |
361 ASSERT(width > 0 && height > 0); | |
362 if (dest_left > m_Width || dest_top > m_Height) { | |
363 width = 0; | |
364 height = 0; | |
365 return; | |
366 } | |
367 int x_offset = dest_left - src_left; | |
368 int y_offset = dest_top - src_top; | |
369 FX_RECT src_rect(src_left, src_top, src_left + width, src_top + height); | |
370 FX_RECT src_bound(0, 0, src_width, src_height); | |
371 src_rect.Intersect(src_bound); | |
372 FX_RECT dest_rect(src_rect.left + x_offset, src_rect.top + y_offset, | |
373 src_rect.right + x_offset, src_rect.bottom + y_offset); | |
374 FX_RECT dest_bound(0, 0, m_Width, m_Height); | |
375 dest_rect.Intersect(dest_bound); | |
376 if (pClipRgn) { | |
377 dest_rect.Intersect(pClipRgn->GetBox()); | |
378 } | |
379 dest_left = dest_rect.left; | |
380 dest_top = dest_rect.top; | |
381 src_left = dest_left - x_offset; | |
382 src_top = dest_top - y_offset; | |
383 width = dest_rect.right - dest_rect.left; | |
384 height = dest_rect.bottom - dest_rect.top; | |
385 } | |
386 FX_BOOL CFX_DIBitmap::TransferBitmap(int dest_left, int dest_top, int width, int
height, | |
387 const CFX_DIBSource* pSrcBitmap, int src_le
ft, int src_top, void* pIccTransform) | |
388 { | |
389 if (m_pBuffer == NULL) { | |
390 return FALSE; | |
391 } | |
392 GetOverlapRect(dest_left, dest_top, width, height, pSrcBitmap->GetWidth(), p
SrcBitmap->GetHeight(), src_left, src_top, NULL); | |
393 if (width == 0 || height == 0) { | |
394 return TRUE; | |
395 } | |
396 FXDIB_Format dest_format = GetFormat(); | |
397 FXDIB_Format src_format = pSrcBitmap->GetFormat(); | |
398 if (dest_format == src_format && pIccTransform == NULL) { | |
399 if (GetBPP() == 1) { | |
400 for (int row = 0; row < height; row ++) { | |
401 FX_LPBYTE dest_scan = m_pBuffer + (dest_top + row) * m_Pitch; | |
402 FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row); | |
403 for (int col = 0; col < width; col ++) { | |
404 if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left +
col) % 8))) { | |
405 dest_scan[(dest_left + col) / 8] |= 1 << (7 - (dest_left
+ col) % 8); | |
406 } else { | |
407 dest_scan[(dest_left + col) / 8] &= ~(1 << (7 - (dest_le
ft + col) % 8)); | |
408 } | |
409 } | |
410 } | |
411 } else { | |
412 int Bpp = GetBPP() / 8; | |
413 for (int row = 0; row < height; row ++) { | |
414 FX_LPBYTE dest_scan = m_pBuffer + (dest_top + row) * m_Pitch + d
est_left * Bpp; | |
415 FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + s
rc_left * Bpp; | |
416 FXSYS_memcpy32(dest_scan, src_scan, width * Bpp); | |
417 } | |
418 } | |
419 } else { | |
420 if (m_pPalette) { | |
421 return FALSE; | |
422 } | |
423 if (m_bpp == 8) { | |
424 dest_format = FXDIB_8bppMask; | |
425 } | |
426 FX_LPBYTE dest_buf = m_pBuffer + dest_top * m_Pitch + dest_left * GetBPP
() / 8; | |
427 FX_DWORD* d_plt = NULL; | |
428 if(!ConvertBuffer(dest_format, dest_buf, m_Pitch, width, height, pSrcBit
map, src_left, src_top, d_plt, pIccTransform)) { | |
429 return FALSE; | |
430 } | |
431 } | |
432 return TRUE; | |
433 } | |
434 #ifndef _FPDFAPI_MINI_ | |
435 FX_BOOL CFX_DIBitmap::TransferMask(int dest_left, int dest_top, int width, int h
eight, | |
436 const CFX_DIBSource* pMask, FX_DWORD color, i
nt src_left, int src_top, int alpha_flag, void* pIccTransform) | |
437 { | |
438 if (m_pBuffer == NULL) { | |
439 return FALSE; | |
440 } | |
441 ASSERT(HasAlpha() && (m_bpp >= 24)); | |
442 ASSERT(pMask->IsAlphaMask()); | |
443 if (!HasAlpha() || !pMask->IsAlphaMask() || m_bpp < 24) { | |
444 return FALSE; | |
445 } | |
446 GetOverlapRect(dest_left, dest_top, width, height, pMask->GetWidth(), pMask-
>GetHeight(), src_left, src_top, NULL); | |
447 if (width == 0 || height == 0) { | |
448 return TRUE; | |
449 } | |
450 int src_bpp = pMask->GetBPP(); | |
451 int alpha; | |
452 FX_DWORD dst_color; | |
453 if (alpha_flag >> 8) { | |
454 alpha = alpha_flag & 0xff; | |
455 dst_color = FXCMYK_TODIB(color); | |
456 } else { | |
457 alpha = FXARGB_A(color); | |
458 dst_color = FXARGB_TODIB(color); | |
459 } | |
460 FX_LPBYTE color_p = (FX_LPBYTE)&dst_color; | |
461 if (pIccTransform && CFX_GEModule::Get()->GetCodecModule() && CFX_GEModule::
Get()->GetCodecModule()->GetIccModule()) { | |
462 ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->Ge
tIccModule(); | |
463 pIccModule->TranslateScanline(pIccTransform, color_p, color_p, 1); | |
464 } else { | |
465 if (alpha_flag >> 8 && !IsCmykImage()) | |
466 AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color), F
XSYS_GetYValue(color), FXSYS_GetKValue(color), | |
467 color_p[2], color_p[1], color_p[0]); | |
468 else if (!(alpha_flag >> 8) && IsCmykImage()) { | |
469 return FALSE; | |
470 } | |
471 } | |
472 if(!IsCmykImage()) { | |
473 color_p[3] = (FX_BYTE)alpha; | |
474 } | |
475 if (GetFormat() == FXDIB_Argb) { | |
476 for (int row = 0; row < height; row ++) { | |
477 FX_DWORD* dest_pos = (FX_DWORD*)(m_pBuffer + (dest_top + row) * m_Pi
tch + dest_left * 4); | |
478 FX_LPCBYTE src_scan = pMask->GetScanline(src_top + row); | |
479 if (src_bpp == 1) { | |
480 for (int col = 0; col < width; col ++) { | |
481 int src_bitpos = src_left + col; | |
482 if (src_scan[src_bitpos / 8] & (1 << (7 - src_bitpos % 8)))
{ | |
483 *dest_pos = dst_color; | |
484 } else { | |
485 *dest_pos = 0; | |
486 } | |
487 dest_pos ++; | |
488 } | |
489 } else { | |
490 src_scan += src_left; | |
491 dst_color = FXARGB_TODIB(dst_color); | |
492 dst_color &= 0xffffff; | |
493 for (int col = 0; col < width; col ++) { | |
494 FXARGB_SETDIB(dest_pos++, dst_color | ((alpha * (*src_scan++
) / 255) << 24)); | |
495 } | |
496 } | |
497 } | |
498 } else { | |
499 int comps = m_bpp / 8; | |
500 for (int row = 0; row < height; row ++) { | |
501 FX_LPBYTE dest_color_pos = m_pBuffer + (dest_top + row) * m_Pitch +
dest_left * comps; | |
502 FX_LPBYTE dest_alpha_pos = (FX_LPBYTE)m_pAlphaMask->GetScanline(dest
_top + row) + dest_left; | |
503 FX_LPCBYTE src_scan = pMask->GetScanline(src_top + row); | |
504 if (src_bpp == 1) { | |
505 for (int col = 0; col < width; col ++) { | |
506 int src_bitpos = src_left + col; | |
507 if (src_scan[src_bitpos / 8] & (1 << (7 - src_bitpos % 8)))
{ | |
508 FXSYS_memcpy32(dest_color_pos, color_p, comps); | |
509 *dest_alpha_pos = 0xff; | |
510 } else { | |
511 FXSYS_memset32(dest_color_pos, 0, comps); | |
512 *dest_alpha_pos = 0; | |
513 } | |
514 dest_color_pos += comps; | |
515 dest_alpha_pos ++; | |
516 } | |
517 } else { | |
518 src_scan += src_left; | |
519 for (int col = 0; col < width; col ++) { | |
520 FXSYS_memcpy32(dest_color_pos, color_p, comps); | |
521 dest_color_pos += comps; | |
522 *dest_alpha_pos++ = (alpha * (*src_scan++) / 255); | |
523 } | |
524 } | |
525 } | |
526 } | |
527 return TRUE; | |
528 } | |
529 #endif | |
530 void CFX_DIBSource::CopyPalette(const FX_DWORD* pSrc, FX_DWORD size) | |
531 { | |
532 if (pSrc == NULL || GetBPP() > 8) { | |
533 if (m_pPalette) { | |
534 FX_Free(m_pPalette); | |
535 } | |
536 m_pPalette = NULL; | |
537 } else { | |
538 FX_DWORD pal_size = 1 << GetBPP(); | |
539 if (m_pPalette == NULL) { | |
540 m_pPalette = FX_Alloc(FX_DWORD, pal_size); | |
541 } | |
542 if (!m_pPalette) { | |
543 return; | |
544 } | |
545 if (pal_size > size) { | |
546 pal_size = size; | |
547 } | |
548 FXSYS_memcpy32(m_pPalette, pSrc, pal_size * sizeof(FX_DWORD)); | |
549 } | |
550 } | |
551 void CFX_DIBSource::GetPalette(FX_DWORD* pal, int alpha) const | |
552 { | |
553 ASSERT(GetBPP() <= 8 && !IsCmykImage()); | |
554 if (GetBPP() == 1) { | |
555 pal[0] = ((m_pPalette ? m_pPalette[0] : 0xff000000) & 0xffffff) | (alpha
<< 24); | |
556 pal[1] = ((m_pPalette ? m_pPalette[1] : 0xffffffff) & 0xffffff) | (alpha
<< 24); | |
557 return; | |
558 } | |
559 if (m_pPalette) { | |
560 for (int i = 0; i < 256; i ++) { | |
561 pal[i] = (m_pPalette[i] & 0x00ffffff) | (alpha << 24); | |
562 } | |
563 } else { | |
564 for (int i = 0; i < 256; i ++) { | |
565 pal[i] = (i * 0x10101) | (alpha << 24); | |
566 } | |
567 } | |
568 } | |
569 CFX_DIBitmap* CFX_DIBSource::GetAlphaMask(const FX_RECT* pClip) const | |
570 { | |
571 ASSERT(GetFormat() == FXDIB_Argb); | |
572 FX_RECT rect(0, 0, m_Width, m_Height); | |
573 if (pClip) { | |
574 rect.Intersect(*pClip); | |
575 if (rect.IsEmpty()) { | |
576 return NULL; | |
577 } | |
578 } | |
579 CFX_DIBitmap* pMask = FX_NEW CFX_DIBitmap; | |
580 if (!pMask) { | |
581 return NULL; | |
582 } | |
583 if (!pMask->Create(rect.Width(), rect.Height(), FXDIB_8bppMask)) { | |
584 delete pMask; | |
585 return NULL; | |
586 } | |
587 for (int row = rect.top; row < rect.bottom; row ++) { | |
588 FX_LPCBYTE src_scan = GetScanline(row) + rect.left * 4 + 3; | |
589 FX_LPBYTE dest_scan = (FX_LPBYTE)pMask->GetScanline(row - rect.top); | |
590 for (int col = rect.left; col < rect.right; col ++) { | |
591 *dest_scan ++ = *src_scan; | |
592 src_scan += 4; | |
593 } | |
594 } | |
595 return pMask; | |
596 } | |
597 FX_BOOL CFX_DIBSource::CopyAlphaMask(const CFX_DIBSource* pAlphaMask, const FX_R
ECT* pClip) | |
598 { | |
599 if (!HasAlpha() || GetFormat() == FXDIB_Argb) { | |
600 return FALSE; | |
601 } | |
602 if (pAlphaMask) { | |
603 FX_RECT rect(0, 0, pAlphaMask->m_Width, pAlphaMask->m_Height); | |
604 if (pClip) { | |
605 rect.Intersect(*pClip); | |
606 if (rect.IsEmpty() || rect.Width() != m_Width || rect.Height() != m_
Height) { | |
607 return FALSE; | |
608 } | |
609 } else { | |
610 if (pAlphaMask->m_Width != m_Width || pAlphaMask->m_Height != m_Heig
ht) { | |
611 return FALSE; | |
612 } | |
613 } | |
614 for (int row = 0; row < m_Height; row ++) | |
615 FXSYS_memcpy32((void*)m_pAlphaMask->GetScanline(row), | |
616 pAlphaMask->GetScanline(row + rect.top) + rect.left,
m_pAlphaMask->m_Pitch); | |
617 } else { | |
618 m_pAlphaMask->Clear(0xff000000); | |
619 } | |
620 return TRUE; | |
621 } | |
622 const int g_ChannelOffset[] = {0, 2, 1, 0, 0, 1, 2, 3, 3}; | |
623 FX_BOOL CFX_DIBitmap::LoadChannel(FXDIB_Channel destChannel, const CFX_DIBSource
* pSrcBitmap, FXDIB_Channel srcChannel) | |
624 { | |
625 if (m_pBuffer == NULL) { | |
626 return FALSE; | |
627 } | |
628 CFX_DIBSource* pSrcClone = (CFX_DIBSource*)pSrcBitmap; | |
629 CFX_DIBitmap* pDst = this; | |
630 int destOffset, srcOffset; | |
631 if (srcChannel == FXDIB_Alpha) { | |
632 if (!pSrcBitmap->HasAlpha() && !pSrcBitmap->IsAlphaMask()) { | |
633 return FALSE; | |
634 } | |
635 if (pSrcBitmap->GetBPP() == 1) { | |
636 pSrcClone = pSrcBitmap->CloneConvert(FXDIB_8bppMask); | |
637 if (pSrcClone == NULL) { | |
638 return FALSE; | |
639 } | |
640 } | |
641 if(pSrcBitmap->GetFormat() == FXDIB_Argb) { | |
642 srcOffset = 3; | |
643 } else { | |
644 srcOffset = 0; | |
645 } | |
646 } else { | |
647 if (pSrcBitmap->IsAlphaMask()) { | |
648 return FALSE; | |
649 } | |
650 if (pSrcBitmap->GetBPP() < 24) { | |
651 if (pSrcBitmap->IsCmykImage()) { | |
652 pSrcClone = pSrcBitmap->CloneConvert((FXDIB_Format)((pSrcBitmap-
>GetFormat() & 0xff00) | 0x20)); | |
653 } else { | |
654 pSrcClone = pSrcBitmap->CloneConvert((FXDIB_Format)((pSrcBitmap-
>GetFormat() & 0xff00) | 0x18)); | |
655 } | |
656 if (pSrcClone == NULL) { | |
657 return FALSE; | |
658 } | |
659 } | |
660 srcOffset = g_ChannelOffset[srcChannel]; | |
661 } | |
662 if (destChannel == FXDIB_Alpha) { | |
663 if (IsAlphaMask()) { | |
664 if(!ConvertFormat(FXDIB_8bppMask)) { | |
665 if (pSrcClone != pSrcBitmap) { | |
666 delete pSrcClone; | |
667 } | |
668 return FALSE; | |
669 } | |
670 destOffset = 0; | |
671 } else { | |
672 destOffset = 0; | |
673 if(!ConvertFormat(IsCmykImage() ? FXDIB_Cmyka : FXDIB_Argb)) { | |
674 if (pSrcClone != pSrcBitmap) { | |
675 delete pSrcClone; | |
676 } | |
677 return FALSE; | |
678 } | |
679 if (GetFormat() == FXDIB_Argb) { | |
680 destOffset = 3; | |
681 } | |
682 } | |
683 } else { | |
684 if (IsAlphaMask()) { | |
685 if (pSrcClone != pSrcBitmap) { | |
686 delete pSrcClone; | |
687 } | |
688 return FALSE; | |
689 } | |
690 if (GetBPP() < 24) { | |
691 if (HasAlpha()) { | |
692 if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyka : FXDIB_Argb)) { | |
693 if (pSrcClone != pSrcBitmap) { | |
694 delete pSrcClone; | |
695 } | |
696 return FALSE; | |
697 } | |
698 } else | |
699 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ | |
700 if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyk : FXDIB_Rgb32)) { | |
701 #else | |
702 if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyk : FXDIB_Rgb)) { | |
703 #endif | |
704 if (pSrcClone != pSrcBitmap) { | |
705 delete pSrcClone; | |
706 } | |
707 return FALSE; | |
708 } | |
709 } | |
710 destOffset = g_ChannelOffset[destChannel]; | |
711 } | |
712 if (srcChannel == FXDIB_Alpha && pSrcClone->m_pAlphaMask) { | |
713 CFX_DIBitmap* pAlphaMask = pSrcClone->m_pAlphaMask; | |
714 if (pSrcClone->GetWidth() != m_Width || pSrcClone->GetHeight() != m_Heig
ht) { | |
715 if (pAlphaMask) { | |
716 pAlphaMask = pAlphaMask->StretchTo(m_Width, m_Height); | |
717 if (pAlphaMask == NULL) { | |
718 if (pSrcClone != pSrcBitmap) { | |
719 delete pSrcClone; | |
720 } | |
721 return FALSE; | |
722 } | |
723 } | |
724 } | |
725 if (pSrcClone != pSrcBitmap) { | |
726 pSrcClone->m_pAlphaMask = NULL; | |
727 delete pSrcClone; | |
728 } | |
729 pSrcClone = pAlphaMask; | |
730 srcOffset = 0; | |
731 } else if (pSrcClone->GetWidth() != m_Width || pSrcClone->GetHeight() != m_H
eight) { | |
732 CFX_DIBitmap* pSrcMatched = pSrcClone->StretchTo(m_Width, m_Height); | |
733 if (pSrcClone != pSrcBitmap) { | |
734 delete pSrcClone; | |
735 } | |
736 if (pSrcMatched == NULL) { | |
737 return FALSE; | |
738 } | |
739 pSrcClone = pSrcMatched; | |
740 } | |
741 if (destChannel == FXDIB_Alpha && m_pAlphaMask) { | |
742 pDst = m_pAlphaMask; | |
743 destOffset = 0; | |
744 } | |
745 int srcBytes = pSrcClone->GetBPP() / 8; | |
746 int destBytes = pDst->GetBPP() / 8; | |
747 for (int row = 0; row < m_Height; row ++) { | |
748 FX_LPBYTE dest_pos = (FX_LPBYTE)pDst->GetScanline(row) + destOffset; | |
749 FX_LPCBYTE src_pos = pSrcClone->GetScanline(row) + srcOffset; | |
750 for (int col = 0; col < m_Width; col ++) { | |
751 *dest_pos = *src_pos; | |
752 dest_pos += destBytes; | |
753 src_pos += srcBytes; | |
754 } | |
755 } | |
756 if (pSrcClone != pSrcBitmap && pSrcClone != pSrcBitmap->m_pAlphaMask) { | |
757 delete pSrcClone; | |
758 } | |
759 return TRUE; | |
760 } | |
761 FX_BOOL CFX_DIBitmap::LoadChannel(FXDIB_Channel destChannel, int value) | |
762 { | |
763 if (m_pBuffer == NULL) { | |
764 return FALSE; | |
765 } | |
766 int destOffset; | |
767 if (destChannel == FXDIB_Alpha) { | |
768 if (IsAlphaMask()) { | |
769 if(!ConvertFormat(FXDIB_8bppMask)) { | |
770 return FALSE; | |
771 } | |
772 destOffset = 0; | |
773 } else { | |
774 destOffset = 0; | |
775 if(!ConvertFormat(IsCmykImage() ? FXDIB_Cmyka : FXDIB_Argb)) { | |
776 return FALSE; | |
777 } | |
778 if (GetFormat() == FXDIB_Argb) { | |
779 destOffset = 3; | |
780 } | |
781 } | |
782 } else { | |
783 if (IsAlphaMask()) { | |
784 return FALSE; | |
785 } | |
786 if (GetBPP() < 24) { | |
787 if (HasAlpha()) { | |
788 if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyka : FXDIB_Argb)) { | |
789 return FALSE; | |
790 } | |
791 } else | |
792 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ | |
793 if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyk : FXDIB_Rgb)) { | |
794 return FALSE; | |
795 } | |
796 #else | |
797 if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyk : FXDIB_Rgb32)) { | |
798 return FALSE; | |
799 } | |
800 #endif | |
801 } | |
802 destOffset = g_ChannelOffset[destChannel]; | |
803 } | |
804 int Bpp = GetBPP() / 8; | |
805 if (Bpp == 1) { | |
806 FXSYS_memset8(m_pBuffer, value, m_Height * m_Pitch); | |
807 return TRUE; | |
808 } | |
809 if (destChannel == FXDIB_Alpha && m_pAlphaMask) { | |
810 FXSYS_memset8(m_pAlphaMask->GetBuffer(), value, m_pAlphaMask->GetHeight(
)*m_pAlphaMask->GetPitch()); | |
811 return TRUE; | |
812 } | |
813 for (int row = 0; row < m_Height; row ++) { | |
814 FX_LPBYTE scan_line = m_pBuffer + row * m_Pitch + destOffset; | |
815 for (int col = 0; col < m_Width; col ++) { | |
816 *scan_line = value; | |
817 scan_line += Bpp; | |
818 } | |
819 } | |
820 return TRUE; | |
821 } | |
822 FX_BOOL CFX_DIBitmap::MultiplyAlpha(const CFX_DIBSource* pSrcBitmap) | |
823 { | |
824 if (m_pBuffer == NULL) { | |
825 return FALSE; | |
826 } | |
827 ASSERT(pSrcBitmap->IsAlphaMask()); | |
828 if (!pSrcBitmap->IsAlphaMask()) { | |
829 return FALSE; | |
830 } | |
831 if (!IsAlphaMask() && !HasAlpha()) { | |
832 return LoadChannel(FXDIB_Alpha, pSrcBitmap, FXDIB_Alpha); | |
833 } | |
834 CFX_DIBitmap* pSrcClone = (CFX_DIBitmap*)pSrcBitmap; | |
835 if (pSrcBitmap->GetWidth() != m_Width || pSrcBitmap->GetHeight() != m_Height
) { | |
836 pSrcClone = pSrcBitmap->StretchTo(m_Width, m_Height); | |
837 ASSERT(pSrcClone != NULL); | |
838 if (pSrcClone == NULL) { | |
839 return FALSE; | |
840 } | |
841 } | |
842 if (IsAlphaMask()) { | |
843 if(!ConvertFormat(FXDIB_8bppMask)) { | |
844 if (pSrcClone != pSrcBitmap) { | |
845 delete pSrcClone; | |
846 } | |
847 return FALSE; | |
848 } | |
849 for (int row = 0; row < m_Height; row ++) { | |
850 FX_LPBYTE dest_scan = m_pBuffer + m_Pitch * row; | |
851 FX_LPBYTE src_scan = pSrcClone->m_pBuffer + pSrcClone->m_Pitch * row
; | |
852 if (pSrcClone->GetBPP() == 1) { | |
853 for (int col = 0; col < m_Width; col ++) { | |
854 if (!((1 << (7 - col % 8)) & src_scan[col / 8])) { | |
855 dest_scan[col] = 0; | |
856 } | |
857 } | |
858 } else { | |
859 for (int col = 0; col < m_Width; col ++) { | |
860 *dest_scan = (*dest_scan) * src_scan[col] / 255; | |
861 dest_scan ++; | |
862 } | |
863 } | |
864 } | |
865 } else { | |
866 if(GetFormat() == FXDIB_Argb) { | |
867 if (pSrcClone->GetBPP() == 1) { | |
868 if (pSrcClone != pSrcBitmap) { | |
869 delete pSrcClone; | |
870 } | |
871 return FALSE; | |
872 } | |
873 for (int row = 0; row < m_Height; row ++) { | |
874 FX_LPBYTE dest_scan = m_pBuffer + m_Pitch * row + 3; | |
875 FX_LPBYTE src_scan = pSrcClone->m_pBuffer + pSrcClone->m_Pitch *
row; | |
876 for (int col = 0; col < m_Width; col ++) { | |
877 *dest_scan = (*dest_scan) * src_scan[col] / 255; | |
878 dest_scan += 4; | |
879 } | |
880 } | |
881 } else { | |
882 m_pAlphaMask->MultiplyAlpha(pSrcClone); | |
883 } | |
884 } | |
885 if (pSrcClone != pSrcBitmap) { | |
886 delete pSrcClone; | |
887 } | |
888 return TRUE; | |
889 } | |
890 FX_BOOL CFX_DIBitmap::GetGrayData(void* pIccTransform) | |
891 { | |
892 if (m_pBuffer == NULL) { | |
893 return FALSE; | |
894 } | |
895 switch (GetFormat()) { | |
896 case FXDIB_1bppRgb: { | |
897 if (m_pPalette == NULL) { | |
898 return FALSE; | |
899 } | |
900 FX_BYTE gray[2]; | |
901 for (int i = 0; i < 2; i ++) { | |
902 int r = (FX_BYTE)(m_pPalette[i] >> 16); | |
903 int g = (FX_BYTE)(m_pPalette[i] >> 8); | |
904 int b = (FX_BYTE)m_pPalette[i]; | |
905 gray[i] = (FX_BYTE)FXRGB2GRAY(r, g, b); | |
906 } | |
907 CFX_DIBitmap* pMask = FX_NEW CFX_DIBitmap; | |
908 if (!pMask) { | |
909 return FALSE; | |
910 } | |
911 if (!pMask->Create(m_Width, m_Height, FXDIB_8bppMask)) { | |
912 delete pMask; | |
913 return FALSE; | |
914 } | |
915 FXSYS_memset8(pMask->GetBuffer(), gray[0], pMask->GetPitch() * m
_Height); | |
916 for (int row = 0; row < m_Height; row ++) { | |
917 FX_LPBYTE src_pos = m_pBuffer + row * m_Pitch; | |
918 FX_LPBYTE dest_pos = (FX_LPBYTE)pMask->GetScanline(row); | |
919 for (int col = 0; col < m_Width; col ++) { | |
920 if (src_pos[col / 8] & (1 << (7 - col % 8))) { | |
921 *dest_pos = gray[1]; | |
922 } | |
923 dest_pos ++; | |
924 } | |
925 } | |
926 TakeOver(pMask); | |
927 delete pMask; | |
928 break; | |
929 } | |
930 case FXDIB_8bppRgb: { | |
931 if (m_pPalette == NULL) { | |
932 return FALSE; | |
933 } | |
934 FX_BYTE gray[256]; | |
935 for (int i = 0; i < 256; i ++) { | |
936 int r = (FX_BYTE)(m_pPalette[i] >> 16); | |
937 int g = (FX_BYTE)(m_pPalette[i] >> 8); | |
938 int b = (FX_BYTE)m_pPalette[i]; | |
939 gray[i] = (FX_BYTE)FXRGB2GRAY(r, g, b); | |
940 } | |
941 CFX_DIBitmap* pMask = FX_NEW CFX_DIBitmap; | |
942 if (!pMask) { | |
943 return FALSE; | |
944 } | |
945 if (!pMask->Create(m_Width, m_Height, FXDIB_8bppMask)) { | |
946 delete pMask; | |
947 return FALSE; | |
948 } | |
949 for (int row = 0; row < m_Height; row ++) { | |
950 FX_LPBYTE dest_pos = pMask->GetBuffer() + row * pMask->GetPi
tch(); | |
951 FX_LPBYTE src_pos = m_pBuffer + row * m_Pitch; | |
952 for (int col = 0; col < m_Width; col ++) { | |
953 *dest_pos ++ = gray[*src_pos ++]; | |
954 } | |
955 } | |
956 TakeOver(pMask); | |
957 delete pMask; | |
958 break; | |
959 } | |
960 case FXDIB_Rgb: { | |
961 CFX_DIBitmap* pMask = FX_NEW CFX_DIBitmap; | |
962 if (!pMask) { | |
963 return FALSE; | |
964 } | |
965 if (!pMask->Create(m_Width, m_Height, FXDIB_8bppMask)) { | |
966 delete pMask; | |
967 return FALSE; | |
968 } | |
969 for (int row = 0; row < m_Height; row ++) { | |
970 FX_LPBYTE src_pos = m_pBuffer + row * m_Pitch; | |
971 FX_LPBYTE dest_pos = pMask->GetBuffer() + row * pMask->GetPi
tch(); | |
972 for (int col = 0; col < m_Width; col ++) { | |
973 *dest_pos ++ = FXRGB2GRAY(src_pos[2], src_pos[1], *src_p
os); | |
974 src_pos += 3; | |
975 } | |
976 } | |
977 TakeOver(pMask); | |
978 delete pMask; | |
979 break; | |
980 } | |
981 case FXDIB_Rgb32: { | |
982 CFX_DIBitmap* pMask = FX_NEW CFX_DIBitmap; | |
983 if (!pMask) { | |
984 return FALSE; | |
985 } | |
986 if (!pMask->Create(m_Width, m_Height, FXDIB_8bppMask)) { | |
987 delete pMask; | |
988 return FALSE; | |
989 } | |
990 for (int row = 0; row < m_Height; row ++) { | |
991 FX_LPBYTE src_pos = m_pBuffer + row * m_Pitch; | |
992 FX_LPBYTE dest_pos = pMask->GetBuffer() + row * pMask->GetPi
tch(); | |
993 for (int col = 0; col < m_Width; col ++) { | |
994 *dest_pos ++ = FXRGB2GRAY(src_pos[2], src_pos[1], *src_p
os); | |
995 src_pos += 4; | |
996 } | |
997 } | |
998 TakeOver(pMask); | |
999 delete pMask; | |
1000 break; | |
1001 } | |
1002 default: | |
1003 return FALSE; | |
1004 } | |
1005 return TRUE; | |
1006 } | |
1007 FX_BOOL CFX_DIBitmap::MultiplyAlpha(int alpha) | |
1008 { | |
1009 if (m_pBuffer == NULL) { | |
1010 return FALSE; | |
1011 } | |
1012 switch (GetFormat()) { | |
1013 case FXDIB_1bppMask: | |
1014 if (!ConvertFormat(FXDIB_8bppMask)) { | |
1015 return FALSE; | |
1016 } | |
1017 MultiplyAlpha(alpha); | |
1018 break; | |
1019 case FXDIB_8bppMask: { | |
1020 for (int row = 0; row < m_Height; row ++) { | |
1021 FX_LPBYTE scan_line = m_pBuffer + row * m_Pitch; | |
1022 for (int col = 0; col < m_Width; col ++) { | |
1023 scan_line[col] = scan_line[col] * alpha / 255; | |
1024 } | |
1025 } | |
1026 break; | |
1027 } | |
1028 case FXDIB_Argb: { | |
1029 for (int row = 0; row < m_Height; row ++) { | |
1030 FX_LPBYTE scan_line = m_pBuffer + row * m_Pitch + 3; | |
1031 for (int col = 0; col < m_Width; col ++) { | |
1032 *scan_line = (*scan_line) * alpha / 255; | |
1033 scan_line += 4; | |
1034 } | |
1035 } | |
1036 break; | |
1037 } | |
1038 default: | |
1039 if (HasAlpha()) { | |
1040 m_pAlphaMask->MultiplyAlpha(alpha); | |
1041 } else if (IsCmykImage()) { | |
1042 if (!ConvertFormat((FXDIB_Format)(GetFormat() | 0x0200))) { | |
1043 return FALSE; | |
1044 } | |
1045 m_pAlphaMask->MultiplyAlpha(alpha); | |
1046 } else { | |
1047 if (!ConvertFormat(FXDIB_Argb)) { | |
1048 return FALSE; | |
1049 } | |
1050 MultiplyAlpha(alpha); | |
1051 } | |
1052 break; | |
1053 } | |
1054 return TRUE; | |
1055 } | |
1056 #if !defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_) | |
1057 FX_DWORD CFX_DIBitmap::GetPixel(int x, int y) const | |
1058 { | |
1059 if (m_pBuffer == NULL) { | |
1060 return 0; | |
1061 } | |
1062 FX_LPBYTE pos = m_pBuffer + y * m_Pitch + x * GetBPP() / 8; | |
1063 switch (GetFormat()) { | |
1064 case FXDIB_1bppMask: { | |
1065 if ((*pos) & (1 << (7 - x % 8))) { | |
1066 return 0xff000000; | |
1067 } | |
1068 return 0; | |
1069 } | |
1070 case FXDIB_1bppRgb: { | |
1071 if ((*pos) & (1 << (7 - x % 8))) { | |
1072 return m_pPalette ? m_pPalette[1] : 0xffffffff; | |
1073 } else { | |
1074 return m_pPalette ? m_pPalette[0] : 0xff000000; | |
1075 } | |
1076 break; | |
1077 } | |
1078 case FXDIB_8bppMask: | |
1079 return (*pos) << 24; | |
1080 case FXDIB_8bppRgb: | |
1081 return m_pPalette ? m_pPalette[*pos] : (0xff000000 | ((*pos) * 0x101
01)); | |
1082 case FXDIB_Rgb: | |
1083 case FXDIB_Rgba: | |
1084 case FXDIB_Rgb32: | |
1085 return FXARGB_GETDIB(pos) | 0xff000000; | |
1086 case FXDIB_Argb: | |
1087 return FXARGB_GETDIB(pos); | |
1088 default: | |
1089 break; | |
1090 } | |
1091 return 0; | |
1092 } | |
1093 #endif | |
1094 void CFX_DIBitmap::SetPixel(int x, int y, FX_DWORD color) | |
1095 { | |
1096 if (m_pBuffer == NULL) { | |
1097 return; | |
1098 } | |
1099 if (x < 0 || x >= m_Width || y < 0 || y >= m_Height) { | |
1100 return; | |
1101 } | |
1102 FX_LPBYTE pos = m_pBuffer + y * m_Pitch + x * GetBPP() / 8; | |
1103 switch (GetFormat()) { | |
1104 case FXDIB_1bppMask: | |
1105 if (color >> 24) { | |
1106 *pos |= 1 << (7 - x % 8); | |
1107 } else { | |
1108 *pos &= ~(1 << (7 - x % 8)); | |
1109 } | |
1110 break; | |
1111 case FXDIB_1bppRgb: | |
1112 if (m_pPalette) { | |
1113 if (color == m_pPalette[1]) { | |
1114 *pos |= 1 << (7 - x % 8); | |
1115 } else { | |
1116 *pos &= ~(1 << (7 - x % 8)); | |
1117 } | |
1118 } else { | |
1119 if (color == 0xffffffff) { | |
1120 *pos |= 1 << (7 - x % 8); | |
1121 } else { | |
1122 *pos &= ~(1 << (7 - x % 8)); | |
1123 } | |
1124 } | |
1125 break; | |
1126 case FXDIB_8bppMask: | |
1127 *pos = (FX_BYTE)(color >> 24); | |
1128 break; | |
1129 case FXDIB_8bppRgb: { | |
1130 if (m_pPalette) { | |
1131 for (int i = 0; i < 256; i ++) { | |
1132 if (m_pPalette[i] == color) { | |
1133 *pos = (FX_BYTE)i; | |
1134 return; | |
1135 } | |
1136 } | |
1137 *pos = 0; | |
1138 } else { | |
1139 *pos = FXRGB2GRAY(FXARGB_R(color), FXARGB_G(color), FXARGB_B
(color)); | |
1140 } | |
1141 break; | |
1142 } | |
1143 case FXDIB_Rgb: | |
1144 case FXDIB_Rgb32: { | |
1145 int alpha = FXARGB_A(color); | |
1146 pos[0] = (FXARGB_B(color) * alpha + pos[0] * (255 - alpha)) / 25
5; | |
1147 pos[1] = (FXARGB_G(color) * alpha + pos[1] * (255 - alpha)) / 25
5; | |
1148 pos[2] = (FXARGB_R(color) * alpha + pos[2] * (255 - alpha)) / 25
5; | |
1149 break; | |
1150 } | |
1151 case FXDIB_Rgba: { | |
1152 pos[0] = FXARGB_B(color); | |
1153 pos[1] = FXARGB_G(color); | |
1154 pos[2] = FXARGB_R(color); | |
1155 break; | |
1156 } | |
1157 case FXDIB_Argb: | |
1158 FXARGB_SETDIB(pos, color); | |
1159 break; | |
1160 default: | |
1161 break; | |
1162 } | |
1163 } | |
1164 void CFX_DIBitmap::DownSampleScanline(int line, FX_LPBYTE dest_scan, int dest_bp
p, | |
1165 int dest_width, FX_BOOL bFlipX, int clip_l
eft, int clip_width) const | |
1166 { | |
1167 if (m_pBuffer == NULL) { | |
1168 return; | |
1169 } | |
1170 int src_Bpp = m_bpp / 8; | |
1171 FX_LPBYTE scanline = m_pBuffer + line * m_Pitch; | |
1172 if (src_Bpp == 0) { | |
1173 for (int i = 0; i < clip_width; i ++) { | |
1174 FX_DWORD dest_x = clip_left + i; | |
1175 FX_DWORD src_x = dest_x * m_Width / dest_width; | |
1176 if (bFlipX) { | |
1177 src_x = m_Width - src_x - 1; | |
1178 } | |
1179 #ifdef FOXIT_CHROME_BUILD | |
1180 src_x %= m_Width; | |
1181 #endif | |
1182 dest_scan[i] = (scanline[src_x / 8] & (1 << (7 - src_x % 8))) ? 255
: 0; | |
1183 } | |
1184 } else if (src_Bpp == 1) { | |
1185 for (int i = 0; i < clip_width; i ++) { | |
1186 FX_DWORD dest_x = clip_left + i; | |
1187 FX_DWORD src_x = dest_x * m_Width / dest_width; | |
1188 if (bFlipX) { | |
1189 src_x = m_Width - src_x - 1; | |
1190 } | |
1191 #ifdef FOXIT_CHROME_BUILD | |
1192 src_x %= m_Width; | |
1193 #endif | |
1194 int dest_pos = i; | |
1195 if (m_pPalette) { | |
1196 if (!IsCmykImage()) { | |
1197 dest_pos *= 3; | |
1198 FX_ARGB argb = m_pPalette[scanline[src_x]]; | |
1199 dest_scan[dest_pos] = FXARGB_B(argb); | |
1200 dest_scan[dest_pos + 1] = FXARGB_G(argb); | |
1201 dest_scan[dest_pos + 2] = FXARGB_R(argb); | |
1202 } else { | |
1203 dest_pos *= 4; | |
1204 FX_CMYK cmyk = m_pPalette[scanline[src_x]]; | |
1205 dest_scan[dest_pos] = FXSYS_GetCValue(cmyk); | |
1206 dest_scan[dest_pos + 1] = FXSYS_GetMValue(cmyk); | |
1207 dest_scan[dest_pos + 2] = FXSYS_GetYValue(cmyk); | |
1208 dest_scan[dest_pos + 3] = FXSYS_GetKValue(cmyk); | |
1209 } | |
1210 } else { | |
1211 dest_scan[dest_pos] = scanline[src_x]; | |
1212 } | |
1213 } | |
1214 } else { | |
1215 for (int i = 0; i < clip_width; i ++) { | |
1216 FX_DWORD dest_x = clip_left + i; | |
1217 FX_DWORD src_x = bFlipX ? (m_Width - dest_x * m_Width / dest_width -
1) * src_Bpp : (dest_x * m_Width / dest_width) * src_Bpp; | |
1218 #ifdef FOXIT_CHROME_BUILD | |
1219 src_x %= m_Width * src_Bpp; | |
1220 #endif | |
1221 int dest_pos = i * src_Bpp; | |
1222 for (int b = 0; b < src_Bpp; b ++) { | |
1223 dest_scan[dest_pos + b] = scanline[src_x + b]; | |
1224 } | |
1225 } | |
1226 } | |
1227 } | |
1228 FX_BOOL CFX_DIBitmap::ConvertColorScale(FX_DWORD forecolor, FX_DWORD backcolor) | |
1229 { | |
1230 ASSERT(!IsAlphaMask()); | |
1231 if (m_pBuffer == NULL || IsAlphaMask()) { | |
1232 return FALSE; | |
1233 } | |
1234 int fc, fm, fy, fk, bc, bm, by, bk; | |
1235 int fr, fg, fb, br, bg, bb; | |
1236 FX_BOOL isCmykImage = IsCmykImage(); | |
1237 if (isCmykImage) { | |
1238 fc = FXSYS_GetCValue(forecolor); | |
1239 fm = FXSYS_GetMValue(forecolor); | |
1240 fy = FXSYS_GetYValue(forecolor); | |
1241 fk = FXSYS_GetKValue(forecolor); | |
1242 bc = FXSYS_GetCValue(backcolor); | |
1243 bm = FXSYS_GetMValue(backcolor); | |
1244 by = FXSYS_GetYValue(backcolor); | |
1245 bk = FXSYS_GetKValue(backcolor); | |
1246 } else { | |
1247 fr = FXSYS_GetRValue(forecolor); | |
1248 fg = FXSYS_GetGValue(forecolor); | |
1249 fb = FXSYS_GetBValue(forecolor); | |
1250 br = FXSYS_GetRValue(backcolor); | |
1251 bg = FXSYS_GetGValue(backcolor); | |
1252 bb = FXSYS_GetBValue(backcolor); | |
1253 } | |
1254 if (m_bpp <= 8) { | |
1255 if (isCmykImage) { | |
1256 if (forecolor == 0xff && backcolor == 0 && m_pPalette == NULL) { | |
1257 return TRUE; | |
1258 } | |
1259 } else if (forecolor == 0 && backcolor == 0xffffff && m_pPalette == NULL
) { | |
1260 return TRUE; | |
1261 } | |
1262 if (m_pPalette == NULL) { | |
1263 BuildPalette(); | |
1264 } | |
1265 int size = 1 << m_bpp; | |
1266 if (isCmykImage) { | |
1267 for (int i = 0; i < size; i ++) { | |
1268 FX_BYTE b, g, r; | |
1269 AdobeCMYK_to_sRGB1(FXSYS_GetCValue(m_pPalette[i]), FXSYS_GetMVal
ue(m_pPalette[i]), FXSYS_GetYValue(m_pPalette[i]), FXSYS_GetKValue(m_pPalette[i]
), | |
1270 r, g, b); | |
1271 int gray = 255 - FXRGB2GRAY(r, g, b); | |
1272 m_pPalette[i] = CmykEncode(bc + (fc - bc) * gray / 255, bm + (fm
- bm) * gray / 255, | |
1273 by + (fy - by) * gray / 255, bk + (fk
- bk) * gray / 255); | |
1274 } | |
1275 } else | |
1276 for (int i = 0; i < size; i ++) { | |
1277 int gray = FXRGB2GRAY(FXARGB_R(m_pPalette[i]), FXARGB_G(m_pPalet
te[i]), FXARGB_B(m_pPalette[i])); | |
1278 m_pPalette[i] = FXARGB_MAKE(0xff, br + (fr - br) * gray / 255, b
g + (fg - bg) * gray / 255, | |
1279 bb + (fb - bb) * gray / 255); | |
1280 } | |
1281 return TRUE; | |
1282 } | |
1283 if (isCmykImage) { | |
1284 if (forecolor == 0xff && backcolor == 0x00) { | |
1285 for (int row = 0; row < m_Height; row ++) { | |
1286 FX_LPBYTE scanline = m_pBuffer + row * m_Pitch; | |
1287 for (int col = 0; col < m_Width; col ++) { | |
1288 FX_BYTE b, g, r; | |
1289 AdobeCMYK_to_sRGB1(scanline[0], scanline[1], scanline[2], sc
anline[3], | |
1290 r, g, b); | |
1291 *scanline ++ = 0; | |
1292 *scanline ++ = 0; | |
1293 *scanline ++ = 0; | |
1294 *scanline ++ = 255 - FXRGB2GRAY(r, g, b); | |
1295 } | |
1296 } | |
1297 return TRUE; | |
1298 } | |
1299 } else if (forecolor == 0 && backcolor == 0xffffff) { | |
1300 for (int row = 0; row < m_Height; row ++) { | |
1301 FX_LPBYTE scanline = m_pBuffer + row * m_Pitch; | |
1302 int gap = m_bpp / 8 - 2; | |
1303 for (int col = 0; col < m_Width; col ++) { | |
1304 int gray = FXRGB2GRAY(scanline[2], scanline[1], scanline[0]); | |
1305 *scanline ++ = gray; | |
1306 *scanline ++ = gray; | |
1307 *scanline = gray; | |
1308 scanline += gap; | |
1309 } | |
1310 } | |
1311 return TRUE; | |
1312 } | |
1313 if (isCmykImage) { | |
1314 for (int row = 0; row < m_Height; row ++) { | |
1315 FX_LPBYTE scanline = m_pBuffer + row * m_Pitch; | |
1316 for (int col = 0; col < m_Width; col ++) { | |
1317 FX_BYTE b, g, r; | |
1318 AdobeCMYK_to_sRGB1(scanline[0], scanline[1], scanline[2], scanli
ne[3], | |
1319 r, g, b); | |
1320 int gray = 255 - FXRGB2GRAY(r, g, b); | |
1321 *scanline ++ = bc + (fc - bc) * gray / 255; | |
1322 *scanline ++ = bm + (fm - bm) * gray / 255; | |
1323 *scanline ++ = by + (fy - by) * gray / 255; | |
1324 *scanline ++ = bk + (fk - bk) * gray / 255; | |
1325 } | |
1326 } | |
1327 } else { | |
1328 for (int row = 0; row < m_Height; row ++) { | |
1329 FX_LPBYTE scanline = m_pBuffer + row * m_Pitch; | |
1330 int gap = m_bpp / 8 - 2; | |
1331 for (int col = 0; col < m_Width; col ++) { | |
1332 int gray = FXRGB2GRAY(scanline[2], scanline[1], scanline[0]); | |
1333 *scanline ++ = bb + (fb - bb) * gray / 255; | |
1334 *scanline ++ = bg + (fg - bg) * gray / 255; | |
1335 *scanline = br + (fr - br) * gray / 255; | |
1336 scanline += gap; | |
1337 } | |
1338 } | |
1339 } | |
1340 return TRUE; | |
1341 } | |
1342 FX_BOOL CFX_DIBitmap::DitherFS(const FX_DWORD* pPalette, int pal_size, const FX_
RECT* pRect) | |
1343 { | |
1344 if (m_pBuffer == NULL) { | |
1345 return FALSE; | |
1346 } | |
1347 if (m_bpp != 8 && m_pPalette != NULL && m_AlphaFlag != 0) { | |
1348 return FALSE; | |
1349 } | |
1350 if (m_Width < 4 && m_Height < 4) { | |
1351 return FALSE; | |
1352 } | |
1353 FX_RECT rect(0, 0, m_Width, m_Height); | |
1354 if (pRect) { | |
1355 rect.Intersect(*pRect); | |
1356 } | |
1357 FX_BYTE translate[256]; | |
1358 for (int i = 0; i < 256; i ++) { | |
1359 int err2 = 65536; | |
1360 for (int j = 0; j < pal_size; j ++) { | |
1361 FX_BYTE entry = (FX_BYTE)pPalette[j]; | |
1362 int err = (int)entry - i; | |
1363 if (err * err < err2) { | |
1364 err2 = err * err; | |
1365 translate[i] = entry; | |
1366 } | |
1367 } | |
1368 } | |
1369 for (int row = rect.top; row < rect.bottom; row ++) { | |
1370 FX_LPBYTE scan = m_pBuffer + row * m_Pitch; | |
1371 FX_LPBYTE next_scan = m_pBuffer + (row + 1) * m_Pitch; | |
1372 for (int col = rect.left; col < rect.right; col ++) { | |
1373 int src_pixel = scan[col]; | |
1374 int dest_pixel = translate[src_pixel]; | |
1375 scan[col] = (FX_BYTE)dest_pixel; | |
1376 int error = -dest_pixel + src_pixel; | |
1377 if (col < rect.right - 1) { | |
1378 int src = scan[col + 1]; | |
1379 src += error * 7 / 16; | |
1380 if (src > 255) { | |
1381 scan[col + 1] = 255; | |
1382 } else if (src < 0) { | |
1383 scan[col + 1] = 0; | |
1384 } else { | |
1385 scan[col + 1] = src; | |
1386 } | |
1387 } | |
1388 if (col < rect.right - 1 && row < rect.bottom - 1) { | |
1389 int src = next_scan[col + 1]; | |
1390 src += error * 1 / 16; | |
1391 if (src > 255) { | |
1392 next_scan[col + 1] = 255; | |
1393 } else if (src < 0) { | |
1394 next_scan[col + 1] = 0; | |
1395 } else { | |
1396 next_scan[col + 1] = src; | |
1397 } | |
1398 } | |
1399 if (row < rect.bottom - 1) { | |
1400 int src = next_scan[col]; | |
1401 src += error * 5 / 16; | |
1402 if (src > 255) { | |
1403 next_scan[col] = 255; | |
1404 } else if (src < 0) { | |
1405 next_scan[col] = 0; | |
1406 } else { | |
1407 next_scan[col] = src; | |
1408 } | |
1409 } | |
1410 if (col > rect.left && row < rect.bottom - 1) { | |
1411 int src = next_scan[col - 1]; | |
1412 src += error * 3 / 16; | |
1413 if (src > 255) { | |
1414 next_scan[col - 1] = 255; | |
1415 } else if (src < 0) { | |
1416 next_scan[col - 1] = 0; | |
1417 } else { | |
1418 next_scan[col - 1] = src; | |
1419 } | |
1420 } | |
1421 } | |
1422 } | |
1423 return TRUE; | |
1424 } | |
1425 CFX_DIBitmap* CFX_DIBSource::FlipImage(FX_BOOL bXFlip, FX_BOOL bYFlip) const | |
1426 { | |
1427 CFX_DIBitmap* pFlipped = FX_NEW CFX_DIBitmap; | |
1428 if (!pFlipped) { | |
1429 return NULL; | |
1430 } | |
1431 if (!pFlipped->Create(m_Width, m_Height, GetFormat())) { | |
1432 delete pFlipped; | |
1433 return NULL; | |
1434 } | |
1435 pFlipped->CopyPalette(m_pPalette); | |
1436 FX_LPBYTE pDestBuffer = pFlipped->GetBuffer(); | |
1437 int Bpp = m_bpp / 8; | |
1438 for (int row = 0; row < m_Height; row ++) { | |
1439 FX_LPCBYTE src_scan = GetScanline(row); | |
1440 FX_LPBYTE dest_scan = pDestBuffer + m_Pitch * (bYFlip ? (m_Height - row
- 1) : row); | |
1441 if (!bXFlip) { | |
1442 FXSYS_memcpy32(dest_scan, src_scan, m_Pitch); | |
1443 continue; | |
1444 } | |
1445 if (m_bpp == 1) { | |
1446 FXSYS_memset32(dest_scan, 0, m_Pitch); | |
1447 for (int col = 0; col < m_Width; col ++) | |
1448 if (src_scan[col / 8] & (1 << (7 - col % 8))) { | |
1449 int dest_col = m_Width - col - 1; | |
1450 dest_scan[dest_col / 8] |= (1 << (7 - dest_col % 8)); | |
1451 } | |
1452 } else { | |
1453 dest_scan += (m_Width - 1) * Bpp; | |
1454 if (Bpp == 1) { | |
1455 for (int col = 0; col < m_Width; col ++) { | |
1456 *dest_scan = *src_scan; | |
1457 dest_scan --; | |
1458 src_scan ++; | |
1459 } | |
1460 } else if (Bpp == 3) { | |
1461 for (int col = 0; col < m_Width; col ++) { | |
1462 dest_scan[0] = src_scan[0]; | |
1463 dest_scan[1] = src_scan[1]; | |
1464 dest_scan[2] = src_scan[2]; | |
1465 dest_scan -= 3; | |
1466 src_scan += 3; | |
1467 } | |
1468 } else { | |
1469 ASSERT(Bpp == 4); | |
1470 for (int col = 0; col < m_Width; col ++) { | |
1471 *(FX_DWORD*)dest_scan = *(FX_DWORD*)src_scan; | |
1472 dest_scan -= 4; | |
1473 src_scan += 4; | |
1474 } | |
1475 } | |
1476 } | |
1477 } | |
1478 if (m_pAlphaMask) { | |
1479 pDestBuffer = pFlipped->m_pAlphaMask->GetBuffer(); | |
1480 FX_DWORD dest_pitch = pFlipped->m_pAlphaMask->GetPitch(); | |
1481 for (int row = 0; row < m_Height; row ++) { | |
1482 FX_LPCBYTE src_scan = m_pAlphaMask->GetScanline(row); | |
1483 FX_LPBYTE dest_scan = pDestBuffer + dest_pitch * (bYFlip ? (m_Height
- row - 1) : row); | |
1484 if (!bXFlip) { | |
1485 FXSYS_memcpy32(dest_scan, src_scan, dest_pitch); | |
1486 continue; | |
1487 } | |
1488 dest_scan += (m_Width - 1); | |
1489 for (int col = 0; col < m_Width; col ++) { | |
1490 *dest_scan = *src_scan; | |
1491 dest_scan --; | |
1492 src_scan ++; | |
1493 } | |
1494 } | |
1495 } | |
1496 return pFlipped; | |
1497 } | |
1498 CFX_DIBExtractor::CFX_DIBExtractor(const CFX_DIBSource* pSrc) | |
1499 { | |
1500 m_pBitmap = NULL; | |
1501 if (pSrc->GetBuffer() == NULL) { | |
1502 m_pBitmap = pSrc->Clone(); | |
1503 } else { | |
1504 m_pBitmap = FX_NEW CFX_DIBitmap; | |
1505 if (!m_pBitmap) { | |
1506 return; | |
1507 } | |
1508 if (!m_pBitmap->Create(pSrc->GetWidth(), pSrc->GetHeight(), pSrc->GetFor
mat(), pSrc->GetBuffer())) { | |
1509 delete m_pBitmap; | |
1510 m_pBitmap = NULL; | |
1511 return; | |
1512 } | |
1513 m_pBitmap->CopyPalette(pSrc->GetPalette()); | |
1514 m_pBitmap->CopyAlphaMask(pSrc->m_pAlphaMask); | |
1515 } | |
1516 } | |
1517 CFX_DIBExtractor::~CFX_DIBExtractor() | |
1518 { | |
1519 if (m_pBitmap) { | |
1520 delete m_pBitmap; | |
1521 } | |
1522 } | |
1523 CFX_FilteredDIB::CFX_FilteredDIB() | |
1524 { | |
1525 m_pScanline = NULL; | |
1526 m_pSrc = NULL; | |
1527 } | |
1528 CFX_FilteredDIB::~CFX_FilteredDIB() | |
1529 { | |
1530 if (m_pSrc && m_bAutoDropSrc) { | |
1531 delete m_pSrc; | |
1532 } | |
1533 if (m_pScanline) { | |
1534 FX_Free(m_pScanline); | |
1535 } | |
1536 } | |
1537 void CFX_FilteredDIB::LoadSrc(const CFX_DIBSource* pSrc, FX_BOOL bAutoDropSrc) | |
1538 { | |
1539 m_pSrc = pSrc; | |
1540 m_bAutoDropSrc = bAutoDropSrc; | |
1541 m_Width = pSrc->GetWidth(); | |
1542 m_Height = pSrc->GetHeight(); | |
1543 FXDIB_Format format = GetDestFormat(); | |
1544 m_bpp = (FX_BYTE)format; | |
1545 m_AlphaFlag = (FX_BYTE)(format >> 8); | |
1546 m_Pitch = (m_Width * (format & 0xff) + 31) / 32 * 4; | |
1547 m_pPalette = GetDestPalette(); | |
1548 m_pScanline = FX_Alloc(FX_BYTE, m_Pitch); | |
1549 } | |
1550 FX_LPCBYTE CFX_FilteredDIB::GetScanline(int line) const | |
1551 { | |
1552 TranslateScanline(m_pScanline, m_pSrc->GetScanline(line)); | |
1553 return m_pScanline; | |
1554 } | |
1555 void CFX_FilteredDIB::DownSampleScanline(int line, FX_LPBYTE dest_scan, int dest
_bpp, | |
1556 int dest_width, FX_BOOL bFlipX, int clip_left, int clip_width) const | |
1557 { | |
1558 m_pSrc->DownSampleScanline(line, dest_scan, dest_bpp, dest_width, bFlipX, cl
ip_left, clip_width); | |
1559 TranslateDownSamples(dest_scan, dest_scan, clip_width, dest_bpp); | |
1560 } | |
1561 CFX_ImageRenderer::CFX_ImageRenderer() | |
1562 { | |
1563 m_Status = 0; | |
1564 m_pTransformer = NULL; | |
1565 m_bRgbByteOrder = FALSE; | |
1566 m_BlendType = FXDIB_BLEND_NORMAL; | |
1567 } | |
1568 CFX_ImageRenderer::~CFX_ImageRenderer() | |
1569 { | |
1570 if (m_pTransformer) { | |
1571 delete m_pTransformer; | |
1572 } | |
1573 } | |
1574 extern FX_RECT _FXDIB_SwapClipBox(FX_RECT& clip, int width, int height, FX_BOOL
bFlipX, FX_BOOL bFlipY); | |
1575 FX_BOOL CFX_ImageRenderer::Start(CFX_DIBitmap* pDevice, const CFX_ClipRgn* pClip
Rgn, | |
1576 const CFX_DIBSource* pSource, int bitmap_alpha, | |
1577 FX_DWORD mask_color, const CFX_AffineMatrix* pM
atrix, | |
1578 FX_DWORD dib_flags, FX_BOOL bRgbByteOrder, | |
1579 int alpha_flag, void* pIccTransform, int blend_
type) | |
1580 { | |
1581 m_Matrix = *pMatrix; | |
1582 CFX_FloatRect image_rect_f = m_Matrix.GetUnitRect(); | |
1583 FX_RECT image_rect = image_rect_f.GetOutterRect(); | |
1584 m_ClipBox = pClipRgn ? pClipRgn->GetBox() : FX_RECT(0, 0, pDevice->GetWidth(
), pDevice->GetHeight()); | |
1585 m_ClipBox.Intersect(image_rect); | |
1586 if (m_ClipBox.IsEmpty()) { | |
1587 return FALSE; | |
1588 } | |
1589 m_pDevice = pDevice; | |
1590 m_pClipRgn = pClipRgn; | |
1591 m_MaskColor = mask_color; | |
1592 m_BitmapAlpha = bitmap_alpha; | |
1593 m_Matrix = *pMatrix; | |
1594 m_Flags = dib_flags; | |
1595 m_AlphaFlag = alpha_flag; | |
1596 m_pIccTransform = pIccTransform; | |
1597 m_bRgbByteOrder = bRgbByteOrder; | |
1598 m_BlendType = blend_type; | |
1599 FX_BOOL ret = TRUE; | |
1600 if ((FXSYS_fabs(m_Matrix.b) >= 0.5f || m_Matrix.a == 0) || | |
1601 (FXSYS_fabs(m_Matrix.c) >= 0.5f || m_Matrix.d == 0) ) { | |
1602 if (FXSYS_fabs(m_Matrix.a) < FXSYS_fabs(m_Matrix.b) / 20 && FXSYS_fabs(m
_Matrix.d) < FXSYS_fabs(m_Matrix.c) / 20 && | |
1603 FXSYS_fabs(m_Matrix.a) < 0.5f && FXSYS_fabs(m_Matrix.d) < 0.5f)
{ | |
1604 int dest_width = image_rect.Width(); | |
1605 int dest_height = image_rect.Height(); | |
1606 FX_RECT bitmap_clip = m_ClipBox; | |
1607 bitmap_clip.Offset(-image_rect.left, -image_rect.top); | |
1608 bitmap_clip = _FXDIB_SwapClipBox(bitmap_clip, dest_width, dest_heigh
t, m_Matrix.c > 0, m_Matrix.b < 0); | |
1609 m_Composer.Compose(pDevice, pClipRgn, bitmap_alpha, mask_color, m_Cl
ipBox, TRUE, | |
1610 m_Matrix.c > 0, m_Matrix.b < 0, m_bRgbByteOrder,
alpha_flag, pIccTransform, m_BlendType); | |
1611 if (!m_Stretcher.Start(&m_Composer, pSource, dest_height, dest_width
, bitmap_clip, dib_flags)) { | |
1612 return FALSE; | |
1613 } | |
1614 m_Status = 1; | |
1615 return TRUE; | |
1616 } | |
1617 m_Status = 2; | |
1618 m_pTransformer = FX_NEW CFX_ImageTransformer; | |
1619 if (!m_pTransformer) { | |
1620 return FALSE; | |
1621 } | |
1622 m_pTransformer->Start(pSource, &m_Matrix, dib_flags, &m_ClipBox); | |
1623 return TRUE; | |
1624 } | |
1625 int dest_width = image_rect.Width(); | |
1626 if (m_Matrix.a < 0) { | |
1627 dest_width = -dest_width; | |
1628 } | |
1629 int dest_height = image_rect.Height(); | |
1630 if (m_Matrix.d > 0) { | |
1631 dest_height = -dest_height; | |
1632 } | |
1633 if (dest_width == 0 || dest_height == 0) { | |
1634 return FALSE; | |
1635 } | |
1636 FX_RECT bitmap_clip = m_ClipBox; | |
1637 bitmap_clip.Offset(-image_rect.left, -image_rect.top); | |
1638 m_Composer.Compose(pDevice, pClipRgn, bitmap_alpha, mask_color, | |
1639 m_ClipBox, FALSE, FALSE, FALSE, m_bRgbByteOrder, alpha_fl
ag, pIccTransform, m_BlendType); | |
1640 m_Status = 1; | |
1641 ret = m_Stretcher.Start(&m_Composer, pSource, dest_width, dest_height, bitma
p_clip, dib_flags); | |
1642 return ret; | |
1643 } | |
1644 FX_BOOL CFX_ImageRenderer::Continue(IFX_Pause* pPause) | |
1645 { | |
1646 if (m_Status == 1) { | |
1647 return m_Stretcher.Continue(pPause); | |
1648 } else if (m_Status == 2) { | |
1649 if (m_pTransformer->Continue(pPause)) { | |
1650 return TRUE; | |
1651 } | |
1652 CFX_DIBitmap* pBitmap = m_pTransformer->m_Storer.Detach(); | |
1653 if (pBitmap == NULL) { | |
1654 return FALSE; | |
1655 } | |
1656 if (pBitmap->GetBuffer() == NULL) { | |
1657 delete pBitmap; | |
1658 return FALSE; | |
1659 } | |
1660 if (pBitmap->IsAlphaMask()) { | |
1661 if (m_BitmapAlpha != 255) { | |
1662 if (m_AlphaFlag >> 8) { | |
1663 m_AlphaFlag = (((FX_BYTE)((m_AlphaFlag & 0xff) * m_BitmapAlp
ha / 255)) | ((m_AlphaFlag >> 8) << 8)); | |
1664 } else { | |
1665 m_MaskColor = FXARGB_MUL_ALPHA(m_MaskColor, m_BitmapAlpha); | |
1666 } | |
1667 } | |
1668 m_pDevice->CompositeMask(m_pTransformer->m_ResultLeft, m_pTransforme
r->m_ResultTop, | |
1669 pBitmap->GetWidth(), pBitmap->GetHeight(),
pBitmap, m_MaskColor, | |
1670 0, 0, m_BlendType, m_pClipRgn, m_bRgbByteOr
der, m_AlphaFlag, m_pIccTransform); | |
1671 } else { | |
1672 if (m_BitmapAlpha != 255) { | |
1673 pBitmap->MultiplyAlpha(m_BitmapAlpha); | |
1674 } | |
1675 m_pDevice->CompositeBitmap(m_pTransformer->m_ResultLeft, m_pTransfor
mer->m_ResultTop, | |
1676 pBitmap->GetWidth(), pBitmap->GetHeight()
, pBitmap, 0, 0, m_BlendType, m_pClipRgn, m_bRgbByteOrder, m_pIccTransform); | |
1677 } | |
1678 delete pBitmap; | |
1679 return FALSE; | |
1680 } | |
1681 return FALSE; | |
1682 } | |
1683 CFX_BitmapStorer::CFX_BitmapStorer() | |
1684 { | |
1685 m_pBitmap = NULL; | |
1686 } | |
1687 CFX_BitmapStorer::~CFX_BitmapStorer() | |
1688 { | |
1689 if (m_pBitmap) { | |
1690 delete m_pBitmap; | |
1691 } | |
1692 } | |
1693 CFX_DIBitmap* CFX_BitmapStorer::Detach() | |
1694 { | |
1695 CFX_DIBitmap* pBitmap = m_pBitmap; | |
1696 m_pBitmap = NULL; | |
1697 return pBitmap; | |
1698 } | |
1699 void CFX_BitmapStorer::Replace(CFX_DIBitmap* pBitmap) | |
1700 { | |
1701 if (m_pBitmap) { | |
1702 delete m_pBitmap; | |
1703 } | |
1704 m_pBitmap = pBitmap; | |
1705 } | |
1706 void CFX_BitmapStorer::ComposeScanline(int line, FX_LPCBYTE scanline, FX_LPCBYTE
scan_extra_alpha) | |
1707 { | |
1708 FX_LPBYTE dest_buf = (FX_LPBYTE)m_pBitmap->GetScanline(line); | |
1709 FX_LPBYTE dest_alpha_buf = m_pBitmap->m_pAlphaMask ? | |
1710 (FX_LPBYTE)m_pBitmap->m_pAlphaMask->GetScanline(l
ine) : NULL; | |
1711 if (dest_buf) { | |
1712 FXSYS_memcpy32(dest_buf, scanline, m_pBitmap->GetPitch()); | |
1713 } | |
1714 if (dest_alpha_buf) { | |
1715 FXSYS_memcpy32(dest_alpha_buf, scan_extra_alpha, m_pBitmap->m_pAlphaMask
->GetPitch()); | |
1716 } | |
1717 } | |
1718 FX_BOOL CFX_BitmapStorer::SetInfo(int width, int height, FXDIB_Format src_format
, FX_DWORD* pSrcPalette) | |
1719 { | |
1720 m_pBitmap = FX_NEW CFX_DIBitmap; | 1585 m_pBitmap = FX_NEW CFX_DIBitmap; |
1721 if (!m_pBitmap) { | 1586 if (!m_pBitmap) { |
1722 return FALSE; | 1587 return; |
1723 } | 1588 } |
1724 if (!m_pBitmap->Create(width, height, src_format)) { | 1589 if (!m_pBitmap->Create(pSrc->GetWidth(), |
1725 delete m_pBitmap; | 1590 pSrc->GetHeight(), |
1726 m_pBitmap = NULL; | 1591 pSrc->GetFormat(), |
1727 return FALSE; | 1592 pSrc->GetBuffer())) { |
1728 } | 1593 delete m_pBitmap; |
1729 if (pSrcPalette) { | 1594 m_pBitmap = NULL; |
1730 m_pBitmap->CopyPalette(pSrcPalette); | 1595 return; |
1731 } | 1596 } |
| 1597 m_pBitmap->CopyPalette(pSrc->GetPalette()); |
| 1598 m_pBitmap->CopyAlphaMask(pSrc->m_pAlphaMask); |
| 1599 } |
| 1600 } |
| 1601 CFX_DIBExtractor::~CFX_DIBExtractor() { |
| 1602 if (m_pBitmap) { |
| 1603 delete m_pBitmap; |
| 1604 } |
| 1605 } |
| 1606 CFX_FilteredDIB::CFX_FilteredDIB() { |
| 1607 m_pScanline = NULL; |
| 1608 m_pSrc = NULL; |
| 1609 } |
| 1610 CFX_FilteredDIB::~CFX_FilteredDIB() { |
| 1611 if (m_pSrc && m_bAutoDropSrc) { |
| 1612 delete m_pSrc; |
| 1613 } |
| 1614 if (m_pScanline) { |
| 1615 FX_Free(m_pScanline); |
| 1616 } |
| 1617 } |
| 1618 void CFX_FilteredDIB::LoadSrc(const CFX_DIBSource* pSrc, FX_BOOL bAutoDropSrc) { |
| 1619 m_pSrc = pSrc; |
| 1620 m_bAutoDropSrc = bAutoDropSrc; |
| 1621 m_Width = pSrc->GetWidth(); |
| 1622 m_Height = pSrc->GetHeight(); |
| 1623 FXDIB_Format format = GetDestFormat(); |
| 1624 m_bpp = (FX_BYTE)format; |
| 1625 m_AlphaFlag = (FX_BYTE)(format >> 8); |
| 1626 m_Pitch = (m_Width * (format & 0xff) + 31) / 32 * 4; |
| 1627 m_pPalette = GetDestPalette(); |
| 1628 m_pScanline = FX_Alloc(FX_BYTE, m_Pitch); |
| 1629 } |
| 1630 FX_LPCBYTE CFX_FilteredDIB::GetScanline(int line) const { |
| 1631 TranslateScanline(m_pScanline, m_pSrc->GetScanline(line)); |
| 1632 return m_pScanline; |
| 1633 } |
| 1634 void CFX_FilteredDIB::DownSampleScanline(int line, |
| 1635 FX_LPBYTE dest_scan, |
| 1636 int dest_bpp, |
| 1637 int dest_width, |
| 1638 FX_BOOL bFlipX, |
| 1639 int clip_left, |
| 1640 int clip_width) const { |
| 1641 m_pSrc->DownSampleScanline( |
| 1642 line, dest_scan, dest_bpp, dest_width, bFlipX, clip_left, clip_width); |
| 1643 TranslateDownSamples(dest_scan, dest_scan, clip_width, dest_bpp); |
| 1644 } |
| 1645 CFX_ImageRenderer::CFX_ImageRenderer() { |
| 1646 m_Status = 0; |
| 1647 m_pTransformer = NULL; |
| 1648 m_bRgbByteOrder = FALSE; |
| 1649 m_BlendType = FXDIB_BLEND_NORMAL; |
| 1650 } |
| 1651 CFX_ImageRenderer::~CFX_ImageRenderer() { |
| 1652 if (m_pTransformer) { |
| 1653 delete m_pTransformer; |
| 1654 } |
| 1655 } |
| 1656 extern FX_RECT _FXDIB_SwapClipBox(FX_RECT& clip, |
| 1657 int width, |
| 1658 int height, |
| 1659 FX_BOOL bFlipX, |
| 1660 FX_BOOL bFlipY); |
| 1661 FX_BOOL CFX_ImageRenderer::Start(CFX_DIBitmap* pDevice, |
| 1662 const CFX_ClipRgn* pClipRgn, |
| 1663 const CFX_DIBSource* pSource, |
| 1664 int bitmap_alpha, |
| 1665 FX_DWORD mask_color, |
| 1666 const CFX_AffineMatrix* pMatrix, |
| 1667 FX_DWORD dib_flags, |
| 1668 FX_BOOL bRgbByteOrder, |
| 1669 int alpha_flag, |
| 1670 void* pIccTransform, |
| 1671 int blend_type) { |
| 1672 m_Matrix = *pMatrix; |
| 1673 CFX_FloatRect image_rect_f = m_Matrix.GetUnitRect(); |
| 1674 FX_RECT image_rect = image_rect_f.GetOutterRect(); |
| 1675 m_ClipBox = pClipRgn |
| 1676 ? pClipRgn->GetBox() |
| 1677 : FX_RECT(0, 0, pDevice->GetWidth(), pDevice->GetHeight()); |
| 1678 m_ClipBox.Intersect(image_rect); |
| 1679 if (m_ClipBox.IsEmpty()) { |
| 1680 return FALSE; |
| 1681 } |
| 1682 m_pDevice = pDevice; |
| 1683 m_pClipRgn = pClipRgn; |
| 1684 m_MaskColor = mask_color; |
| 1685 m_BitmapAlpha = bitmap_alpha; |
| 1686 m_Matrix = *pMatrix; |
| 1687 m_Flags = dib_flags; |
| 1688 m_AlphaFlag = alpha_flag; |
| 1689 m_pIccTransform = pIccTransform; |
| 1690 m_bRgbByteOrder = bRgbByteOrder; |
| 1691 m_BlendType = blend_type; |
| 1692 FX_BOOL ret = TRUE; |
| 1693 if ((FXSYS_fabs(m_Matrix.b) >= 0.5f || m_Matrix.a == 0) || |
| 1694 (FXSYS_fabs(m_Matrix.c) >= 0.5f || m_Matrix.d == 0)) { |
| 1695 if (FXSYS_fabs(m_Matrix.a) < FXSYS_fabs(m_Matrix.b) / 20 && |
| 1696 FXSYS_fabs(m_Matrix.d) < FXSYS_fabs(m_Matrix.c) / 20 && |
| 1697 FXSYS_fabs(m_Matrix.a) < 0.5f && FXSYS_fabs(m_Matrix.d) < 0.5f) { |
| 1698 int dest_width = image_rect.Width(); |
| 1699 int dest_height = image_rect.Height(); |
| 1700 FX_RECT bitmap_clip = m_ClipBox; |
| 1701 bitmap_clip.Offset(-image_rect.left, -image_rect.top); |
| 1702 bitmap_clip = _FXDIB_SwapClipBox( |
| 1703 bitmap_clip, dest_width, dest_height, m_Matrix.c > 0, m_Matrix.b < 0); |
| 1704 m_Composer.Compose(pDevice, |
| 1705 pClipRgn, |
| 1706 bitmap_alpha, |
| 1707 mask_color, |
| 1708 m_ClipBox, |
| 1709 TRUE, |
| 1710 m_Matrix.c > 0, |
| 1711 m_Matrix.b < 0, |
| 1712 m_bRgbByteOrder, |
| 1713 alpha_flag, |
| 1714 pIccTransform, |
| 1715 m_BlendType); |
| 1716 if (!m_Stretcher.Start(&m_Composer, |
| 1717 pSource, |
| 1718 dest_height, |
| 1719 dest_width, |
| 1720 bitmap_clip, |
| 1721 dib_flags)) { |
| 1722 return FALSE; |
| 1723 } |
| 1724 m_Status = 1; |
| 1725 return TRUE; |
| 1726 } |
| 1727 m_Status = 2; |
| 1728 m_pTransformer = FX_NEW CFX_ImageTransformer; |
| 1729 if (!m_pTransformer) { |
| 1730 return FALSE; |
| 1731 } |
| 1732 m_pTransformer->Start(pSource, &m_Matrix, dib_flags, &m_ClipBox); |
1732 return TRUE; | 1733 return TRUE; |
1733 } | 1734 } |
| 1735 int dest_width = image_rect.Width(); |
| 1736 if (m_Matrix.a < 0) { |
| 1737 dest_width = -dest_width; |
| 1738 } |
| 1739 int dest_height = image_rect.Height(); |
| 1740 if (m_Matrix.d > 0) { |
| 1741 dest_height = -dest_height; |
| 1742 } |
| 1743 if (dest_width == 0 || dest_height == 0) { |
| 1744 return FALSE; |
| 1745 } |
| 1746 FX_RECT bitmap_clip = m_ClipBox; |
| 1747 bitmap_clip.Offset(-image_rect.left, -image_rect.top); |
| 1748 m_Composer.Compose(pDevice, |
| 1749 pClipRgn, |
| 1750 bitmap_alpha, |
| 1751 mask_color, |
| 1752 m_ClipBox, |
| 1753 FALSE, |
| 1754 FALSE, |
| 1755 FALSE, |
| 1756 m_bRgbByteOrder, |
| 1757 alpha_flag, |
| 1758 pIccTransform, |
| 1759 m_BlendType); |
| 1760 m_Status = 1; |
| 1761 ret = m_Stretcher.Start( |
| 1762 &m_Composer, pSource, dest_width, dest_height, bitmap_clip, dib_flags); |
| 1763 return ret; |
| 1764 } |
| 1765 FX_BOOL CFX_ImageRenderer::Continue(IFX_Pause* pPause) { |
| 1766 if (m_Status == 1) { |
| 1767 return m_Stretcher.Continue(pPause); |
| 1768 } else if (m_Status == 2) { |
| 1769 if (m_pTransformer->Continue(pPause)) { |
| 1770 return TRUE; |
| 1771 } |
| 1772 CFX_DIBitmap* pBitmap = m_pTransformer->m_Storer.Detach(); |
| 1773 if (pBitmap == NULL) { |
| 1774 return FALSE; |
| 1775 } |
| 1776 if (pBitmap->GetBuffer() == NULL) { |
| 1777 delete pBitmap; |
| 1778 return FALSE; |
| 1779 } |
| 1780 if (pBitmap->IsAlphaMask()) { |
| 1781 if (m_BitmapAlpha != 255) { |
| 1782 if (m_AlphaFlag >> 8) { |
| 1783 m_AlphaFlag = |
| 1784 (((FX_BYTE)((m_AlphaFlag & 0xff) * m_BitmapAlpha / 255)) | |
| 1785 ((m_AlphaFlag >> 8) << 8)); |
| 1786 } else { |
| 1787 m_MaskColor = FXARGB_MUL_ALPHA(m_MaskColor, m_BitmapAlpha); |
| 1788 } |
| 1789 } |
| 1790 m_pDevice->CompositeMask(m_pTransformer->m_ResultLeft, |
| 1791 m_pTransformer->m_ResultTop, |
| 1792 pBitmap->GetWidth(), |
| 1793 pBitmap->GetHeight(), |
| 1794 pBitmap, |
| 1795 m_MaskColor, |
| 1796 0, |
| 1797 0, |
| 1798 m_BlendType, |
| 1799 m_pClipRgn, |
| 1800 m_bRgbByteOrder, |
| 1801 m_AlphaFlag, |
| 1802 m_pIccTransform); |
| 1803 } else { |
| 1804 if (m_BitmapAlpha != 255) { |
| 1805 pBitmap->MultiplyAlpha(m_BitmapAlpha); |
| 1806 } |
| 1807 m_pDevice->CompositeBitmap(m_pTransformer->m_ResultLeft, |
| 1808 m_pTransformer->m_ResultTop, |
| 1809 pBitmap->GetWidth(), |
| 1810 pBitmap->GetHeight(), |
| 1811 pBitmap, |
| 1812 0, |
| 1813 0, |
| 1814 m_BlendType, |
| 1815 m_pClipRgn, |
| 1816 m_bRgbByteOrder, |
| 1817 m_pIccTransform); |
| 1818 } |
| 1819 delete pBitmap; |
| 1820 return FALSE; |
| 1821 } |
| 1822 return FALSE; |
| 1823 } |
| 1824 CFX_BitmapStorer::CFX_BitmapStorer() { |
| 1825 m_pBitmap = NULL; |
| 1826 } |
| 1827 CFX_BitmapStorer::~CFX_BitmapStorer() { |
| 1828 if (m_pBitmap) { |
| 1829 delete m_pBitmap; |
| 1830 } |
| 1831 } |
| 1832 CFX_DIBitmap* CFX_BitmapStorer::Detach() { |
| 1833 CFX_DIBitmap* pBitmap = m_pBitmap; |
| 1834 m_pBitmap = NULL; |
| 1835 return pBitmap; |
| 1836 } |
| 1837 void CFX_BitmapStorer::Replace(CFX_DIBitmap* pBitmap) { |
| 1838 if (m_pBitmap) { |
| 1839 delete m_pBitmap; |
| 1840 } |
| 1841 m_pBitmap = pBitmap; |
| 1842 } |
| 1843 void CFX_BitmapStorer::ComposeScanline(int line, |
| 1844 FX_LPCBYTE scanline, |
| 1845 FX_LPCBYTE scan_extra_alpha) { |
| 1846 FX_LPBYTE dest_buf = (FX_LPBYTE)m_pBitmap->GetScanline(line); |
| 1847 FX_LPBYTE dest_alpha_buf = |
| 1848 m_pBitmap->m_pAlphaMask |
| 1849 ? (FX_LPBYTE)m_pBitmap->m_pAlphaMask->GetScanline(line) |
| 1850 : NULL; |
| 1851 if (dest_buf) { |
| 1852 FXSYS_memcpy32(dest_buf, scanline, m_pBitmap->GetPitch()); |
| 1853 } |
| 1854 if (dest_alpha_buf) { |
| 1855 FXSYS_memcpy32( |
| 1856 dest_alpha_buf, scan_extra_alpha, m_pBitmap->m_pAlphaMask->GetPitch()); |
| 1857 } |
| 1858 } |
| 1859 FX_BOOL CFX_BitmapStorer::SetInfo(int width, |
| 1860 int height, |
| 1861 FXDIB_Format src_format, |
| 1862 FX_DWORD* pSrcPalette) { |
| 1863 m_pBitmap = FX_NEW CFX_DIBitmap; |
| 1864 if (!m_pBitmap) { |
| 1865 return FALSE; |
| 1866 } |
| 1867 if (!m_pBitmap->Create(width, height, src_format)) { |
| 1868 delete m_pBitmap; |
| 1869 m_pBitmap = NULL; |
| 1870 return FALSE; |
| 1871 } |
| 1872 if (pSrcPalette) { |
| 1873 m_pBitmap->CopyPalette(pSrcPalette); |
| 1874 } |
| 1875 return TRUE; |
| 1876 } |
OLD | NEW |