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