tor-browser

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

enc_progressive_split.cc (3161B)


      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/enc_progressive_split.h"
      7 
      8 #include <string.h>
      9 
     10 #include <algorithm>
     11 #include <memory>
     12 
     13 #include "lib/jxl/ac_strategy.h"
     14 #include "lib/jxl/common.h"  // kMaxNumPasses
     15 #include "lib/jxl/image.h"
     16 
     17 namespace jxl {
     18 
     19 template <typename T>
     20 void ProgressiveSplitter::SplitACCoefficients(
     21    const T* JXL_RESTRICT block, const AcStrategy& acs, size_t bx, size_t by,
     22    T* JXL_RESTRICT output[kMaxNumPasses]) {
     23  size_t size = acs.covered_blocks_x() * acs.covered_blocks_y() * kDCTBlockSize;
     24  auto shift_right_round0 = [&](T v, int shift) {
     25    T one_if_negative = static_cast<uint32_t>(v) >> 31;
     26    T add = (one_if_negative << shift) - one_if_negative;
     27    return (v + add) >> shift;
     28  };
     29  // Early quit for the simple case of only one pass.
     30  if (mode_.num_passes == 1) {
     31    memcpy(output[0], block, sizeof(T) * size);
     32    return;
     33  }
     34  size_t ncoeffs_all_done_from_earlier_passes = 1;
     35 
     36  int previous_pass_shift = 0;
     37  for (size_t num_pass = 0; num_pass < mode_.num_passes; num_pass++) {  // pass
     38    // Zero out output block.
     39    memset(output[num_pass], 0, size * sizeof(T));
     40    const int pass_shift = mode_.passes[num_pass].shift;
     41    size_t frame_ncoeffs = mode_.passes[num_pass].num_coefficients;
     42    size_t xsize = acs.covered_blocks_x();
     43    size_t ysize = acs.covered_blocks_y();
     44    CoefficientLayout(&ysize, &xsize);
     45    for (size_t y = 0; y < ysize * frame_ncoeffs; y++) {    // superblk-y
     46      for (size_t x = 0; x < xsize * frame_ncoeffs; x++) {  // superblk-x
     47        size_t pos = y * xsize * kBlockDim + x;
     48        if (x < xsize * ncoeffs_all_done_from_earlier_passes &&
     49            y < ysize * ncoeffs_all_done_from_earlier_passes) {
     50          // This coefficient was already included in an earlier pass,
     51          // which included a genuinely smaller set of coefficients.
     52          continue;
     53        }
     54        T v = block[pos];
     55        // Previous pass discarded some bits: do not encode them again.
     56        if (previous_pass_shift != 0) {
     57          T previous_v = shift_right_round0(v, previous_pass_shift) *
     58                         (1 << previous_pass_shift);
     59          v -= previous_v;
     60        }
     61        output[num_pass][pos] = shift_right_round0(v, pass_shift);
     62      }  // superblk-x
     63    }    // superblk-y
     64    // We just finished a pass.
     65    // Hence, we are now guaranteed to have included all coeffs up to
     66    // frame_ncoeffs in every block, unless the current pass is shifted.
     67    if (mode_.passes[num_pass].shift == 0) {
     68      ncoeffs_all_done_from_earlier_passes = frame_ncoeffs;
     69    }
     70    previous_pass_shift = mode_.passes[num_pass].shift;
     71  }  // num_pass
     72 }
     73 
     74 template void ProgressiveSplitter::SplitACCoefficients<int32_t>(
     75    const int32_t* JXL_RESTRICT, const AcStrategy&, size_t, size_t,
     76    int32_t* JXL_RESTRICT[kMaxNumPasses]);
     77 
     78 template void ProgressiveSplitter::SplitACCoefficients<int16_t>(
     79    const int16_t* JXL_RESTRICT, const AcStrategy&, size_t, size_t,
     80    int16_t* JXL_RESTRICT[kMaxNumPasses]);
     81 
     82 }  // namespace jxl