7#include "core/fxge/dib/cfx_dibbase.h"
16#include "core/fxcrt/data_vector.h"
17#include "core/fxcrt/fx_2d_size.h"
18#include "core/fxcrt/fx_coordinates.h"
19#include "core/fxcrt/fx_memory.h"
20#include "core/fxcrt/fx_safe_types.h"
21#include "core/fxcrt/span_util.h"
22#include "core/fxge/calculate_pitch.h"
23#include "core/fxge/cfx_cliprgn.h"
24#include "core/fxge/dib/cfx_bitmapstorer.h"
25#include "core/fxge/dib/cfx_dibitmap.h"
26#include "core/fxge/dib/cfx_imagestretcher.h"
27#include "core/fxge/dib/cfx_imagetransformer.h"
28#include "third_party/base/check.h"
29#include "third_party/base/check_op.h"
30#include "third_party/base/containers/span.h"
31#include "third_party/base/notreached.h"
35void ColorDecode(uint32_t pal_v, uint8_t* r, uint8_t* g, uint8_t* b) {
36 *r =
static_cast<uint8_t>((pal_v & 0xf00) >> 4);
37 *g =
static_cast<uint8_t>(pal_v & 0x0f0);
38 *b =
static_cast<uint8_t>((pal_v & 0x00f) << 4);
44 using LutsData =
std::pair<uint32_t, uint32_t>;
49 pdfium::span<
const uint32_t> GetPalette() {
return m_Palette; }
50 pdfium::span<
const LutsData> GetValidLuts() {
51 return pdfium::make_span(m_Luts).first(m_lut);
57 std::vector<uint32_t> m_Palette;
58 std::vector<LutsData> m_Luts;
63 : m_Palette(256), m_Luts(4096) {
64 int bpp = pBitmap->GetBPP() / 8;
65 int width = pBitmap->GetWidth();
66 int height = pBitmap->GetHeight();
67 for (
int row = 0; row < height; ++row) {
68 pdfium::span<
const uint8_t> scan_line = pBitmap->GetScanline(row);
69 for (
int col = 0; col < width; ++col) {
70 const uint8_t* src_port =
71 scan_line.subspan(Fx2DSizeOrDie(col, bpp)).data();
72 uint32_t b = src_port[0] & 0xf0;
73 uint32_t g = src_port[1] & 0xf0;
74 uint32_t r = src_port[2] & 0xf0;
75 uint32_t index = (r << 4) + g + (b >> 4);
76 ++m_Luts[index].first;
80 for (uint32_t row = 0; row < m_Luts.size(); ++row) {
81 if (m_Luts[row].first != 0) {
82 m_Luts[m_lut].first = m_Luts[row].first;
83 m_Luts[m_lut].second = row;
87 pdfium::span<LutsData> lut_span = pdfium::make_span(m_Luts).first(m_lut);
88 std::sort(lut_span.begin(), lut_span.end(),
89 [](
const LutsData& arg1,
const LutsData& arg2) {
90 return arg1.first < arg2.first;
95CFX_Palette::~CFX_Palette() =
default;
97void CFX_Palette::ObtainPalette() {
98 for (uint32_t row = 0; row < m_Palette.size(); ++row) {
99 const uint32_t lut_offset = (m_lut - row - 1) % m_Palette.size();
100 const uint32_t color = m_Luts[lut_offset].second;
104 ColorDecode(color, &r, &g, &b);
105 m_Palette[row] = (
static_cast<uint32_t>(r) << 16) |
106 (
static_cast<uint32_t>(g) << 8) | b | 0xff000000;
107 m_Luts[lut_offset].first = row;
112 const uint32_t lut_256 = m_lut - 256;
113 for (uint32_t row = 0; row < lut_256; ++row) {
118 ColorDecode(m_Luts[row].second, &r, &g, &b);
119 uint32_t clrindex = 0;
120 for (
int col = 0; col < 256; ++col) {
121 uint32_t p_color = m_Palette[col];
122 int d_r = r -
static_cast<uint8_t>(p_color >> 16);
123 int d_g = g -
static_cast<uint8_t>(p_color >> 8);
124 int d_b = b -
static_cast<uint8_t>(p_color);
125 err = d_r * d_r + d_g * d_g + d_b * d_b;
131 m_Luts[row].first = clrindex;
136void ConvertBuffer_1bppMask2Gray(pdfium::span<uint8_t> dest_buf,
143 static constexpr uint8_t kSetGray = 0xff;
144 static constexpr uint8_t kResetGray = 0x00;
145 for (
int row = 0; row < height; ++row) {
146 pdfium::span<uint8_t> dest_span =
147 dest_buf.subspan(Fx2DSizeOrDie(row, dest_pitch));
148 pdfium::span<
const uint8_t> src_span =
149 pSrcBitmap->GetScanline(src_top + row);
150 fxcrt::spanset(dest_span.first(width), kResetGray);
151 uint8_t* dest_scan = dest_span.data();
152 const uint8_t* src_scan = src_span.data();
153 for (
int col = src_left; col < src_left + width; ++col) {
154 if (src_scan[col / 8] & (1 << (7 - col % 8)))
155 *dest_scan = kSetGray;
161void ConvertBuffer_8bppMask2Gray(pdfium::span<uint8_t> dest_buf,
168 for (
int row = 0; row < height; ++row) {
170 dest_buf.subspan(Fx2DSizeOrDie(row, dest_pitch)),
171 pSrcBitmap->GetScanline(src_top + row).subspan(src_left, width));
175void ConvertBuffer_1bppPlt2Gray(pdfium::span<uint8_t> dest_buf,
182 pdfium::span<
const uint32_t> src_palette = pSrcBitmap->GetPaletteSpan();
183 const uint8_t reset_r =
FXARGB_R(src_palette[0]);
184 const uint8_t reset_g =
FXARGB_G(src_palette[0]);
185 const uint8_t reset_b =
FXARGB_B(src_palette[0]);
186 const uint8_t set_r =
FXARGB_R(src_palette[1]);
187 const uint8_t set_g =
FXARGB_G(src_palette[1]);
188 const uint8_t set_b =
FXARGB_B(src_palette[1]);
189 const uint8_t gray0 =
FXRGB2GRAY(reset_r, reset_g, reset_b);
190 const uint8_t gray1 =
FXRGB2GRAY(set_r, set_g, set_b);
192 for (
int row = 0; row < height; ++row) {
193 pdfium::span<uint8_t> dest_span =
194 dest_buf.subspan(Fx2DSizeOrDie(row, dest_pitch));
195 fxcrt::spanset(dest_span.first(width), gray0);
196 uint8_t* dest_scan = dest_span.data();
197 const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row).data();
198 for (
int col = src_left; col < src_left + width; ++col) {
199 if (src_scan[col / 8] & (1 << (7 - col % 8)))
206void ConvertBuffer_8bppPlt2Gray(pdfium::span<uint8_t> dest_buf,
213 pdfium::span<
const uint32_t> src_palette = pSrcBitmap->GetPaletteSpan();
215 for (size_t i = 0; i <
std::size(gray); ++i) {
220 for (
int row = 0; row < height; ++row) {
222 dest_buf.subspan(Fx2DSizeOrDie(row, dest_pitch)).data();
223 const uint8_t* src_scan =
224 pSrcBitmap->GetScanline(src_top + row).subspan(src_left).data();
225 for (
int col = 0; col < width; ++col)
226 *dest_scan++ = gray[*src_scan++];
230void ConvertBuffer_Rgb2Gray(pdfium::span<uint8_t> dest_buf,
237 const int Bpp = pSrcBitmap->GetBPP() / 8;
238 const size_t x_offset = Fx2DSizeOrDie(src_left, Bpp);
239 for (
int row = 0; row < height; ++row) {
241 dest_buf.subspan(Fx2DSizeOrDie(row, dest_pitch)).data();
242 const uint8_t* src_scan =
243 pSrcBitmap->GetScanline(src_top + row).subspan(x_offset).data();
244 for (
int col = 0; col < width; ++col) {
245 *dest_scan++ =
FXRGB2GRAY(src_scan[2], src_scan[1], src_scan[0]);
251void ConvertBuffer_IndexCopy(pdfium::span<uint8_t> dest_buf,
258 if (pSrcBitmap->GetBPP() == 1) {
259 for (
int row = 0; row < height; ++row) {
260 pdfium::span<uint8_t> dest_span =
261 dest_buf.subspan(Fx2DSizeOrDie(row, dest_pitch));
263 fxcrt::spanset(dest_span.first(width), 255);
264 uint8_t* dest_scan = dest_span.data();
265 const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row).data();
266 for (
int col = src_left; col < src_left + width; ++col) {
268 if (src_scan[col / 8] & (1 << (7 - col % 8)))
275 for (
int row = 0; row < height; ++row) {
277 dest_buf.subspan(Fx2DSizeOrDie(row, dest_pitch)),
278 pSrcBitmap->GetScanline(src_top + row).subspan(src_left, width));
284DataVector<uint32_t> ConvertBuffer_Plt2PltRgb8(
285 pdfium::span<uint8_t> dest_buf,
292 ConvertBuffer_IndexCopy(dest_buf, dest_pitch, width, height, pSrcBitmap,
294 const size_t plt_size = pSrcBitmap->GetRequiredPaletteSize();
295 pdfium::span<
const uint32_t> src_span = pSrcBitmap->GetPaletteSpan();
296 CHECK_LE(plt_size, src_span.size());
298 pdfium::span<
const uint32_t> src_palette_span = src_span.first(plt_size);
299 return DataVector<uint32_t>(src_palette_span.begin(), src_palette_span.end());
302DataVector<uint32_t> ConvertBuffer_Rgb2PltRgb8(
303 pdfium::span<uint8_t> dest_buf,
310 int bpp = pSrcBitmap->GetBPP() / 8;
311 CFX_Palette src_palette(pSrcBitmap);
312 pdfium::span<
const CFX_Palette::LutsData> luts = src_palette.GetValidLuts();
313 for (
int row = 0; row < height; ++row) {
314 pdfium::span<
const uint8_t> src_span =
315 pSrcBitmap->GetScanline(src_top + row).subspan(src_left);
317 dest_buf.subspan(Fx2DSizeOrDie(row, dest_pitch)).data();
318 for (
int col = 0; col < width; ++col) {
319 const uint8_t* src_port =
320 src_span.subspan(Fx2DSizeOrDie(col, bpp)).data();
321 int r = src_port[2] & 0xf0;
322 int g = src_port[1] & 0xf0;
323 int b = src_port[0] & 0xf0;
324 uint32_t clrindex = (r << 4) + g + (b >> 4);
325 for (size_t i = luts.size(); i > 0; --i) {
326 if (clrindex == luts[i - 1].second) {
327 *(dest_scan + col) =
static_cast<uint8_t>(luts[i - 1].first);
334 pdfium::span<
const uint32_t> src_palette_span = src_palette.GetPalette();
335 return DataVector<uint32_t>(src_palette_span.begin(), src_palette_span.end());
338void ConvertBuffer_1bppMask2Rgb(
FXDIB_Format dest_format,
339 pdfium::span<uint8_t> dest_buf,
347 static constexpr uint8_t kSetGray = 0xff;
348 static constexpr uint8_t kResetGray = 0x00;
349 for (
int row = 0; row < height; ++row) {
351 dest_buf.subspan(Fx2DSizeOrDie(row, dest_pitch)).data();
352 const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row).data();
353 for (
int col = src_left; col < src_left + width; ++col) {
355 (src_scan[col / 8] & (1 << (7 - col % 8))) ? kSetGray : kResetGray;
356 memset(dest_scan, value, 3);
362void ConvertBuffer_8bppMask2Rgb(
FXDIB_Format dest_format,
363 pdfium::span<uint8_t> dest_buf,
371 for (
int row = 0; row < height; ++row) {
373 dest_buf.subspan(Fx2DSizeOrDie(row, dest_pitch)).data();
374 const uint8_t* src_scan =
375 pSrcBitmap->GetScanline(src_top + row).subspan(src_left).data();
376 for (
int col = 0; col < width; ++col) {
377 memset(dest_scan, *src_scan, 3);
385 pdfium::span<uint8_t> dest_buf,
392 pdfium::span<
const uint32_t> src_palette = pSrcBitmap->GetPaletteSpan();
393 const uint8_t dst_palette[6] = {
398 for (
int row = 0; row < height; ++row) {
400 dest_buf.subspan(Fx2DSizeOrDie(row, dest_pitch)).data();
401 const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row).data();
402 for (
int col = src_left; col < src_left + width; ++col) {
403 size_t offset = (src_scan[col / 8] & (1 << (7 - col % 8))) ? 3 : 0;
404 memcpy(dest_scan, dst_palette + offset, 3);
411 pdfium::span<uint8_t> dest_buf,
418 pdfium::span<
const uint32_t> src_palette = pSrcBitmap->GetPaletteSpan();
419 uint8_t dst_palette[768];
420 for (
int i = 0; i < 256; ++i) {
421 dst_palette[3 * i] =
FXARGB_B(src_palette[i]);
422 dst_palette[3 * i + 1] =
FXARGB_G(src_palette[i]);
423 dst_palette[3 * i + 2] =
FXARGB_R(src_palette[i]);
426 for (
int row = 0; row < height; ++row) {
428 dest_buf.subspan(Fx2DSizeOrDie(row, dest_pitch)).data();
429 const uint8_t* src_scan =
430 pSrcBitmap->GetScanline(src_top + row).subspan(src_left).data();
431 for (
int col = 0; col < width; ++col) {
432 uint8_t* src_pixel = dst_palette + 3 * (*src_scan++);
433 memcpy(dest_scan, src_pixel, 3);
439void ConvertBuffer_24bppRgb2Rgb24(
440 pdfium::span<uint8_t> dest_buf,
447 const size_t x_offset = Fx2DSizeOrDie(src_left, 3);
448 const size_t byte_count = Fx2DSizeOrDie(width, 3);
449 for (
int row = 0; row < height; ++row) {
451 dest_buf.subspan(Fx2DSizeOrDie(row, dest_pitch)),
452 pSrcBitmap->GetScanline(src_top + row).subspan(x_offset, byte_count));
456void ConvertBuffer_32bppRgb2Rgb24(
457 pdfium::span<uint8_t> dest_buf,
464 const size_t x_offset = Fx2DSizeOrDie(src_left, 4);
465 for (
int row = 0; row < height; ++row) {
467 dest_buf.subspan(Fx2DSizeOrDie(row, dest_pitch)).data();
468 const uint8_t* src_scan =
469 pSrcBitmap->GetScanline(src_top + row).subspan(x_offset).data();
470 for (
int col = 0; col < width; ++col) {
471 memcpy(dest_scan, src_scan, 3);
478void ConvertBuffer_Rgb2Rgb32(pdfium::span<uint8_t> dest_buf,
485 const int comps = pSrcBitmap->GetBPP() / 8;
486 const size_t x_offset = Fx2DSizeOrDie(src_left, comps);
487 for (
int row = 0; row < height; ++row) {
489 dest_buf.subspan(Fx2DSizeOrDie(row, dest_pitch)).data();
490 const uint8_t* src_scan =
491 pSrcBitmap->GetScanline(src_top + row).subspan(x_offset).data();
492 for (
int col = 0; col < width; ++col) {
493 memcpy(dest_scan, src_scan, 3);
500void ConvertBuffer_8bppMask(
int bpp,
501 pdfium::span<uint8_t> dest_buf,
510 if (pSrcBitmap->HasPalette()) {
511 ConvertBuffer_1bppPlt2Gray(dest_buf, dest_pitch, width, height,
512 pSrcBitmap, src_left, src_top);
514 ConvertBuffer_1bppMask2Gray(dest_buf, dest_pitch, width, height,
515 pSrcBitmap, src_left, src_top);
519 if (pSrcBitmap->HasPalette()) {
520 ConvertBuffer_8bppPlt2Gray(dest_buf, dest_pitch, width, height,
521 pSrcBitmap, src_left, src_top);
523 ConvertBuffer_8bppMask2Gray(dest_buf, dest_pitch, width, height,
524 pSrcBitmap, src_left, src_top);
529 ConvertBuffer_Rgb2Gray(dest_buf, dest_pitch, width, height, pSrcBitmap,
533 NOTREACHED_NORETURN();
537void ConvertBuffer_Rgb(
int bpp,
539 pdfium::span<uint8_t> dest_buf,
548 if (pSrcBitmap->HasPalette()) {
549 ConvertBuffer_1bppPlt2Rgb(dest_format, dest_buf, dest_pitch, width,
550 height, pSrcBitmap, src_left, src_top);
552 ConvertBuffer_1bppMask2Rgb(dest_format, dest_buf, dest_pitch, width,
553 height, pSrcBitmap, src_left, src_top);
557 if (pSrcBitmap->HasPalette()) {
558 ConvertBuffer_8bppPlt2Rgb(dest_format, dest_buf, dest_pitch, width,
559 height, pSrcBitmap, src_left, src_top);
561 ConvertBuffer_8bppMask2Rgb(dest_format, dest_buf, dest_pitch, width,
562 height, pSrcBitmap, src_left, src_top);
566 ConvertBuffer_24bppRgb2Rgb24(dest_buf, dest_pitch, width, height,
567 pSrcBitmap, src_left, src_top);
570 ConvertBuffer_32bppRgb2Rgb24(dest_buf, dest_pitch, width, height,
571 pSrcBitmap, src_left, src_top);
574 NOTREACHED_NORETURN();
578void ConvertBuffer_Argb(
int bpp,
580 pdfium::span<uint8_t> dest_buf,
589 if (pSrcBitmap->HasPalette()) {
590 ConvertBuffer_1bppPlt2Rgb(dest_format, dest_buf, dest_pitch, width,
591 height, pSrcBitmap, src_left, src_top);
593 ConvertBuffer_1bppMask2Rgb(dest_format, dest_buf, dest_pitch, width,
594 height, pSrcBitmap, src_left, src_top);
598 if (pSrcBitmap->HasPalette()) {
599 ConvertBuffer_8bppPlt2Rgb(dest_format, dest_buf, dest_pitch, width,
600 height, pSrcBitmap, src_left, src_top);
602 ConvertBuffer_8bppMask2Rgb(dest_format, dest_buf, dest_pitch, width,
603 height, pSrcBitmap, src_left, src_top);
608 ConvertBuffer_Rgb2Rgb32(dest_buf, dest_pitch, width, height, pSrcBitmap,
612 NOTREACHED_NORETURN();
627 return GetRequiredPaletteSize() *
sizeof(uint32_t);
630#if BUILDFLAG(IS_WIN) || defined(PDF_USE_SKIA)
631RetainPtr<
const CFX_DIBitmap> CFX_DIBBase::RealizeIfNeeded()
const {
652 auto pNewBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
656 pNewBitmap->SetPalette(GetPaletteSpan());
658 int left_shift = rect
.left % 32;
659 int right_shift = 32 - left_shift;
660 int dword_count = pNewBitmap->m_Pitch / 4;
661 for (
int row = rect
.top; row < rect
.bottom; ++row) {
663 auto dst_span =
fxcrt::reinterpret_span<uint32_t>(
664 pNewBitmap->GetWritableScanline(row - rect
.top));
666 const uint32_t* src_scan =
667 src_span.subspan(rect
.left / 32, dword_count + 1).data();
668 uint32_t* dst_scan = dst_span.first(dword_count).data();
669 for (
int i = 0; i < dword_count; ++i) {
671 (src_scan[i] << left_shift) | (src_scan[i + 1] >> right_shift);
675 absl::optional<uint32_t> copy_len = fxge::CalculatePitch8(
676 pNewBitmap->GetBPP(), 1, pNewBitmap->GetWidth());
677 if (!copy_len.has_value()) {
681 copy_len = std::min<uint32_t>(m_Pitch, copy_len.value());
683 FX_SAFE_UINT32 offset = rect.left;
686 if (!offset.IsValid())
689 for (
int row = rect
.top; row < rect
.bottom; ++row) {
690 const uint8_t* src_scan =
691 GetScanline(row).subspan(offset.ValueOrDie()).data();
693 pNewBitmap->GetWritableScanline(row - rect
.top).data();
694 memcpy(dest_scan, src_scan, copy_len.value());
705 m_palette = {0xff000000, 0xffffffff};
707 m_palette.resize(256);
708 for (
int i = 0; i < 256; ++i)
709 m_palette[i] = ArgbEncode(0xff, i, i, i);
728 DCHECK((GetBPP() == 1 || GetBPP() == 8) && !IsMaskFormat());
730 return GetPaletteSpan()[index];
733 return index ? 0xffffffff : 0xff000000;
739 DCHECK((GetBPP() == 1 || GetBPP() == 8) && !IsMaskFormat());
741 m_palette[index] = color;
745 DCHECK((GetBPP() == 1 || GetBPP() == 8) && !IsMaskFormat());
748 pdfium::span<
const uint32_t> palette = GetPaletteSpan();
749 for (
int i = 0; i < palsize; ++i) {
750 if (palette[i] == color)
757 return (
static_cast<uint8_t>(color) == 0xff) ? 1 : 0;
758 return static_cast<uint8_t>(color);
770 if (width == 0 || height == 0)
774 DCHECK_GT(height, 0);
779 FX_SAFE_INT32 safe_src_width = src_left;
780 safe_src_width += width;
781 if (!safe_src_width.IsValid())
784 FX_SAFE_INT32 safe_src_height = src_top;
785 safe_src_height += height;
786 if (!safe_src_height.IsValid())
789 FX_RECT src_rect(src_left, src_top, safe_src_width.ValueOrDie(),
790 safe_src_height.ValueOrDie());
794 FX_SAFE_INT32 safe_x_offset = dest_left;
795 safe_x_offset -= src_left;
796 if (!safe_x_offset.IsValid())
799 FX_SAFE_INT32 safe_y_offset = dest_top;
800 safe_y_offset -= src_top;
801 if (!safe_y_offset.IsValid())
804 FX_SAFE_INT32 safe_dest_left = safe_x_offset;
805 safe_dest_left += src_rect
.left;
806 if (!safe_dest_left.IsValid())
809 FX_SAFE_INT32 safe_dest_top = safe_y_offset;
810 safe_dest_top += src_rect
.top;
811 if (!safe_dest_top.IsValid())
814 FX_SAFE_INT32 safe_dest_right = safe_x_offset;
815 safe_dest_right += src_rect
.right;
816 if (!safe_dest_right.IsValid())
819 FX_SAFE_INT32 safe_dest_bottom = safe_y_offset;
820 safe_dest_bottom += src_rect
.bottom;
821 if (!safe_dest_bottom.IsValid())
824 FX_RECT dest_rect(safe_dest_left.ValueOrDie(), safe_dest_top.ValueOrDie(),
825 safe_dest_right.ValueOrDie(),
826 safe_dest_bottom.ValueOrDie());
832 dest_left = dest_rect
.left;
833 dest_top = dest_rect
.top;
835 FX_SAFE_INT32 safe_new_src_left = dest_left;
836 safe_new_src_left -= safe_x_offset;
837 if (!safe_new_src_left.IsValid())
839 src_left = safe_new_src_left.ValueOrDie();
841 FX_SAFE_INT32 safe_new_src_top = dest_top;
842 safe_new_src_top -= safe_y_offset;
843 if (!safe_new_src_top.IsValid())
845 src_top = safe_new_src_top.ValueOrDie();
856 TakePalette(DataVector<uint32_t>(src_palette.begin(), src_palette.end()));
860 if (src_palette.empty() ||
GetBPP() > 8) {
865 m_palette = std::move(src_palette);
868 m_palette.resize(pal_size);
873 auto pMask = pdfium::MakeRetain<CFX_DIBitmap>();
877 for (
int row = 0; row <
m_Height; ++row) {
878 const uint8_t* src_scan =
GetScanline(row).subspan(3).data();
879 uint8_t* dest_scan = pMask->GetWritableScanline(row).data();
880 for (
int col = 0; col <
m_Width; ++col) {
881 *dest_scan++ = *src_scan;
889 auto pFlipped = pdfium::MakeRetain<CFX_DIBitmap>();
893 pFlipped->SetPalette(GetPaletteSpan());
895 for (
int row = 0; row <
m_Height; ++row) {
898 pFlipped->GetWritableScanline(bYFlip ?
m_Height - row - 1 : row).data();
900 memcpy(dest_scan, src_scan,
m_Pitch);
905 for (
int col = 0; col <
m_Width; ++col) {
906 if (src_scan[col / 8] & (1 << (7 - col % 8))) {
907 int dest_col =
m_Width - col - 1;
908 dest_scan[dest_col / 8] |= (1 << (7 - dest_col % 8));
914 dest_scan += (
m_Width - 1) * Bpp;
916 for (
int col = 0; col <
m_Width; ++col) {
917 *dest_scan = *src_scan;
921 }
else if (Bpp == 3) {
922 for (
int col = 0; col <
m_Width; ++col) {
923 memcpy(dest_scan, src_scan, 3);
929 for (
int col = 0; col <
m_Width; ++col) {
930 const auto* src_scan32 =
reinterpret_cast<
const uint32_t*>(src_scan);
931 uint32_t* dest_scan32 =
reinterpret_cast<uint32_t*>(dest_scan);
932 *dest_scan32 = *src_scan32;
942 if (dest_format == GetFormat())
945 auto pClone = pdfium::MakeRetain<CFX_DIBitmap>();
950 if (!pClone->SetUniformOpaqueAlpha()) {
956 DataVector<uint32_t> pal_8bpp =
957 ConvertBuffer(dest_format, pClone->GetWritableBuffer(),
958 pClone->GetPitch(), m_Width, m_Height, holder, 0, 0);
959 if (!pal_8bpp.empty()) {
960 pClone->TakePalette(
std::move(pal_8bpp));
970 auto pTransBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
971 const int result_height = dest_clip
.Height();
972 const int result_width = dest_clip
.Width();
973 if (!pTransBitmap->Create(result_width, result_height,
GetFormat()))
976 pTransBitmap->SetPalette(GetPaletteSpan());
977 const int dest_pitch = pTransBitmap->GetPitch();
978 pdfium::span<uint8_t> dest_span = pTransBitmap->GetWritableBuffer().first(
979 Fx2DSizeOrDie(dest_pitch, result_height));
980 const size_t dest_last_row_offset =
981 Fx2DSizeOrDie(dest_pitch, result_height - 1);
987 fxcrt::spanset(dest_span, 0xff);
989 dest_span = dest_span.subspan(dest_last_row_offset);
990 const int dest_step = bYFlip ? -dest_pitch : dest_pitch;
991 for (
int row = row_start; row < row_end; ++row) {
993 int dest_col = (bXFlip ? dest_clip
.right - (row - row_start) - 1 : row) -
995 uint8_t* dest_scan = dest_span.data();
996 for (
int col = col_start; col < col_end; ++col) {
997 if (!(src_scan[col / 8] & (1 << (7 - col % 8))))
998 dest_scan[dest_col / 8] &= ~(1 << (7 - dest_col % 8));
999 dest_scan += dest_step;
1004 int dest_step = bYFlip ? -dest_pitch : dest_pitch;
1008 dest_span = dest_span.subspan(dest_last_row_offset);
1009 for (
int row = row_start; row < row_end; ++row) {
1010 int dest_col = (bXFlip ? dest_clip
.right - (row - row_start) - 1 : row) -
1012 size_t dest_offset = Fx2DSizeOrDie(dest_col, nBytes);
1013 uint8_t* dest_scan = dest_span.subspan(dest_offset).data();
1015 const uint32_t* src_scan =
1019 for (
int col = col_start; col < col_end; ++col) {
1020 uint32_t* dest_scan32 =
reinterpret_cast<uint32_t*>(dest_scan);
1021 *dest_scan32 = *src_scan++;
1022 dest_scan += dest_step;
1025 const uint8_t* src_scan =
1026 GetScanline(row).subspan(col_start * nBytes).data();
1028 for (
int col = col_start; col < col_end; ++col) {
1029 *dest_scan = *src_scan++;
1030 dest_scan += dest_step;
1033 for (
int col = col_start; col < col_end; ++col) {
1034 memcpy(dest_scan, src_scan, 3);
1035 dest_scan += 2 + dest_step;
1042 return pTransBitmap;
1047 int* result_top)
const {
1063 FX_RECT clip_rect
(0
, 0
, abs(dest_width)
, abs(dest_height)
);
1070 if (dest_width == m_Width && dest_height == m_Height)
1071 return ClipTo(clip_rect);
1073 CFX_BitmapStorer storer;
1075 clip_rect, options);
1085 pdfium::span<uint8_t> dest_buf,
1094 switch (dest_format) {
1096 ConvertBuffer_8bppMask(src_bpp, dest_buf, dest_pitch, width, height,
1097 pSrcBitmap, src_left, src_top);
1101 if (src_bpp == 1 || src_bpp == 8) {
1102 if (pSrcBitmap->HasPalette()) {
1103 return ConvertBuffer_Plt2PltRgb8(dest_buf, dest_pitch, width, height,
1104 pSrcBitmap, src_left, src_top);
1106 return ConvertBuffer(FXDIB_Format::k8bppMask, dest_buf, dest_pitch,
1107 width, height, pSrcBitmap, src_left, src_top);
1109 CHECK_GE(src_bpp, 24);
1110 return ConvertBuffer_Rgb2PltRgb8(dest_buf, dest_pitch, width, height,
1111 pSrcBitmap, src_left, src_top);
1114 ConvertBuffer_Rgb(src_bpp, dest_format, dest_buf, dest_pitch, width,
1115 height, pSrcBitmap, src_left, src_top);
1120 ConvertBuffer_Argb(src_bpp, dest_format, dest_buf, dest_pitch, width,
1121 height, pSrcBitmap, src_left, src_top);
1125 NOTREACHED_NORETURN();
RetainPtr< CFX_DIBitmap > Detach()
const FX_RECT & GetBox() const
int FindPalette(uint32_t color) const
virtual size_t GetEstimatedImageMemoryBurden() const
RetainPtr< CFX_DIBitmap > ClipTo(const FX_RECT &rect) const
RetainPtr< CFX_DIBitmap > Realize() const
RetainPtr< CFX_DIBitmap > SwapXY(bool bXFlip, bool bYFlip) const
void TakePalette(DataVector< uint32_t > src_palette)
virtual pdfium::span< const uint8_t > GetScanline(int line) const =0
virtual bool SkipToScanline(int line, PauseIndicatorIface *pPause) const
RetainPtr< CFX_DIBitmap > CloneAlphaMask() const
void SetPalette(pdfium::span< const uint32_t > src_palette)
FXDIB_Format GetFormat() const
bool GetOverlapRect(int &dest_left, int &dest_top, int &width, int &height, int src_width, int src_height, int &src_left, int &src_top, const CFX_ClipRgn *pClipRgn) const
RetainPtr< CFX_DIBitmap > TransformTo(const CFX_Matrix &mtDest, int *left, int *top) const
void SetPaletteArgb(int index, uint32_t color)
RetainPtr< CFX_DIBitmap > ClipToInternal(const FX_RECT *pClip) const
RetainPtr< CFX_DIBitmap > ConvertTo(FXDIB_Format format) const
RetainPtr< CFX_DIBitmap > StretchTo(int dest_width, int dest_height, const FXDIB_ResampleOptions &options, const FX_RECT *pClip) const
static constexpr uint32_t kPaletteSize
size_t GetRequiredPaletteSize() const
bool IsMaskFormat() const
RetainPtr< CFX_DIBitmap > FlipImage(bool bXFlip, bool bYFlip) const
uint32_t GetPaletteArgb(int index) const
bool Continue(PauseIndicatorIface *pPause)
#define FXRGB2GRAY(r, g, b)
constexpr FX_ARGB ArgbEncode(uint32_t a, uint32_t r, uint32_t g, uint32_t b)
int GetBppFromFormat(FXDIB_Format format)
int GetCompsFromFormat(FXDIB_Format format)
void Intersect(const FX_RECT &src)
constexpr FX_RECT(int l, int t, int r, int b)