| 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 |