@@ -89,7 +89,8 @@ static SkColorType export_format_to_skia_color_type(ExportFormat format)
8989 case ExportFormat::RGBA4444:
9090 return SkColorType::kARGB_4444_SkColorType ;
9191 case ExportFormat::RGB888:
92- return SkColorType::kRGB_888x_SkColorType ;
92+ // This one needs to be converted manually because Skia has no valid 24-bit color type.
93+ VERIFY_NOT_REACHED ();
9394 case ExportFormat::RGBA8888:
9495 return SkColorType::kRGBA_8888_SkColorType ;
9596 default :
@@ -102,6 +103,12 @@ ErrorOr<BitmapExportResult> ImmutableBitmap::export_to_byte_buffer(ExportFormat
102103 int width = target_width.value_or (this ->width ());
103104 int height = target_height.value_or (this ->height ());
104105
106+ if (format == ExportFormat::RGB888 && (width != this ->width () || height != this ->height ())) {
107+ dbgln (" FIXME: Ignoring target width and height because scaling is not implemented for this export format." );
108+ width = this ->width ();
109+ height = this ->height ();
110+ }
111+
105112 Checked<size_t > buffer_pitch = width;
106113 int number_of_bytes = bytes_per_pixel_for_export_format (format);
107114 buffer_pitch *= number_of_bytes;
@@ -114,21 +121,36 @@ ErrorOr<BitmapExportResult> ImmutableBitmap::export_to_byte_buffer(ExportFormat
114121 auto buffer = MUST (ByteBuffer::create_zeroed (buffer_pitch.value () * height));
115122
116123 if (width > 0 && height > 0 ) {
117- auto skia_format = export_format_to_skia_color_type (format);
118- auto color_space = SkColorSpace::MakeSRGB ();
119-
120- auto image_info = SkImageInfo::Make (width, height, skia_format, flags & ExportFlags::PremultiplyAlpha ? SkAlphaType::kPremul_SkAlphaType : SkAlphaType::kUnpremul_SkAlphaType , color_space);
121- auto surface = SkSurfaces::WrapPixels (image_info, buffer.data (), buffer_pitch.value ());
122- VERIFY (surface);
123- auto * surface_canvas = surface->getCanvas ();
124- auto dst_rect = Gfx::to_skia_rect (Gfx::Rect { 0 , 0 , width, height });
125-
126- if (flags & ExportFlags::FlipY) {
127- surface_canvas->translate (0 , dst_rect.height ());
128- surface_canvas->scale (1 , -1 );
124+ if (format == ExportFormat::RGB888) {
125+ // 24 bit RGB is not supported by Skia, so we need to handle this format ourselves.
126+ auto raw_buffer = buffer.data ();
127+ for (auto y = 0 ; y < height; y++) {
128+ auto target_y = flags & ExportFlags::FlipY ? height - y - 1 : y;
129+ for (auto x = 0 ; x < width; x++) {
130+ auto pixel = get_pixel (x, y);
131+ auto buffer_offset = (target_y * buffer_pitch.value ()) + (x * 3ull );
132+ raw_buffer[buffer_offset + 0 ] = pixel.red ();
133+ raw_buffer[buffer_offset + 1 ] = pixel.green ();
134+ raw_buffer[buffer_offset + 2 ] = pixel.blue ();
135+ }
136+ }
137+ } else {
138+ auto skia_format = export_format_to_skia_color_type (format);
139+ auto color_space = SkColorSpace::MakeSRGB ();
140+
141+ auto image_info = SkImageInfo::Make (width, height, skia_format, flags & ExportFlags::PremultiplyAlpha ? SkAlphaType::kPremul_SkAlphaType : SkAlphaType::kUnpremul_SkAlphaType , color_space);
142+ auto surface = SkSurfaces::WrapPixels (image_info, buffer.data (), buffer_pitch.value ());
143+ VERIFY (surface);
144+ auto * surface_canvas = surface->getCanvas ();
145+ auto dst_rect = Gfx::to_skia_rect (Gfx::Rect { 0 , 0 , width, height });
146+
147+ if (flags & ExportFlags::FlipY) {
148+ surface_canvas->translate (0 , dst_rect.height ());
149+ surface_canvas->scale (1 , -1 );
150+ }
151+
152+ surface_canvas->drawImageRect (sk_image (), dst_rect, Gfx::to_skia_sampling_options (Gfx::ScalingMode::NearestNeighbor));
129153 }
130-
131- surface_canvas->drawImageRect (sk_image (), dst_rect, Gfx::to_skia_sampling_options (Gfx::ScalingMode::NearestNeighbor));
132154 } else {
133155 VERIFY (buffer.is_empty ());
134156 }
0 commit comments