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