mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 01:22:43 +00:00 
			
		
		
		
	LibGfx+Userland: Make PNGWriter::encode() return ErrorOr<ByteBuffer>
This is a first step towards handling PNG encoding failures instead of just falling over and crashing the program. This initial step will cause encode() to return an error if the final ByteBuffer copy fails to allocate. There are more potential failures that will be surfaced by subsequent commits. Two FIXMEs were killed in the making of this patch. :^)
This commit is contained in:
		
							parent
							
								
									95b4ffad39
								
							
						
					
					
						commit
						d88c7fee32
					
				
					 9 changed files with 18 additions and 13 deletions
				
			
		|  | @ -744,7 +744,7 @@ ErrorOr<void> BrowserWindow::take_screenshot(ScreenshotType type) | ||||||
|     LexicalPath path { Core::StandardPaths::downloads_directory() }; |     LexicalPath path { Core::StandardPaths::downloads_directory() }; | ||||||
|     path = path.append(Core::DateTime::now().to_deprecated_string("screenshot-%Y-%m-%d-%H-%M-%S.png"sv)); |     path = path.append(Core::DateTime::now().to_deprecated_string("screenshot-%Y-%m-%d-%H-%M-%S.png"sv)); | ||||||
| 
 | 
 | ||||||
|     auto encoded = Gfx::PNGWriter::encode(*bitmap.bitmap()); |     auto encoded = TRY(Gfx::PNGWriter::encode(*bitmap.bitmap())); | ||||||
| 
 | 
 | ||||||
|     auto screenshot_file = TRY(Core::Stream::File::open(path.string(), Core::Stream::OpenMode::Write)); |     auto screenshot_file = TRY(Core::Stream::File::open(path.string(), Core::Stream::OpenMode::Write)); | ||||||
|     TRY(screenshot_file->write(encoded)); |     TRY(screenshot_file->write(encoded)); | ||||||
|  |  | ||||||
|  | @ -193,7 +193,7 @@ ErrorOr<void> Image::export_png_to_file(Core::File& file, bool preserve_alpha_ch | ||||||
|     auto bitmap_format = preserve_alpha_channel ? Gfx::BitmapFormat::BGRA8888 : Gfx::BitmapFormat::BGRx8888; |     auto bitmap_format = preserve_alpha_channel ? Gfx::BitmapFormat::BGRA8888 : Gfx::BitmapFormat::BGRx8888; | ||||||
|     auto bitmap = TRY(try_compose_bitmap(bitmap_format)); |     auto bitmap = TRY(try_compose_bitmap(bitmap_format)); | ||||||
| 
 | 
 | ||||||
|     auto encoded_data = Gfx::PNGWriter::encode(*bitmap); |     auto encoded_data = TRY(Gfx::PNGWriter::encode(*bitmap)); | ||||||
|     if (!file.write(encoded_data.data(), encoded_data.size())) |     if (!file.write(encoded_data.data(), encoded_data.size())) | ||||||
|         return Error::from_errno(file.error()); |         return Error::from_errno(file.error()); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -377,7 +377,7 @@ ErrorOr<void> Mandelbrot::export_image(DeprecatedString const& export_path, Imag | ||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
|     case ImageType::PNG: |     case ImageType::PNG: | ||||||
|         encoded_data = Gfx::PNGWriter::encode(m_set.bitmap()); |         encoded_data = TRY(Gfx::PNGWriter::encode(m_set.bitmap())); | ||||||
|         break; |         break; | ||||||
|     case ImageType::QOI: |     case ImageType::QOI: | ||||||
|         encoded_data = Gfx::QOIWriter::encode(m_set.bitmap()); |         encoded_data = Gfx::QOIWriter::encode(m_set.bitmap()); | ||||||
|  |  | ||||||
|  | @ -261,15 +261,14 @@ void PNGWriter::add_IDAT_chunk(Gfx::Bitmap const& bitmap) | ||||||
|     add_chunk(png_chunk); |     add_chunk(png_chunk); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ByteBuffer PNGWriter::encode(Gfx::Bitmap const& bitmap) | ErrorOr<ByteBuffer> PNGWriter::encode(Gfx::Bitmap const& bitmap) | ||||||
| { | { | ||||||
|     PNGWriter writer; |     PNGWriter writer; | ||||||
|     writer.add_png_header(); |     writer.add_png_header(); | ||||||
|     writer.add_IHDR_chunk(bitmap.width(), bitmap.height(), 8, PNG::ColorType::TruecolorWithAlpha, 0, 0, 0); |     writer.add_IHDR_chunk(bitmap.width(), bitmap.height(), 8, PNG::ColorType::TruecolorWithAlpha, 0, 0, 0); | ||||||
|     writer.add_IDAT_chunk(bitmap); |     writer.add_IDAT_chunk(bitmap); | ||||||
|     writer.add_IEND_chunk(); |     writer.add_IEND_chunk(); | ||||||
|     // FIXME: Handle OOM failure.
 |     return ByteBuffer::copy(writer.m_data); | ||||||
|     return ByteBuffer::copy(writer.m_data).release_value_but_fixme_should_propagate_errors(); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -17,7 +17,7 @@ class PNGChunk; | ||||||
| 
 | 
 | ||||||
| class PNGWriter { | class PNGWriter { | ||||||
| public: | public: | ||||||
|     static ByteBuffer encode(Gfx::Bitmap const&); |     static ErrorOr<ByteBuffer> encode(Gfx::Bitmap const&); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     PNGWriter() = default; |     PNGWriter() = default; | ||||||
|  |  | ||||||
|  | @ -176,8 +176,12 @@ DeprecatedString HTMLCanvasElement::to_data_url(DeprecatedString const& type, [[ | ||||||
|         return {}; |         return {}; | ||||||
|     if (type != "image/png") |     if (type != "image/png") | ||||||
|         return {}; |         return {}; | ||||||
|     auto encoded_bitmap = Gfx::PNGWriter::encode(*m_bitmap); |     auto encoded_bitmap_or_error = Gfx::PNGWriter::encode(*m_bitmap); | ||||||
|     return AK::URL::create_with_data(type, encode_base64(encoded_bitmap), true).to_deprecated_string(); |     if (encoded_bitmap_or_error.is_error()) { | ||||||
|  |         dbgln("Gfx::PNGWriter failed to encode the HTMLCanvasElement: {}", encoded_bitmap_or_error.error()); | ||||||
|  |         return {}; | ||||||
|  |     } | ||||||
|  |     return AK::URL::create_with_data(type, encode_base64(encoded_bitmap_or_error.value()), true).to_deprecated_string(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void HTMLCanvasElement::present() | void HTMLCanvasElement::present() | ||||||
|  |  | ||||||
|  | @ -79,7 +79,7 @@ void SpiceAgent::on_message_received() | ||||||
|         ReadonlyBytes bytes; |         ReadonlyBytes bytes; | ||||||
|         if (mime == "image/x-serenityos") { |         if (mime == "image/x-serenityos") { | ||||||
|             auto bitmap = m_clipboard_connection.get_bitmap(); |             auto bitmap = m_clipboard_connection.get_bitmap(); | ||||||
|             backing_byte_buffer = Gfx::PNGWriter::encode(*bitmap); |             backing_byte_buffer = MUST(Gfx::PNGWriter::encode(*bitmap)); | ||||||
|             bytes = backing_byte_buffer; |             bytes = backing_byte_buffer; | ||||||
|         } else { |         } else { | ||||||
|             auto data = clipboard.data(); |             auto data = clipboard.data(); | ||||||
|  |  | ||||||
|  | @ -703,7 +703,7 @@ static void load_page_for_screenshot_and_exit(HeadlessBrowserPageClient& page_cl | ||||||
| 
 | 
 | ||||||
|             page_client.paint(output_rect, output_bitmap); |             page_client.paint(output_rect, output_bitmap); | ||||||
| 
 | 
 | ||||||
|             auto image_buffer = Gfx::PNGWriter::encode(output_bitmap); |             auto image_buffer = MUST(Gfx::PNGWriter::encode(output_bitmap)); | ||||||
|             MUST(output_file->write(image_buffer.bytes())); |             MUST(output_file->write(image_buffer.bytes())); | ||||||
| 
 | 
 | ||||||
|             exit(0); |             exit(0); | ||||||
|  |  | ||||||
|  | @ -151,11 +151,13 @@ ErrorOr<int> serenity_main(Main::Arguments arguments) | ||||||
|         return 0; |         return 0; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     auto encoded_bitmap = Gfx::PNGWriter::encode(*bitmap); |     auto encoded_bitmap_or_error = Gfx::PNGWriter::encode(*bitmap); | ||||||
|     if (encoded_bitmap.is_empty()) { |     if (encoded_bitmap_or_error.is_error()) { | ||||||
|         warnln("Failed to encode PNG"); |         warnln("Failed to encode PNG"); | ||||||
|         return 1; |         return 1; | ||||||
|     } |     } | ||||||
|  |     auto encoded_bitmap = encoded_bitmap_or_error.release_value(); | ||||||
|  | 
 | ||||||
|     if (edit_image) |     if (edit_image) | ||||||
|         output_path = Core::DateTime::now().to_deprecated_string("/tmp/screenshot-%Y-%m-%d-%H-%M-%S.png"sv); |         output_path = Core::DateTime::now().to_deprecated_string("/tmp/screenshot-%Y-%m-%d-%H-%M-%S.png"sv); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling