jpeg_data.h (7176B)
1 // Copyright (c) the JPEG XL Project Authors. All rights reserved. 2 // 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 5 6 // Data structures that represent the non-pixel contents of a jpeg file. 7 8 #ifndef LIB_JXL_JPEG_JPEG_DATA_H_ 9 #define LIB_JXL_JPEG_JPEG_DATA_H_ 10 11 #include <array> 12 #include <cstddef> 13 #include <cstdint> 14 #include <vector> 15 16 #include "lib/jxl/base/status.h" 17 #include "lib/jxl/common.h" // JPEGXL_ENABLE_TRANSCODE_JPEG 18 #include "lib/jxl/field_encodings.h" 19 #include "lib/jxl/fields.h" 20 #include "lib/jxl/frame_dimensions.h" 21 22 namespace jxl { 23 namespace jpeg { 24 25 constexpr int kMaxComponents = 4; 26 constexpr int kMaxQuantTables = 4; 27 constexpr int kMaxHuffmanTables = 4; 28 constexpr size_t kJpegHuffmanMaxBitLength = 16; 29 constexpr int kJpegHuffmanAlphabetSize = 256; 30 constexpr int kJpegDCAlphabetSize = 12; 31 constexpr int kMaxDHTMarkers = 512; 32 constexpr int kMaxDimPixels = 65535; 33 constexpr uint8_t kApp1 = 0xE1; 34 constexpr uint8_t kApp2 = 0xE2; 35 const uint8_t kIccProfileTag[12] = "ICC_PROFILE"; 36 const uint8_t kExifTag[6] = "Exif\0"; 37 const uint8_t kXMPTag[29] = "http://ns.adobe.com/xap/1.0/"; 38 39 /* clang-format off */ 40 constexpr uint32_t kJPEGNaturalOrder[80] = { 41 0, 1, 8, 16, 9, 2, 3, 10, 42 17, 24, 32, 25, 18, 11, 4, 5, 43 12, 19, 26, 33, 40, 48, 41, 34, 44 27, 20, 13, 6, 7, 14, 21, 28, 45 35, 42, 49, 56, 57, 50, 43, 36, 46 29, 22, 15, 23, 30, 37, 44, 51, 47 58, 59, 52, 45, 38, 31, 39, 46, 48 53, 60, 61, 54, 47, 55, 62, 63, 49 // extra entries for safety in decoder 50 63, 63, 63, 63, 63, 63, 63, 63, 51 63, 63, 63, 63, 63, 63, 63, 63 52 }; 53 54 constexpr uint32_t kJPEGZigZagOrder[64] = { 55 0, 1, 5, 6, 14, 15, 27, 28, 56 2, 4, 7, 13, 16, 26, 29, 42, 57 3, 8, 12, 17, 25, 30, 41, 43, 58 9, 11, 18, 24, 31, 40, 44, 53, 59 10, 19, 23, 32, 39, 45, 52, 54, 60 20, 22, 33, 38, 46, 51, 55, 60, 61 21, 34, 37, 47, 50, 56, 59, 61, 62 35, 36, 48, 49, 57, 58, 62, 63 63 }; 64 /* clang-format on */ 65 66 // Quantization values for an 8x8 pixel block. 67 struct JPEGQuantTable { 68 std::array<int32_t, kDCTBlockSize> values; 69 uint32_t precision = 0; 70 // The index of this quantization table as it was parsed from the input JPEG. 71 // Each DQT marker segment contains an 'index' field, and we save this index 72 // here. Valid values are 0 to 3. 73 uint32_t index = 0; 74 // Set to true if this table is the last one within its marker segment. 75 bool is_last = true; 76 }; 77 78 // Huffman code and decoding lookup table used for DC and AC coefficients. 79 struct JPEGHuffmanCode { 80 // Bit length histogram. 81 std::array<uint32_t, kJpegHuffmanMaxBitLength + 1> counts = {}; 82 // Symbol values sorted by increasing bit lengths. 83 std::array<uint32_t, kJpegHuffmanAlphabetSize + 1> values = {}; 84 // The index of the Huffman code in the current set of Huffman codes. For AC 85 // component Huffman codes, 0x10 is added to the index. 86 int slot_id = 0; 87 // Set to true if this Huffman code is the last one within its marker segment. 88 bool is_last = true; 89 }; 90 91 // Huffman table indexes used for one component of one scan. 92 struct JPEGComponentScanInfo { 93 uint32_t comp_idx; 94 uint32_t dc_tbl_idx; 95 uint32_t ac_tbl_idx; 96 }; 97 98 // Contains information that is used in one scan. 99 struct JPEGScanInfo { 100 // Parameters used for progressive scans (named the same way as in the spec): 101 // Ss : Start of spectral band in zig-zag sequence. 102 // Se : End of spectral band in zig-zag sequence. 103 // Ah : Successive approximation bit position, high. 104 // Al : Successive approximation bit position, low. 105 uint32_t Ss; 106 uint32_t Se; 107 uint32_t Ah; 108 uint32_t Al; 109 uint32_t num_components = 0; 110 std::array<JPEGComponentScanInfo, 4> components; 111 // Last codestream pass that is needed to write this scan. 112 uint32_t last_needed_pass = 0; 113 114 // Extra information required for bit-precise JPEG file reconstruction. 115 116 // Set of block indexes where the JPEG encoder has to flush the end-of-block 117 // runs and refinement bits. 118 std::vector<uint32_t> reset_points; 119 // The number of extra zero runs (Huffman symbol 0xf0) before the end of 120 // block (if nonzero), indexed by block index. 121 // All of these symbols can be omitted without changing the pixel values, but 122 // some jpeg encoders put these at the end of blocks. 123 typedef struct { 124 uint32_t block_idx; 125 uint32_t num_extra_zero_runs; 126 } ExtraZeroRunInfo; 127 std::vector<ExtraZeroRunInfo> extra_zero_runs; 128 }; 129 130 typedef int16_t coeff_t; 131 132 // Represents one component of a jpeg file. 133 struct JPEGComponent { 134 JPEGComponent() 135 : id(0), 136 h_samp_factor(1), 137 v_samp_factor(1), 138 quant_idx(0), 139 width_in_blocks(0), 140 height_in_blocks(0) {} 141 142 // One-byte id of the component. 143 uint32_t id; 144 // Horizontal and vertical sampling factors. 145 // In interleaved mode, each minimal coded unit (MCU) has 146 // h_samp_factor x v_samp_factor DCT blocks from this component. 147 int h_samp_factor; 148 int v_samp_factor; 149 // The index of the quantization table used for this component. 150 uint32_t quant_idx; 151 // The dimensions of the component measured in 8x8 blocks. 152 uint32_t width_in_blocks; 153 uint32_t height_in_blocks; 154 // The DCT coefficients of this component, laid out block-by-block, divided 155 // through the quantization matrix values. 156 std::vector<coeff_t> coeffs; 157 }; 158 159 enum class AppMarkerType : uint32_t { 160 kUnknown = 0, 161 kICC = 1, 162 kExif = 2, 163 kXMP = 3, 164 }; 165 166 // Represents a parsed jpeg file. 167 struct JPEGData : public Fields { 168 JPEGData() 169 : width(0), height(0), restart_interval(0), has_zero_padding_bit(false) {} 170 171 JXL_FIELDS_NAME(JPEGData) 172 #if JPEGXL_ENABLE_TRANSCODE_JPEG 173 // Doesn't serialize everything - skips brotli-encoded data and what is 174 // already encoded in the codestream. 175 Status VisitFields(Visitor* visitor) override; 176 #else 177 Status VisitFields(Visitor* /* visitor */) override { 178 return JXL_UNREACHABLE("JPEG transcoding support not enabled"); 179 } 180 #endif // JPEGXL_ENABLE_TRANSCODE_JPEG 181 182 void CalculateMcuSize(const JPEGScanInfo& scan, int* MCUs_per_row, 183 int* MCU_rows) const; 184 185 int width; 186 int height; 187 uint32_t restart_interval; 188 std::vector<std::vector<uint8_t>> app_data; 189 std::vector<AppMarkerType> app_marker_type; 190 std::vector<std::vector<uint8_t>> com_data; 191 std::vector<JPEGQuantTable> quant; 192 std::vector<JPEGHuffmanCode> huffman_code; 193 std::vector<JPEGComponent> components; 194 std::vector<JPEGScanInfo> scan_info; 195 std::vector<uint8_t> marker_order; 196 std::vector<std::vector<uint8_t>> inter_marker_data; 197 std::vector<uint8_t> tail_data; 198 199 // Extra information required for bit-precise JPEG file reconstruction. 200 201 bool has_zero_padding_bit; 202 std::vector<uint8_t> padding_bits; 203 }; 204 205 #if JPEGXL_ENABLE_TRANSCODE_JPEG 206 // Set ICC profile in jpeg_data. 207 Status SetJPEGDataFromICC(const std::vector<uint8_t>& icc, 208 jpeg::JPEGData* jpeg_data); 209 #else 210 static JXL_INLINE Status SetJPEGDataFromICC( 211 const std::vector<uint8_t>& /* icc */, jpeg::JPEGData* /* jpeg_data */) { 212 return JXL_UNREACHABLE("JPEG transcoding support not enabled"); 213 } 214 #endif // JPEGXL_ENABLE_TRANSCODE_JPEG 215 216 } // namespace jpeg 217 } // namespace jxl 218 219 #endif // LIB_JXL_JPEG_JPEG_DATA_H_