tor-browser

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

headers.cc (6674B)


      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 #include "lib/jxl/headers.h"
      7 
      8 #include <cstdint>
      9 #include <limits>
     10 
     11 #include "lib/jxl/fields.h"
     12 #include "lib/jxl/frame_dimensions.h"
     13 
     14 namespace jxl {
     15 namespace {
     16 
     17 struct Rational {
     18  constexpr explicit Rational(uint32_t num, uint32_t den)
     19      : num(num), den(den) {}
     20 
     21  // Returns floor(multiplicand * rational).
     22  constexpr uint32_t MulTruncate(uint32_t multiplicand) const {
     23    return static_cast<uint64_t>(multiplicand) * num / den;
     24  }
     25 
     26  uint32_t num;
     27  uint32_t den;
     28 };
     29 
     30 Rational FixedAspectRatios(uint32_t ratio) {
     31  JXL_DASSERT(0 != ratio && ratio < 8);
     32  // Other candidates: 5/4, 7/5, 14/9, 16/10, 5/3, 21/9, 12/5
     33  constexpr Rational kRatios[7] = {Rational(1, 1),    // square
     34                                   Rational(12, 10),  //
     35                                   Rational(4, 3),    // camera
     36                                   Rational(3, 2),    // mobile camera
     37                                   Rational(16, 9),   // camera/display
     38                                   Rational(5, 4),    //
     39                                   Rational(2, 1)};   //
     40  return kRatios[ratio - 1];
     41 }
     42 
     43 uint32_t FindAspectRatio(uint32_t xsize, uint32_t ysize) {
     44  for (uint32_t r = 1; r < 8; ++r) {
     45    if (xsize == FixedAspectRatios(r).MulTruncate(ysize)) {
     46      return r;
     47    }
     48  }
     49  return 0;  // Must send xsize instead
     50 }
     51 
     52 }  // namespace
     53 
     54 size_t SizeHeader::xsize() const {
     55  if (ratio_ != 0) {
     56    return FixedAspectRatios(ratio_).MulTruncate(
     57        static_cast<uint32_t>(ysize()));
     58  }
     59  return small_ ? ((xsize_div8_minus_1_ + 1) * 8) : xsize_;
     60 }
     61 
     62 Status SizeHeader::Set(size_t xsize64, size_t ysize64) {
     63  constexpr size_t kDimensionCap = std::numeric_limits<uint32_t>::max();
     64  if (xsize64 > kDimensionCap || ysize64 > kDimensionCap) {
     65    return JXL_FAILURE("Image too large");
     66  }
     67  const uint32_t xsize32 = static_cast<uint32_t>(xsize64);
     68  const uint32_t ysize32 = static_cast<uint32_t>(ysize64);
     69  if (xsize64 == 0 || ysize64 == 0) return JXL_FAILURE("Empty image");
     70  ratio_ = FindAspectRatio(xsize32, ysize32);
     71  small_ = ysize64 <= 256 && (ysize64 % kBlockDim) == 0 &&
     72           (ratio_ != 0 || (xsize64 <= 256 && (xsize64 % kBlockDim) == 0));
     73  if (small_) {
     74    ysize_div8_minus_1_ = ysize32 / 8 - 1;
     75  } else {
     76    ysize_ = ysize32;
     77  }
     78 
     79  if (ratio_ == 0) {
     80    if (small_) {
     81      xsize_div8_minus_1_ = xsize32 / 8 - 1;
     82    } else {
     83      xsize_ = xsize32;
     84    }
     85  }
     86  JXL_ENSURE(xsize() == xsize64);
     87  JXL_ENSURE(ysize() == ysize64);
     88  return true;
     89 }
     90 
     91 Status PreviewHeader::Set(size_t xsize64, size_t ysize64) {
     92  const uint32_t xsize32 = static_cast<uint32_t>(xsize64);
     93  const uint32_t ysize32 = static_cast<uint32_t>(ysize64);
     94  if (xsize64 == 0 || ysize64 == 0) return JXL_FAILURE("Empty preview");
     95  div8_ = (xsize64 % kBlockDim) == 0 && (ysize64 % kBlockDim) == 0;
     96  if (div8_) {
     97    ysize_div8_ = ysize32 / 8;
     98  } else {
     99    ysize_ = ysize32;
    100  }
    101 
    102  ratio_ = FindAspectRatio(xsize32, ysize32);
    103  if (ratio_ == 0) {
    104    if (div8_) {
    105      xsize_div8_ = xsize32 / 8;
    106    } else {
    107      xsize_ = xsize32;
    108    }
    109  }
    110  JXL_ENSURE(xsize() == xsize64);
    111  JXL_ENSURE(ysize() == ysize64);
    112  return true;
    113 }
    114 
    115 size_t PreviewHeader::xsize() const {
    116  if (ratio_ != 0) {
    117    return FixedAspectRatios(ratio_).MulTruncate(
    118        static_cast<uint32_t>(ysize()));
    119  }
    120  return div8_ ? (xsize_div8_ * 8) : xsize_;
    121 }
    122 
    123 SizeHeader::SizeHeader() { Bundle::Init(this); }
    124 Status SizeHeader::VisitFields(Visitor* JXL_RESTRICT visitor) {
    125  JXL_QUIET_RETURN_IF_ERROR(visitor->Bool(false, &small_));
    126 
    127  if (visitor->Conditional(small_)) {
    128    JXL_QUIET_RETURN_IF_ERROR(visitor->Bits(5, 0, &ysize_div8_minus_1_));
    129  }
    130  if (visitor->Conditional(!small_)) {
    131    // (Could still be small, but non-multiple of 8.)
    132    JXL_QUIET_RETURN_IF_ERROR(visitor->U32(BitsOffset(9, 1), BitsOffset(13, 1),
    133                                           BitsOffset(18, 1), BitsOffset(30, 1),
    134                                           1, &ysize_));
    135  }
    136 
    137  JXL_QUIET_RETURN_IF_ERROR(visitor->Bits(3, 0, &ratio_));
    138  if (visitor->Conditional(ratio_ == 0 && small_)) {
    139    JXL_QUIET_RETURN_IF_ERROR(visitor->Bits(5, 0, &xsize_div8_minus_1_));
    140  }
    141  if (visitor->Conditional(ratio_ == 0 && !small_)) {
    142    JXL_QUIET_RETURN_IF_ERROR(visitor->U32(BitsOffset(9, 1), BitsOffset(13, 1),
    143                                           BitsOffset(18, 1), BitsOffset(30, 1),
    144                                           1, &xsize_));
    145  }
    146 
    147  return true;
    148 }
    149 
    150 PreviewHeader::PreviewHeader() { Bundle::Init(this); }
    151 Status PreviewHeader::VisitFields(Visitor* JXL_RESTRICT visitor) {
    152  JXL_QUIET_RETURN_IF_ERROR(visitor->Bool(false, &div8_));
    153 
    154  if (visitor->Conditional(div8_)) {
    155    JXL_QUIET_RETURN_IF_ERROR(visitor->U32(Val(16), Val(32), BitsOffset(5, 1),
    156                                           BitsOffset(9, 33), 1, &ysize_div8_));
    157  }
    158  if (visitor->Conditional(!div8_)) {
    159    JXL_QUIET_RETURN_IF_ERROR(visitor->U32(BitsOffset(6, 1), BitsOffset(8, 65),
    160                                           BitsOffset(10, 321),
    161                                           BitsOffset(12, 1345), 1, &ysize_));
    162  }
    163 
    164  JXL_QUIET_RETURN_IF_ERROR(visitor->Bits(3, 0, &ratio_));
    165  if (visitor->Conditional(ratio_ == 0 && div8_)) {
    166    JXL_QUIET_RETURN_IF_ERROR(visitor->U32(Val(16), Val(32), BitsOffset(5, 1),
    167                                           BitsOffset(9, 33), 1, &xsize_div8_));
    168  }
    169  if (visitor->Conditional(ratio_ == 0 && !div8_)) {
    170    JXL_QUIET_RETURN_IF_ERROR(visitor->U32(BitsOffset(6, 1), BitsOffset(8, 65),
    171                                           BitsOffset(10, 321),
    172                                           BitsOffset(12, 1345), 1, &xsize_));
    173  }
    174 
    175  return true;
    176 }
    177 
    178 AnimationHeader::AnimationHeader() { Bundle::Init(this); }
    179 Status AnimationHeader::VisitFields(Visitor* JXL_RESTRICT visitor) {
    180  JXL_QUIET_RETURN_IF_ERROR(visitor->U32(Val(100), Val(1000), BitsOffset(10, 1),
    181                                         BitsOffset(30, 1), 1, &tps_numerator));
    182  JXL_QUIET_RETURN_IF_ERROR(visitor->U32(Val(1), Val(1001), BitsOffset(8, 1),
    183                                         BitsOffset(10, 1), 1,
    184                                         &tps_denominator));
    185 
    186  JXL_QUIET_RETURN_IF_ERROR(
    187      visitor->U32(Val(0), Bits(3), Bits(16), Bits(32), 0, &num_loops));
    188 
    189  JXL_QUIET_RETURN_IF_ERROR(visitor->Bool(false, &have_timecodes));
    190  return true;
    191 }
    192 
    193 Status ReadSizeHeader(BitReader* JXL_RESTRICT reader,
    194                      SizeHeader* JXL_RESTRICT size) {
    195  return Bundle::Read(reader, size);
    196 }
    197 
    198 }  // namespace jxl