libjxl

FORK: libjxl patches used on blog
git clone https://git.neptards.moe/blog/libjxl.git
Log | Files | Refs | Submodules | README | LICENSE

frame_header.h (16848B)


      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 #ifndef LIB_JXL_FRAME_HEADER_H_
      7 #define LIB_JXL_FRAME_HEADER_H_
      8 
      9 // Frame header with backward and forward-compatible extension capability and
     10 // compressed integer fields.
     11 
     12 #include <stddef.h>
     13 #include <stdint.h>
     14 
     15 #include <algorithm>
     16 #include <string>
     17 
     18 #include "lib/jxl/base/compiler_specific.h"
     19 #include "lib/jxl/base/override.h"
     20 #include "lib/jxl/base/status.h"
     21 #include "lib/jxl/coeff_order_fwd.h"
     22 #include "lib/jxl/common.h"  // kMaxNumPasses
     23 #include "lib/jxl/dec_bit_reader.h"
     24 #include "lib/jxl/fields.h"
     25 #include "lib/jxl/frame_dimensions.h"
     26 #include "lib/jxl/image_metadata.h"
     27 #include "lib/jxl/loop_filter.h"
     28 
     29 namespace jxl {
     30 
     31 // TODO(eustas): move to proper place?
     32 // Also used by extra channel names.
     33 static inline Status VisitNameString(Visitor* JXL_RESTRICT visitor,
     34                                      std::string* name) {
     35   uint32_t name_length = static_cast<uint32_t>(name->length());
     36   // Allows layer name lengths up to 1071 bytes
     37   JXL_QUIET_RETURN_IF_ERROR(visitor->U32(Val(0), Bits(4), BitsOffset(5, 16),
     38                                          BitsOffset(10, 48), 0, &name_length));
     39   if (visitor->IsReading()) {
     40     name->resize(name_length);
     41   }
     42   for (size_t i = 0; i < name_length; i++) {
     43     uint32_t c = static_cast<uint8_t>((*name)[i]);
     44     JXL_QUIET_RETURN_IF_ERROR(visitor->Bits(8, 0, &c));
     45     (*name)[i] = static_cast<char>(c);
     46   }
     47   return true;
     48 }
     49 
     50 enum class FrameEncoding : uint32_t {
     51   kVarDCT,
     52   kModular,
     53 };
     54 
     55 enum class ColorTransform : uint32_t {
     56   kXYB,    // Values are encoded with XYB. May only be used if
     57            // ImageBundle::xyb_encoded.
     58   kNone,   // Values are encoded according to the attached color profile. May
     59            // only be used if !ImageBundle::xyb_encoded.
     60   kYCbCr,  // Values are encoded according to the attached color profile, but
     61            // transformed to YCbCr. May only be used if
     62            // !ImageBundle::xyb_encoded.
     63 };
     64 
     65 inline std::array<int, 3> JpegOrder(ColorTransform ct, bool is_gray) {
     66   if (is_gray) {
     67     return {{0, 0, 0}};
     68   }
     69   JXL_ASSERT(ct != ColorTransform::kXYB);
     70   if (ct == ColorTransform::kYCbCr) {
     71     return {{1, 0, 2}};
     72   } else {
     73     return {{0, 1, 2}};
     74   }
     75 }
     76 
     77 struct YCbCrChromaSubsampling : public Fields {
     78   YCbCrChromaSubsampling();
     79   JXL_FIELDS_NAME(YCbCrChromaSubsampling)
     80   size_t HShift(size_t c) const { return maxhs_ - kHShift[channel_mode_[c]]; }
     81   size_t VShift(size_t c) const { return maxvs_ - kVShift[channel_mode_[c]]; }
     82 
     83   Status VisitFields(Visitor* JXL_RESTRICT visitor) override {
     84     // TODO(veluca): consider allowing 4x downsamples
     85     for (uint32_t& ch : channel_mode_) {
     86       JXL_QUIET_RETURN_IF_ERROR(visitor->Bits(2, 0, &ch));
     87     }
     88     Recompute();
     89     return true;
     90   }
     91 
     92   uint8_t MaxHShift() const { return maxhs_; }
     93   uint8_t MaxVShift() const { return maxvs_; }
     94 
     95   uint8_t RawHShift(size_t c) const { return kHShift[channel_mode_[c]]; }
     96   uint8_t RawVShift(size_t c) const { return kVShift[channel_mode_[c]]; }
     97 
     98   // Uses JPEG channel order (Y, Cb, Cr).
     99   Status Set(const uint8_t* hsample, const uint8_t* vsample) {
    100     for (size_t c = 0; c < 3; c++) {
    101       size_t cjpeg = c < 2 ? c ^ 1 : c;
    102       size_t i = 0;
    103       for (; i < 4; i++) {
    104         if (1 << kHShift[i] == hsample[cjpeg] &&
    105             1 << kVShift[i] == vsample[cjpeg]) {
    106           channel_mode_[c] = i;
    107           break;
    108         }
    109       }
    110       if (i == 4) {
    111         return JXL_FAILURE("Invalid subsample mode");
    112       }
    113     }
    114     Recompute();
    115     return true;
    116   }
    117 
    118   bool Is444() const {
    119     return HShift(0) == 0 && VShift(0) == 0 &&  // Cb
    120            HShift(2) == 0 && VShift(2) == 0 &&  // Cr
    121            HShift(1) == 0 && VShift(1) == 0;    // Y
    122   }
    123 
    124   bool Is420() const {
    125     return HShift(0) == 1 && VShift(0) == 1 &&  // Cb
    126            HShift(2) == 1 && VShift(2) == 1 &&  // Cr
    127            HShift(1) == 0 && VShift(1) == 0;    // Y
    128   }
    129 
    130   bool Is422() const {
    131     return HShift(0) == 1 && VShift(0) == 0 &&  // Cb
    132            HShift(2) == 1 && VShift(2) == 0 &&  // Cr
    133            HShift(1) == 0 && VShift(1) == 0;    // Y
    134   }
    135 
    136   bool Is440() const {
    137     return HShift(0) == 0 && VShift(0) == 1 &&  // Cb
    138            HShift(2) == 0 && VShift(2) == 1 &&  // Cr
    139            HShift(1) == 0 && VShift(1) == 0;    // Y
    140   }
    141 
    142   std::string DebugString() const {
    143     if (Is444()) return "444";
    144     if (Is420()) return "420";
    145     if (Is422()) return "422";
    146     if (Is440()) return "440";
    147     return "cs" + std::to_string(channel_mode_[0]) +
    148            std::to_string(channel_mode_[1]) + std::to_string(channel_mode_[2]);
    149   }
    150 
    151  private:
    152   void Recompute() {
    153     maxhs_ = 0;
    154     maxvs_ = 0;
    155     for (uint32_t ch : channel_mode_) {
    156       maxhs_ = std::max(maxhs_, kHShift[ch]);
    157       maxvs_ = std::max(maxvs_, kVShift[ch]);
    158     }
    159   }
    160   static const uint8_t kHShift[4];
    161   static const uint8_t kVShift[4];
    162   uint32_t channel_mode_[3];
    163   uint8_t maxhs_;
    164   uint8_t maxvs_;
    165 };
    166 
    167 // Indicates how to combine the current frame with a previously-saved one. Can
    168 // be independently controlled for color and extra channels. Formulas are
    169 // indicative and treat alpha as if it is in range 0.0-1.0. In descriptions
    170 // below, alpha channel is the extra channel of type alpha used for blending
    171 // according to the blend_channel, or fully opaque if there is no alpha channel.
    172 // The blending specified here is used for performing blending *after* color
    173 // transforms - in linear sRGB if blending a XYB-encoded frame on another
    174 // XYB-encoded frame, in sRGB if blending a frame with kColorSpace == kSRGB, or
    175 // in the original colorspace otherwise. Blending in XYB or YCbCr is done by
    176 // using patches.
    177 enum class BlendMode {
    178   // The new values (in the crop) replace the old ones: sample = new
    179   kReplace = 0,
    180   // The new values (in the crop) get added to the old ones: sample = old + new
    181   kAdd = 1,
    182   // The new values (in the crop) replace the old ones if alpha>0:
    183   // For the alpha channel that is used as source:
    184   // alpha = old + new * (1 - old)
    185   // For other channels if !alpha_associated:
    186   // sample = ((1 - new_alpha) * old * old_alpha + new_alpha * new) / alpha
    187   // For other channels if alpha_associated:
    188   // sample = (1 - new_alpha) * old + new
    189   // The alpha formula applies to the alpha used for the division in the other
    190   // channels formula, and applies to the alpha channel itself if its
    191   // blend_channel value matches itself.
    192   kBlend = 2,
    193   // The new values (in the crop) are added to the old ones if alpha>0:
    194   // For the alpha channel that is used as source:
    195   // sample = sample = old + new * (1 - old)
    196   // For other channels: sample = old + alpha * new
    197   kAlphaWeightedAdd = 3,
    198   // The new values (in the crop) get multiplied by the old ones:
    199   // sample = old * new
    200   // The range of the new value matters for multiplication purposes, and its
    201   // nominal range of 0..1 is computed the same way as this is done for the
    202   // alpha values in kBlend and kAlphaWeightedAdd.
    203   // If using kMul as a blend mode for color channels, no color transform is
    204   // performed on the current frame.
    205   kMul = 4,
    206 };
    207 
    208 struct BlendingInfo : public Fields {
    209   BlendingInfo();
    210   JXL_FIELDS_NAME(BlendingInfo)
    211   Status VisitFields(Visitor* JXL_RESTRICT visitor) override;
    212   BlendMode mode;
    213   // Which extra channel to use as alpha channel for blending, only encoded
    214   // for blend modes that involve alpha and if there are more than 1 extra
    215   // channels.
    216   uint32_t alpha_channel;
    217   // Clamp alpha or channel values to 0-1 range.
    218   bool clamp;
    219   // Frame ID to copy from (0-3). Only encoded if blend_mode is not kReplace.
    220   uint32_t source;
    221 
    222   std::string DebugString() const;
    223 
    224   size_t nonserialized_num_extra_channels = 0;
    225   bool nonserialized_is_partial_frame = false;
    226 };
    227 
    228 // Origin of the current frame. Not present for frames of type
    229 // kOnlyPatches.
    230 struct FrameOrigin {
    231   int32_t x0, y0;  // can be negative.
    232 };
    233 
    234 // Size of the current frame.
    235 struct FrameSize {
    236   uint32_t xsize, ysize;
    237 };
    238 
    239 // AnimationFrame defines duration of animation frames.
    240 struct AnimationFrame : public Fields {
    241   explicit AnimationFrame(const CodecMetadata* metadata);
    242   JXL_FIELDS_NAME(AnimationFrame)
    243 
    244   Status VisitFields(Visitor* JXL_RESTRICT visitor) override;
    245 
    246   // How long to wait [in ticks, see Animation{}] after rendering.
    247   // May be 0 if the current frame serves as a foundation for another frame.
    248   uint32_t duration;
    249 
    250   uint32_t timecode;  // 0xHHMMSSFF
    251 
    252   // Must be set to the one ImageMetadata acting as the full codestream header,
    253   // with correct xyb_encoded, list of extra channels, etc...
    254   const CodecMetadata* nonserialized_metadata = nullptr;
    255 };
    256 
    257 // For decoding to lower resolutions. Only used for kRegular frames.
    258 struct Passes : public Fields {
    259   Passes();
    260   JXL_FIELDS_NAME(Passes)
    261 
    262   Status VisitFields(Visitor* JXL_RESTRICT visitor) override;
    263 
    264   void GetDownsamplingBracket(size_t pass, int& minShift, int& maxShift) const {
    265     maxShift = 2;
    266     minShift = 3;
    267     for (size_t i = 0;; i++) {
    268       for (uint32_t j = 0; j < num_downsample; ++j) {
    269         if (i == last_pass[j]) {
    270           if (downsample[j] == 8) minShift = 3;
    271           if (downsample[j] == 4) minShift = 2;
    272           if (downsample[j] == 2) minShift = 1;
    273           if (downsample[j] == 1) minShift = 0;
    274         }
    275       }
    276       if (i == num_passes - 1) minShift = 0;
    277       if (i == pass) return;
    278       maxShift = minShift - 1;
    279     }
    280   }
    281 
    282   uint32_t GetDownsamplingTargetForCompletedPasses(uint32_t num_p) const {
    283     if (num_p >= num_passes) return 1;
    284     uint32_t retval = 8;
    285     for (uint32_t i = 0; i < num_downsample; ++i) {
    286       if (num_p > last_pass[i]) {
    287         retval = std::min(retval, downsample[i]);
    288       }
    289     }
    290     return retval;
    291   }
    292 
    293   std::string DebugString() const;
    294 
    295   uint32_t num_passes;      // <= kMaxNumPasses
    296   uint32_t num_downsample;  // <= num_passes
    297 
    298   // Array of num_downsample pairs. downsample=1/last_pass=num_passes-1 and
    299   // downsample=8/last_pass=0 need not be specified; they are implicit.
    300   uint32_t downsample[kMaxNumPasses];
    301   uint32_t last_pass[kMaxNumPasses];
    302   // Array of shift values for each pass. It is implicitly assumed to be 0 for
    303   // the last pass.
    304   uint32_t shift[kMaxNumPasses];
    305 };
    306 
    307 enum FrameType {
    308   // A "regular" frame: might be a crop, and will be blended on a previous
    309   // frame, if any, and displayed or blended in future frames.
    310   kRegularFrame = 0,
    311   // A DC frame: this frame is downsampled and will be *only* used as the DC of
    312   // a future frame and, possibly, for previews. Cannot be cropped, blended, or
    313   // referenced by patches or blending modes. Frames that *use* a DC frame
    314   // cannot have non-default sizes either.
    315   kDCFrame = 1,
    316   // A PatchesSource frame: this frame will be only used as a source frame for
    317   // taking patches. Can be cropped, but cannot have non-(0, 0) x0 and y0.
    318   kReferenceOnly = 2,
    319   // Same as kRegularFrame, but not used for progressive rendering. This also
    320   // implies no early display of DC.
    321   kSkipProgressive = 3,
    322 };
    323 
    324 // Image/frame := one of more of these, where the last has is_last = true.
    325 // Starts at a byte-aligned address "a"; the next pass starts at "a + size".
    326 struct FrameHeader : public Fields {
    327   // Optional postprocessing steps. These flags are the source of truth;
    328   // Override must set/clear them rather than change their meaning. Values
    329   // chosen such that typical flags == 0 (encoded in only two bits).
    330   enum Flags {
    331     // Often but not always off => low bit value:
    332 
    333     // Inject noise into decoded output.
    334     kNoise = 1,
    335 
    336     // Overlay patches.
    337     kPatches = 2,
    338 
    339     // 4, 8 = reserved for future sometimes-off
    340 
    341     // Overlay splines.
    342     kSplines = 16,
    343 
    344     kUseDcFrame = 32,  // Implies kSkipAdaptiveDCSmoothing.
    345 
    346     // 64 = reserved for future often-off
    347 
    348     // Almost always on => negated:
    349 
    350     kSkipAdaptiveDCSmoothing = 128,
    351   };
    352 
    353   explicit FrameHeader(const CodecMetadata* metadata);
    354   JXL_FIELDS_NAME(FrameHeader)
    355 
    356   Status VisitFields(Visitor* JXL_RESTRICT visitor) override;
    357 
    358   // Sets/clears `flag` based upon `condition`.
    359   void UpdateFlag(const bool condition, const uint64_t flag) {
    360     if (condition) {
    361       flags |= flag;
    362     } else {
    363       flags &= ~flag;
    364     }
    365   }
    366 
    367   // Returns true if this frame is supposed to be saved for future usage by
    368   // other frames.
    369   bool CanBeReferenced() const {
    370     // DC frames cannot be referenced. The last frame cannot be referenced. A
    371     // duration 0 frame makes little sense if it is not referenced. A
    372     // non-duration 0 frame may or may not be referenced.
    373     return !is_last && frame_type != FrameType::kDCFrame &&
    374            (animation_frame.duration == 0 || save_as_reference != 0);
    375   }
    376 
    377   mutable bool all_default;
    378 
    379   // Always present
    380   FrameEncoding encoding;
    381   // Some versions of UBSAN complain in VisitFrameType if not initialized.
    382   FrameType frame_type = FrameType::kRegularFrame;
    383 
    384   uint64_t flags;
    385 
    386   ColorTransform color_transform;
    387   YCbCrChromaSubsampling chroma_subsampling;
    388 
    389   uint32_t group_size_shift;  // only if encoding == kModular;
    390 
    391   uint32_t x_qm_scale;  // only if VarDCT and color_transform == kXYB
    392   uint32_t b_qm_scale;  // only if VarDCT and color_transform == kXYB
    393 
    394   std::string name;
    395 
    396   // Skipped for kReferenceOnly.
    397   Passes passes;
    398 
    399   // Skipped for kDCFrame
    400   bool custom_size_or_origin;
    401   FrameSize frame_size;
    402 
    403   // upsampling factors for color and extra channels.
    404   // Upsampling is always performed before applying any inverse color transform.
    405   // Skipped (1) if kUseDCFrame
    406   uint32_t upsampling;
    407   std::vector<uint32_t> extra_channel_upsampling;
    408 
    409   // Only for kRegular frames.
    410   FrameOrigin frame_origin;
    411 
    412   BlendingInfo blending_info;
    413   std::vector<BlendingInfo> extra_channel_blending_info;
    414 
    415   // Animation info for this frame.
    416   AnimationFrame animation_frame;
    417 
    418   // This is the last frame.
    419   bool is_last;
    420 
    421   // ID to refer to this frame with. 0-3, not present if kDCFrame.
    422   // 0 has a special meaning for kRegular frames of nonzero duration: it defines
    423   // a frame that will not be referenced in the future.
    424   uint32_t save_as_reference;
    425 
    426   // Whether to save this frame before or after the color transform. A frame
    427   // that is saved before the color tansform can only be used for blending
    428   // through patches. On the contrary, a frame that is saved after the color
    429   // transform can only be used for blending through blending modes.
    430   // Irrelevant for extra channel blending. Can only be true if
    431   // blending_info.mode == kReplace and this is not a partial kRegularFrame; if
    432   // this is a DC frame, it is always true.
    433   bool save_before_color_transform;
    434 
    435   uint32_t dc_level;  // 1-4 if kDCFrame (0 otherwise).
    436 
    437   // Must be set to the one ImageMetadata acting as the full codestream header,
    438   // with correct xyb_encoded, list of extra channels, etc...
    439   const CodecMetadata* nonserialized_metadata = nullptr;
    440 
    441   // NOTE: This is ignored by AllDefault.
    442   LoopFilter loop_filter;
    443 
    444   bool nonserialized_is_preview = false;
    445 
    446   size_t default_xsize() const {
    447     if (!nonserialized_metadata) return 0;
    448     if (nonserialized_is_preview) {
    449       return nonserialized_metadata->m.preview_size.xsize();
    450     }
    451     return nonserialized_metadata->xsize();
    452   }
    453 
    454   size_t default_ysize() const {
    455     if (!nonserialized_metadata) return 0;
    456     if (nonserialized_is_preview) {
    457       return nonserialized_metadata->m.preview_size.ysize();
    458     }
    459     return nonserialized_metadata->ysize();
    460   }
    461 
    462   FrameDimensions ToFrameDimensions() const {
    463     size_t xsize = default_xsize();
    464     size_t ysize = default_ysize();
    465 
    466     xsize = frame_size.xsize ? frame_size.xsize : xsize;
    467     ysize = frame_size.ysize ? frame_size.ysize : ysize;
    468 
    469     if (dc_level != 0) {
    470       xsize = DivCeil(xsize, 1 << (3 * dc_level));
    471       ysize = DivCeil(ysize, 1 << (3 * dc_level));
    472     }
    473 
    474     FrameDimensions frame_dim;
    475     frame_dim.Set(xsize, ysize, group_size_shift,
    476                   chroma_subsampling.MaxHShift(),
    477                   chroma_subsampling.MaxVShift(),
    478                   encoding == FrameEncoding::kModular, upsampling);
    479     return frame_dim;
    480   }
    481 
    482   // True if a color transform should be applied to this frame.
    483   bool needs_color_transform() const {
    484     return !save_before_color_transform ||
    485            frame_type == FrameType::kRegularFrame ||
    486            frame_type == FrameType::kSkipProgressive;
    487   }
    488 
    489   std::string DebugString() const;
    490 
    491   uint64_t extensions;
    492 };
    493 
    494 Status ReadFrameHeader(BitReader* JXL_RESTRICT reader,
    495                        FrameHeader* JXL_RESTRICT frame);
    496 
    497 // Shared by enc/dec. 5F and 13 are by far the most common for d1/2/4/8, 0
    498 // ensures low overhead for small images.
    499 static constexpr U32Enc kOrderEnc =
    500     U32Enc(Val(0x5F), Val(0x13), Val(0), Bits(kNumOrders));
    501 
    502 }  // namespace jxl
    503 
    504 #endif  // LIB_JXL_FRAME_HEADER_H_