1 /*****************************************************************************
2 *
3 * XVID MPEG-4 VIDEO CODEC
4 * - MPEG4 Quantization related header -
5 *
6 * Copyright(C) 2001-2003 Peter Ross <pross@xvid.org>
7 *
8 * This program is free software ; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation ; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY ; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program ; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 * $Id: quant_mpeg.c 1985 2011-05-18 09:02:35Z Isibaar $
23 *
24 ****************************************************************************/
25
26 #include "../global.h"
27 #include "quant.h"
28 #include "quant_matrix.h"
29
30 /*****************************************************************************
31 * Global function pointers
32 ****************************************************************************/
33
34 /* Quant */
35 quant_intraFuncPtr quant_mpeg_intra;
36 quant_interFuncPtr quant_mpeg_inter;
37
38 /* DeQuant */
39 quant_intraFuncPtr dequant_mpeg_intra;
40 quant_interFuncPtr dequant_mpeg_inter;
41
42 /*****************************************************************************
43 * Local data
44 ****************************************************************************/
45
46 /* divide-by-multiply table
47 * needs 17 bit shift (16 causes slight errors when q > 19) */
48
49 #define FIX(X) ((1UL << SCALEBITS) / (X) + 1)
50
51 static const uint32_t multipliers[32] =
52 {
53 0, FIX(2), FIX(4), FIX(6),
54 FIX(8), FIX(10), FIX(12), FIX(14),
55 FIX(16), FIX(18), FIX(20), FIX(22),
56 FIX(24), FIX(26), FIX(28), FIX(30),
57 FIX(32), FIX(34), FIX(36), FIX(38),
58 FIX(40), FIX(42), FIX(44), FIX(46),
59 FIX(48), FIX(50), FIX(52), FIX(54),
60 FIX(56), FIX(58), FIX(60), FIX(62)
61 };
62
63 /*****************************************************************************
64 * Function definitions
65 ****************************************************************************/
66
67 /* quantize intra-block
68 */
69
70 uint32_t
quant_mpeg_intra_c(int16_t * coeff,const int16_t * data,const uint32_t quant,const uint32_t dcscalar,const uint16_t * mpeg_quant_matrices)71 quant_mpeg_intra_c(int16_t * coeff,
72 const int16_t * data,
73 const uint32_t quant,
74 const uint32_t dcscalar,
75 const uint16_t * mpeg_quant_matrices)
76 {
77 const uint16_t * intra_matrix_rec = mpeg_quant_matrices + 1*64;
78 int i;
79 int rounding = 1<<(SCALEBITS-1-3);
80
81 coeff[0] = DIV_DIV(data[0], (int32_t) dcscalar);
82
83 for (i = 1; i < 64; i++) {
84 int32_t level = data[i];
85 level *= intra_matrix_rec[i];
86 level = (level + rounding)>>(SCALEBITS-3);
87 coeff[i] = level;
88 }
89
90 return(0);
91 }
92
93 /* quantize inter-block
94 *
95 * level = DIV_DIV(16 * data[i], default_intra_matrix[i]);
96 * coeff[i] = (level + quantd) / quant2;
97 * sum += abs(level);
98 */
99
100 uint32_t
quant_mpeg_inter_c(int16_t * coeff,const int16_t * data,const uint32_t quant,const uint16_t * mpeg_quant_matrices)101 quant_mpeg_inter_c(int16_t * coeff,
102 const int16_t * data,
103 const uint32_t quant,
104 const uint16_t * mpeg_quant_matrices)
105 {
106 const uint32_t mult = multipliers[quant];
107 const uint16_t *inter_matrix = get_inter_matrix(mpeg_quant_matrices);
108 uint32_t sum = 0;
109 int i;
110
111 for (i = 0; i < 64; i++) {
112 if (data[i] < 0) {
113 uint32_t level = -data[i];
114
115 level = ((level << 4) + (inter_matrix[i] >> 1)) / inter_matrix[i];
116 level = (level * mult) >> 17;
117 sum += level;
118 coeff[i] = -(int16_t) level;
119 } else if (data[i] > 0) {
120 uint32_t level = data[i];
121
122 level = ((level << 4) + (inter_matrix[i] >> 1)) / inter_matrix[i];
123 level = (level * mult) >> 17;
124 sum += level;
125 coeff[i] = level;
126 } else {
127 coeff[i] = 0;
128 }
129 }
130
131 return(sum);
132 }
133
134 /* dequantize intra-block & clamp to [-2048,2047]
135 *
136 * data[i] = (coeff[i] * default_intra_matrix[i] * quant2) >> 4;
137 */
138
139 uint32_t
dequant_mpeg_intra_c(int16_t * data,const int16_t * coeff,const uint32_t quant,const uint32_t dcscalar,const uint16_t * mpeg_quant_matrices)140 dequant_mpeg_intra_c(int16_t * data,
141 const int16_t * coeff,
142 const uint32_t quant,
143 const uint32_t dcscalar,
144 const uint16_t * mpeg_quant_matrices)
145 {
146 const uint16_t *intra_matrix = get_intra_matrix(mpeg_quant_matrices);
147 int i;
148
149 data[0] = coeff[0] * dcscalar;
150 if (data[0] < -2048) {
151 data[0] = -2048;
152 } else if (data[0] > 2047) {
153 data[0] = 2047;
154 }
155
156 for (i = 1; i < 64; i++) {
157 if (coeff[i] == 0) {
158 data[i] = 0;
159 } else if (coeff[i] < 0) {
160 uint32_t level = -coeff[i];
161
162 level = (level * intra_matrix[i] * quant) >> 3;
163 data[i] = (level <= 2048 ? -(int16_t) level : -2048);
164 } else {
165 uint32_t level = coeff[i];
166
167 level = (level * intra_matrix[i] * quant) >> 3;
168 data[i] = (level <= 2047 ? level : 2047);
169 }
170 }
171
172 return(0);
173 }
174
175
176 /* dequantize inter-block & clamp to [-2048,2047]
177 * data = ((2 * coeff + SIGN(coeff)) * inter_matrix[i] * quant) / 16
178 */
179
180 uint32_t
dequant_mpeg_inter_c(int16_t * data,const int16_t * coeff,const uint32_t quant,const uint16_t * mpeg_quant_matrices)181 dequant_mpeg_inter_c(int16_t * data,
182 const int16_t * coeff,
183 const uint32_t quant,
184 const uint16_t * mpeg_quant_matrices)
185 {
186 uint32_t sum = 0;
187 const uint16_t *inter_matrix = get_inter_matrix(mpeg_quant_matrices);
188 int i;
189
190 for (i = 0; i < 64; i++) {
191 if (coeff[i] == 0) {
192 data[i] = 0;
193 } else if (coeff[i] < 0) {
194 int32_t level = -coeff[i];
195
196 level = ((2 * level + 1) * inter_matrix[i] * quant) >> 4;
197 data[i] = (level <= 2048 ? -level : -2048);
198 } else {
199 uint32_t level = coeff[i];
200
201 level = ((2 * level + 1) * inter_matrix[i] * quant) >> 4;
202 data[i] = (level <= 2047 ? level : 2047);
203 }
204
205 sum ^= data[i];
206 }
207
208 /* mismatch control */
209 if ((sum & 1) == 0) {
210 data[63] ^= 1;
211 }
212
213 return(0);
214 }
215