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