mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 21:22:46 +00:00 
			
		
		
		
	LibGfx: Move ICC on-disk structs to new BinaryFormat.h
Removes some existing code duplication and allows future files to use these structs too.
This commit is contained in:
		
							parent
							
								
									2a1cd84155
								
							
						
					
					
						commit
						429467f46c
					
				
					 3 changed files with 113 additions and 110 deletions
				
			
		
							
								
								
									
										111
									
								
								Userland/Libraries/LibGfx/ICC/BinaryFormat.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								Userland/Libraries/LibGfx/ICC/BinaryFormat.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,111 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2023, Nico Weber <thakis@chromium.org> | ||||
|  * | ||||
|  * SPDX-License-Identifier: BSD-2-Clause | ||||
|  */ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <AK/Endian.h> | ||||
| #include <LibGfx/ICC/DistinctFourCC.h> | ||||
| #include <LibGfx/ICC/Profile.h> | ||||
| #include <LibGfx/ICC/TagTypes.h> | ||||
| 
 | ||||
| namespace Gfx::ICC { | ||||
| 
 | ||||
| // ICC V4, 4.2 dateTimeNumber
 | ||||
| // "All the dateTimeNumber values in a profile shall be in Coordinated Universal Time [...]."
 | ||||
| struct DateTimeNumber { | ||||
|     BigEndian<u16> year; | ||||
|     BigEndian<u16> month; | ||||
|     BigEndian<u16> day; | ||||
|     BigEndian<u16> hours; | ||||
|     BigEndian<u16> minutes; | ||||
|     BigEndian<u16> seconds; | ||||
| }; | ||||
| 
 | ||||
| // ICC V4, 4.6 s15Fixed16Number
 | ||||
| using s15Fixed16Number = i32; | ||||
| 
 | ||||
| // ICC V4, 4.7 u16Fixed16Number
 | ||||
| using u16Fixed16Number = u32; | ||||
| 
 | ||||
| // ICC V4, 4.14 XYZNumber
 | ||||
| struct XYZNumber { | ||||
|     BigEndian<s15Fixed16Number> x; | ||||
|     BigEndian<s15Fixed16Number> y; | ||||
|     BigEndian<s15Fixed16Number> z; | ||||
| 
 | ||||
|     operator XYZ() const | ||||
|     { | ||||
|         return XYZ { x / (double)0x1'0000, y / (double)0x1'0000, z / (double)0x1'0000 }; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| // ICC V4, 7.2 Profile header
 | ||||
| struct ICCHeader { | ||||
|     BigEndian<u32> profile_size; | ||||
|     BigEndian<PreferredCMMType> preferred_cmm_type; | ||||
| 
 | ||||
|     u8 profile_version_major; | ||||
|     u8 profile_version_minor_bugfix; | ||||
|     BigEndian<u16> profile_version_zero; | ||||
| 
 | ||||
|     BigEndian<DeviceClass> profile_device_class; | ||||
|     BigEndian<ColorSpace> data_color_space; | ||||
|     BigEndian<ColorSpace> profile_connection_space; // "PCS" in the spec.
 | ||||
| 
 | ||||
|     DateTimeNumber profile_creation_time; | ||||
| 
 | ||||
|     BigEndian<u32> profile_file_signature; | ||||
|     BigEndian<PrimaryPlatform> primary_platform; | ||||
| 
 | ||||
|     BigEndian<u32> profile_flags; | ||||
|     BigEndian<DeviceManufacturer> device_manufacturer; | ||||
|     BigEndian<DeviceModel> device_model; | ||||
|     BigEndian<u64> device_attributes; | ||||
|     BigEndian<u32> rendering_intent; | ||||
| 
 | ||||
|     XYZNumber pcs_illuminant; | ||||
| 
 | ||||
|     BigEndian<Creator> profile_creator; | ||||
| 
 | ||||
|     u8 profile_id[16]; | ||||
|     u8 reserved[28]; | ||||
| }; | ||||
| static_assert(AssertSize<ICCHeader, 128>()); | ||||
| 
 | ||||
| // Common bits of ICC v4, Table 40 — lut16Type encoding and Table 44 — lut8Type encoding
 | ||||
| struct LUTHeader { | ||||
|     u8 number_of_input_channels; | ||||
|     u8 number_of_output_channels; | ||||
|     u8 number_of_clut_grid_points; | ||||
|     u8 reserved_for_padding; | ||||
|     BigEndian<s15Fixed16Number> e_parameters[9]; | ||||
| }; | ||||
| static_assert(AssertSize<LUTHeader, 40>()); | ||||
| 
 | ||||
| // Common bits of ICC v4, Table 45 — lutAToBType encoding and Table 47 — lutBToAType encoding
 | ||||
| struct AdvancedLUTHeader { | ||||
|     u8 number_of_input_channels; | ||||
|     u8 number_of_output_channels; | ||||
|     BigEndian<u16> reserved_for_padding; | ||||
|     BigEndian<u32> offset_to_b_curves; | ||||
|     BigEndian<u32> offset_to_matrix; | ||||
|     BigEndian<u32> offset_to_m_curves; | ||||
|     BigEndian<u32> offset_to_clut; | ||||
|     BigEndian<u32> offset_to_a_curves; | ||||
| }; | ||||
| static_assert(AssertSize<AdvancedLUTHeader, 24>()); | ||||
| 
 | ||||
| // ICC v4, Table 46 — lutAToBType CLUT encoding
 | ||||
| // ICC v4, Table 48 — lutBToAType CLUT encoding
 | ||||
| // (They're identical.)
 | ||||
| struct CLUTHeader { | ||||
|     u8 number_of_grid_points_in_dimension[16]; | ||||
|     u8 precision_of_data_elements; // 1 for u8 entries, 2 for u16 entries.
 | ||||
|     u8 reserved_for_padding[3]; | ||||
| }; | ||||
| static_assert(AssertSize<CLUTHeader, 20>()); | ||||
| 
 | ||||
| } | ||||
|  | @ -5,6 +5,7 @@ | |||
|  */ | ||||
| 
 | ||||
| #include <AK/Endian.h> | ||||
| #include <LibGfx/ICC/BinaryFormat.h> | ||||
| #include <LibGfx/ICC/Profile.h> | ||||
| #include <LibGfx/ICC/Tags.h> | ||||
| #include <math.h> | ||||
|  | @ -17,32 +18,6 @@ namespace Gfx::ICC { | |||
| 
 | ||||
| namespace { | ||||
| 
 | ||||
| // ICC V4, 4.2 dateTimeNumber
 | ||||
| // "All the dateTimeNumber values in a profile shall be in Coordinated Universal Time [...]."
 | ||||
| struct DateTimeNumber { | ||||
|     BigEndian<u16> year; | ||||
|     BigEndian<u16> month; | ||||
|     BigEndian<u16> day; | ||||
|     BigEndian<u16> hours; | ||||
|     BigEndian<u16> minutes; | ||||
|     BigEndian<u16> seconds; | ||||
| }; | ||||
| 
 | ||||
| // ICC V4, 4.6 s15Fixed16Number
 | ||||
| using s15Fixed16Number = i32; | ||||
| 
 | ||||
| // ICC V4, 4.14 XYZNumber
 | ||||
| struct XYZNumber { | ||||
|     BigEndian<s15Fixed16Number> x; | ||||
|     BigEndian<s15Fixed16Number> y; | ||||
|     BigEndian<s15Fixed16Number> z; | ||||
| 
 | ||||
|     operator XYZ() const | ||||
|     { | ||||
|         return XYZ { x / (double)0x1'0000, y / (double)0x1'0000, z / (double)0x1'0000 }; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| ErrorOr<time_t> parse_date_time_number(DateTimeNumber const& date_time) | ||||
| { | ||||
|     // ICC V4, 4.2 dateTimeNumber
 | ||||
|  | @ -84,39 +59,6 @@ ErrorOr<time_t> parse_date_time_number(DateTimeNumber const& date_time) | |||
|     return timestamp; | ||||
| } | ||||
| 
 | ||||
| // ICC V4, 7.2 Profile header
 | ||||
| struct ICCHeader { | ||||
|     BigEndian<u32> profile_size; | ||||
|     BigEndian<PreferredCMMType> preferred_cmm_type; | ||||
| 
 | ||||
|     u8 profile_version_major; | ||||
|     u8 profile_version_minor_bugfix; | ||||
|     BigEndian<u16> profile_version_zero; | ||||
| 
 | ||||
|     BigEndian<DeviceClass> profile_device_class; | ||||
|     BigEndian<ColorSpace> data_color_space; | ||||
|     BigEndian<ColorSpace> profile_connection_space; // "PCS" in the spec.
 | ||||
| 
 | ||||
|     DateTimeNumber profile_creation_time; | ||||
| 
 | ||||
|     BigEndian<u32> profile_file_signature; | ||||
|     BigEndian<PrimaryPlatform> primary_platform; | ||||
| 
 | ||||
|     BigEndian<u32> profile_flags; | ||||
|     BigEndian<DeviceManufacturer> device_manufacturer; | ||||
|     BigEndian<DeviceModel> device_model; | ||||
|     BigEndian<u64> device_attributes; | ||||
|     BigEndian<u32> rendering_intent; | ||||
| 
 | ||||
|     XYZNumber pcs_illuminant; | ||||
| 
 | ||||
|     BigEndian<Creator> profile_creator; | ||||
| 
 | ||||
|     u8 profile_id[16]; | ||||
|     u8 reserved[28]; | ||||
| }; | ||||
| static_assert(AssertSize<ICCHeader, 128>()); | ||||
| 
 | ||||
| ErrorOr<u32> parse_size(ICCHeader const& header, ReadonlyBytes icc_bytes) | ||||
| { | ||||
|     // ICC v4, 7.2.2 Profile size field
 | ||||
|  |  | |||
|  | @ -6,6 +6,7 @@ | |||
| 
 | ||||
| #include <AK/DeprecatedString.h> | ||||
| #include <AK/Endian.h> | ||||
| #include <LibGfx/ICC/BinaryFormat.h> | ||||
| #include <LibGfx/ICC/TagTypes.h> | ||||
| #include <LibGfx/ICC/Tags.h> | ||||
| #include <LibTextCodec/Decoder.h> | ||||
|  | @ -14,57 +15,6 @@ namespace Gfx::ICC { | |||
| 
 | ||||
| namespace { | ||||
| 
 | ||||
| // ICC V4, 4.6 s15Fixed16Number
 | ||||
| using s15Fixed16Number = i32; | ||||
| 
 | ||||
| // ICC V4, 4.7 u16Fixed16Number
 | ||||
| using u16Fixed16Number = u32; | ||||
| 
 | ||||
| // ICC V4, 4.14 XYZNumber
 | ||||
| struct XYZNumber { | ||||
|     BigEndian<s15Fixed16Number> x; | ||||
|     BigEndian<s15Fixed16Number> y; | ||||
|     BigEndian<s15Fixed16Number> z; | ||||
| 
 | ||||
|     operator XYZ() const | ||||
|     { | ||||
|         return XYZ { x / (double)0x1'0000, y / (double)0x1'0000, z / (double)0x1'0000 }; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| // Common bits of ICC v4, Table 40 — lut16Type encoding and Table 44 — lut8Type encoding
 | ||||
| struct LUTHeader { | ||||
|     u8 number_of_input_channels; | ||||
|     u8 number_of_output_channels; | ||||
|     u8 number_of_clut_grid_points; | ||||
|     u8 reserved_for_padding; | ||||
|     BigEndian<s15Fixed16Number> e_parameters[9]; | ||||
| }; | ||||
| static_assert(AssertSize<LUTHeader, 40>()); | ||||
| 
 | ||||
| // Common bits of ICC v4, Table 45 — lutAToBType encoding and Table 47 — lutBToAType encoding
 | ||||
| struct AdvancedLUTHeader { | ||||
|     u8 number_of_input_channels; | ||||
|     u8 number_of_output_channels; | ||||
|     BigEndian<u16> reserved_for_padding; | ||||
|     BigEndian<u32> offset_to_b_curves; | ||||
|     BigEndian<u32> offset_to_matrix; | ||||
|     BigEndian<u32> offset_to_m_curves; | ||||
|     BigEndian<u32> offset_to_clut; | ||||
|     BigEndian<u32> offset_to_a_curves; | ||||
| }; | ||||
| static_assert(AssertSize<AdvancedLUTHeader, 24>()); | ||||
| 
 | ||||
| // ICC v4, Table 46 — lutAToBType CLUT encoding
 | ||||
| // ICC v4, Table 48 — lutBToAType CLUT encoding
 | ||||
| // (They're identical.)
 | ||||
| struct CLUTHeader { | ||||
|     u8 number_of_grid_points_in_dimension[16]; | ||||
|     u8 precision_of_data_elements; // 1 for u8 entries, 2 for u16 entries.
 | ||||
|     u8 reserved_for_padding[3]; | ||||
| }; | ||||
| static_assert(AssertSize<CLUTHeader, 20>()); | ||||
| 
 | ||||
| ErrorOr<void> check_reserved(ReadonlyBytes tag_bytes) | ||||
| { | ||||
|     if (tag_bytes.size() < 2 * sizeof(u32)) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Nico Weber
						Nico Weber