tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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_