5#include "core/fxge/dib/cfx_dibbase.h"
14#include "core/fxcrt/check_op.h"
15#include "core/fxcrt/compiler_specific.h"
16#include "core/fxcrt/fx_2d_size.h"
17#include "core/fxcrt/fx_memory.h"
18#include "core/fxcrt/fx_memory_wrappers.h"
19#include "core/fxcrt/fx_safe_types.h"
20#include "core/fxcrt/notreached.h"
21#include "core/fxcrt/retain_ptr.h"
22#include "core/fxcrt/span.h"
23#include "core/fxge/calculate_pitch.h"
24#include "core/fxge/dib/cfx_dibitmap.h"
25#include "core/fxge/dib/fx_dib.h"
26#include "third_party/skia/include/core/SkAlphaType.h"
27#include "third_party/skia/include/core/SkColor.h"
28#include "third_party/skia/include/core/SkColorPriv.h"
29#include "third_party/skia/include/core/SkColorType.h"
30#include "third_party/skia/include/core/SkImage.h"
31#include "third_party/skia/include/core/SkImageInfo.h"
32#include "third_party/skia/include/core/SkPixmap.h"
33#include "third_party/skia/include/core/SkRefCnt.h"
38void ReleaseRetainedHeldBySkImage(
const void* ,
39 SkImages::ReleaseContext context) {
40 RetainPtr<
const CFX_DIBitmap> realized_bitmap;
41 realized_bitmap.Unleak(
reinterpret_cast<
const CFX_DIBitmap*>(context));
45sk_sp<SkImage> CreateSkiaImageFromDib(
const CFX_DIBBase* source,
46 SkColorType color_type,
47 SkAlphaType alpha_type) {
49 RetainPtr<
const CFX_DIBitmap> realized_bitmap = source->RealizeIfNeeded();
50 if (!realized_bitmap) {
53 CHECK(!realized_bitmap->GetBuffer().empty());
57 const CFX_DIBitmap* bitmap = realized_bitmap.Leak();
58 SkImageInfo info = SkImageInfo::Make(bitmap->GetWidth(), bitmap->GetHeight(),
59 color_type, alpha_type);
60 auto result = SkImages::RasterFromPixmap(
61 SkPixmap(info, bitmap->GetBuffer().data(), bitmap->GetPitch()),
62 ReleaseRetainedHeldBySkImage,
63 const_cast<CFX_DIBitmap*>(bitmap));
69void ReleaseAllocatedHeldBySkImage(
const void* pixels,
70 SkImages::ReleaseContext ) {
71 FX_Free
(const_cast<
void*>(pixels));
75template <size_t source_bits_per_pixel,
typename PixelTransform>
76class PixelTransformTraits;
78template <
typename PixelTransform>
79class PixelTransformTraits<1, PixelTransform> {
81 using Result = std::invoke_result_t<PixelTransform,
bool>;
83 static Result Invoke(PixelTransform&& pixel_transform,
84 pdfium::span<
const uint8_t> scanline,
86 uint8_t kMask = 1 << (7 - column % 8);
87 return pixel_transform(!!(scanline[column / 8] & kMask));
91template <
typename PixelTransform>
92class PixelTransformTraits<8, PixelTransform> {
94 using Result = std::invoke_result_t<PixelTransform, uint8_t>;
96 static Result Invoke(PixelTransform&& pixel_transform,
97 pdfium::span<
const uint8_t> scanline,
99 return pixel_transform(scanline[column]);
103template <
typename PixelTransform>
104class PixelTransformTraits<24, PixelTransform> {
107 std::invoke_result_t<PixelTransform, uint8_t, uint8_t, uint8_t>;
109 static Result Invoke(PixelTransform&& pixel_transform,
110 pdfium::span<
const uint8_t> scanline,
112 size_t offset = column * 3;
113 return pixel_transform(scanline[offset + 2], scanline[offset + 1],
118template <
typename PixelTransform>
119class PixelTransformTraits<32, PixelTransform> {
122 std::invoke_result_t<PixelTransform, uint8_t, uint8_t, uint8_t>;
124 static Result Invoke(PixelTransform&& pixel_transform,
125 pdfium::span<
const uint8_t> scanline,
127 size_t offset = column * 4;
128 return pixel_transform(scanline[offset + 2], scanline[offset + 1],
133void ValidateScanlineSize(pdfium::span<
const uint8_t> scanline,
134 size_t min_row_bytes) {
135 DCHECK_GE(scanline.size(), min_row_bytes);
142template <size_t source_bits_per_pixel,
typename PixelTransform>
143sk_sp<SkImage> CreateSkiaImageFromTransformedDib(
145 SkColorType color_type,
146 SkAlphaType alpha_type,
147 PixelTransform&& pixel_transform) {
148 using Traits = PixelTransformTraits<source_bits_per_pixel, PixelTransform>;
149 using Result =
typename Traits::Result;
154 SkImageInfo info = SkImageInfo::Make(width, height, color_type, alpha_type);
155 DCHECK_EQ(info.minRowBytes(), width *
sizeof(Result));
157 size_t output_size = Fx2DSizeOrDie(info.minRowBytes(), height);
159 FX_TryAlloc(uint8_t, output_size));
165 Result* output_cursor =
reinterpret_cast<Result*>(output.get());
166 const size_t min_row_bytes =
171 for (
int row = 0; row < height; ++row) {
172 pdfium::span<
const uint8_t> scanline = source.GetScanline(line++);
173 ValidateScanlineSize(scanline, min_row_bytes);
175 for (
int column = 0; column < width; ++column) {
177 std::forward<PixelTransform>(pixel_transform), scanline, column);
182 return SkImages::RasterFromPixmap(
183 SkPixmap(info, output.release(), info.minRowBytes()),
184 ReleaseAllocatedHeldBySkImage,
188bool IsRGBColorGrayScale(uint32_t color) {
195sk_sp<SkImage>
CFX_DIBBase::RealizeSkImage()
const {
200 uint8_t color0 = 0x00;
201 uint8_t color1 = 0xFF;
206 bool use_gray_colors = IsRGBColorGrayScale(palette_color0) &&
207 IsRGBColorGrayScale(palette_color1);
208 if (!use_gray_colors) {
209 return CreateSkiaImageFromTransformedDib<1>(
210 *
this, kBGRA_8888_SkColorType, kPremul_SkAlphaType,
211 [palette_color0, palette_color1](
bool bit) {
212 return bit ? palette_color1 : palette_color0;
220 return CreateSkiaImageFromTransformedDib<1>(
221 *
this, IsMaskFormat() ? kAlpha_8_SkColorType : kGray_8_SkColorType,
223 [color0, color1](
bool bit) {
return bit ? color1 : color0; });
229 return CreateSkiaImageFromTransformedDib<8>(
230 *
this, kBGRA_8888_SkColorType, kPremul_SkAlphaType,
231 [palette = GetPaletteSpan().first(GetRequiredPaletteSize())](
233 if (index >= palette.size()) {
236 return palette[index];
239 return CreateSkiaImageFromDib(
240 this, IsMaskFormat() ? kAlpha_8_SkColorType : kGray_8_SkColorType,
241 kPremul_SkAlphaType);
244 return CreateSkiaImageFromTransformedDib<24>(
245 *
this, kBGRA_8888_SkColorType, kOpaque_SkAlphaType,
246 [](uint8_t red, uint8_t green, uint8_t blue) {
247 return SkPackARGB32(0xFF, red, green, blue);
252 case FXDIB_Format::kBgrx:
253 return CreateSkiaImageFromTransformedDib<
255 *
this, kBGRA_8888_SkColorType, kOpaque_SkAlphaType,
256 [](uint8_t red, uint8_t green, uint8_t blue) {
257 return SkPackARGB32(0xFF, red, green, blue);
259 case FXDIB_Format::kBgra:
260 return CreateSkiaImageFromDib(
this, kBGRA_8888_SkColorType,
261 kUnpremul_SkAlphaType);
262 case FXDIB_Format::kBgraPremul:
263 return CreateSkiaImageFromDib(
this, kBGRA_8888_SkColorType,
264 kPremul_SkAlphaType);
FXDIB_Format GetFormat() const
uint32_t GetPitch() const
uint32_t GetPaletteArgb(int index) const
uint32_t CalculatePitch8OrDie(uint32_t bits_per_component, uint32_t components_per_pixel, int width_in_pixels)
#define NOTREACHED_NORETURN()