BinaryFormat.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*
  2. * Copyright (c) 2023, Nico Weber <thakis@chromium.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Endian.h>
  8. #include <LibGfx/ICC/DistinctFourCC.h>
  9. #include <LibGfx/ICC/Profile.h>
  10. #include <LibGfx/ICC/TagTypes.h>
  11. #include <math.h>
  12. namespace Gfx::ICC {
  13. // ICC V4, 4.2 dateTimeNumber
  14. // "All the dateTimeNumber values in a profile shall be in Coordinated Universal Time [...]."
  15. struct DateTimeNumber {
  16. BigEndian<u16> year;
  17. BigEndian<u16> month;
  18. BigEndian<u16> day;
  19. BigEndian<u16> hours;
  20. BigEndian<u16> minutes;
  21. BigEndian<u16> seconds;
  22. };
  23. // ICC V4, 4.6 s15Fixed16Number
  24. using s15Fixed16Number = i32;
  25. // ICC V4, 4.7 u16Fixed16Number
  26. using u16Fixed16Number = u32;
  27. // ICC V4, 4.14 XYZNumber
  28. struct XYZNumber {
  29. BigEndian<s15Fixed16Number> X;
  30. BigEndian<s15Fixed16Number> Y;
  31. BigEndian<s15Fixed16Number> Z;
  32. XYZNumber() = default;
  33. XYZNumber(XYZ const& xyz)
  34. : X(round(xyz.X * 0x1'0000))
  35. , Y(round(xyz.Y * 0x1'0000))
  36. , Z(round(xyz.Z * 0x1'0000))
  37. {
  38. }
  39. operator XYZ() const
  40. {
  41. return XYZ { X / (float)0x1'0000, Y / (float)0x1'0000, Z / (float)0x1'0000 };
  42. }
  43. };
  44. // ICC V4, 7.2 Profile header
  45. struct ICCHeader {
  46. BigEndian<u32> profile_size;
  47. BigEndian<PreferredCMMType> preferred_cmm_type;
  48. u8 profile_version_major;
  49. u8 profile_version_minor_bugfix;
  50. BigEndian<u16> profile_version_zero;
  51. BigEndian<DeviceClass> profile_device_class;
  52. BigEndian<ColorSpace> data_color_space;
  53. BigEndian<ColorSpace> profile_connection_space; // "PCS" in the spec.
  54. DateTimeNumber profile_creation_time;
  55. BigEndian<u32> profile_file_signature;
  56. BigEndian<PrimaryPlatform> primary_platform;
  57. BigEndian<u32> profile_flags;
  58. BigEndian<DeviceManufacturer> device_manufacturer;
  59. BigEndian<DeviceModel> device_model;
  60. BigEndian<u64> device_attributes;
  61. BigEndian<RenderingIntent> rendering_intent;
  62. XYZNumber pcs_illuminant;
  63. BigEndian<Creator> profile_creator;
  64. u8 profile_id[16];
  65. u8 reserved[28];
  66. };
  67. static_assert(AssertSize<ICCHeader, 128>());
  68. // ICC v4, 7.2.9 Profile file signature field
  69. // "The profile file signature field shall contain the value “acsp” (61637370h) as a profile file signature."
  70. constexpr u32 ProfileFileSignature = 0x61637370;
  71. // ICC V4, 7.3 Tag table, Table 24 - Tag table structure
  72. struct TagTableEntry {
  73. BigEndian<TagSignature> tag_signature;
  74. BigEndian<u32> offset_to_beginning_of_tag_data_element;
  75. BigEndian<u32> size_of_tag_data_element;
  76. };
  77. static_assert(AssertSize<TagTableEntry, 12>());
  78. // Common bits of ICC v4, Table 40 — lut16Type encoding and Table 44 — lut8Type encoding
  79. struct LUTHeader {
  80. u8 number_of_input_channels;
  81. u8 number_of_output_channels;
  82. u8 number_of_clut_grid_points;
  83. u8 reserved_for_padding;
  84. BigEndian<s15Fixed16Number> e_parameters[9];
  85. };
  86. static_assert(AssertSize<LUTHeader, 40>());
  87. // Common bits of ICC v4, Table 45 — lutAToBType encoding and Table 47 — lutBToAType encoding
  88. struct AdvancedLUTHeader {
  89. u8 number_of_input_channels;
  90. u8 number_of_output_channels;
  91. BigEndian<u16> reserved_for_padding;
  92. BigEndian<u32> offset_to_b_curves;
  93. BigEndian<u32> offset_to_matrix;
  94. BigEndian<u32> offset_to_m_curves;
  95. BigEndian<u32> offset_to_clut;
  96. BigEndian<u32> offset_to_a_curves;
  97. };
  98. static_assert(AssertSize<AdvancedLUTHeader, 24>());
  99. // ICC v4, Table 46 — lutAToBType CLUT encoding
  100. // ICC v4, Table 48 — lutBToAType CLUT encoding
  101. // (They're identical.)
  102. struct CLUTHeader {
  103. u8 number_of_grid_points_in_dimension[16];
  104. u8 precision_of_data_elements; // 1 for u8 entries, 2 for u16 entries.
  105. u8 reserved_for_padding[3];
  106. };
  107. static_assert(AssertSize<CLUTHeader, 20>());
  108. // Table 49 — measurementType structure
  109. struct MeasurementHeader {
  110. BigEndian<MeasurementTagData::StandardObserver> standard_observer;
  111. XYZNumber tristimulus_value_for_measurement_backing;
  112. BigEndian<MeasurementTagData::MeasurementGeometry> measurement_geometry;
  113. BigEndian<u16Fixed16Number> measurement_flare;
  114. BigEndian<MeasurementTagData::StandardIlluminant> standard_illuminant;
  115. };
  116. static_assert(AssertSize<MeasurementHeader, 28>());
  117. // ICC v4, 10.15 multiLocalizedUnicodeType
  118. struct MultiLocalizedUnicodeRawRecord {
  119. BigEndian<u16> language_code;
  120. BigEndian<u16> country_code;
  121. BigEndian<u32> string_length_in_bytes;
  122. BigEndian<u32> string_offset_in_bytes;
  123. };
  124. static_assert(AssertSize<MultiLocalizedUnicodeRawRecord, 12>());
  125. // Table 66 — namedColor2Type encoding
  126. struct NamedColorHeader {
  127. BigEndian<u32> vendor_specific_flag;
  128. BigEndian<u32> count_of_named_colors;
  129. BigEndian<u32> number_of_device_coordinates_of_each_named_color;
  130. u8 prefix_for_each_color_name[32]; // null-terminated
  131. u8 suffix_for_each_color_name[32]; // null-terminated
  132. };
  133. static_assert(AssertSize<NamedColorHeader, 76>());
  134. // Table 84 — viewingConditionsType encoding
  135. struct ViewingConditionsHeader {
  136. XYZNumber unnormalized_ciexyz_values_for_illuminant; // "(in which Y is in cd/m2)"
  137. XYZNumber unnormalized_ciexyz_values_for_surround; // "(in which Y is in cd/m2)"
  138. BigEndian<MeasurementTagData::StandardIlluminant> illuminant_type;
  139. };
  140. static_assert(AssertSize<ViewingConditionsHeader, 28>());
  141. }