tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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_