dct_for_test.h (2749B)
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 #ifndef LIB_JXL_DCT_FOR_TEST_H_ 7 #define LIB_JXL_DCT_FOR_TEST_H_ 8 9 // Unoptimized DCT only for use in tests. 10 11 #include <cmath> 12 #include <cstring> // memcpy 13 #include <vector> 14 15 #include "lib/jxl/base/common.h" 16 17 namespace jxl { 18 19 namespace test { 20 static inline double alpha(int u) { return u == 0 ? 0.7071067811865475 : 1.0; } 21 22 // N-DCT on M columns, divided by sqrt(N). Matches the definition in the spec. 23 template <size_t N, size_t M> 24 void DCT1D(const double block[N * M], double out[N * M]) { 25 std::vector<double> matrix(N * N); 26 const double scale = std::sqrt(2.0) / N; 27 for (size_t y = 0; y < N; y++) { 28 for (size_t u = 0; u < N; u++) { 29 matrix[N * u + y] = alpha(u) * cos((y + 0.5) * u * Pi(1.0 / N)) * scale; 30 } 31 } 32 for (size_t x = 0; x < M; x++) { 33 for (size_t u = 0; u < N; u++) { 34 out[M * u + x] = 0; 35 for (size_t y = 0; y < N; y++) { 36 out[M * u + x] += matrix[N * u + y] * block[M * y + x]; 37 } 38 } 39 } 40 } 41 42 // N-IDCT on M columns, multiplied by sqrt(N). Matches the definition in the 43 // spec. 44 template <size_t N, size_t M> 45 void IDCT1D(const double block[N * M], double out[N * M]) { 46 std::vector<double> matrix(N * N); 47 const double scale = std::sqrt(2.0); 48 for (size_t y = 0; y < N; y++) { 49 for (size_t u = 0; u < N; u++) { 50 // Transpose of DCT matrix. 51 matrix[N * y + u] = alpha(u) * cos((y + 0.5) * u * Pi(1.0 / N)) * scale; 52 } 53 } 54 for (size_t x = 0; x < M; x++) { 55 for (size_t u = 0; u < N; u++) { 56 out[M * u + x] = 0; 57 for (size_t y = 0; y < N; y++) { 58 out[M * u + x] += matrix[N * u + y] * block[M * y + x]; 59 } 60 } 61 } 62 } 63 64 template <size_t N, size_t M> 65 void TransposeBlock(const double in[N * M], double out[M * N]) { 66 for (size_t x = 0; x < N; x++) { 67 for (size_t y = 0; y < M; y++) { 68 out[y * N + x] = in[x * M + y]; 69 } 70 } 71 } 72 } // namespace test 73 74 // Untransposed DCT. 75 template <size_t N> 76 void DCTSlow(double block[N * N]) { 77 constexpr size_t kBlockSize = N * N; 78 std::vector<double> g(kBlockSize); 79 test::DCT1D<N, N>(block, g.data()); 80 test::TransposeBlock<N, N>(g.data(), block); 81 test::DCT1D<N, N>(block, g.data()); 82 test::TransposeBlock<N, N>(g.data(), block); 83 } 84 85 // Untransposed IDCT. 86 template <size_t N> 87 void IDCTSlow(double block[N * N]) { 88 constexpr size_t kBlockSize = N * N; 89 std::vector<double> g(kBlockSize); 90 test::IDCT1D<N, N>(block, g.data()); 91 test::TransposeBlock<N, N>(g.data(), block); 92 test::IDCT1D<N, N>(block, g.data()); 93 test::TransposeBlock<N, N>(g.data(), block); 94 } 95 96 } // namespace jxl 97 98 #endif // LIB_JXL_DCT_FOR_TEST_H_