/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 | dst[0] = totalSum << 1; |
62 | 0 | } |
63 | | |
64 | | static void lowPassDct16_c(const int16_t* src, int16_t* dst, intptr_t srcStride) |
65 | 0 | { |
66 | 0 | ALIGN_VAR_32(int16_t, coef[8 * 8]); |
67 | 0 | ALIGN_VAR_32(int16_t, avgBlock[8 * 8]); |
68 | 0 | int32_t totalSum = 0; |
69 | 0 | int16_t sum = 0; |
70 | 0 | for (int i = 0; i < 8; i++) |
71 | 0 | for (int j =0; j < 8; j++) |
72 | 0 | { |
73 | 0 | sum = src[2*i*srcStride + 2*j] + src[2*i*srcStride + 2*j + 1] |
74 | 0 | + src[(2*i+1)*srcStride + 2*j] + src[(2*i+1)*srcStride + 2*j + 1]; |
75 | 0 | avgBlock[i*8 + j] = sum >> 2; |
76 | |
|
77 | 0 | totalSum += sum; |
78 | 0 | } |
79 | |
|
80 | 0 | (*s_dct8x8)(avgBlock, coef, 8); |
81 | 0 | memset(dst, 0, 256 * sizeof(int16_t)); |
82 | 0 | for (int i = 0; i < 8; i++) |
83 | 0 | { |
84 | 0 | memcpy(&dst[i * 16], &coef[i * 8], 8 * sizeof(int16_t)); |
85 | 0 | } |
86 | 0 | dst[0] = static_cast<int16_t>(totalSum >> 1); |
87 | 0 | } |
88 | | |
89 | | static void lowPassDct32_c(const int16_t* src, int16_t* dst, intptr_t srcStride) |
90 | 0 | { |
91 | 0 | ALIGN_VAR_32(int16_t, coef[16 * 16]); |
92 | 0 | ALIGN_VAR_32(int16_t, avgBlock[16 * 16]); |
93 | 0 | int32_t totalSum = 0; |
94 | 0 | int16_t sum = 0; |
95 | 0 | for (int i = 0; i < 16; i++) |
96 | 0 | for (int j =0; j < 16; j++) |
97 | 0 | { |
98 | 0 | sum = src[2*i*srcStride + 2*j] + src[2*i*srcStride + 2*j + 1] |
99 | 0 | + src[(2*i+1)*srcStride + 2*j] + src[(2*i+1)*srcStride + 2*j + 1]; |
100 | 0 | avgBlock[i*16 + j] = sum >> 2; |
101 | |
|
102 | 0 | totalSum += sum; |
103 | 0 | } |
104 | |
|
105 | 0 | (*s_dct16x16)(avgBlock, coef, 16); |
106 | 0 | memset(dst, 0, 1024 * sizeof(int16_t)); |
107 | 0 | for (int i = 0; i < 16; i++) |
108 | 0 | { |
109 | 0 | memcpy(&dst[i * 32], &coef[i * 16], 16 * sizeof(int16_t)); |
110 | 0 | } |
111 | 0 | dst[0] = static_cast<int16_t>(totalSum >> 3); |
112 | 0 | } |
113 | | |
114 | | namespace X265_NS { |
115 | | // x265 private namespace |
116 | | |
117 | | void setupLowPassPrimitives_c(EncoderPrimitives& p) |
118 | 1 | { |
119 | 1 | s_dct4x4 = &(p.cu[BLOCK_4x4].standard_dct); |
120 | 1 | s_dct8x8 = &(p.cu[BLOCK_8x8].standard_dct); |
121 | 1 | s_dct16x16 = &(p.cu[BLOCK_16x16].standard_dct); |
122 | | |
123 | 1 | p.cu[BLOCK_8x8].lowpass_dct = lowPassDct8_c; |
124 | 1 | p.cu[BLOCK_16x16].lowpass_dct = lowPassDct16_c; |
125 | 1 | p.cu[BLOCK_32x32].lowpass_dct = lowPassDct32_c; |
126 | 1 | } |
127 | | } |