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