// 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.
#if defined (LIB_JXL_DEC_TRANSFORMS_INL_H_) == defined (HWY_TARGET_TOGGLE)
#ifdef LIB_JXL_DEC_TRANSFORMS_INL_H_
#undef LIB_JXL_DEC_TRANSFORMS_INL_H_
#else
#define LIB_JXL_DEC_TRANSFORMS_INL_H_
#endif
#include <cstddef>
#include <hwy/highway.h>
#include "lib/jxl/ac_strategy.h"
#include "lib/jxl/dct-inl.h"
#include "lib/jxl/dct_scales.h"
HWY_BEFORE_NAMESPACE();
namespace jxl {
namespace HWY_NAMESPACE {
namespace {
// These templates are not found via ADL.
using hwy::HWY_NAMESPACE::MulAdd;
// Computes the lowest-frequency LF_ROWSxLF_COLS-sized square in output, which
// is a DCT_ROWS*DCT_COLS-sized DCT block, by doing a ROWS*COLS DCT on the
// input block.
template <size_t DCT_ROWS, size_t DCT_COLS, size_t LF_ROWS, size_t LF_COLS,
size_t ROWS, size_t COLS>
JXL_INLINE void ReinterpretingDCT(const float * input, const size_t input_stride,
float * output, const size_t output_stride,
float * JXL_RESTRICT block,
float * JXL_RESTRICT scratch_space) {
static_assert(LF_ROWS == ROWS,
"ReinterpretingDCT should only be called with LF == N" );
static_assert(LF_COLS == COLS,
"ReinterpretingDCT should only be called with LF == N" );
ComputeScaledDCT<ROWS, COLS>()(DCTFrom(input, input_stride), block,
scratch_space);
if (ROWS < COLS) {
for (size_t y = 0 ; y < LF_ROWS; y++) {
for (size_t x = 0 ; x < LF_COLS; x++) {
output[y * output_stride + x] =
block[y * COLS + x] * DCTTotalResampleScale<ROWS, DCT_ROWS>(y) *
DCTTotalResampleScale<COLS, DCT_COLS>(x);
}
}
} else {
for (size_t y = 0 ; y < LF_COLS; y++) {
for (size_t x = 0 ; x < LF_ROWS; x++) {
output[y * output_stride + x] =
block[y * ROWS + x] * DCTTotalResampleScale<COLS, DCT_COLS>(y) *
DCTTotalResampleScale<ROWS, DCT_ROWS>(x);
}
}
}
}
template <size_t S>
void IDCT2TopBlock(const float * block, size_t stride_out, float * out) {
static_assert(kBlockDim % S == 0 , "S should be a divisor of kBlockDim" );
static_assert(S % 2 == 0 , "S should be even" );
float temp[kDCTBlockSize];
constexpr size_t num_2x2 = S / 2 ;
for (size_t y = 0 ; y < num_2x2; y++) {
for (size_t x = 0 ; x < num_2x2; x++) {
float c00 = block[y * kBlockDim + x];
float c01 = block[y * kBlockDim + num_2x2 + x];
float c10 = block[(y + num_2x2) * kBlockDim + x];
float c11 = block[(y + num_2x2) * kBlockDim + num_2x2 + x];
float r00 = c00 + c01 + c10 + c11;
float r01 = c00 + c01 - c10 - c11;
float r10 = c00 - c01 + c10 - c11;
float r11 = c00 - c01 - c10 + c11;
temp[y * 2 * kBlockDim + x * 2 ] = r00;
temp[y * 2 * kBlockDim + x * 2 + 1 ] = r01;
temp[(y * 2 + 1 ) * kBlockDim + x * 2 ] = r10;
temp[(y * 2 + 1 ) * kBlockDim + x * 2 + 1 ] = r11;
}
}
for (size_t y = 0 ; y < S; y++) {
for (size_t x = 0 ; x < S; x++) {
out[y * stride_out + x] = temp[y * kBlockDim + x];
}
}
}
void AFVIDCT4x4(const float * JXL_RESTRICT coeffs, float * JXL_RESTRICT pixels) {
HWY_ALIGN static constexpr float k4x4AFVBasis[16 ][16 ] = {
{
0 .25 ,
0 .25 ,
0 .25 ,
0 .25 ,
0 .25 ,
0 .25 ,
0 .25 ,
0 .25 ,
0 .25 ,
0 .25 ,
0 .25 ,
0 .25 ,
0 .25 ,
0 .25 ,
0 .25 ,
0 .25 ,
},
{
0 .876902929799142 f,
0 .2206518106944235 f,
-0 .10140050393753763 f,
-0 .1014005039375375 f,
0 .2206518106944236 f,
-0 .10140050393753777 f,
-0 .10140050393753772 f,
-0 .10140050393753763 f,
-0 .10140050393753758 f,
-0 .10140050393753769 f,
-0 .1014005039375375 f,
-0 .10140050393753768 f,
-0 .10140050393753768 f,
-0 .10140050393753759 f,
-0 .10140050393753763 f,
-0 .10140050393753741 f,
},
{
0 .0 ,
0 .0 ,
0 .40670075830260755 f,
0 .44444816619734445 f,
0 .0 ,
0 .0 ,
0 .19574399372042936 f,
0 .2929100136981264 f,
-0 .40670075830260716 f,
-0 .19574399372042872 f,
0 .0 ,
0 .11379074460448091 f,
-0 .44444816619734384 f,
-0 .29291001369812636 f,
-0 .1137907446044814 f,
0 .0 ,
},
{
0 .0 ,
0 .0 ,
-0 .21255748058288748 f,
0 .3085497062849767 f,
0 .0 ,
0 .4706702258572536 f,
-0 .1621205195722993 f,
0 .0 ,
-0 .21255748058287047 f,
-0 .16212051957228327 f,
-0 .47067022585725277 f,
-0 .1464291867126764 f,
0 .3085497062849487 f,
0 .0 ,
-0 .14642918671266536 f,
0 .4251149611657548 f,
},
{
0 .0 ,
-0 .7071067811865474 f,
0 .0 ,
0 .0 ,
0 .7071067811865476 f,
0 .0 ,
0 .0 ,
0 .0 ,
0 .0 ,
0 .0 ,
0 .0 ,
0 .0 ,
0 .0 ,
0 .0 ,
0 .0 ,
0 .0 ,
},
{
-0 .4105377591765233 f,
0 .6235485373547691 f,
-0 .06435071657946274 f,
-0 .06435071657946266 f,
0 .6235485373547694 f,
-0 .06435071657946284 f,
-0 .0643507165794628 f,
-0 .06435071657946274 f,
-0 .06435071657946272 f,
-0 .06435071657946279 f,
-0 .06435071657946266 f,
-0 .06435071657946277 f,
-0 .06435071657946277 f,
-0 .06435071657946273 f,
-0 .06435071657946274 f,
-0 .0643507165794626 f,
},
{
0 .0 ,
0 .0 ,
-0 .4517556589999482 f,
0 .15854503551840063 f,
0 .0 ,
-0 .04038515160822202 f,
0 .0074182263792423875 f,
0 .39351034269210167 f,
-0 .45175565899994635 f,
0 .007418226379244351 f,
0 .1107416575309343 f,
0 .08298163094882051 f,
0 .15854503551839705 f,
0 .3935103426921022 f,
0 .0829816309488214 f,
-0 .45175565899994796 f,
},
{
0 .0 ,
0 .0 ,
-0 .304684750724869 f,
0 .5112616136591823 f,
0 .0 ,
0 .0 ,
-0 .290480129728998 f,
-0 .06578701549142804 f,
0 .304684750724884 f,
0 .2904801297290076 f,
0 .0 ,
-0 .23889773523344604 f,
-0 .5112616136592012 f,
0 .06578701549142545 f,
0 .23889773523345467 f,
0 .0 ,
},
{
0 .0 ,
0 .0 ,
0 .3017929516615495 f,
0 .25792362796341184 f,
0 .0 ,
0 .16272340142866204 f,
0 .09520022653475037 f,
0 .0 ,
0 .3017929516615503 f,
0 .09520022653475055 f,
-0 .16272340142866173 f,
-0 .35312385449816297 f,
0 .25792362796341295 f,
0 .0 ,
-0 .3531238544981624 f,
-0 .6035859033230976 f,
},
{
0 .0 ,
0 .0 ,
0 .40824829046386274 f,
0 .0 ,
0 .0 ,
0 .0 ,
0 .0 ,
-0 .4082482904638628 f,
-0 .4082482904638635 f,
0 .0 ,
0 .0 ,
-0 .40824829046386296 f,
0 .0 ,
0 .4082482904638634 f,
0 .408248290463863 f,
0 .0 ,
},
{
0 .0 ,
0 .0 ,
0 .1747866975480809 f,
0 .0812611176717539 f,
0 .0 ,
0 .0 ,
-0 .3675398009862027 f,
-0 .307882213957909 f,
-0 .17478669754808135 f,
0 .3675398009862011 f,
0 .0 ,
0 .4826689115059883 f,
-0 .08126111767175039 f,
0 .30788221395790305 f,
-0 .48266891150598584 f,
0 .0 ,
},
{
0 .0 ,
0 .0 ,
-0 .21105601049335784 f,
0 .18567180916109802 f,
0 .0 ,
0 .0 ,
0 .49215859013738733 f,
-0 .38525013709251915 f,
0 .21105601049335806 f,
-0 .49215859013738905 f,
0 .0 ,
0 .17419412659916217 f,
-0 .18567180916109904 f,
0 .3852501370925211 f,
-0 .1741941265991621 f,
0 .0 ,
},
{
0 .0 ,
0 .0 ,
-0 .14266084808807264 f,
-0 .3416446842253372 f,
0 .0 ,
0 .7367497537172237 f,
0 .24627107722075148 f,
-0 .08574019035519306 f,
-0 .14266084808807344 f,
0 .24627107722075137 f,
0 .14883399227113567 f,
-0 .04768680350229251 f,
-0 .3416446842253373 f,
-0 .08574019035519267 f,
-0 .047686803502292804 f,
-0 .14266084808807242 f,
},
{
0 .0 ,
0 .0 ,
-0 .13813540350758585 f,
0 .3302282550303788 f,
0 .0 ,
0 .08755115000587084 f,
-0 .07946706605909573 f,
-0 .4613374887461511 f,
-0 .13813540350758294 f,
-0 .07946706605910261 f,
0 .49724647109535086 f,
0 .12538059448563663 f,
0 .3302282550303805 f,
-0 .4613374887461554 f,
0 .12538059448564315 f,
-0 .13813540350758452 f,
},
{
0 .0 ,
0 .0 ,
-0 .17437602599651067 f,
0 .0702790691196284 f,
0 .0 ,
-0 .2921026642334881 f,
0 .3623817333531167 f,
0 .0 ,
-0 .1743760259965108 f,
0 .36238173335311646 f,
0 .29210266423348785 f,
-0 .4326608024727445 f,
0 .07027906911962818 f,
0 .0 ,
-0 .4326608024727457 f,
0 .34875205199302267 f,
},
{
0 .0 ,
0 .0 ,
0 .11354987314994337 f,
-0 .07417504595810355 f,
0 .0 ,
0 .19402893032594343 f,
-0 .435190496523228 f,
0 .21918684838857466 f,
0 .11354987314994257 f,
-0 .4351904965232251 f,
0 .5550443808910661 f,
-0 .25468277124066463 f,
-0 .07417504595810233 f,
0 .2191868483885728 f,
-0 .25468277124066413 f,
0 .1135498731499429 f,
},
};
const HWY_CAPPED(float , 16 ) d;
for (size_t i = 0 ; i < 16 ; i += Lanes(d)) {
auto pixel = Zero(d);
for (size_t j = 0 ; j < 16 ; j++) {
auto cf = Set(d, coeffs[j]);
auto basis = Load(d, k4x4AFVBasis[j] + i);
pixel = MulAdd(cf, basis, pixel);
}
Store(pixel, d, pixels + i);
}
}
template <size_t afv_kind>
void AFVTransformToPixels(const float * JXL_RESTRICT coefficients,
float * JXL_RESTRICT pixels, size_t pixels_stride) {
HWY_ALIGN float scratch_space[4 * 8 * 4 ];
size_t afv_x = afv_kind & 1 ;
size_t afv_y = afv_kind / 2 ;
float dcs[3 ] = {};
float block00 = coefficients[0 ];
float block01 = coefficients[1 ];
float block10 = coefficients[8 ];
dcs[0 ] = (block00 + block10 + block01) * 4 .0 f;
dcs[1 ] = (block00 + block10 - block01);
dcs[2 ] = block00 - block10;
// IAFV: (even, even) positions.
HWY_ALIGN float coeff[4 * 4 ];
coeff[0 ] = dcs[0 ];
for (size_t iy = 0 ; iy < 4 ; iy++) {
for (size_t ix = 0 ; ix < 4 ; ix++) {
if (ix == 0 && iy == 0 ) continue ;
coeff[iy * 4 + ix] = coefficients[iy * 2 * 8 + ix * 2 ];
}
}
HWY_ALIGN float block[4 * 8 ];
AFVIDCT4x4(coeff, block);
for (size_t iy = 0 ; iy < 4 ; iy++) {
for (size_t ix = 0 ; ix < 4 ; ix++) {
pixels[(iy + afv_y * 4 ) * pixels_stride + afv_x * 4 + ix] =
block[(afv_y == 1 ? 3 - iy : iy) * 4 + (afv_x == 1 ? 3 - ix : ix)];
}
}
// IDCT4x4 in (odd, even) positions.
block[0 ] = dcs[1 ];
for (size_t iy = 0 ; iy < 4 ; iy++) {
for (size_t ix = 0 ; ix < 4 ; ix++) {
if (ix == 0 && iy == 0 ) continue ;
block[iy * 4 + ix] = coefficients[iy * 2 * 8 + ix * 2 + 1 ];
}
}
ComputeScaledIDCT<4 , 4 >()(
block,
DCTTo(pixels + afv_y * 4 * pixels_stride + (afv_x == 1 ? 0 : 4 ),
pixels_stride),
scratch_space);
// IDCT4x8.
block[0 ] = dcs[2 ];
for (size_t iy = 0 ; iy < 4 ; iy++) {
for (size_t ix = 0 ; ix < 8 ; ix++) {
if (ix == 0 && iy == 0 ) continue ;
block[iy * 8 + ix] = coefficients[(1 + iy * 2 ) * 8 + ix];
}
}
ComputeScaledIDCT<4 , 8 >()(
block,
DCTTo(pixels + (afv_y == 1 ? 0 : 4 ) * pixels_stride, pixels_stride),
scratch_space);
}
HWY_MAYBE_UNUSED void TransformToPixels(const AcStrategyType strategy,
float * JXL_RESTRICT coefficients,
float * JXL_RESTRICT pixels,
size_t pixels_stride,
float * scratch_space) {
using Type = AcStrategyType;
switch (strategy) {
case Type::IDENTITY: {
float dcs[4 ] = {};
float block00 = coefficients[0 ];
float block01 = coefficients[1 ];
float block10 = coefficients[8 ];
float block11 = coefficients[9 ];
dcs[0 ] = block00 + block01 + block10 + block11;
dcs[1 ] = block00 + block01 - block10 - block11;
dcs[2 ] = block00 - block01 + block10 - block11;
dcs[3 ] = block00 - block01 - block10 + block11;
for (size_t y = 0 ; y < 2 ; y++) {
for (size_t x = 0 ; x < 2 ; x++) {
float block_dc = dcs[y * 2 + x];
float residual_sum = 0 ;
for (size_t iy = 0 ; iy < 4 ; iy++) {
for (size_t ix = 0 ; ix < 4 ; ix++) {
if (ix == 0 && iy == 0 ) continue ;
residual_sum += coefficients[(y + iy * 2 ) * 8 + x + ix * 2 ];
}
}
pixels[(4 * y + 1 ) * pixels_stride + 4 * x + 1 ] =
block_dc - residual_sum * (1 .0 f / 16 );
for (size_t iy = 0 ; iy < 4 ; iy++) {
for (size_t ix = 0 ; ix < 4 ; ix++) {
if (ix == 1 && iy == 1 ) continue ;
pixels[(y * 4 + iy) * pixels_stride + x * 4 + ix] =
coefficients[(y + iy * 2 ) * 8 + x + ix * 2 ] +
pixels[(4 * y + 1 ) * pixels_stride + 4 * x + 1 ];
}
}
pixels[y * 4 * pixels_stride + x * 4 ] =
coefficients[(y + 2 ) * 8 + x + 2 ] +
pixels[(4 * y + 1 ) * pixels_stride + 4 * x + 1 ];
}
}
break ;
}
case Type::DCT8X4: {
float dcs[2 ] = {};
float block0 = coefficients[0 ];
float block1 = coefficients[8 ];
dcs[0 ] = block0 + block1;
dcs[1 ] = block0 - block1;
for (size_t x = 0 ; x < 2 ; x++) {
HWY_ALIGN float block[4 * 8 ];
block[0 ] = dcs[x];
for (size_t iy = 0 ; iy < 4 ; iy++) {
for (size_t ix = 0 ; ix < 8 ; ix++) {
if (ix == 0 && iy == 0 ) continue ;
block[iy * 8 + ix] = coefficients[(x + iy * 2 ) * 8 + ix];
}
}
ComputeScaledIDCT<8 , 4 >()(block, DCTTo(pixels + x * 4 , pixels_stride),
scratch_space);
}
break ;
}
case Type::DCT4X8: {
float dcs[2 ] = {};
float block0 = coefficients[0 ];
float block1 = coefficients[8 ];
dcs[0 ] = block0 + block1;
dcs[1 ] = block0 - block1;
for (size_t y = 0 ; y < 2 ; y++) {
HWY_ALIGN float block[4 * 8 ];
block[0 ] = dcs[y];
for (size_t iy = 0 ; iy < 4 ; iy++) {
for (size_t ix = 0 ; ix < 8 ; ix++) {
if (ix == 0 && iy == 0 ) continue ;
block[iy * 8 + ix] = coefficients[(y + iy * 2 ) * 8 + ix];
}
}
ComputeScaledIDCT<4 , 8 >()(
block, DCTTo(pixels + y * 4 * pixels_stride, pixels_stride),
scratch_space);
}
break ;
}
case Type::DCT4X4: {
float dcs[4 ] = {};
float block00 = coefficients[0 ];
float block01 = coefficients[1 ];
float block10 = coefficients[8 ];
float block11 = coefficients[9 ];
dcs[0 ] = block00 + block01 + block10 + block11;
dcs[1 ] = block00 + block01 - block10 - block11;
dcs[2 ] = block00 - block01 + block10 - block11;
dcs[3 ] = block00 - block01 - block10 + block11;
for (size_t y = 0 ; y < 2 ; y++) {
for (size_t x = 0 ; x < 2 ; x++) {
HWY_ALIGN float block[4 * 4 ];
block[0 ] = dcs[y * 2 + x];
for (size_t iy = 0 ; iy < 4 ; iy++) {
for (size_t ix = 0 ; ix < 4 ; ix++) {
if (ix == 0 && iy == 0 ) continue ;
block[iy * 4 + ix] = coefficients[(y + iy * 2 ) * 8 + x + ix * 2 ];
}
}
ComputeScaledIDCT<4 , 4 >()(
block,
DCTTo(pixels + y * 4 * pixels_stride + x * 4 , pixels_stride),
scratch_space);
}
}
break ;
}
case Type::DCT2X2: {
HWY_ALIGN float coeffs[kDCTBlockSize];
memcpy(coeffs, coefficients, sizeof (float ) * kDCTBlockSize);
IDCT2TopBlock<2 >(coeffs, kBlockDim, coeffs);
IDCT2TopBlock<4 >(coeffs, kBlockDim, coeffs);
IDCT2TopBlock<8 >(coeffs, kBlockDim, coeffs);
for (size_t y = 0 ; y < kBlockDim; y++) {
for (size_t x = 0 ; x < kBlockDim; x++) {
pixels[y * pixels_stride + x] = coeffs[y * kBlockDim + x];
}
}
break ;
}
case Type::DCT16X16: {
ComputeScaledIDCT<16 , 16 >()(coefficients, DCTTo(pixels, pixels_stride),
scratch_space);
break ;
}
case Type::DCT16X8: {
ComputeScaledIDCT<16 , 8 >()(coefficients, DCTTo(pixels, pixels_stride),
scratch_space);
break ;
}
case Type::DCT8X16: {
ComputeScaledIDCT<8 , 16 >()(coefficients, DCTTo(pixels, pixels_stride),
scratch_space);
break ;
}
case Type::DCT32X8: {
ComputeScaledIDCT<32 , 8 >()(coefficients, DCTTo(pixels, pixels_stride),
scratch_space);
break ;
}
case Type::DCT8X32: {
ComputeScaledIDCT<8 , 32 >()(coefficients, DCTTo(pixels, pixels_stride),
scratch_space);
break ;
}
case Type::DCT32X16: {
ComputeScaledIDCT<32 , 16 >()(coefficients, DCTTo(pixels, pixels_stride),
scratch_space);
break ;
}
case Type::DCT16X32: {
ComputeScaledIDCT<16 , 32 >()(coefficients, DCTTo(pixels, pixels_stride),
scratch_space);
break ;
}
case Type::DCT32X32: {
ComputeScaledIDCT<32 , 32 >()(coefficients, DCTTo(pixels, pixels_stride),
scratch_space);
break ;
}
case Type::DCT: {
ComputeScaledIDCT<8 , 8 >()(coefficients, DCTTo(pixels, pixels_stride),
scratch_space);
break ;
}
case Type::AFV0: {
AFVTransformToPixels<0 >(coefficients, pixels, pixels_stride);
break ;
}
case Type::AFV1: {
AFVTransformToPixels<1 >(coefficients, pixels, pixels_stride);
break ;
}
case Type::AFV2: {
AFVTransformToPixels<2 >(coefficients, pixels, pixels_stride);
break ;
}
case Type::AFV3: {
AFVTransformToPixels<3 >(coefficients, pixels, pixels_stride);
break ;
}
case Type::DCT64X32: {
ComputeScaledIDCT<64 , 32 >()(coefficients, DCTTo(pixels, pixels_stride),
scratch_space);
break ;
}
case Type::DCT32X64: {
ComputeScaledIDCT<32 , 64 >()(coefficients, DCTTo(pixels, pixels_stride),
scratch_space);
break ;
}
case Type::DCT64X64: {
ComputeScaledIDCT<64 , 64 >()(coefficients, DCTTo(pixels, pixels_stride),
scratch_space);
break ;
}
case Type::DCT128X64: {
ComputeScaledIDCT<128 , 64 >()(coefficients, DCTTo(pixels, pixels_stride),
scratch_space);
break ;
}
case Type::DCT64X128: {
ComputeScaledIDCT<64 , 128 >()(coefficients, DCTTo(pixels, pixels_stride),
scratch_space);
break ;
}
case Type::DCT128X128: {
ComputeScaledIDCT<128 , 128 >()(coefficients, DCTTo(pixels, pixels_stride),
scratch_space);
break ;
}
case Type::DCT256X128: {
ComputeScaledIDCT<256 , 128 >()(coefficients, DCTTo(pixels, pixels_stride),
scratch_space);
break ;
}
case Type::DCT128X256: {
ComputeScaledIDCT<128 , 256 >()(coefficients, DCTTo(pixels, pixels_stride),
scratch_space);
break ;
}
case Type::DCT256X256: {
ComputeScaledIDCT<256 , 256 >()(coefficients, DCTTo(pixels, pixels_stride),
scratch_space);
break ;
}
}
}
HWY_MAYBE_UNUSED void LowestFrequenciesFromDC(const AcStrategyType strategy,
const float * dc, size_t dc_stride,
float * llf,
float * JXL_RESTRICT scratch) {
using Type = AcStrategyType;
HWY_ALIGN float warm_block[4 * 4 ];
HWY_ALIGN float warm_scratch_space[4 * 4 * 4 ];
switch (strategy) {
case Type::DCT16X8: {
ReinterpretingDCT</*DCT_ROWS=*/2 * kBlockDim, /*DCT_COLS=*/kBlockDim,
/*LF_ROWS=*/2, /*LF_COLS=*/1, /*ROWS=*/2, /*COLS=*/1>(
dc, dc_stride, llf, 2 * kBlockDim, warm_block, warm_scratch_space);
break ;
}
case Type::DCT8X16: {
ReinterpretingDCT</*DCT_ROWS=*/kBlockDim, /*DCT_COLS=*/2 * kBlockDim,
/*LF_ROWS=*/1, /*LF_COLS=*/2, /*ROWS=*/1, /*COLS=*/2>(
dc, dc_stride, llf, 2 * kBlockDim, warm_block, warm_scratch_space);
break ;
}
case Type::DCT16X16: {
ReinterpretingDCT</*DCT_ROWS=*/2 * kBlockDim, /*DCT_COLS=*/2 * kBlockDim,
/*LF_ROWS=*/2, /*LF_COLS=*/2, /*ROWS=*/2, /*COLS=*/2>(
dc, dc_stride, llf, 2 * kBlockDim, warm_block, warm_scratch_space);
break ;
}
case Type::DCT32X8: {
ReinterpretingDCT</*DCT_ROWS=*/4 * kBlockDim, /*DCT_COLS=*/kBlockDim,
/*LF_ROWS=*/4, /*LF_COLS=*/1, /*ROWS=*/4, /*COLS=*/1>(
dc, dc_stride, llf, 4 * kBlockDim, warm_block, warm_scratch_space);
break ;
}
case Type::DCT8X32: {
ReinterpretingDCT</*DCT_ROWS=*/kBlockDim, /*DCT_COLS=*/4 * kBlockDim,
/*LF_ROWS=*/1, /*LF_COLS=*/4, /*ROWS=*/1, /*COLS=*/4>(
dc, dc_stride, llf, 4 * kBlockDim, warm_block, warm_scratch_space);
break ;
}
case Type::DCT32X16: {
ReinterpretingDCT</*DCT_ROWS=*/4 * kBlockDim, /*DCT_COLS=*/2 * kBlockDim,
/*LF_ROWS=*/4, /*LF_COLS=*/2, /*ROWS=*/4, /*COLS=*/2>(
dc, dc_stride, llf, 4 * kBlockDim, warm_block, warm_scratch_space);
break ;
}
case Type::DCT16X32: {
ReinterpretingDCT</*DCT_ROWS=*/2 * kBlockDim, /*DCT_COLS=*/4 * kBlockDim,
/*LF_ROWS=*/2, /*LF_COLS=*/4, /*ROWS=*/2, /*COLS=*/4>(
dc, dc_stride, llf, 4 * kBlockDim, warm_block, warm_scratch_space);
break ;
}
case Type::DCT32X32: {
ReinterpretingDCT</*DCT_ROWS=*/4 * kBlockDim, /*DCT_COLS=*/4 * kBlockDim,
/*LF_ROWS=*/4, /*LF_COLS=*/4, /*ROWS=*/4, /*COLS=*/4>(
dc, dc_stride, llf, 4 * kBlockDim, warm_block, warm_scratch_space);
break ;
}
case Type::DCT64X32: {
ReinterpretingDCT</*DCT_ROWS=*/8 * kBlockDim, /*DCT_COLS=*/4 * kBlockDim,
/*LF_ROWS=*/8, /*LF_COLS=*/4, /*ROWS=*/8, /*COLS=*/4>(
dc, dc_stride, llf, 8 * kBlockDim, scratch, scratch + 8 * 4 );
break ;
}
case Type::DCT32X64: {
ReinterpretingDCT</*DCT_ROWS=*/4 * kBlockDim, /*DCT_COLS=*/8 * kBlockDim,
/*LF_ROWS=*/4, /*LF_COLS=*/8, /*ROWS=*/4, /*COLS=*/8>(
dc, dc_stride, llf, 8 * kBlockDim, scratch, scratch + 4 * 8 );
break ;
}
case Type::DCT64X64: {
ReinterpretingDCT</*DCT_ROWS=*/8 * kBlockDim, /*DCT_COLS=*/8 * kBlockDim,
/*LF_ROWS=*/8, /*LF_COLS=*/8, /*ROWS=*/8, /*COLS=*/8>(
dc, dc_stride, llf, 8 * kBlockDim, scratch, scratch + 8 * 8 );
break ;
}
case Type::DCT128X64: {
ReinterpretingDCT</*DCT_ROWS=*/16 * kBlockDim, /*DCT_COLS=*/8 * kBlockDim,
/*LF_ROWS=*/16, /*LF_COLS=*/8, /*ROWS=*/16, /*COLS=*/8>(
dc, dc_stride, llf, 16 * kBlockDim, scratch, scratch + 16 * 8 );
break ;
}
case Type::DCT64X128: {
ReinterpretingDCT</*DCT_ROWS=*/8 * kBlockDim, /*DCT_COLS=*/16 * kBlockDim,
/*LF_ROWS=*/8, /*LF_COLS=*/16, /*ROWS=*/8, /*COLS=*/16>(
dc, dc_stride, llf, 16 * kBlockDim, scratch, scratch + 8 * 16 );
break ;
}
case Type::DCT128X128: {
ReinterpretingDCT<
/*DCT_ROWS=*/16 * kBlockDim, /*DCT_COLS=*/16 * kBlockDim,
/*LF_ROWS=*/16, /*LF_COLS=*/16, /*ROWS=*/16, /*COLS=*/16>(
dc, dc_stride, llf, 16 * kBlockDim, scratch, scratch + 16 * 16 );
break ;
}
case Type::DCT256X128: {
ReinterpretingDCT<
/*DCT_ROWS=*/32 * kBlockDim, /*DCT_COLS=*/16 * kBlockDim,
/*LF_ROWS=*/32, /*LF_COLS=*/16, /*ROWS=*/32, /*COLS=*/16>(
dc, dc_stride, llf, 32 * kBlockDim, scratch, scratch + 32 * 16 );
break ;
}
case Type::DCT128X256: {
ReinterpretingDCT<
/*DCT_ROWS=*/16 * kBlockDim, /*DCT_COLS=*/32 * kBlockDim,
/*LF_ROWS=*/16, /*LF_COLS=*/32, /*ROWS=*/16, /*COLS=*/32>(
dc, dc_stride, llf, 32 * kBlockDim, scratch, scratch + 16 * 32 );
break ;
}
case Type::DCT256X256: {
ReinterpretingDCT<
/*DCT_ROWS=*/32 * kBlockDim, /*DCT_COLS=*/32 * kBlockDim,
/*LF_ROWS=*/32, /*LF_COLS=*/32, /*ROWS=*/32, /*COLS=*/32>(
dc, dc_stride, llf, 32 * kBlockDim, scratch, scratch + 32 * 32 );
break ;
}
case Type::DCT:
case Type::DCT2X2:
case Type::DCT4X4:
case Type::DCT4X8:
case Type::DCT8X4:
case Type::AFV0:
case Type::AFV1:
case Type::AFV2:
case Type::AFV3:
case Type::IDENTITY:
llf[0 ] = dc[0 ];
break ;
};
}
} // namespace
// NOLINTNEXTLINE(google-readability-namespace-comments)
} // namespace HWY_NAMESPACE
} // namespace jxl
HWY_AFTER_NAMESPACE();
#endif // LIB_JXL_DEC_TRANSFORMS_INL_H_
Messung V0.5 in Prozent C=86 H=86 G=85
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet am 2026-06-04)
¤
*© Formatika GbR, Deutschland