libjxl

FORK: libjxl patches used on blog
git clone https://git.neptards.moe/blog/libjxl.git
Log | Files | Refs | Submodules | README | LICENSE

enc_rct.cc (2454B)


      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/modular/transform/enc_rct.h"
      7 
      8 #include "lib/jxl/base/status.h"
      9 #include "lib/jxl/modular/modular_image.h"
     10 #include "lib/jxl/modular/transform/transform.h"  // CheckEqualChannels
     11 
     12 namespace jxl {
     13 
     14 Status FwdRCT(Image& input, size_t begin_c, size_t rct_type, ThreadPool* pool) {
     15   JXL_RETURN_IF_ERROR(CheckEqualChannels(input, begin_c, begin_c + 2));
     16   if (rct_type == 0) {  // noop
     17     return false;
     18   }
     19   // Permutation: 0=RGB, 1=GBR, 2=BRG, 3=RBG, 4=GRB, 5=BGR
     20   int permutation = rct_type / 7;
     21   // 0-5 values have the low bit corresponding to Third and the high bits
     22   // corresponding to Second. 6 corresponds to YCoCg.
     23   //
     24   // Second: 0=nop, 1=SubtractFirst, 2=SubtractAvgFirstThird
     25   //
     26   // Third: 0=nop, 1=SubtractFirst
     27   int custom = rct_type % 7;
     28   size_t m = begin_c;
     29   size_t w = input.channel[m + 0].w;
     30   size_t h = input.channel[m + 0].h;
     31   int second = (custom % 7) >> 1;
     32   int third = (custom % 7) & 1;
     33   const auto do_rct = [&](const int y, const int thread) {
     34     const pixel_type* in0 = input.channel[m + (permutation % 3)].Row(y);
     35     const pixel_type* in1 =
     36         input.channel[m + ((permutation + 1 + permutation / 3) % 3)].Row(y);
     37     const pixel_type* in2 =
     38         input.channel[m + ((permutation + 2 - permutation / 3) % 3)].Row(y);
     39     pixel_type* out0 = input.channel[m].Row(y);
     40     pixel_type* out1 = input.channel[m + 1].Row(y);
     41     pixel_type* out2 = input.channel[m + 2].Row(y);
     42     if (custom == 6) {
     43       for (size_t x = 0; x < w; x++) {
     44         pixel_type R = in0[x];
     45         pixel_type G = in1[x];
     46         pixel_type B = in2[x];
     47         out1[x] = R - B;
     48         pixel_type tmp = B + (out1[x] >> 1);
     49         out2[x] = G - tmp;
     50         out0[x] = tmp + (out2[x] >> 1);
     51       }
     52     } else {
     53       for (size_t x = 0; x < w; x++) {
     54         pixel_type First = in0[x];
     55         pixel_type Second = in1[x];
     56         pixel_type Third = in2[x];
     57         if (second == 1) {
     58           Second = Second - First;
     59         } else if (second == 2) {
     60           Second = Second - ((First + Third) >> 1);
     61         }
     62         if (third) Third = Third - First;
     63         out0[x] = First;
     64         out1[x] = Second;
     65         out2[x] = Third;
     66       }
     67     }
     68   };
     69   return RunOnPool(pool, 0, h, ThreadPool::NoInit, do_rct, "FwdRCT");
     70 }
     71 
     72 }  // namespace jxl