enc_transforms-inl.h (26716B)
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 #if defined(LIB_JXL_ENC_TRANSFORMS_INL_H_) == defined(HWY_TARGET_TOGGLE) 7 #ifdef LIB_JXL_ENC_TRANSFORMS_INL_H_ 8 #undef LIB_JXL_ENC_TRANSFORMS_INL_H_ 9 #else 10 #define LIB_JXL_ENC_TRANSFORMS_INL_H_ 11 #endif 12 13 #include <cstddef> 14 #include <cstdint> 15 #include <hwy/highway.h> 16 17 #include "lib/jxl/ac_strategy.h" 18 #include "lib/jxl/dct-inl.h" 19 #include "lib/jxl/dct_scales.h" 20 21 HWY_BEFORE_NAMESPACE(); 22 namespace jxl { 23 24 enum class AcStrategyType : uint32_t; 25 26 namespace HWY_NAMESPACE { 27 namespace { 28 29 // Inverse of ReinterpretingDCT. 30 template <size_t DCT_ROWS, size_t DCT_COLS, size_t LF_ROWS, size_t LF_COLS, 31 size_t ROWS, size_t COLS> 32 HWY_INLINE void ReinterpretingIDCT(const float* input, 33 const size_t input_stride, float* output, 34 const size_t output_stride) { 35 HWY_ALIGN float block[ROWS * COLS] = {}; 36 if (ROWS < COLS) { 37 for (size_t y = 0; y < LF_ROWS; y++) { 38 for (size_t x = 0; x < LF_COLS; x++) { 39 block[y * COLS + x] = input[y * input_stride + x] * 40 DCTTotalResampleScale<DCT_ROWS, ROWS>(y) * 41 DCTTotalResampleScale<DCT_COLS, COLS>(x); 42 } 43 } 44 } else { 45 for (size_t y = 0; y < LF_COLS; y++) { 46 for (size_t x = 0; x < LF_ROWS; x++) { 47 block[y * ROWS + x] = input[y * input_stride + x] * 48 DCTTotalResampleScale<DCT_COLS, COLS>(y) * 49 DCTTotalResampleScale<DCT_ROWS, ROWS>(x); 50 } 51 } 52 } 53 54 // ROWS, COLS <= 8, so we can put scratch space on the stack. 55 HWY_ALIGN float scratch_space[ROWS * COLS * 3]; 56 ComputeScaledIDCT<ROWS, COLS>()(block, DCTTo(output, output_stride), 57 scratch_space); 58 } 59 60 template <size_t S> 61 void DCT2TopBlock(const float* block, size_t stride, float* out) { 62 static_assert(kBlockDim % S == 0, "S should be a divisor of kBlockDim"); 63 static_assert(S % 2 == 0, "S should be even"); 64 float temp[kDCTBlockSize]; 65 constexpr size_t num_2x2 = S / 2; 66 for (size_t y = 0; y < num_2x2; y++) { 67 for (size_t x = 0; x < num_2x2; x++) { 68 float c00 = block[y * 2 * stride + x * 2]; 69 float c01 = block[y * 2 * stride + x * 2 + 1]; 70 float c10 = block[(y * 2 + 1) * stride + x * 2]; 71 float c11 = block[(y * 2 + 1) * stride + x * 2 + 1]; 72 float r00 = c00 + c01 + c10 + c11; 73 float r01 = c00 + c01 - c10 - c11; 74 float r10 = c00 - c01 + c10 - c11; 75 float r11 = c00 - c01 - c10 + c11; 76 r00 *= 0.25f; 77 r01 *= 0.25f; 78 r10 *= 0.25f; 79 r11 *= 0.25f; 80 temp[y * kBlockDim + x] = r00; 81 temp[y * kBlockDim + num_2x2 + x] = r01; 82 temp[(y + num_2x2) * kBlockDim + x] = r10; 83 temp[(y + num_2x2) * kBlockDim + num_2x2 + x] = r11; 84 } 85 } 86 for (size_t y = 0; y < S; y++) { 87 for (size_t x = 0; x < S; x++) { 88 out[y * kBlockDim + x] = temp[y * kBlockDim + x]; 89 } 90 } 91 } 92 93 void AFVDCT4x4(const float* JXL_RESTRICT pixels, float* JXL_RESTRICT coeffs) { 94 HWY_ALIGN static constexpr float k4x4AFVBasisTranspose[16][16] = { 95 { 96 0.2500000000000000, 97 0.8769029297991420f, 98 0.0000000000000000, 99 0.0000000000000000, 100 0.0000000000000000, 101 -0.4105377591765233f, 102 0.0000000000000000, 103 0.0000000000000000, 104 0.0000000000000000, 105 0.0000000000000000, 106 0.0000000000000000, 107 0.0000000000000000, 108 0.0000000000000000, 109 0.0000000000000000, 110 0.0000000000000000, 111 0.0000000000000000, 112 }, 113 { 114 0.2500000000000000, 115 0.2206518106944235f, 116 0.0000000000000000, 117 0.0000000000000000, 118 -0.7071067811865474f, 119 0.6235485373547691f, 120 0.0000000000000000, 121 0.0000000000000000, 122 0.0000000000000000, 123 0.0000000000000000, 124 0.0000000000000000, 125 0.0000000000000000, 126 0.0000000000000000, 127 0.0000000000000000, 128 0.0000000000000000, 129 0.0000000000000000, 130 }, 131 { 132 0.2500000000000000, 133 -0.1014005039375376f, 134 0.4067007583026075f, 135 -0.2125574805828875f, 136 0.0000000000000000, 137 -0.0643507165794627f, 138 -0.4517556589999482f, 139 -0.3046847507248690f, 140 0.3017929516615495f, 141 0.4082482904638627f, 142 0.1747866975480809f, 143 -0.2110560104933578f, 144 -0.1426608480880726f, 145 -0.1381354035075859f, 146 -0.1743760259965107f, 147 0.1135498731499434f, 148 }, 149 { 150 0.2500000000000000, 151 -0.1014005039375375f, 152 0.4444481661973445f, 153 0.3085497062849767f, 154 0.0000000000000000f, 155 -0.0643507165794627f, 156 0.1585450355184006f, 157 0.5112616136591823f, 158 0.2579236279634118f, 159 0.0000000000000000, 160 0.0812611176717539f, 161 0.1856718091610980f, 162 -0.3416446842253372f, 163 0.3302282550303788f, 164 0.0702790691196284f, 165 -0.0741750459581035f, 166 }, 167 { 168 0.2500000000000000, 169 0.2206518106944236f, 170 0.0000000000000000, 171 0.0000000000000000, 172 0.7071067811865476f, 173 0.6235485373547694f, 174 0.0000000000000000, 175 0.0000000000000000, 176 0.0000000000000000, 177 0.0000000000000000, 178 0.0000000000000000, 179 0.0000000000000000, 180 0.0000000000000000, 181 0.0000000000000000, 182 0.0000000000000000, 183 0.0000000000000000, 184 }, 185 { 186 0.2500000000000000, 187 -0.1014005039375378f, 188 0.0000000000000000, 189 0.4706702258572536f, 190 0.0000000000000000, 191 -0.0643507165794628f, 192 -0.0403851516082220f, 193 0.0000000000000000, 194 0.1627234014286620f, 195 0.0000000000000000, 196 0.0000000000000000, 197 0.0000000000000000, 198 0.7367497537172237f, 199 0.0875511500058708f, 200 -0.2921026642334881f, 201 0.1940289303259434f, 202 }, 203 { 204 0.2500000000000000, 205 -0.1014005039375377f, 206 0.1957439937204294f, 207 -0.1621205195722993f, 208 0.0000000000000000, 209 -0.0643507165794628f, 210 0.0074182263792424f, 211 -0.2904801297289980f, 212 0.0952002265347504f, 213 0.0000000000000000, 214 -0.3675398009862027f, 215 0.4921585901373873f, 216 0.2462710772207515f, 217 -0.0794670660590957f, 218 0.3623817333531167f, 219 -0.4351904965232280f, 220 }, 221 { 222 0.2500000000000000, 223 -0.1014005039375376f, 224 0.2929100136981264f, 225 0.0000000000000000, 226 0.0000000000000000, 227 -0.0643507165794627f, 228 0.3935103426921017f, 229 -0.0657870154914280f, 230 0.0000000000000000, 231 -0.4082482904638628f, 232 -0.3078822139579090f, 233 -0.3852501370925192f, 234 -0.0857401903551931f, 235 -0.4613374887461511f, 236 0.0000000000000000, 237 0.2191868483885747f, 238 }, 239 { 240 0.2500000000000000, 241 -0.1014005039375376f, 242 -0.4067007583026072f, 243 -0.2125574805828705f, 244 0.0000000000000000, 245 -0.0643507165794627f, 246 -0.4517556589999464f, 247 0.3046847507248840f, 248 0.3017929516615503f, 249 -0.4082482904638635f, 250 -0.1747866975480813f, 251 0.2110560104933581f, 252 -0.1426608480880734f, 253 -0.1381354035075829f, 254 -0.1743760259965108f, 255 0.1135498731499426f, 256 }, 257 { 258 0.2500000000000000, 259 -0.1014005039375377f, 260 -0.1957439937204287f, 261 -0.1621205195722833f, 262 0.0000000000000000, 263 -0.0643507165794628f, 264 0.0074182263792444f, 265 0.2904801297290076f, 266 0.0952002265347505f, 267 0.0000000000000000, 268 0.3675398009862011f, 269 -0.4921585901373891f, 270 0.2462710772207514f, 271 -0.0794670660591026f, 272 0.3623817333531165f, 273 -0.4351904965232251f, 274 }, 275 { 276 0.2500000000000000, 277 -0.1014005039375375f, 278 0.0000000000000000, 279 -0.4706702258572528f, 280 0.0000000000000000, 281 -0.0643507165794627f, 282 0.1107416575309343f, 283 0.0000000000000000, 284 -0.1627234014286617f, 285 0.0000000000000000, 286 0.0000000000000000, 287 0.0000000000000000, 288 0.1488339922711357f, 289 0.4972464710953509f, 290 0.2921026642334879f, 291 0.5550443808910661f, 292 }, 293 { 294 0.2500000000000000, 295 -0.1014005039375377f, 296 0.1137907446044809f, 297 -0.1464291867126764f, 298 0.0000000000000000, 299 -0.0643507165794628f, 300 0.0829816309488205f, 301 -0.2388977352334460f, 302 -0.3531238544981630f, 303 -0.4082482904638630f, 304 0.4826689115059883f, 305 0.1741941265991622f, 306 -0.0476868035022925f, 307 0.1253805944856366f, 308 -0.4326608024727445f, 309 -0.2546827712406646f, 310 }, 311 { 312 0.2500000000000000, 313 -0.1014005039375377f, 314 -0.4444481661973438f, 315 0.3085497062849487f, 316 0.0000000000000000, 317 -0.0643507165794628f, 318 0.1585450355183970f, 319 -0.5112616136592012f, 320 0.2579236279634129f, 321 0.0000000000000000, 322 -0.0812611176717504f, 323 -0.1856718091610990f, 324 -0.3416446842253373f, 325 0.3302282550303805f, 326 0.0702790691196282f, 327 -0.0741750459581023f, 328 }, 329 { 330 0.2500000000000000, 331 -0.1014005039375376f, 332 -0.2929100136981264f, 333 0.0000000000000000, 334 0.0000000000000000, 335 -0.0643507165794627f, 336 0.3935103426921022f, 337 0.0657870154914254f, 338 0.0000000000000000, 339 0.4082482904638634f, 340 0.3078822139579031f, 341 0.3852501370925211f, 342 -0.0857401903551927f, 343 -0.4613374887461554f, 344 0.0000000000000000, 345 0.2191868483885728f, 346 }, 347 { 348 0.2500000000000000, 349 -0.1014005039375376f, 350 -0.1137907446044814f, 351 -0.1464291867126654f, 352 0.0000000000000000, 353 -0.0643507165794627f, 354 0.0829816309488214f, 355 0.2388977352334547f, 356 -0.3531238544981624f, 357 0.4082482904638630f, 358 -0.4826689115059858f, 359 -0.1741941265991621f, 360 -0.0476868035022928f, 361 0.1253805944856431f, 362 -0.4326608024727457f, 363 -0.2546827712406641f, 364 }, 365 { 366 0.2500000000000000, 367 -0.1014005039375374f, 368 0.0000000000000000, 369 0.4251149611657548f, 370 0.0000000000000000, 371 -0.0643507165794626f, 372 -0.4517556589999480f, 373 0.0000000000000000, 374 -0.6035859033230976f, 375 0.0000000000000000, 376 0.0000000000000000, 377 0.0000000000000000, 378 -0.1426608480880724f, 379 -0.1381354035075845f, 380 0.3487520519930227f, 381 0.1135498731499429f, 382 }, 383 }; 384 385 const HWY_CAPPED(float, 16) d; 386 for (size_t i = 0; i < 16; i += Lanes(d)) { 387 auto scalar = Zero(d); 388 for (size_t j = 0; j < 16; j++) { 389 auto px = Set(d, pixels[j]); 390 auto basis = Load(d, k4x4AFVBasisTranspose[j] + i); 391 scalar = MulAdd(px, basis, scalar); 392 } 393 Store(scalar, d, coeffs + i); 394 } 395 } 396 397 // Coefficient layout: 398 // - (even, even) positions hold AFV coefficients 399 // - (odd, even) positions hold DCT4x4 coefficients 400 // - (any, odd) positions hold DCT4x8 coefficients 401 template <size_t afv_kind> 402 void AFVTransformFromPixels(const float* JXL_RESTRICT pixels, 403 size_t pixels_stride, 404 float* JXL_RESTRICT coefficients) { 405 HWY_ALIGN float scratch_space[4 * 8 * 5]; 406 size_t afv_x = afv_kind & 1; 407 size_t afv_y = afv_kind / 2; 408 HWY_ALIGN float block[4 * 8] = {}; 409 for (size_t iy = 0; iy < 4; iy++) { 410 for (size_t ix = 0; ix < 4; ix++) { 411 block[(afv_y == 1 ? 3 - iy : iy) * 4 + (afv_x == 1 ? 3 - ix : ix)] = 412 pixels[(iy + 4 * afv_y) * pixels_stride + ix + 4 * afv_x]; 413 } 414 } 415 // AFV coefficients in (even, even) positions. 416 HWY_ALIGN float coeff[4 * 4]; 417 AFVDCT4x4(block, coeff); 418 for (size_t iy = 0; iy < 4; iy++) { 419 for (size_t ix = 0; ix < 4; ix++) { 420 coefficients[iy * 2 * 8 + ix * 2] = coeff[iy * 4 + ix]; 421 } 422 } 423 // 4x4 DCT of the block with same y and different x. 424 ComputeScaledDCT<4, 4>()( 425 DCTFrom(pixels + afv_y * 4 * pixels_stride + (afv_x == 1 ? 0 : 4), 426 pixels_stride), 427 block, scratch_space); 428 // ... in (odd, even) positions. 429 for (size_t iy = 0; iy < 4; iy++) { 430 for (size_t ix = 0; ix < 8; ix++) { 431 coefficients[iy * 2 * 8 + ix * 2 + 1] = block[iy * 4 + ix]; 432 } 433 } 434 // 4x8 DCT of the other half of the block. 435 ComputeScaledDCT<4, 8>()( 436 DCTFrom(pixels + (afv_y == 1 ? 0 : 4) * pixels_stride, pixels_stride), 437 block, scratch_space); 438 for (size_t iy = 0; iy < 4; iy++) { 439 for (size_t ix = 0; ix < 8; ix++) { 440 coefficients[(1 + iy * 2) * 8 + ix] = block[iy * 8 + ix]; 441 } 442 } 443 float block00 = coefficients[0] * 0.25f; 444 float block01 = coefficients[1]; 445 float block10 = coefficients[8]; 446 coefficients[0] = (block00 + block01 + 2 * block10) * 0.25f; 447 coefficients[1] = (block00 - block01) * 0.5f; 448 coefficients[8] = (block00 + block01 - 2 * block10) * 0.25f; 449 } 450 451 HWY_MAYBE_UNUSED void TransformFromPixels(const AcStrategyType strategy, 452 const float* JXL_RESTRICT pixels, 453 size_t pixels_stride, 454 float* JXL_RESTRICT coefficients, 455 float* JXL_RESTRICT scratch_space) { 456 using Type = AcStrategyType; 457 switch (strategy) { 458 case Type::IDENTITY: { 459 for (size_t y = 0; y < 2; y++) { 460 for (size_t x = 0; x < 2; x++) { 461 float block_dc = 0; 462 for (size_t iy = 0; iy < 4; iy++) { 463 for (size_t ix = 0; ix < 4; ix++) { 464 block_dc += pixels[(y * 4 + iy) * pixels_stride + x * 4 + ix]; 465 } 466 } 467 block_dc *= 1.0f / 16; 468 for (size_t iy = 0; iy < 4; iy++) { 469 for (size_t ix = 0; ix < 4; ix++) { 470 if (ix == 1 && iy == 1) continue; 471 coefficients[(y + iy * 2) * 8 + x + ix * 2] = 472 pixels[(y * 4 + iy) * pixels_stride + x * 4 + ix] - 473 pixels[(y * 4 + 1) * pixels_stride + x * 4 + 1]; 474 } 475 } 476 coefficients[(y + 2) * 8 + x + 2] = coefficients[y * 8 + x]; 477 coefficients[y * 8 + x] = block_dc; 478 } 479 } 480 float block00 = coefficients[0]; 481 float block01 = coefficients[1]; 482 float block10 = coefficients[8]; 483 float block11 = coefficients[9]; 484 coefficients[0] = (block00 + block01 + block10 + block11) * 0.25f; 485 coefficients[1] = (block00 + block01 - block10 - block11) * 0.25f; 486 coefficients[8] = (block00 - block01 + block10 - block11) * 0.25f; 487 coefficients[9] = (block00 - block01 - block10 + block11) * 0.25f; 488 break; 489 } 490 case Type::DCT8X4: { 491 for (size_t x = 0; x < 2; x++) { 492 HWY_ALIGN float block[4 * 8]; 493 ComputeScaledDCT<8, 4>()(DCTFrom(pixels + x * 4, pixels_stride), block, 494 scratch_space); 495 for (size_t iy = 0; iy < 4; iy++) { 496 for (size_t ix = 0; ix < 8; ix++) { 497 // Store transposed. 498 coefficients[(x + iy * 2) * 8 + ix] = block[iy * 8 + ix]; 499 } 500 } 501 } 502 float block0 = coefficients[0]; 503 float block1 = coefficients[8]; 504 coefficients[0] = (block0 + block1) * 0.5f; 505 coefficients[8] = (block0 - block1) * 0.5f; 506 break; 507 } 508 case Type::DCT4X8: { 509 for (size_t y = 0; y < 2; y++) { 510 HWY_ALIGN float block[4 * 8]; 511 ComputeScaledDCT<4, 8>()( 512 DCTFrom(pixels + y * 4 * pixels_stride, pixels_stride), block, 513 scratch_space); 514 for (size_t iy = 0; iy < 4; iy++) { 515 for (size_t ix = 0; ix < 8; ix++) { 516 coefficients[(y + iy * 2) * 8 + ix] = block[iy * 8 + ix]; 517 } 518 } 519 } 520 float block0 = coefficients[0]; 521 float block1 = coefficients[8]; 522 coefficients[0] = (block0 + block1) * 0.5f; 523 coefficients[8] = (block0 - block1) * 0.5f; 524 break; 525 } 526 case Type::DCT4X4: { 527 for (size_t y = 0; y < 2; y++) { 528 for (size_t x = 0; x < 2; x++) { 529 HWY_ALIGN float block[4 * 4]; 530 ComputeScaledDCT<4, 4>()( 531 DCTFrom(pixels + y * 4 * pixels_stride + x * 4, pixels_stride), 532 block, scratch_space); 533 for (size_t iy = 0; iy < 4; iy++) { 534 for (size_t ix = 0; ix < 4; ix++) { 535 coefficients[(y + iy * 2) * 8 + x + ix * 2] = block[iy * 4 + ix]; 536 } 537 } 538 } 539 } 540 float block00 = coefficients[0]; 541 float block01 = coefficients[1]; 542 float block10 = coefficients[8]; 543 float block11 = coefficients[9]; 544 coefficients[0] = (block00 + block01 + block10 + block11) * 0.25f; 545 coefficients[1] = (block00 + block01 - block10 - block11) * 0.25f; 546 coefficients[8] = (block00 - block01 + block10 - block11) * 0.25f; 547 coefficients[9] = (block00 - block01 - block10 + block11) * 0.25f; 548 break; 549 } 550 case Type::DCT2X2: { 551 DCT2TopBlock<8>(pixels, pixels_stride, coefficients); 552 DCT2TopBlock<4>(coefficients, kBlockDim, coefficients); 553 DCT2TopBlock<2>(coefficients, kBlockDim, coefficients); 554 break; 555 } 556 case Type::DCT16X16: { 557 ComputeScaledDCT<16, 16>()(DCTFrom(pixels, pixels_stride), coefficients, 558 scratch_space); 559 break; 560 } 561 case Type::DCT16X8: { 562 ComputeScaledDCT<16, 8>()(DCTFrom(pixels, pixels_stride), coefficients, 563 scratch_space); 564 break; 565 } 566 case Type::DCT8X16: { 567 ComputeScaledDCT<8, 16>()(DCTFrom(pixels, pixels_stride), coefficients, 568 scratch_space); 569 break; 570 } 571 case Type::DCT32X8: { 572 ComputeScaledDCT<32, 8>()(DCTFrom(pixels, pixels_stride), coefficients, 573 scratch_space); 574 break; 575 } 576 case Type::DCT8X32: { 577 ComputeScaledDCT<8, 32>()(DCTFrom(pixels, pixels_stride), coefficients, 578 scratch_space); 579 break; 580 } 581 case Type::DCT32X16: { 582 ComputeScaledDCT<32, 16>()(DCTFrom(pixels, pixels_stride), coefficients, 583 scratch_space); 584 break; 585 } 586 case Type::DCT16X32: { 587 ComputeScaledDCT<16, 32>()(DCTFrom(pixels, pixels_stride), coefficients, 588 scratch_space); 589 break; 590 } 591 case Type::DCT32X32: { 592 ComputeScaledDCT<32, 32>()(DCTFrom(pixels, pixels_stride), coefficients, 593 scratch_space); 594 break; 595 } 596 case Type::DCT: { 597 ComputeScaledDCT<8, 8>()(DCTFrom(pixels, pixels_stride), coefficients, 598 scratch_space); 599 break; 600 } 601 case Type::AFV0: { 602 AFVTransformFromPixels<0>(pixels, pixels_stride, coefficients); 603 break; 604 } 605 case Type::AFV1: { 606 AFVTransformFromPixels<1>(pixels, pixels_stride, coefficients); 607 break; 608 } 609 case Type::AFV2: { 610 AFVTransformFromPixels<2>(pixels, pixels_stride, coefficients); 611 break; 612 } 613 case Type::AFV3: { 614 AFVTransformFromPixels<3>(pixels, pixels_stride, coefficients); 615 break; 616 } 617 case Type::DCT64X64: { 618 ComputeScaledDCT<64, 64>()(DCTFrom(pixels, pixels_stride), coefficients, 619 scratch_space); 620 break; 621 } 622 case Type::DCT64X32: { 623 ComputeScaledDCT<64, 32>()(DCTFrom(pixels, pixels_stride), coefficients, 624 scratch_space); 625 break; 626 } 627 case Type::DCT32X64: { 628 ComputeScaledDCT<32, 64>()(DCTFrom(pixels, pixels_stride), coefficients, 629 scratch_space); 630 break; 631 } 632 case Type::DCT128X128: { 633 ComputeScaledDCT<128, 128>()(DCTFrom(pixels, pixels_stride), coefficients, 634 scratch_space); 635 break; 636 } 637 case Type::DCT128X64: { 638 ComputeScaledDCT<128, 64>()(DCTFrom(pixels, pixels_stride), coefficients, 639 scratch_space); 640 break; 641 } 642 case Type::DCT64X128: { 643 ComputeScaledDCT<64, 128>()(DCTFrom(pixels, pixels_stride), coefficients, 644 scratch_space); 645 break; 646 } 647 case Type::DCT256X256: { 648 ComputeScaledDCT<256, 256>()(DCTFrom(pixels, pixels_stride), coefficients, 649 scratch_space); 650 break; 651 } 652 case Type::DCT256X128: { 653 ComputeScaledDCT<256, 128>()(DCTFrom(pixels, pixels_stride), coefficients, 654 scratch_space); 655 break; 656 } 657 case Type::DCT128X256: { 658 ComputeScaledDCT<128, 256>()(DCTFrom(pixels, pixels_stride), coefficients, 659 scratch_space); 660 break; 661 } 662 } 663 } 664 665 HWY_MAYBE_UNUSED void DCFromLowestFrequencies(const AcStrategyType strategy, 666 const float* block, float* dc, 667 size_t dc_stride) { 668 using Type = AcStrategyType; 669 switch (strategy) { 670 case Type::DCT16X8: { 671 ReinterpretingIDCT</*DCT_ROWS=*/2 * kBlockDim, /*DCT_COLS=*/kBlockDim, 672 /*LF_ROWS=*/2, /*LF_COLS=*/1, /*ROWS=*/2, /*COLS=*/1>( 673 block, 2 * kBlockDim, dc, dc_stride); 674 break; 675 } 676 case Type::DCT8X16: { 677 ReinterpretingIDCT</*DCT_ROWS=*/kBlockDim, /*DCT_COLS=*/2 * kBlockDim, 678 /*LF_ROWS=*/1, /*LF_COLS=*/2, /*ROWS=*/1, /*COLS=*/2>( 679 block, 2 * kBlockDim, dc, dc_stride); 680 break; 681 } 682 case Type::DCT16X16: { 683 ReinterpretingIDCT</*DCT_ROWS=*/2 * kBlockDim, /*DCT_COLS=*/2 * kBlockDim, 684 /*LF_ROWS=*/2, /*LF_COLS=*/2, /*ROWS=*/2, /*COLS=*/2>( 685 block, 2 * kBlockDim, dc, dc_stride); 686 break; 687 } 688 case Type::DCT32X8: { 689 ReinterpretingIDCT</*DCT_ROWS=*/4 * kBlockDim, /*DCT_COLS=*/kBlockDim, 690 /*LF_ROWS=*/4, /*LF_COLS=*/1, /*ROWS=*/4, /*COLS=*/1>( 691 block, 4 * kBlockDim, dc, dc_stride); 692 break; 693 } 694 case Type::DCT8X32: { 695 ReinterpretingIDCT</*DCT_ROWS=*/kBlockDim, /*DCT_COLS=*/4 * kBlockDim, 696 /*LF_ROWS=*/1, /*LF_COLS=*/4, /*ROWS=*/1, /*COLS=*/4>( 697 block, 4 * kBlockDim, dc, dc_stride); 698 break; 699 } 700 case Type::DCT32X16: { 701 ReinterpretingIDCT</*DCT_ROWS=*/4 * kBlockDim, /*DCT_COLS=*/2 * kBlockDim, 702 /*LF_ROWS=*/4, /*LF_COLS=*/2, /*ROWS=*/4, /*COLS=*/2>( 703 block, 4 * kBlockDim, dc, dc_stride); 704 break; 705 } 706 case Type::DCT16X32: { 707 ReinterpretingIDCT</*DCT_ROWS=*/2 * kBlockDim, /*DCT_COLS=*/4 * kBlockDim, 708 /*LF_ROWS=*/2, /*LF_COLS=*/4, /*ROWS=*/2, /*COLS=*/4>( 709 block, 4 * kBlockDim, dc, dc_stride); 710 break; 711 } 712 case Type::DCT32X32: { 713 ReinterpretingIDCT</*DCT_ROWS=*/4 * kBlockDim, /*DCT_COLS=*/4 * kBlockDim, 714 /*LF_ROWS=*/4, /*LF_COLS=*/4, /*ROWS=*/4, /*COLS=*/4>( 715 block, 4 * kBlockDim, dc, dc_stride); 716 break; 717 } 718 case Type::DCT64X32: { 719 ReinterpretingIDCT</*DCT_ROWS=*/8 * kBlockDim, /*DCT_COLS=*/4 * kBlockDim, 720 /*LF_ROWS=*/8, /*LF_COLS=*/4, /*ROWS=*/8, /*COLS=*/4>( 721 block, 8 * kBlockDim, dc, dc_stride); 722 break; 723 } 724 case Type::DCT32X64: { 725 ReinterpretingIDCT</*DCT_ROWS=*/4 * kBlockDim, /*DCT_COLS=*/8 * kBlockDim, 726 /*LF_ROWS=*/4, /*LF_COLS=*/8, /*ROWS=*/4, /*COLS=*/8>( 727 block, 8 * kBlockDim, dc, dc_stride); 728 break; 729 } 730 case Type::DCT64X64: { 731 ReinterpretingIDCT</*DCT_ROWS=*/8 * kBlockDim, /*DCT_COLS=*/8 * kBlockDim, 732 /*LF_ROWS=*/8, /*LF_COLS=*/8, /*ROWS=*/8, /*COLS=*/8>( 733 block, 8 * kBlockDim, dc, dc_stride); 734 break; 735 } 736 case Type::DCT128X64: { 737 ReinterpretingIDCT< 738 /*DCT_ROWS=*/16 * kBlockDim, /*DCT_COLS=*/8 * kBlockDim, 739 /*LF_ROWS=*/16, /*LF_COLS=*/8, /*ROWS=*/16, /*COLS=*/8>( 740 block, 16 * kBlockDim, dc, dc_stride); 741 break; 742 } 743 case Type::DCT64X128: { 744 ReinterpretingIDCT< 745 /*DCT_ROWS=*/8 * kBlockDim, /*DCT_COLS=*/16 * kBlockDim, 746 /*LF_ROWS=*/8, /*LF_COLS=*/16, /*ROWS=*/8, /*COLS=*/16>( 747 block, 16 * kBlockDim, dc, dc_stride); 748 break; 749 } 750 case Type::DCT128X128: { 751 ReinterpretingIDCT< 752 /*DCT_ROWS=*/16 * kBlockDim, /*DCT_COLS=*/16 * kBlockDim, 753 /*LF_ROWS=*/16, /*LF_COLS=*/16, /*ROWS=*/16, /*COLS=*/16>( 754 block, 16 * kBlockDim, dc, dc_stride); 755 break; 756 } 757 case Type::DCT256X128: { 758 ReinterpretingIDCT< 759 /*DCT_ROWS=*/32 * kBlockDim, /*DCT_COLS=*/16 * kBlockDim, 760 /*LF_ROWS=*/32, /*LF_COLS=*/16, /*ROWS=*/32, /*COLS=*/16>( 761 block, 32 * kBlockDim, dc, dc_stride); 762 break; 763 } 764 case Type::DCT128X256: { 765 ReinterpretingIDCT< 766 /*DCT_ROWS=*/16 * kBlockDim, /*DCT_COLS=*/32 * kBlockDim, 767 /*LF_ROWS=*/16, /*LF_COLS=*/32, /*ROWS=*/16, /*COLS=*/32>( 768 block, 32 * kBlockDim, dc, dc_stride); 769 break; 770 } 771 case Type::DCT256X256: { 772 ReinterpretingIDCT< 773 /*DCT_ROWS=*/32 * kBlockDim, /*DCT_COLS=*/32 * kBlockDim, 774 /*LF_ROWS=*/32, /*LF_COLS=*/32, /*ROWS=*/32, /*COLS=*/32>( 775 block, 32 * kBlockDim, dc, dc_stride); 776 break; 777 } 778 case Type::DCT: 779 case Type::DCT2X2: 780 case Type::DCT4X4: 781 case Type::DCT4X8: 782 case Type::DCT8X4: 783 case Type::AFV0: 784 case Type::AFV1: 785 case Type::AFV2: 786 case Type::AFV3: 787 case Type::IDENTITY: 788 dc[0] = block[0]; 789 break; 790 } 791 } 792 793 } // namespace 794 // NOLINTNEXTLINE(google-readability-namespace-comments) 795 } // namespace HWY_NAMESPACE 796 } // namespace jxl 797 HWY_AFTER_NAMESPACE(); 798 799 #endif // LIB_JXL_ENC_TRANSFORMS_INL_H_