libjxl

FORK: libjxl patches used on blog
git clone https://git.neptards.moe/blog/libjxl.git
Log | Files | Refs | Submodules | 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