1// Copyright 2017 PDFium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7#include "core/fxge/dib/cfx_dibsource.h" 8 9#include <algorithm> 10#include <memory> 11#include <utility> 12#include <vector> 13 14#include "core/fxcodec/fx_codec.h" 15#include "core/fxge/cfx_cliprgn.h" 16#include "core/fxge/dib/cfx_bitmapstorer.h" 17#include "core/fxge/dib/cfx_dibitmap.h" 18#include "core/fxge/dib/cfx_imagestretcher.h" 19#include "core/fxge/dib/cfx_imagetransformer.h" 20#include "third_party/base/logging.h" 21#include "third_party/base/ptr_util.h" 22 23namespace { 24 25class CFX_Palette { 26 public: 27 explicit CFX_Palette(const RetainPtr<CFX_DIBSource>& pBitmap); 28 ~CFX_Palette(); 29 30 const uint32_t* GetPalette() { return m_Palette.data(); } 31 const std::pair<uint32_t, uint32_t>* GetLuts() const { return m_Luts.data(); } 32 int32_t GetLutCount() const { return m_lut; } 33 void SetAmountLut(int row, uint32_t value) { m_Luts[row].first = value; } 34 35 private: 36 std::vector<uint32_t> m_Palette; 37 // (Amount, Color) pairs 38 std::vector<std::pair<uint32_t, uint32_t>> m_Luts; 39 int m_lut; 40}; 41 42void ColorDecode(uint32_t pal_v, uint8_t* r, uint8_t* g, uint8_t* b) { 43 *r = static_cast<uint8_t>((pal_v & 0xf00) >> 4); 44 *g = static_cast<uint8_t>(pal_v & 0x0f0); 45 *b = static_cast<uint8_t>((pal_v & 0x00f) << 4); 46} 47 48void Obtain_Pal(std::pair<uint32_t, uint32_t>* luts, 49 uint32_t* dest_pal, 50 uint32_t lut) { 51 uint32_t lut_1 = lut - 1; 52 for (int row = 0; row < 256; ++row) { 53 int lut_offset = lut_1 - row; 54 if (lut_offset < 0) 55 lut_offset += 256; 56 uint32_t color = luts[lut_offset].second; 57 uint8_t r; 58 uint8_t g; 59 uint8_t b; 60 ColorDecode(color, &r, &g, &b); 61 dest_pal[row] = (static_cast<uint32_t>(r) << 16) | 62 (static_cast<uint32_t>(g) << 8) | b | 0xff000000; 63 luts[lut_offset].first = row; 64 } 65} 66 67CFX_Palette::CFX_Palette(const RetainPtr<CFX_DIBSource>& pBitmap) 68 : m_Palette(256), m_Luts(4096), m_lut(0) { 69 int bpp = pBitmap->GetBPP() / 8; 70 int width = pBitmap->GetWidth(); 71 int height = pBitmap->GetHeight(); 72 for (int row = 0; row < height; ++row) { 73 const uint8_t* scan_line = pBitmap->GetScanline(row); 74 for (int col = 0; col < width; ++col) { 75 const uint8_t* src_port = scan_line + col * bpp; 76 uint32_t b = src_port[0] & 0xf0; 77 uint32_t g = src_port[1] & 0xf0; 78 uint32_t r = src_port[2] & 0xf0; 79 uint32_t index = (r << 4) + g + (b >> 4); 80 ++m_Luts[index].first; 81 } 82 } 83 // Move non-zeros to the front and count them 84 for (int row = 0; row < 4096; ++row) { 85 if (m_Luts[row].first != 0) { 86 m_Luts[m_lut].first = m_Luts[row].first; 87 m_Luts[m_lut].second = row; 88 ++m_lut; 89 } 90 } 91 std::sort(m_Luts.begin(), m_Luts.begin() + m_lut, 92 [](const std::pair<uint32_t, uint32_t>& arg1, 93 const std::pair<uint32_t, uint32_t>& arg2) { 94 return arg1.first < arg2.first; 95 }); 96 Obtain_Pal(m_Luts.data(), m_Palette.data(), m_lut); 97} 98 99CFX_Palette::~CFX_Palette() {} 100 101void ConvertBuffer_1bppMask2Gray(uint8_t* dest_buf, 102 int dest_pitch, 103 int width, 104 int height, 105 const RetainPtr<CFX_DIBSource>& pSrcBitmap, 106 int src_left, 107 int src_top) { 108 uint8_t set_gray, reset_gray; 109 set_gray = 0xff; 110 reset_gray = 0x00; 111 for (int row = 0; row < height; ++row) { 112 uint8_t* dest_scan = dest_buf + row * dest_pitch; 113 memset(dest_scan, reset_gray, width); 114 const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row); 115 for (int col = src_left; col < src_left + width; ++col) { 116 if (src_scan[col / 8] & (1 << (7 - col % 8))) 117 *dest_scan = set_gray; 118 ++dest_scan; 119 } 120 } 121} 122 123void ConvertBuffer_8bppMask2Gray(uint8_t* dest_buf, 124 int dest_pitch, 125 int width, 126 int height, 127 const RetainPtr<CFX_DIBSource>& pSrcBitmap, 128 int src_left, 129 int src_top) { 130 for (int row = 0; row < height; ++row) { 131 uint8_t* dest_scan = dest_buf + row * dest_pitch; 132 const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left; 133 memcpy(dest_scan, src_scan, width); 134 } 135} 136 137void ConvertBuffer_1bppPlt2Gray(uint8_t* dest_buf, 138 int dest_pitch, 139 int width, 140 int height, 141 const RetainPtr<CFX_DIBSource>& pSrcBitmap, 142 int src_left, 143 int src_top) { 144 uint32_t* src_plt = pSrcBitmap->GetPalette(); 145 uint8_t gray[2]; 146 uint8_t reset_r; 147 uint8_t reset_g; 148 uint8_t reset_b; 149 uint8_t set_r; 150 uint8_t set_g; 151 uint8_t set_b; 152 if (pSrcBitmap->IsCmykImage()) { 153 std::tie(reset_r, reset_g, reset_b) = AdobeCMYK_to_sRGB1( 154 FXSYS_GetCValue(src_plt[0]), FXSYS_GetMValue(src_plt[0]), 155 FXSYS_GetYValue(src_plt[0]), FXSYS_GetKValue(src_plt[0])); 156 std::tie(set_r, set_g, set_b) = AdobeCMYK_to_sRGB1( 157 FXSYS_GetCValue(src_plt[1]), FXSYS_GetMValue(src_plt[1]), 158 FXSYS_GetYValue(src_plt[1]), FXSYS_GetKValue(src_plt[1])); 159 } else { 160 reset_r = FXARGB_R(src_plt[0]); 161 reset_g = FXARGB_G(src_plt[0]); 162 reset_b = FXARGB_B(src_plt[0]); 163 set_r = FXARGB_R(src_plt[1]); 164 set_g = FXARGB_G(src_plt[1]); 165 set_b = FXARGB_B(src_plt[1]); 166 } 167 gray[0] = FXRGB2GRAY(reset_r, reset_g, reset_b); 168 gray[1] = FXRGB2GRAY(set_r, set_g, set_b); 169 170 for (int row = 0; row < height; ++row) { 171 uint8_t* dest_scan = dest_buf + row * dest_pitch; 172 memset(dest_scan, gray[0], width); 173 const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row); 174 for (int col = src_left; col < src_left + width; ++col) { 175 if (src_scan[col / 8] & (1 << (7 - col % 8))) 176 *dest_scan = gray[1]; 177 ++dest_scan; 178 } 179 } 180} 181 182void ConvertBuffer_8bppPlt2Gray(uint8_t* dest_buf, 183 int dest_pitch, 184 int width, 185 int height, 186 const RetainPtr<CFX_DIBSource>& pSrcBitmap, 187 int src_left, 188 int src_top) { 189 uint32_t* src_plt = pSrcBitmap->GetPalette(); 190 uint8_t gray[256]; 191 if (pSrcBitmap->IsCmykImage()) { 192 uint8_t r; 193 uint8_t g; 194 uint8_t b; 195 for (size_t i = 0; i < FX_ArraySize(gray); ++i) { 196 std::tie(r, g, b) = AdobeCMYK_to_sRGB1( 197 FXSYS_GetCValue(src_plt[i]), FXSYS_GetMValue(src_plt[i]), 198 FXSYS_GetYValue(src_plt[i]), FXSYS_GetKValue(src_plt[i])); 199 gray[i] = FXRGB2GRAY(r, g, b); 200 } 201 } else { 202 for (size_t i = 0; i < FX_ArraySize(gray); ++i) { 203 gray[i] = FXRGB2GRAY(FXARGB_R(src_plt[i]), FXARGB_G(src_plt[i]), 204 FXARGB_B(src_plt[i])); 205 } 206 } 207 208 for (int row = 0; row < height; ++row) { 209 uint8_t* dest_scan = dest_buf + row * dest_pitch; 210 const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left; 211 for (int col = 0; col < width; ++col) 212 *dest_scan++ = gray[*src_scan++]; 213 } 214} 215 216void ConvertBuffer_RgbOrCmyk2Gray(uint8_t* dest_buf, 217 int dest_pitch, 218 int width, 219 int height, 220 const RetainPtr<CFX_DIBSource>& pSrcBitmap, 221 int src_left, 222 int src_top) { 223 int Bpp = pSrcBitmap->GetBPP() / 8; 224 if (pSrcBitmap->IsCmykImage()) { 225 for (int row = 0; row < height; ++row) { 226 uint8_t* dest_scan = dest_buf + row * dest_pitch; 227 const uint8_t* src_scan = 228 pSrcBitmap->GetScanline(src_top + row) + src_left * 4; 229 for (int col = 0; col < width; ++col) { 230 uint8_t r; 231 uint8_t g; 232 uint8_t b; 233 std::tie(r, g, b) = AdobeCMYK_to_sRGB1( 234 FXSYS_GetCValue(static_cast<uint32_t>(src_scan[0])), 235 FXSYS_GetMValue(static_cast<uint32_t>(src_scan[1])), 236 FXSYS_GetYValue(static_cast<uint32_t>(src_scan[2])), 237 FXSYS_GetKValue(static_cast<uint32_t>(src_scan[3]))); 238 *dest_scan++ = FXRGB2GRAY(r, g, b); 239 src_scan += 4; 240 } 241 } 242 } else { 243 for (int row = 0; row < height; ++row) { 244 uint8_t* dest_scan = dest_buf + row * dest_pitch; 245 const uint8_t* src_scan = 246 pSrcBitmap->GetScanline(src_top + row) + src_left * Bpp; 247 for (int col = 0; col < width; ++col) { 248 *dest_scan++ = FXRGB2GRAY(src_scan[2], src_scan[1], src_scan[0]); 249 src_scan += Bpp; 250 } 251 } 252 } 253} 254 255void ConvertBuffer_IndexCopy(uint8_t* dest_buf, 256 int dest_pitch, 257 int width, 258 int height, 259 const RetainPtr<CFX_DIBSource>& pSrcBitmap, 260 int src_left, 261 int src_top) { 262 if (pSrcBitmap->GetBPP() == 1) { 263 for (int row = 0; row < height; ++row) { 264 uint8_t* dest_scan = dest_buf + row * dest_pitch; 265 // Set all destination pixels to be white initially. 266 memset(dest_scan, 255, width); 267 const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row); 268 for (int col = src_left; col < src_left + width; ++col) { 269 // If the source bit is set, then set the destination pixel to be black. 270 if (src_scan[col / 8] & (1 << (7 - col % 8))) 271 *dest_scan = 0; 272 273 ++dest_scan; 274 } 275 } 276 } else { 277 for (int row = 0; row < height; ++row) { 278 uint8_t* dest_scan = dest_buf + row * dest_pitch; 279 const uint8_t* src_scan = 280 pSrcBitmap->GetScanline(src_top + row) + src_left; 281 memcpy(dest_scan, src_scan, width); 282 } 283 } 284} 285 286void ConvertBuffer_Plt2PltRgb8(uint8_t* dest_buf, 287 int dest_pitch, 288 int width, 289 int height, 290 const RetainPtr<CFX_DIBSource>& pSrcBitmap, 291 int src_left, 292 int src_top, 293 uint32_t* dst_plt) { 294 ConvertBuffer_IndexCopy(dest_buf, dest_pitch, width, height, pSrcBitmap, 295 src_left, src_top); 296 uint32_t* src_plt = pSrcBitmap->GetPalette(); 297 int plt_size = pSrcBitmap->GetPaletteSize(); 298 if (pSrcBitmap->IsCmykImage()) { 299 for (int i = 0; i < plt_size; ++i) { 300 uint8_t r; 301 uint8_t g; 302 uint8_t b; 303 std::tie(r, g, b) = AdobeCMYK_to_sRGB1( 304 FXSYS_GetCValue(src_plt[i]), FXSYS_GetMValue(src_plt[i]), 305 FXSYS_GetYValue(src_plt[i]), FXSYS_GetKValue(src_plt[i])); 306 dst_plt[i] = FXARGB_MAKE(0xff, r, g, b); 307 } 308 } else { 309 memcpy(dst_plt, src_plt, plt_size * 4); 310 } 311} 312 313void ConvertBuffer_Rgb2PltRgb8(uint8_t* dest_buf, 314 int dest_pitch, 315 int width, 316 int height, 317 const RetainPtr<CFX_DIBSource>& pSrcBitmap, 318 int src_left, 319 int src_top, 320 uint32_t* dst_plt) { 321 int bpp = pSrcBitmap->GetBPP() / 8; 322 CFX_Palette palette(pSrcBitmap); 323 const std::pair<uint32_t, uint32_t>* Luts = palette.GetLuts(); 324 int lut = palette.GetLutCount(); 325 const uint32_t* pal = palette.GetPalette(); 326 if (lut > 256) { 327 int err; 328 int min_err; 329 int lut_256 = lut - 256; 330 for (int row = 0; row < lut_256; ++row) { 331 min_err = 1000000; 332 uint8_t r; 333 uint8_t g; 334 uint8_t b; 335 ColorDecode(Luts[row].second, &r, &g, &b); 336 uint32_t clrindex = 0; 337 for (int col = 0; col < 256; ++col) { 338 uint32_t p_color = pal[col]; 339 int d_r = r - static_cast<uint8_t>(p_color >> 16); 340 int d_g = g - static_cast<uint8_t>(p_color >> 8); 341 int d_b = b - static_cast<uint8_t>(p_color); 342 err = d_r * d_r + d_g * d_g + d_b * d_b; 343 if (err < min_err) { 344 min_err = err; 345 clrindex = col; 346 } 347 } 348 palette.SetAmountLut(row, clrindex); 349 } 350 } 351 int32_t lut_1 = lut - 1; 352 for (int row = 0; row < height; ++row) { 353 uint8_t* src_scan = 354 const_cast<uint8_t*>(pSrcBitmap->GetScanline(src_top + row)) + src_left; 355 uint8_t* dest_scan = dest_buf + row * dest_pitch; 356 for (int col = 0; col < width; ++col) { 357 uint8_t* src_port = src_scan + col * bpp; 358 int r = src_port[2] & 0xf0; 359 int g = src_port[1] & 0xf0; 360 int b = src_port[0] & 0xf0; 361 uint32_t clrindex = (r << 4) + g + (b >> 4); 362 for (int i = lut_1; i >= 0; --i) 363 if (clrindex == Luts[i].second) { 364 *(dest_scan + col) = static_cast<uint8_t>(Luts[i].first); 365 break; 366 } 367 } 368 } 369 memcpy(dst_plt, pal, sizeof(uint32_t) * 256); 370} 371 372void ConvertBuffer_1bppMask2Rgb(FXDIB_Format dst_format, 373 uint8_t* dest_buf, 374 int dest_pitch, 375 int width, 376 int height, 377 const RetainPtr<CFX_DIBSource>& pSrcBitmap, 378 int src_left, 379 int src_top) { 380 int comps = (dst_format & 0xff) / 8; 381 uint8_t set_gray, reset_gray; 382 set_gray = 0xff; 383 reset_gray = 0x00; 384 for (int row = 0; row < height; ++row) { 385 uint8_t* dest_scan = dest_buf + row * dest_pitch; 386 const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row); 387 for (int col = src_left; col < src_left + width; ++col) { 388 if (src_scan[col / 8] & (1 << (7 - col % 8))) { 389 dest_scan[0] = set_gray; 390 dest_scan[1] = set_gray; 391 dest_scan[2] = set_gray; 392 } else { 393 dest_scan[0] = reset_gray; 394 dest_scan[1] = reset_gray; 395 dest_scan[2] = reset_gray; 396 } 397 dest_scan += comps; 398 } 399 } 400} 401 402void ConvertBuffer_8bppMask2Rgb(FXDIB_Format dst_format, 403 uint8_t* dest_buf, 404 int dest_pitch, 405 int width, 406 int height, 407 const RetainPtr<CFX_DIBSource>& pSrcBitmap, 408 int src_left, 409 int src_top) { 410 int comps = (dst_format & 0xff) / 8; 411 for (int row = 0; row < height; ++row) { 412 uint8_t* dest_scan = dest_buf + row * dest_pitch; 413 const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left; 414 uint8_t src_pixel; 415 for (int col = 0; col < width; ++col) { 416 src_pixel = *src_scan++; 417 *dest_scan++ = src_pixel; 418 *dest_scan++ = src_pixel; 419 *dest_scan = src_pixel; 420 dest_scan += comps - 2; 421 } 422 } 423} 424 425void ConvertBuffer_1bppPlt2Rgb(FXDIB_Format dst_format, 426 uint8_t* dest_buf, 427 int dest_pitch, 428 int width, 429 int height, 430 const RetainPtr<CFX_DIBSource>& pSrcBitmap, 431 int src_left, 432 int src_top) { 433 int comps = (dst_format & 0xff) / 8; 434 uint32_t* src_plt = pSrcBitmap->GetPalette(); 435 uint32_t plt[2]; 436 uint8_t* bgr_ptr = reinterpret_cast<uint8_t*>(plt); 437 if (pSrcBitmap->IsCmykImage()) { 438 plt[0] = FXCMYK_TODIB(src_plt[0]); 439 plt[1] = FXCMYK_TODIB(src_plt[1]); 440 } else { 441 bgr_ptr[0] = FXARGB_B(src_plt[0]); 442 bgr_ptr[1] = FXARGB_G(src_plt[0]); 443 bgr_ptr[2] = FXARGB_R(src_plt[0]); 444 bgr_ptr[3] = FXARGB_B(src_plt[1]); 445 bgr_ptr[4] = FXARGB_G(src_plt[1]); 446 bgr_ptr[5] = FXARGB_R(src_plt[1]); 447 } 448 449 if (pSrcBitmap->IsCmykImage()) { 450 std::tie(bgr_ptr[2], bgr_ptr[1], bgr_ptr[0]) = AdobeCMYK_to_sRGB1( 451 FXSYS_GetCValue(src_plt[0]), FXSYS_GetMValue(src_plt[0]), 452 FXSYS_GetYValue(src_plt[0]), FXSYS_GetKValue(src_plt[0])); 453 std::tie(bgr_ptr[5], bgr_ptr[4], bgr_ptr[3]) = AdobeCMYK_to_sRGB1( 454 FXSYS_GetCValue(src_plt[1]), FXSYS_GetMValue(src_plt[1]), 455 FXSYS_GetYValue(src_plt[1]), FXSYS_GetKValue(src_plt[1])); 456 } 457 458 for (int row = 0; row < height; ++row) { 459 uint8_t* dest_scan = dest_buf + row * dest_pitch; 460 const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row); 461 for (int col = src_left; col < src_left + width; ++col) { 462 if (src_scan[col / 8] & (1 << (7 - col % 8))) { 463 *dest_scan++ = bgr_ptr[3]; 464 *dest_scan++ = bgr_ptr[4]; 465 *dest_scan = bgr_ptr[5]; 466 } else { 467 *dest_scan++ = bgr_ptr[0]; 468 *dest_scan++ = bgr_ptr[1]; 469 *dest_scan = bgr_ptr[2]; 470 } 471 dest_scan += comps - 2; 472 } 473 } 474} 475 476void ConvertBuffer_8bppPlt2Rgb(FXDIB_Format dst_format, 477 uint8_t* dest_buf, 478 int dest_pitch, 479 int width, 480 int height, 481 const RetainPtr<CFX_DIBSource>& pSrcBitmap, 482 int src_left, 483 int src_top) { 484 int comps = (dst_format & 0xff) / 8; 485 uint32_t* src_plt = pSrcBitmap->GetPalette(); 486 uint32_t plt[256]; 487 uint8_t* bgr_ptr = reinterpret_cast<uint8_t*>(plt); 488 if (!pSrcBitmap->IsCmykImage()) { 489 for (int i = 0; i < 256; ++i) { 490 *bgr_ptr++ = FXARGB_B(src_plt[i]); 491 *bgr_ptr++ = FXARGB_G(src_plt[i]); 492 *bgr_ptr++ = FXARGB_R(src_plt[i]); 493 } 494 bgr_ptr = reinterpret_cast<uint8_t*>(plt); 495 } 496 497 if (pSrcBitmap->IsCmykImage()) { 498 for (int i = 0; i < 256; ++i) { 499 std::tie(bgr_ptr[2], bgr_ptr[1], bgr_ptr[0]) = AdobeCMYK_to_sRGB1( 500 FXSYS_GetCValue(src_plt[i]), FXSYS_GetMValue(src_plt[i]), 501 FXSYS_GetYValue(src_plt[i]), FXSYS_GetKValue(src_plt[i])); 502 bgr_ptr += 3; 503 } 504 bgr_ptr = reinterpret_cast<uint8_t*>(plt); 505 } 506 507 for (int row = 0; row < height; ++row) { 508 uint8_t* dest_scan = dest_buf + row * dest_pitch; 509 const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left; 510 for (int col = 0; col < width; ++col) { 511 uint8_t* src_pixel = bgr_ptr + 3 * (*src_scan++); 512 *dest_scan++ = *src_pixel++; 513 *dest_scan++ = *src_pixel++; 514 *dest_scan = *src_pixel++; 515 dest_scan += comps - 2; 516 } 517 } 518} 519 520void ConvertBuffer_24bppRgb2Rgb24(uint8_t* dest_buf, 521 int dest_pitch, 522 int width, 523 int height, 524 const RetainPtr<CFX_DIBSource>& pSrcBitmap, 525 int src_left, 526 int src_top) { 527 for (int row = 0; row < height; ++row) { 528 uint8_t* dest_scan = dest_buf + row * dest_pitch; 529 const uint8_t* src_scan = 530 pSrcBitmap->GetScanline(src_top + row) + src_left * 3; 531 memcpy(dest_scan, src_scan, width * 3); 532 } 533} 534 535void ConvertBuffer_32bppRgb2Rgb24(uint8_t* dest_buf, 536 int dest_pitch, 537 int width, 538 int height, 539 const RetainPtr<CFX_DIBSource>& pSrcBitmap, 540 int src_left, 541 int src_top) { 542 for (int row = 0; row < height; ++row) { 543 uint8_t* dest_scan = dest_buf + row * dest_pitch; 544 const uint8_t* src_scan = 545 pSrcBitmap->GetScanline(src_top + row) + src_left * 4; 546 for (int col = 0; col < width; ++col) { 547 *dest_scan++ = *src_scan++; 548 *dest_scan++ = *src_scan++; 549 *dest_scan++ = *src_scan++; 550 ++src_scan; 551 } 552 } 553} 554 555void ConvertBuffer_Rgb2Rgb32(uint8_t* dest_buf, 556 int dest_pitch, 557 int width, 558 int height, 559 const RetainPtr<CFX_DIBSource>& pSrcBitmap, 560 int src_left, 561 int src_top) { 562 int comps = pSrcBitmap->GetBPP() / 8; 563 for (int row = 0; row < height; ++row) { 564 uint8_t* dest_scan = dest_buf + row * dest_pitch; 565 const uint8_t* src_scan = 566 pSrcBitmap->GetScanline(src_top + row) + src_left * comps; 567 for (int col = 0; col < width; ++col) { 568 *dest_scan++ = *src_scan++; 569 *dest_scan++ = *src_scan++; 570 *dest_scan++ = *src_scan++; 571 ++dest_scan; 572 src_scan += comps - 3; 573 } 574 } 575} 576 577void ConvertBuffer_32bppCmyk2Rgb32(uint8_t* dest_buf, 578 int dest_pitch, 579 int width, 580 int height, 581 const RetainPtr<CFX_DIBSource>& pSrcBitmap, 582 int src_left, 583 int src_top) { 584 for (int row = 0; row < height; ++row) { 585 uint8_t* dest_scan = dest_buf + row * dest_pitch; 586 const uint8_t* src_scan = 587 pSrcBitmap->GetScanline(src_top + row) + src_left * 4; 588 for (int col = 0; col < width; ++col) { 589 std::tie(dest_scan[2], dest_scan[1], dest_scan[0]) = AdobeCMYK_to_sRGB1( 590 src_scan[0], src_scan[1], src_scan[2], src_scan[3]); 591 dest_scan += 4; 592 src_scan += 4; 593 } 594 } 595} 596 597} // namespace 598 599CFX_DIBSource::CFX_DIBSource() 600 : m_Width(0), m_Height(0), m_bpp(0), m_AlphaFlag(0), m_Pitch(0) {} 601 602CFX_DIBSource::~CFX_DIBSource() {} 603 604uint8_t* CFX_DIBSource::GetBuffer() const { 605 return nullptr; 606} 607 608bool CFX_DIBSource::SkipToScanline(int line, IFX_PauseIndicator* pPause) const { 609 return false; 610} 611 612RetainPtr<CFX_DIBitmap> CFX_DIBSource::Clone(const FX_RECT* pClip) const { 613 FX_RECT rect(0, 0, m_Width, m_Height); 614 if (pClip) { 615 rect.Intersect(*pClip); 616 if (rect.IsEmpty()) 617 return nullptr; 618 } 619 auto pNewBitmap = pdfium::MakeRetain<CFX_DIBitmap>(); 620 if (!pNewBitmap->Create(rect.Width(), rect.Height(), GetFormat())) 621 return nullptr; 622 623 pNewBitmap->SetPalette(m_pPalette.get()); 624 pNewBitmap->SetAlphaMask(m_pAlphaMask, pClip); 625 if (GetBPP() == 1 && rect.left % 8 != 0) { 626 int left_shift = rect.left % 32; 627 int right_shift = 32 - left_shift; 628 int dword_count = pNewBitmap->m_Pitch / 4; 629 for (int row = rect.top; row < rect.bottom; ++row) { 630 uint32_t* src_scan = (uint32_t*)GetScanline(row) + rect.left / 32; 631 uint32_t* dest_scan = (uint32_t*)pNewBitmap->GetScanline(row - rect.top); 632 for (int i = 0; i < dword_count; ++i) { 633 dest_scan[i] = 634 (src_scan[i] << left_shift) | (src_scan[i + 1] >> right_shift); 635 } 636 } 637 } else { 638 int copy_len = (pNewBitmap->GetWidth() * pNewBitmap->GetBPP() + 7) / 8; 639 if (m_Pitch < static_cast<uint32_t>(copy_len)) 640 copy_len = m_Pitch; 641 642 for (int row = rect.top; row < rect.bottom; ++row) { 643 const uint8_t* src_scan = GetScanline(row) + rect.left * m_bpp / 8; 644 uint8_t* dest_scan = (uint8_t*)pNewBitmap->GetScanline(row - rect.top); 645 memcpy(dest_scan, src_scan, copy_len); 646 } 647 } 648 return pNewBitmap; 649} 650 651void CFX_DIBSource::BuildPalette() { 652 if (m_pPalette) 653 return; 654 655 if (GetBPP() == 1) { 656 m_pPalette.reset(FX_Alloc(uint32_t, 2)); 657 if (IsCmykImage()) { 658 m_pPalette.get()[0] = 0xff; 659 m_pPalette.get()[1] = 0; 660 } else { 661 m_pPalette.get()[0] = 0xff000000; 662 m_pPalette.get()[1] = 0xffffffff; 663 } 664 } else if (GetBPP() == 8) { 665 m_pPalette.reset(FX_Alloc(uint32_t, 256)); 666 if (IsCmykImage()) { 667 for (int i = 0; i < 256; ++i) 668 m_pPalette.get()[i] = 0xff - i; 669 } else { 670 for (int i = 0; i < 256; ++i) 671 m_pPalette.get()[i] = 0xff000000 | (i * 0x10101); 672 } 673 } 674} 675 676bool CFX_DIBSource::BuildAlphaMask() { 677 if (m_pAlphaMask) 678 return true; 679 680 m_pAlphaMask = pdfium::MakeRetain<CFX_DIBitmap>(); 681 if (!m_pAlphaMask->Create(m_Width, m_Height, FXDIB_8bppMask)) { 682 m_pAlphaMask = nullptr; 683 return false; 684 } 685 memset(m_pAlphaMask->GetBuffer(), 0xff, 686 m_pAlphaMask->GetHeight() * m_pAlphaMask->GetPitch()); 687 return true; 688} 689 690uint32_t CFX_DIBSource::GetPaletteArgb(int index) const { 691 ASSERT((GetBPP() == 1 || GetBPP() == 8) && !IsAlphaMask()); 692 if (m_pPalette) 693 return m_pPalette.get()[index]; 694 695 if (IsCmykImage()) { 696 if (GetBPP() == 1) 697 return index ? 0 : 0xff; 698 699 return 0xff - index; 700 } 701 if (GetBPP() == 1) 702 return index ? 0xffffffff : 0xff000000; 703 704 return index * 0x10101 | 0xff000000; 705} 706 707void CFX_DIBSource::SetPaletteArgb(int index, uint32_t color) { 708 ASSERT((GetBPP() == 1 || GetBPP() == 8) && !IsAlphaMask()); 709 if (!m_pPalette) { 710 BuildPalette(); 711 } 712 m_pPalette.get()[index] = color; 713} 714 715int CFX_DIBSource::FindPalette(uint32_t color) const { 716 ASSERT((GetBPP() == 1 || GetBPP() == 8) && !IsAlphaMask()); 717 if (!m_pPalette) { 718 if (IsCmykImage()) { 719 if (GetBPP() == 1) 720 return (static_cast<uint8_t>(color) == 0xff) ? 0 : 1; 721 722 return 0xff - static_cast<uint8_t>(color); 723 } 724 if (GetBPP() == 1) 725 return (static_cast<uint8_t>(color) == 0xff) ? 1 : 0; 726 727 return static_cast<uint8_t>(color); 728 } 729 int palsize = (1 << GetBPP()); 730 for (int i = 0; i < palsize; ++i) { 731 if (m_pPalette.get()[i] == color) 732 return i; 733 } 734 return -1; 735} 736 737void CFX_DIBSource::GetOverlapRect(int& dest_left, 738 int& dest_top, 739 int& width, 740 int& height, 741 int src_width, 742 int src_height, 743 int& src_left, 744 int& src_top, 745 const CFX_ClipRgn* pClipRgn) { 746 if (width == 0 || height == 0) 747 return; 748 749 ASSERT(width > 0 && height > 0); 750 if (dest_left > m_Width || dest_top > m_Height) { 751 width = 0; 752 height = 0; 753 return; 754 } 755 int x_offset = dest_left - src_left; 756 int y_offset = dest_top - src_top; 757 FX_RECT src_rect(src_left, src_top, src_left + width, src_top + height); 758 FX_RECT src_bound(0, 0, src_width, src_height); 759 src_rect.Intersect(src_bound); 760 FX_RECT dest_rect(src_rect.left + x_offset, src_rect.top + y_offset, 761 src_rect.right + x_offset, src_rect.bottom + y_offset); 762 FX_RECT dest_bound(0, 0, m_Width, m_Height); 763 dest_rect.Intersect(dest_bound); 764 if (pClipRgn) 765 dest_rect.Intersect(pClipRgn->GetBox()); 766 dest_left = dest_rect.left; 767 dest_top = dest_rect.top; 768 src_left = dest_left - x_offset; 769 src_top = dest_top - y_offset; 770 width = dest_rect.right - dest_rect.left; 771 height = dest_rect.bottom - dest_rect.top; 772} 773 774void CFX_DIBSource::SetPalette(const uint32_t* pSrc) { 775 static const uint32_t kPaletteSize = 256; 776 if (!pSrc || GetBPP() > 8) { 777 m_pPalette.reset(); 778 return; 779 } 780 uint32_t pal_size = 1 << GetBPP(); 781 if (!m_pPalette) 782 m_pPalette.reset(FX_Alloc(uint32_t, pal_size)); 783 pal_size = std::min(pal_size, kPaletteSize); 784 memcpy(m_pPalette.get(), pSrc, pal_size * sizeof(uint32_t)); 785} 786 787void CFX_DIBSource::GetPalette(uint32_t* pal, int alpha) const { 788 ASSERT(GetBPP() <= 8 && !IsCmykImage()); 789 if (GetBPP() == 1) { 790 pal[0] = ((m_pPalette ? m_pPalette.get()[0] : 0xff000000) & 0xffffff) | 791 (alpha << 24); 792 pal[1] = ((m_pPalette ? m_pPalette.get()[1] : 0xffffffff) & 0xffffff) | 793 (alpha << 24); 794 return; 795 } 796 if (m_pPalette) { 797 for (int i = 0; i < 256; ++i) 798 pal[i] = (m_pPalette.get()[i] & 0x00ffffff) | (alpha << 24); 799 } else { 800 for (int i = 0; i < 256; ++i) 801 pal[i] = (i * 0x10101) | (alpha << 24); 802 } 803} 804 805RetainPtr<CFX_DIBitmap> CFX_DIBSource::CloneAlphaMask() const { 806 ASSERT(GetFormat() == FXDIB_Argb); 807 FX_RECT rect(0, 0, m_Width, m_Height); 808 auto pMask = pdfium::MakeRetain<CFX_DIBitmap>(); 809 if (!pMask->Create(rect.Width(), rect.Height(), FXDIB_8bppMask)) 810 return nullptr; 811 812 for (int row = rect.top; row < rect.bottom; ++row) { 813 const uint8_t* src_scan = GetScanline(row) + rect.left * 4 + 3; 814 uint8_t* dest_scan = 815 const_cast<uint8_t*>(pMask->GetScanline(row - rect.top)); 816 for (int col = rect.left; col < rect.right; ++col) { 817 *dest_scan++ = *src_scan; 818 src_scan += 4; 819 } 820 } 821 return pMask; 822} 823 824bool CFX_DIBSource::SetAlphaMask(const RetainPtr<CFX_DIBSource>& pAlphaMask, 825 const FX_RECT* pClip) { 826 if (!HasAlpha() || GetFormat() == FXDIB_Argb) 827 return false; 828 829 if (!pAlphaMask) { 830 m_pAlphaMask->Clear(0xff000000); 831 return true; 832 } 833 FX_RECT rect(0, 0, pAlphaMask->m_Width, pAlphaMask->m_Height); 834 if (pClip) { 835 rect.Intersect(*pClip); 836 if (rect.IsEmpty() || rect.Width() != m_Width || 837 rect.Height() != m_Height) { 838 return false; 839 } 840 } else { 841 if (pAlphaMask->m_Width != m_Width || pAlphaMask->m_Height != m_Height) 842 return false; 843 } 844 for (int row = 0; row < m_Height; ++row) { 845 memcpy(const_cast<uint8_t*>(m_pAlphaMask->GetScanline(row)), 846 pAlphaMask->GetScanline(row + rect.top) + rect.left, 847 m_pAlphaMask->m_Pitch); 848 } 849 return true; 850} 851 852RetainPtr<CFX_DIBitmap> CFX_DIBSource::FlipImage(bool bXFlip, 853 bool bYFlip) const { 854 auto pFlipped = pdfium::MakeRetain<CFX_DIBitmap>(); 855 if (!pFlipped->Create(m_Width, m_Height, GetFormat())) 856 return nullptr; 857 858 pFlipped->SetPalette(m_pPalette.get()); 859 uint8_t* pDestBuffer = pFlipped->GetBuffer(); 860 int Bpp = m_bpp / 8; 861 for (int row = 0; row < m_Height; ++row) { 862 const uint8_t* src_scan = GetScanline(row); 863 uint8_t* dest_scan = 864 pDestBuffer + m_Pitch * (bYFlip ? (m_Height - row - 1) : row); 865 if (!bXFlip) { 866 memcpy(dest_scan, src_scan, m_Pitch); 867 continue; 868 } 869 if (m_bpp == 1) { 870 memset(dest_scan, 0, m_Pitch); 871 for (int col = 0; col < m_Width; ++col) 872 if (src_scan[col / 8] & (1 << (7 - col % 8))) { 873 int dest_col = m_Width - col - 1; 874 dest_scan[dest_col / 8] |= (1 << (7 - dest_col % 8)); 875 } 876 } else { 877 dest_scan += (m_Width - 1) * Bpp; 878 if (Bpp == 1) { 879 for (int col = 0; col < m_Width; ++col) { 880 *dest_scan = *src_scan; 881 --dest_scan; 882 ++src_scan; 883 } 884 } else if (Bpp == 3) { 885 for (int col = 0; col < m_Width; ++col) { 886 dest_scan[0] = src_scan[0]; 887 dest_scan[1] = src_scan[1]; 888 dest_scan[2] = src_scan[2]; 889 dest_scan -= 3; 890 src_scan += 3; 891 } 892 } else { 893 ASSERT(Bpp == 4); 894 for (int col = 0; col < m_Width; ++col) { 895 *(uint32_t*)dest_scan = *(uint32_t*)src_scan; 896 dest_scan -= 4; 897 src_scan += 4; 898 } 899 } 900 } 901 } 902 if (m_pAlphaMask) { 903 pDestBuffer = pFlipped->m_pAlphaMask->GetBuffer(); 904 uint32_t dest_pitch = pFlipped->m_pAlphaMask->GetPitch(); 905 for (int row = 0; row < m_Height; ++row) { 906 const uint8_t* src_scan = m_pAlphaMask->GetScanline(row); 907 uint8_t* dest_scan = 908 pDestBuffer + dest_pitch * (bYFlip ? (m_Height - row - 1) : row); 909 if (!bXFlip) { 910 memcpy(dest_scan, src_scan, dest_pitch); 911 continue; 912 } 913 dest_scan += (m_Width - 1); 914 for (int col = 0; col < m_Width; ++col) { 915 *dest_scan = *src_scan; 916 --dest_scan; 917 ++src_scan; 918 } 919 } 920 } 921 return pFlipped; 922} 923 924RetainPtr<CFX_DIBitmap> CFX_DIBSource::CloneConvert(FXDIB_Format dest_format) { 925 if (dest_format == GetFormat()) 926 return Clone(nullptr); 927 928 auto pClone = pdfium::MakeRetain<CFX_DIBitmap>(); 929 if (!pClone->Create(m_Width, m_Height, dest_format)) 930 return nullptr; 931 932 RetainPtr<CFX_DIBitmap> pSrcAlpha; 933 if (HasAlpha()) { 934 if (GetFormat() == FXDIB_Argb) 935 pSrcAlpha = CloneAlphaMask(); 936 else 937 pSrcAlpha = m_pAlphaMask; 938 939 if (!pSrcAlpha) 940 return nullptr; 941 } 942 bool ret = true; 943 if (dest_format & 0x0200) { 944 if (dest_format == FXDIB_Argb) { 945 ret = pSrcAlpha ? pClone->LoadChannel(FXDIB_Alpha, pSrcAlpha, FXDIB_Alpha) 946 : pClone->LoadChannel(FXDIB_Alpha, 0xff); 947 } else { 948 ret = pClone->SetAlphaMask(pSrcAlpha, nullptr); 949 } 950 } 951 if (!ret) 952 return nullptr; 953 954 RetainPtr<CFX_DIBSource> holder(this); 955 std::unique_ptr<uint32_t, FxFreeDeleter> pal_8bpp; 956 if (!ConvertBuffer(dest_format, pClone->GetBuffer(), pClone->GetPitch(), 957 m_Width, m_Height, holder, 0, 0, &pal_8bpp)) { 958 return nullptr; 959 } 960 if (pal_8bpp) 961 pClone->SetPalette(pal_8bpp.get()); 962 963 return pClone; 964} 965 966RetainPtr<CFX_DIBitmap> CFX_DIBSource::SwapXY(bool bXFlip, bool bYFlip) const { 967 FX_RECT dest_clip(0, 0, m_Height, m_Width); 968 if (dest_clip.IsEmpty()) 969 return nullptr; 970 971 auto pTransBitmap = pdfium::MakeRetain<CFX_DIBitmap>(); 972 int result_height = dest_clip.Height(); 973 int result_width = dest_clip.Width(); 974 if (!pTransBitmap->Create(result_width, result_height, GetFormat())) 975 return nullptr; 976 977 pTransBitmap->SetPalette(m_pPalette.get()); 978 int dest_pitch = pTransBitmap->GetPitch(); 979 uint8_t* dest_buf = pTransBitmap->GetBuffer(); 980 int row_start = bXFlip ? m_Height - dest_clip.right : dest_clip.left; 981 int row_end = bXFlip ? m_Height - dest_clip.left : dest_clip.right; 982 int col_start = bYFlip ? m_Width - dest_clip.bottom : dest_clip.top; 983 int col_end = bYFlip ? m_Width - dest_clip.top : dest_clip.bottom; 984 if (GetBPP() == 1) { 985 memset(dest_buf, 0xff, dest_pitch * result_height); 986 for (int row = row_start; row < row_end; ++row) { 987 const uint8_t* src_scan = GetScanline(row); 988 int dest_col = (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) - 989 dest_clip.left; 990 uint8_t* dest_scan = dest_buf; 991 if (bYFlip) 992 dest_scan += (result_height - 1) * dest_pitch; 993 int dest_step = bYFlip ? -dest_pitch : dest_pitch; 994 for (int col = col_start; col < col_end; ++col) { 995 if (!(src_scan[col / 8] & (1 << (7 - col % 8)))) 996 dest_scan[dest_col / 8] &= ~(1 << (7 - dest_col % 8)); 997 dest_scan += dest_step; 998 } 999 } 1000 } else { 1001 int nBytes = GetBPP() / 8; 1002 int dest_step = bYFlip ? -dest_pitch : dest_pitch; 1003 if (nBytes == 3) 1004 dest_step -= 2; 1005 for (int row = row_start; row < row_end; ++row) { 1006 int dest_col = (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) - 1007 dest_clip.left; 1008 uint8_t* dest_scan = dest_buf + dest_col * nBytes; 1009 if (bYFlip) 1010 dest_scan += (result_height - 1) * dest_pitch; 1011 if (nBytes == 4) { 1012 uint32_t* src_scan = (uint32_t*)GetScanline(row) + col_start; 1013 for (int col = col_start; col < col_end; ++col) { 1014 *(uint32_t*)dest_scan = *src_scan++; 1015 dest_scan += dest_step; 1016 } 1017 } else { 1018 const uint8_t* src_scan = GetScanline(row) + col_start * nBytes; 1019 if (nBytes == 1) { 1020 for (int col = col_start; col < col_end; ++col) { 1021 *dest_scan = *src_scan++; 1022 dest_scan += dest_step; 1023 } 1024 } else { 1025 for (int col = col_start; col < col_end; ++col) { 1026 *dest_scan++ = *src_scan++; 1027 *dest_scan++ = *src_scan++; 1028 *dest_scan = *src_scan++; 1029 dest_scan += dest_step; 1030 } 1031 } 1032 } 1033 } 1034 } 1035 if (m_pAlphaMask) { 1036 dest_pitch = pTransBitmap->m_pAlphaMask->GetPitch(); 1037 dest_buf = pTransBitmap->m_pAlphaMask->GetBuffer(); 1038 int dest_step = bYFlip ? -dest_pitch : dest_pitch; 1039 for (int row = row_start; row < row_end; ++row) { 1040 int dest_col = (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) - 1041 dest_clip.left; 1042 uint8_t* dest_scan = dest_buf + dest_col; 1043 if (bYFlip) 1044 dest_scan += (result_height - 1) * dest_pitch; 1045 const uint8_t* src_scan = m_pAlphaMask->GetScanline(row) + col_start; 1046 for (int col = col_start; col < col_end; ++col) { 1047 *dest_scan = *src_scan++; 1048 dest_scan += dest_step; 1049 } 1050 } 1051 } 1052 return pTransBitmap; 1053} 1054 1055RetainPtr<CFX_DIBitmap> CFX_DIBSource::TransformTo( 1056 const CFX_Matrix* pDestMatrix, 1057 int* result_left, 1058 int* result_top) { 1059 RetainPtr<CFX_DIBSource> holder(this); 1060 CFX_ImageTransformer transformer(holder, pDestMatrix, 0, nullptr); 1061 transformer.Continue(nullptr); 1062 *result_left = transformer.result().left; 1063 *result_top = transformer.result().top; 1064 return transformer.DetachBitmap(); 1065} 1066 1067RetainPtr<CFX_DIBitmap> CFX_DIBSource::StretchTo(int dest_width, 1068 int dest_height, 1069 uint32_t flags, 1070 const FX_RECT* pClip) { 1071 RetainPtr<CFX_DIBSource> holder(this); 1072 FX_RECT clip_rect(0, 0, abs(dest_width), abs(dest_height)); 1073 if (pClip) 1074 clip_rect.Intersect(*pClip); 1075 1076 if (clip_rect.IsEmpty()) 1077 return nullptr; 1078 1079 if (dest_width == m_Width && dest_height == m_Height) 1080 return Clone(&clip_rect); 1081 1082 CFX_BitmapStorer storer; 1083 CFX_ImageStretcher stretcher(&storer, holder, dest_width, dest_height, 1084 clip_rect, flags); 1085 if (stretcher.Start()) 1086 stretcher.Continue(nullptr); 1087 1088 return storer.Detach(); 1089} 1090 1091// static 1092bool CFX_DIBSource::ConvertBuffer( 1093 FXDIB_Format dest_format, 1094 uint8_t* dest_buf, 1095 int dest_pitch, 1096 int width, 1097 int height, 1098 const RetainPtr<CFX_DIBSource>& pSrcBitmap, 1099 int src_left, 1100 int src_top, 1101 std::unique_ptr<uint32_t, FxFreeDeleter>* p_pal) { 1102 FXDIB_Format src_format = pSrcBitmap->GetFormat(); 1103 switch (dest_format) { 1104 case FXDIB_Invalid: 1105 case FXDIB_1bppCmyk: 1106 case FXDIB_1bppMask: 1107 case FXDIB_1bppRgb: 1108 NOTREACHED(); 1109 return false; 1110 case FXDIB_8bppMask: { 1111 if ((src_format & 0xff) == 1) { 1112 if (pSrcBitmap->GetPalette()) { 1113 ConvertBuffer_1bppPlt2Gray(dest_buf, dest_pitch, width, height, 1114 pSrcBitmap, src_left, src_top); 1115 return true; 1116 } 1117 ConvertBuffer_1bppMask2Gray(dest_buf, dest_pitch, width, height, 1118 pSrcBitmap, src_left, src_top); 1119 return true; 1120 } 1121 if ((src_format & 0xff) == 8) { 1122 if (pSrcBitmap->GetPalette()) { 1123 ConvertBuffer_8bppPlt2Gray(dest_buf, dest_pitch, width, height, 1124 pSrcBitmap, src_left, src_top); 1125 return true; 1126 } 1127 ConvertBuffer_8bppMask2Gray(dest_buf, dest_pitch, width, height, 1128 pSrcBitmap, src_left, src_top); 1129 return true; 1130 } 1131 if ((src_format & 0xff) >= 24) { 1132 ConvertBuffer_RgbOrCmyk2Gray(dest_buf, dest_pitch, width, height, 1133 pSrcBitmap, src_left, src_top); 1134 return true; 1135 } 1136 return false; 1137 } 1138 case FXDIB_8bppRgb: 1139 case FXDIB_8bppRgba: { 1140 if ((src_format & 0xff) == 8 && !pSrcBitmap->GetPalette()) { 1141 return ConvertBuffer(FXDIB_8bppMask, dest_buf, dest_pitch, width, 1142 height, pSrcBitmap, src_left, src_top, p_pal); 1143 } 1144 p_pal->reset(FX_Alloc(uint32_t, 256)); 1145 if (((src_format & 0xff) == 1 || (src_format & 0xff) == 8) && 1146 pSrcBitmap->GetPalette()) { 1147 ConvertBuffer_Plt2PltRgb8(dest_buf, dest_pitch, width, height, 1148 pSrcBitmap, src_left, src_top, p_pal->get()); 1149 return true; 1150 } 1151 if ((src_format & 0xff) >= 24) { 1152 ConvertBuffer_Rgb2PltRgb8(dest_buf, dest_pitch, width, height, 1153 pSrcBitmap, src_left, src_top, p_pal->get()); 1154 return true; 1155 } 1156 return false; 1157 } 1158 case FXDIB_Rgb: 1159 case FXDIB_Rgba: { 1160 if ((src_format & 0xff) == 1) { 1161 if (pSrcBitmap->GetPalette()) { 1162 ConvertBuffer_1bppPlt2Rgb(dest_format, dest_buf, dest_pitch, width, 1163 height, pSrcBitmap, src_left, src_top); 1164 return true; 1165 } 1166 ConvertBuffer_1bppMask2Rgb(dest_format, dest_buf, dest_pitch, width, 1167 height, pSrcBitmap, src_left, src_top); 1168 return true; 1169 } 1170 if ((src_format & 0xff) == 8) { 1171 if (pSrcBitmap->GetPalette()) { 1172 ConvertBuffer_8bppPlt2Rgb(dest_format, dest_buf, dest_pitch, width, 1173 height, pSrcBitmap, src_left, src_top); 1174 return true; 1175 } 1176 ConvertBuffer_8bppMask2Rgb(dest_format, dest_buf, dest_pitch, width, 1177 height, pSrcBitmap, src_left, src_top); 1178 return true; 1179 } 1180 if ((src_format & 0xff) == 24) { 1181 ConvertBuffer_24bppRgb2Rgb24(dest_buf, dest_pitch, width, height, 1182 pSrcBitmap, src_left, src_top); 1183 return true; 1184 } 1185 if ((src_format & 0xff) == 32) { 1186 ConvertBuffer_32bppRgb2Rgb24(dest_buf, dest_pitch, width, height, 1187 pSrcBitmap, src_left, src_top); 1188 return true; 1189 } 1190 return false; 1191 } 1192 case FXDIB_Argb: 1193 case FXDIB_Rgb32: { 1194 if ((src_format & 0xff) == 1) { 1195 if (pSrcBitmap->GetPalette()) { 1196 ConvertBuffer_1bppPlt2Rgb(dest_format, dest_buf, dest_pitch, width, 1197 height, pSrcBitmap, src_left, src_top); 1198 return true; 1199 } 1200 ConvertBuffer_1bppMask2Rgb(dest_format, dest_buf, dest_pitch, width, 1201 height, pSrcBitmap, src_left, src_top); 1202 return true; 1203 } 1204 if ((src_format & 0xff) == 8) { 1205 if (pSrcBitmap->GetPalette()) { 1206 ConvertBuffer_8bppPlt2Rgb(dest_format, dest_buf, dest_pitch, width, 1207 height, pSrcBitmap, src_left, src_top); 1208 return true; 1209 } 1210 ConvertBuffer_8bppMask2Rgb(dest_format, dest_buf, dest_pitch, width, 1211 height, pSrcBitmap, src_left, src_top); 1212 return true; 1213 } 1214 if ((src_format & 0xff) >= 24) { 1215 if (src_format & 0x0400) { 1216 ConvertBuffer_32bppCmyk2Rgb32(dest_buf, dest_pitch, width, height, 1217 pSrcBitmap, src_left, src_top); 1218 return true; 1219 } 1220 ConvertBuffer_Rgb2Rgb32(dest_buf, dest_pitch, width, height, pSrcBitmap, 1221 src_left, src_top); 1222 return true; 1223 } 1224 return false; 1225 } 1226 default: 1227 return false; 1228 } 1229} 1230