/src/x265/source/common/lowpassdct.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /***************************************************************************** |
2 | | * Copyright (C) 2017 |
3 | | * |
4 | | * Authors: Humberto Ribeiro Filho <mont3z.claro5@gmail.com> |
5 | | * |
6 | | * This program is free software; you can redistribute it and/or modify |
7 | | * it under the terms of the GNU General Public License as published by |
8 | | * the Free Software Foundation; either version 2 of the License, or |
9 | | * (at your option) any later version. |
10 | | * |
11 | | * This program is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | * GNU General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU General Public License |
17 | | * along with this program; if not, write to the Free Software |
18 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. |
19 | | * |
20 | | * This program is also available under a commercial proprietary license. |
21 | | * For more information, contact us at license @ x265.com. |
22 | | *****************************************************************************/ |
23 | | |
24 | | #include "common.h" |
25 | | #include "primitives.h" |
26 | | |
27 | | using namespace X265_NS; |
28 | | |
29 | | /* standard dct transformations */ |
30 | | static dct_t* s_dct4x4; |
31 | | static dct_t* s_dct8x8; |
32 | | static dct_t* s_dct16x16; |
33 | | |
34 | | static void lowPassDct8_c(const int16_t* src, int16_t* dst, intptr_t srcStride) |
35 | 0 | { |
36 | 0 | ALIGN_VAR_32(int16_t, coef[4 * 4]); |
37 | 0 | ALIGN_VAR_32(int16_t, avgBlock[4 * 4]); |
38 | 0 | int16_t totalSum = 0; |
39 | 0 | int16_t sum = 0; |
40 | | |
41 | 0 | for (int i = 0; i < 4; i++) |
42 | 0 | for (int j =0; j < 4; j++) |
43 | 0 | { |
44 | | // Calculate average of 2x2 cells |
45 | 0 | sum = src[2*i*srcStride + 2*j] + src[2*i*srcStride + 2*j + 1] |
46 | 0 | + src[(2*i+1)*srcStride + 2*j] + src[(2*i+1)*srcStride + 2*j + 1]; |
47 | 0 | avgBlock[i*4 + j] = sum >> 2; |
48 | |
|
49 | 0 | totalSum += sum; // use to calculate total block average |
50 | 0 | } |
51 | | |
52 | | //dct4 |
53 | 0 | (*s_dct4x4)(avgBlock, coef, 4); |
54 | 0 | memset(dst, 0, 64 * sizeof(int16_t)); |
55 | 0 | for (int i = 0; i < 4; i++) |
56 | 0 | { |
57 | 0 | memcpy(&dst[i * 8], &coef[i * 4], 4 * sizeof(int16_t)); |
58 | 0 | } |
59 | | |
60 | | // replace first coef with total block average |
61 | 0 | #if X265_DEPTH == 8 |
62 | 0 | dst[0] = totalSum << 1; |
63 | | #else |
64 | | dst[0] = totalSum >> (X265_DEPTH - 9); |
65 | | #endif |
66 | 0 | } |
67 | | |
68 | | static void lowPassDct16_c(const int16_t* src, int16_t* dst, intptr_t srcStride) |
69 | 0 | { |
70 | 0 | ALIGN_VAR_32(int16_t, coef[8 * 8]); |
71 | 0 | ALIGN_VAR_32(int16_t, avgBlock[8 * 8]); |
72 | 0 | int32_t totalSum = 0; |
73 | 0 | int16_t sum = 0; |
74 | 0 | for (int i = 0; i < 8; i++) |
75 | 0 | for (int j =0; j < 8; j++) |
76 | 0 | { |
77 | 0 | sum = src[2*i*srcStride + 2*j] + src[2*i*srcStride + 2*j + 1] |
78 | 0 | + src[(2*i+1)*srcStride + 2*j] + src[(2*i+1)*srcStride + 2*j + 1]; |
79 | 0 | avgBlock[i*8 + j] = sum >> 2; |
80 | |
|
81 | 0 | totalSum += sum; |
82 | 0 | } |
83 | |
|
84 | 0 | (*s_dct8x8)(avgBlock, coef, 8); |
85 | 0 | memset(dst, 0, 256 * sizeof(int16_t)); |
86 | 0 | for (int i = 0; i < 8; i++) |
87 | 0 | { |
88 | 0 | memcpy(&dst[i * 16], &coef[i * 8], 8 * sizeof(int16_t)); |
89 | 0 | } |
90 | 0 | dst[0] = static_cast<int16_t>(totalSum >> (1 + (X265_DEPTH - 8))); |
91 | 0 | } |
92 | | |
93 | | static void lowPassDct32_c(const int16_t* src, int16_t* dst, intptr_t srcStride) |
94 | 0 | { |
95 | 0 | ALIGN_VAR_32(int16_t, coef[16 * 16]); |
96 | 0 | ALIGN_VAR_32(int16_t, avgBlock[16 * 16]); |
97 | 0 | int32_t totalSum = 0; |
98 | 0 | int16_t sum = 0; |
99 | 0 | for (int i = 0; i < 16; i++) |
100 | 0 | for (int j =0; j < 16; j++) |
101 | 0 | { |
102 | 0 | sum = src[2*i*srcStride + 2*j] + src[2*i*srcStride + 2*j + 1] |
103 | 0 | + src[(2*i+1)*srcStride + 2*j] + src[(2*i+1)*srcStride + 2*j + 1]; |
104 | 0 | avgBlock[i*16 + j] = sum >> 2; |
105 | |
|
106 | 0 | totalSum += sum; |
107 | 0 | } |
108 | |
|
109 | 0 | (*s_dct16x16)(avgBlock, coef, 16); |
110 | 0 | memset(dst, 0, 1024 * sizeof(int16_t)); |
111 | 0 | for (int i = 0; i < 16; i++) |
112 | 0 | { |
113 | 0 | memcpy(&dst[i * 32], &coef[i * 16], 16 * sizeof(int16_t)); |
114 | 0 | } |
115 | 0 | dst[0] = static_cast<int16_t>(totalSum >> (3 + (X265_DEPTH - 8))); |
116 | 0 | } |
117 | | |
118 | | namespace X265_NS { |
119 | | // x265 private namespace |
120 | | |
121 | | void setupLowPassPrimitives_c(EncoderPrimitives& p) |
122 | 0 | { |
123 | 0 | s_dct4x4 = &(p.cu[BLOCK_4x4].standard_dct); |
124 | 0 | s_dct8x8 = &(p.cu[BLOCK_8x8].standard_dct); |
125 | 0 | s_dct16x16 = &(p.cu[BLOCK_16x16].standard_dct); |
126 | |
|
127 | 0 | p.cu[BLOCK_8x8].lowpass_dct = lowPassDct8_c; |
128 | 0 | p.cu[BLOCK_16x16].lowpass_dct = lowPassDct16_c; |
129 | 0 | p.cu[BLOCK_32x32].lowpass_dct = lowPassDct32_c; |
130 | 0 | } |
131 | | } |