Source code

Revision control

Copy as Markdown

Other Tools

// Copyright (c) the JPEG XL Project Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include "lib/jxl/modular/transform/enc_rct.h"
#include "lib/jxl/base/status.h"
#include "lib/jxl/modular/modular_image.h"
#include "lib/jxl/modular/transform/transform.h" // CheckEqualChannels
namespace jxl {
Status FwdRCT(Image& input, size_t begin_c, size_t rct_type, ThreadPool* pool) {
JXL_RETURN_IF_ERROR(CheckEqualChannels(input, begin_c, begin_c + 2));
if (rct_type == 0) { // noop
return false;
}
// Permutation: 0=RGB, 1=GBR, 2=BRG, 3=RBG, 4=GRB, 5=BGR
int permutation = rct_type / 7;
// 0-5 values have the low bit corresponding to Third and the high bits
// corresponding to Second. 6 corresponds to YCoCg.
//
// Second: 0=nop, 1=SubtractFirst, 2=SubtractAvgFirstThird
//
// Third: 0=nop, 1=SubtractFirst
int custom = rct_type % 7;
size_t m = begin_c;
size_t w = input.channel[m + 0].w;
size_t h = input.channel[m + 0].h;
int second = (custom % 7) >> 1;
int third = (custom % 7) & 1;
const auto do_rct = [&](const int y, const int thread) -> Status {
const pixel_type* in0 = input.channel[m + (permutation % 3)].Row(y);
const pixel_type* in1 =
input.channel[m + ((permutation + 1 + permutation / 3) % 3)].Row(y);
const pixel_type* in2 =
input.channel[m + ((permutation + 2 - permutation / 3) % 3)].Row(y);
pixel_type* out0 = input.channel[m].Row(y);
pixel_type* out1 = input.channel[m + 1].Row(y);
pixel_type* out2 = input.channel[m + 2].Row(y);
if (custom == 6) {
for (size_t x = 0; x < w; x++) {
pixel_type R = in0[x];
pixel_type G = in1[x];
pixel_type B = in2[x];
out1[x] = R - B;
pixel_type tmp = B + (out1[x] >> 1);
out2[x] = G - tmp;
out0[x] = tmp + (out2[x] >> 1);
}
} else {
for (size_t x = 0; x < w; x++) {
pixel_type First = in0[x];
pixel_type Second = in1[x];
pixel_type Third = in2[x];
if (second == 1) {
Second = Second - First;
} else if (second == 2) {
Second = Second - ((First + Third) >> 1);
}
if (third) Third = Third - First;
out0[x] = First;
out1[x] = Second;
out2[x] = Third;
}
}
return true;
};
JXL_RETURN_IF_ERROR(
RunOnPool(pool, 0, h, ThreadPool::NoInit, do_rct, "FwdRCT"));
return true;
}
} // namespace jxl