mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 17:12:43 +00:00 
			
		
		
		
	LibGfx: Port ICOLoader to the new AK::Stream
This commit is contained in:
		
							parent
							
								
									492d5d7cb2
								
							
						
					
					
						commit
						e7cc426e05
					
				
					 1 changed files with 30 additions and 18 deletions
				
			
		|  | @ -6,7 +6,7 @@ | ||||||
| 
 | 
 | ||||||
| #include <AK/ByteBuffer.h> | #include <AK/ByteBuffer.h> | ||||||
| #include <AK/Debug.h> | #include <AK/Debug.h> | ||||||
| #include <AK/DeprecatedMemoryStream.h> | #include <AK/MemoryStream.h> | ||||||
| #include <AK/NonnullOwnPtrVector.h> | #include <AK/NonnullOwnPtrVector.h> | ||||||
| #include <AK/Types.h> | #include <AK/Types.h> | ||||||
| #include <LibGfx/BMPLoader.h> | #include <LibGfx/BMPLoader.h> | ||||||
|  | @ -36,6 +36,22 @@ struct ICONDIRENTRY { | ||||||
| }; | }; | ||||||
| static_assert(AssertSize<ICONDIRENTRY, 16>()); | static_assert(AssertSize<ICONDIRENTRY, 16>()); | ||||||
| 
 | 
 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | template<> | ||||||
|  | class AK::Traits<Gfx::ICONDIR> : public GenericTraits<Gfx::ICONDIR> { | ||||||
|  | public: | ||||||
|  |     static constexpr bool is_trivially_serializable() { return true; } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | template<> | ||||||
|  | class AK::Traits<Gfx::ICONDIRENTRY> : public GenericTraits<Gfx::ICONDIRENTRY> { | ||||||
|  | public: | ||||||
|  |     static constexpr bool is_trivially_serializable() { return true; } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | namespace Gfx { | ||||||
|  | 
 | ||||||
| struct ICOImageDescriptor { | struct ICOImageDescriptor { | ||||||
|     u16 width; |     u16 width; | ||||||
|     u16 height; |     u16 height; | ||||||
|  | @ -59,23 +75,17 @@ struct ICOLoadingContext { | ||||||
|     size_t largest_index; |     size_t largest_index; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static ErrorOr<size_t> decode_ico_header(DeprecatedInputMemoryStream& stream) | static ErrorOr<size_t> decode_ico_header(AK::Stream& stream) | ||||||
| { | { | ||||||
|     ICONDIR header; |     auto header = TRY(stream.read_value<ICONDIR>()); | ||||||
|     stream >> Bytes { &header, sizeof(header) }; |  | ||||||
|     TRY(stream.try_handle_any_error()); |  | ||||||
| 
 |  | ||||||
|     if (header.must_be_0 != 0 || header.must_be_1 != 1) |     if (header.must_be_0 != 0 || header.must_be_1 != 1) | ||||||
|         return Error::from_string_literal("Invalid ICO header"); |         return Error::from_string_literal("Invalid ICO header"); | ||||||
|     return { header.image_count }; |     return { header.image_count }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static ErrorOr<ICOImageDescriptor> decode_ico_direntry(DeprecatedInputMemoryStream& stream) | static ErrorOr<ICOImageDescriptor> decode_ico_direntry(AK::Stream& stream) | ||||||
| { | { | ||||||
|     ICONDIRENTRY entry; |     auto entry = TRY(stream.read_value<ICONDIRENTRY>()); | ||||||
|     stream >> Bytes { &entry, sizeof(entry) }; |  | ||||||
|     TRY(stream.try_handle_any_error()); |  | ||||||
| 
 |  | ||||||
|     ICOImageDescriptor desc = { entry.width, entry.height, entry.bits_per_pixel, entry.offset, entry.size, nullptr }; |     ICOImageDescriptor desc = { entry.width, entry.height, entry.bits_per_pixel, entry.offset, entry.size, nullptr }; | ||||||
|     if (desc.width == 0) |     if (desc.width == 0) | ||||||
|         desc.width = 256; |         desc.width = 256; | ||||||
|  | @ -106,14 +116,14 @@ static size_t find_largest_image(ICOLoadingContext const& context) | ||||||
| 
 | 
 | ||||||
| static ErrorOr<void> load_ico_directory(ICOLoadingContext& context) | static ErrorOr<void> load_ico_directory(ICOLoadingContext& context) | ||||||
| { | { | ||||||
|     DeprecatedInputMemoryStream stream { { context.data, context.data_size } }; |     auto stream = TRY(FixedMemoryStream::construct({ context.data, context.data_size })); | ||||||
| 
 | 
 | ||||||
|     auto image_count = TRY(decode_ico_header(stream)); |     auto image_count = TRY(decode_ico_header(*stream)); | ||||||
|     if (image_count == 0) |     if (image_count == 0) | ||||||
|         return Error::from_string_literal("ICO file has no images"); |         return Error::from_string_literal("ICO file has no images"); | ||||||
| 
 | 
 | ||||||
|     for (size_t i = 0; i < image_count; ++i) { |     for (size_t i = 0; i < image_count; ++i) { | ||||||
|         auto desc = TRY(decode_ico_direntry(stream)); |         auto desc = TRY(decode_ico_direntry(*stream)); | ||||||
|         if (desc.offset + desc.size < desc.offset // detect integer overflow
 |         if (desc.offset + desc.size < desc.offset // detect integer overflow
 | ||||||
|             || (desc.offset + desc.size) > context.data_size) { |             || (desc.offset + desc.size) > context.data_size) { | ||||||
|             dbgln_if(ICO_DEBUG, "load_ico_directory: offset: {} size: {} doesn't fit in ICO size: {}", desc.offset, desc.size, context.data_size); |             dbgln_if(ICO_DEBUG, "load_ico_directory: offset: {} size: {} doesn't fit in ICO size: {}", desc.offset, desc.size, context.data_size); | ||||||
|  | @ -173,8 +183,8 @@ ErrorOr<void> ICOImageDecoderPlugin::load_ico_bitmap(ICOLoadingContext& context, | ||||||
| 
 | 
 | ||||||
| ErrorOr<bool> ICOImageDecoderPlugin::sniff(ReadonlyBytes data) | ErrorOr<bool> ICOImageDecoderPlugin::sniff(ReadonlyBytes data) | ||||||
| { | { | ||||||
|     DeprecatedInputMemoryStream stream { { data.data(), data.size() } }; |     auto stream = TRY(FixedMemoryStream::construct(data)); | ||||||
|     return !decode_ico_header(stream).is_error(); |     return !decode_ico_header(*stream).is_error(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ErrorOr<NonnullOwnPtr<ImageDecoderPlugin>> ICOImageDecoderPlugin::create(ReadonlyBytes data) | ErrorOr<NonnullOwnPtr<ImageDecoderPlugin>> ICOImageDecoderPlugin::create(ReadonlyBytes data) | ||||||
|  | @ -223,8 +233,10 @@ bool ICOImageDecoderPlugin::set_nonvolatile(bool& was_purged) | ||||||
| 
 | 
 | ||||||
| bool ICOImageDecoderPlugin::initialize() | bool ICOImageDecoderPlugin::initialize() | ||||||
| { | { | ||||||
|     DeprecatedInputMemoryStream stream { { m_context->data, m_context->data_size } }; |     auto stream_or_error = FixedMemoryStream::construct(ReadonlyBytes { m_context->data, m_context->data_size }); | ||||||
|     return !decode_ico_header(stream).is_error(); |     if (stream_or_error.is_error()) | ||||||
|  |         return false; | ||||||
|  |     return !decode_ico_header(*stream_or_error.value()).is_error(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool ICOImageDecoderPlugin::is_animated() | bool ICOImageDecoderPlugin::is_animated() | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Karol Kosek
						Karol Kosek