tor-browser

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

image_bundle.cc (4512B)


      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/image_bundle.h"
      7 
      8 #include <utility>
      9 
     10 #include "lib/jxl/base/printf_macros.h"
     11 #include "lib/jxl/base/status.h"
     12 #include "lib/jxl/image.h"
     13 
     14 namespace jxl {
     15 
     16 Status ImageBundle::ShrinkTo(size_t xsize, size_t ysize) {
     17  if (HasColor()) {
     18    JXL_RETURN_IF_ERROR(color_.ShrinkTo(xsize, ysize));
     19  }
     20  for (ImageF& ec : extra_channels_) {
     21    JXL_RETURN_IF_ERROR(ec.ShrinkTo(xsize, ysize));
     22  }
     23  return true;
     24 }
     25 
     26 // Called by all other SetFrom*.
     27 Status ImageBundle::SetFromImage(Image3F&& color,
     28                                 const ColorEncoding& c_current) {
     29  JXL_ENSURE(color.xsize() != 0 && color.ysize() != 0);
     30  JXL_ENSURE(metadata_->color_encoding.IsGray() == c_current.IsGray());
     31  color_ = std::move(color);
     32  c_current_ = c_current;
     33  JXL_RETURN_IF_ERROR(VerifySizes());
     34  return true;
     35 }
     36 
     37 Status ImageBundle::VerifyMetadata() const {
     38  JXL_ENSURE(!c_current_.ICC().empty());
     39  JXL_ENSURE(metadata_->color_encoding.IsGray() == IsGray());
     40 
     41  if (metadata_->HasAlpha()) {
     42    const ImageF* a = alpha();
     43    if (a->xsize() == 0) {
     44      return JXL_UNREACHABLE("MD alpha_bits %u IB alpha %" PRIuS " x %" PRIuS
     45                             "\n",
     46                             metadata_->GetAlphaBits(), a->xsize(), a->ysize());
     47    }
     48  }
     49  const uint32_t alpha_bits = metadata_->GetAlphaBits();
     50  JXL_ENSURE(alpha_bits <= 32);
     51 
     52  // metadata_->num_extra_channels may temporarily differ from
     53  // extra_channels_.size(), e.g. after SetAlpha. They are synced by the next
     54  // call to VisitFields.
     55  return true;
     56 }
     57 
     58 Status ImageBundle::VerifySizes() const {
     59  const size_t xs = xsize();
     60  const size_t ys = ysize();
     61 
     62  if (HasExtraChannels()) {
     63    JXL_ENSURE(xs != 0 && ys != 0);
     64    for (const ImageF& ec : extra_channels_) {
     65      JXL_ENSURE(ec.xsize() == xs);
     66      JXL_ENSURE(ec.ysize() == ys);
     67    }
     68  }
     69  return true;
     70 }
     71 
     72 size_t ImageBundle::DetectRealBitdepth() const {
     73  return metadata_->bit_depth.bits_per_sample;
     74 
     75  // TODO(lode): let this function return lower bit depth if possible, e.g.
     76  // return 8 bits in case the original image came from a 16-bit PNG that
     77  // was in fact representable as 8-bit PNG. Ensure that the implementation
     78  // returns 16 if e.g. two consecutive 16-bit values appeared in the original
     79  // image (such as 32768 and 32769), take into account that e.g. the values
     80  // 3-bit can represent is not a superset of the values 2-bit can represent,
     81  // and there may be slight imprecisions in the floating point image.
     82 }
     83 
     84 const ImageF* ImageBundle::black() const {
     85  if (!HasBlack()) return nullptr;
     86  const size_t ec = metadata_->Find(ExtraChannel::kBlack) -
     87                    metadata_->extra_channel_info.data();
     88  JXL_DASSERT(ec < extra_channels_.size());
     89  return &extra_channels_[ec];
     90 }
     91 const ImageF* ImageBundle::alpha() const {
     92  if (!HasAlpha()) return nullptr;
     93  const size_t ec = metadata_->Find(ExtraChannel::kAlpha) -
     94                    metadata_->extra_channel_info.data();
     95  JXL_DASSERT(ec < extra_channels_.size());
     96  return &extra_channels_[ec];
     97 }
     98 ImageF* ImageBundle::alpha() {
     99  if (!HasAlpha()) return nullptr;
    100  const size_t ec = metadata_->Find(ExtraChannel::kAlpha) -
    101                    metadata_->extra_channel_info.data();
    102  JXL_DASSERT(ec < extra_channels_.size());
    103  return &extra_channels_[ec];
    104 }
    105 
    106 Status ImageBundle::SetAlpha(ImageF&& alpha) {
    107  const ExtraChannelInfo* eci = metadata_->Find(ExtraChannel::kAlpha);
    108  // Must call SetAlphaBits first, otherwise we don't know which channel index
    109  JXL_ENSURE(eci != nullptr);
    110  JXL_ENSURE(alpha.xsize() != 0 && alpha.ysize() != 0);
    111  if (extra_channels_.size() < metadata_->extra_channel_info.size()) {
    112    // TODO(jon): get rid of this case
    113    extra_channels_.insert(
    114        extra_channels_.begin() + (eci - metadata_->extra_channel_info.data()),
    115        std::move(alpha));
    116  } else {
    117    extra_channels_[eci - metadata_->extra_channel_info.data()] =
    118        std::move(alpha);
    119  }
    120  // num_extra_channels is automatically set in visitor
    121  JXL_RETURN_IF_ERROR(VerifySizes());
    122  return true;
    123 }
    124 
    125 Status ImageBundle::SetExtraChannels(std::vector<ImageF>&& extra_channels) {
    126  for (const ImageF& plane : extra_channels) {
    127    JXL_ENSURE(plane.xsize() != 0 && plane.ysize() != 0);
    128  }
    129  extra_channels_ = std::move(extra_channels);
    130  JXL_RETURN_IF_ERROR(VerifySizes());
    131  return true;
    132 }
    133 }  // namespace jxl