mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 16:32:45 +00:00 
			
		
		
		
	LibGfx: Add ICCProfile support for textType
This is used in v2 profiles for the required 'cprt' tag.
This commit is contained in:
		
							parent
							
								
									d33eef14a0
								
							
						
					
					
						commit
						3dfb012a1a
					
				
					 2 changed files with 70 additions and 5 deletions
				
			
		|  | @ -532,6 +532,48 @@ DeviceAttributes::DeviceAttributes(u64 bits) | |||
| { | ||||
| } | ||||
| 
 | ||||
| static TagTypeSignature tag_type(ReadonlyBytes tag_bytes) | ||||
| { | ||||
|     VERIFY(tag_bytes.size() >= sizeof(u32)); | ||||
|     return *bit_cast<BigEndian<TagTypeSignature> const*>(tag_bytes.data()); | ||||
| } | ||||
| 
 | ||||
| static ErrorOr<void> check_reserved(ReadonlyBytes tag_bytes) | ||||
| { | ||||
|     if (tag_bytes.size() < 2 * sizeof(u32)) | ||||
|         return Error::from_string_literal("ICC::Profile: Not enough data for tag reserved field"); | ||||
| 
 | ||||
|     if (*bit_cast<BigEndian<u32> const*>(tag_bytes.data() + sizeof(u32)) != 0) | ||||
|         return Error::from_string_literal("ICC::Profile: tag reserved field not 0"); | ||||
| 
 | ||||
|     return {}; | ||||
| } | ||||
| 
 | ||||
| ErrorOr<NonnullRefPtr<TextTagData>> TextTagData::from_bytes(ReadonlyBytes bytes, u32 offset, u32 size) | ||||
| { | ||||
|     // ICC v4, 10.24 textType
 | ||||
|     VERIFY(tag_type(bytes) == TextTagData::Type); | ||||
|     TRY(check_reserved(bytes)); | ||||
| 
 | ||||
|     // "The textType is a simple text structure that contains a 7-bit ASCII text string. The length of the string is obtained
 | ||||
|     //  by subtracting 8 from the element size portion of the tag itself. This string shall be terminated with a 00h byte."
 | ||||
|     u32 length = bytes.size() - 8; | ||||
| 
 | ||||
|     u8 const* text_data = bytes.data() + 8; | ||||
|     for (u32 i = 0; i < length; ++i) { | ||||
|         if (text_data[i] >= 128) | ||||
|             return Error::from_string_literal("ICC::Profile: textType data not 7-byte ASCII"); | ||||
|     } | ||||
| 
 | ||||
|     if (length == 0) | ||||
|         return Error::from_string_literal("ICC::Profile: textType too short for \\0 byte"); | ||||
| 
 | ||||
|     if (text_data[length - 1] != '\0') | ||||
|         return Error::from_string_literal("ICC::Profile: textType data not \\0-terminated"); | ||||
| 
 | ||||
|     return adopt_ref(*new TextTagData(offset, size, TRY(String::from_utf8(StringView(text_data, length - 1))))); | ||||
| } | ||||
| 
 | ||||
| ErrorOr<void> Profile::read_header(ReadonlyBytes bytes) | ||||
| { | ||||
|     if (bytes.size() < sizeof(ICCHeader)) | ||||
|  | @ -574,12 +616,14 @@ ErrorOr<NonnullRefPtr<TagData>> Profile::read_tag(ReadonlyBytes bytes, Detail::T | |||
|     //  what kind of data is contained within a tag."
 | ||||
|     if (tag_bytes.size() < sizeof(u32)) | ||||
|         return Error::from_string_literal("ICC::Profile: Not enough data for tag type"); | ||||
|     auto tag_type = *bit_cast<BigEndian<TagTypeSignature> const*>(tag_bytes.data()); | ||||
| 
 | ||||
|     switch ((u32)(TagTypeSignature)tag_type) { | ||||
|     auto type = tag_type(tag_bytes); | ||||
|     switch (type) { | ||||
|     case TextTagData::Type: | ||||
|         return TextTagData::from_bytes(tag_bytes, entry.offset_to_beginning_of_tag_data_element, entry.size_of_tag_data_element); | ||||
|     default: | ||||
|         // FIXME: optionally ignore tags of unknown type
 | ||||
|         return adopt_ref(*new UnknownTagData(entry.offset_to_beginning_of_tag_data_element, entry.size_of_tag_data_element, tag_type)); | ||||
|         return adopt_ref(*new UnknownTagData(entry.offset_to_beginning_of_tag_data_element, entry.size_of_tag_data_element, type)); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -12,6 +12,7 @@ | |||
| #include <AK/NonnullRefPtr.h> | ||||
| #include <AK/RefCounted.h> | ||||
| #include <AK/Span.h> | ||||
| #include <AK/String.h> | ||||
| #include <AK/URL.h> | ||||
| #include <LibCrypto/Hash/MD5.h> | ||||
| 
 | ||||
|  | @ -31,11 +32,11 @@ enum class FourCCType { | |||
| 
 | ||||
| template<FourCCType type> | ||||
| struct [[gnu::packed]] DistinctFourCC { | ||||
|     explicit DistinctFourCC(u32 value) | ||||
|     constexpr explicit DistinctFourCC(u32 value) | ||||
|         : value(value) | ||||
|     { | ||||
|     } | ||||
|     explicit operator u32() const { return value; } | ||||
|     constexpr operator u32() const { return value; } | ||||
| 
 | ||||
|     char c0() const { return value >> 24; } | ||||
|     char c1() const { return (value >> 16) & 0xff; } | ||||
|  | @ -256,6 +257,26 @@ public: | |||
|     } | ||||
| }; | ||||
| 
 | ||||
| // ICC v4, 10.24 textType
 | ||||
| class TextTagData : public TagData { | ||||
| public: | ||||
|     static constexpr TagTypeSignature Type { 0x74657874 }; // 'text'
 | ||||
| 
 | ||||
|     static ErrorOr<NonnullRefPtr<TextTagData>> from_bytes(ReadonlyBytes, u32 offset, u32 size); | ||||
| 
 | ||||
|     TextTagData(u32 offset, u32 size, String text) | ||||
|         : TagData(offset, size, Type) | ||||
|         , m_text(move(text)) | ||||
|     { | ||||
|     } | ||||
| 
 | ||||
|     // Guaranteed to be 7-bit ASCII.
 | ||||
|     String const& text() const { return m_text; } | ||||
| 
 | ||||
| private: | ||||
|     String m_text; | ||||
| }; | ||||
| 
 | ||||
| namespace Detail { | ||||
| struct TagTableEntry; | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Nico Weber
						Nico Weber