Add an API wrapper to the encoder to export the new theora-exp API.
[xiph/unicode.git] / theora / lib / enc / encoder_quant.c
blob9aa5c19e520e15095d52c7dbce114ba5e081060e
1 /********************************************************************
2 * *
3 * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
7 * *
8 * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2005 *
9 * by the Xiph.Org Foundation http://www.xiph.org/ *
10 * *
11 ********************************************************************
13 function:
14 last mod: $Id$
16 ********************************************************************/
18 #include <stdlib.h>
19 #include <string.h>
20 #include "codec_internal.h"
21 #include "quant_lookup.h"
23 #ifdef _TH_DEBUG_
24 #include <stdio.h>
25 extern FILE *debugout;
26 extern long dframe;
27 #endif
29 #define OC_QUANT_MAX (1024<<2)
30 static const unsigned DC_QUANT_MIN[2]={4<<2,8<<2};
31 static const unsigned AC_QUANT_MIN[2]={2<<2,4<<2};
32 #define OC_MAXI(_a,_b) ((_a)<(_b)?(_b):(_a))
33 #define OC_MINI(_a,_b) ((_a)>(_b)?(_b):(_a))
34 #define OC_CLAMPI(_a,_b,_c) (OC_MAXI(_a,OC_MINI(_b,_c)))
36 static int ilog(unsigned _v){
37 int ret;
38 for(ret=0;_v;ret++)_v>>=1;
39 return ret;
43 void WriteQTables(PB_INSTANCE *pbi,oggpack_buffer* _opb) {
45 th_quant_info *_qinfo = &pbi->quant_info;
47 const th_quant_ranges *qranges;
48 const th_quant_base *base_mats[2*3*64];
49 int indices[2][3][64];
50 int nbase_mats;
51 int nbits;
52 int ci;
53 int qi;
54 int qri;
55 int qti;
56 int pli;
57 int qtj;
58 int plj;
59 int bmi;
60 int i;
62 /*Unlike the scale tables, we can't assume the maximum value will be in
63 index 0, so search for it here.*/
64 i=_qinfo->loop_filter_limits[0];
65 for(qi=1;qi<64;qi++)i=OC_MAXI(i,_qinfo->loop_filter_limits[qi]);
66 nbits=ilog(i);
67 oggpackB_write(_opb,nbits,3);
68 for(qi=0;qi<64;qi++){
69 oggpackB_write(_opb,_qinfo->loop_filter_limits[qi],nbits);
71 /* 580 bits for VP3.*/
72 nbits=OC_MAXI(ilog(_qinfo->ac_scale[0]),1);
73 oggpackB_write(_opb,nbits-1,4);
74 for(qi=0;qi<64;qi++)oggpackB_write(_opb,_qinfo->ac_scale[qi],nbits);
75 /* 516 bits for VP3.*/
76 nbits=OC_MAXI(ilog(_qinfo->dc_scale[0]),1);
77 oggpackB_write(_opb,nbits-1,4);
78 for(qi=0;qi<64;qi++)oggpackB_write(_opb,_qinfo->dc_scale[qi],nbits);
79 /*Consolidate any duplicate base matrices.*/
80 nbase_mats=0;
81 for(qti=0;qti<2;qti++)for(pli=0;pli<3;pli++){
82 qranges=_qinfo->qi_ranges[qti]+pli;
83 for(qri=0;qri<=qranges->nranges;qri++){
84 for(bmi=0;;bmi++){
85 if(bmi>=nbase_mats){
86 base_mats[bmi]=qranges->base_matrices+qri;
87 indices[qti][pli][qri]=nbase_mats++;
88 break;
90 else if(memcmp(base_mats[bmi][0],qranges->base_matrices[qri],
91 sizeof(base_mats[bmi][0]))==0){
92 indices[qti][pli][qri]=bmi;
93 break;
98 /*Write out the list of unique base matrices.
99 1545 bits for VP3 matrices.*/
100 oggpackB_write(_opb,nbase_mats-1,9);
101 for(bmi=0;bmi<nbase_mats;bmi++){
102 for(ci=0;ci<64;ci++)oggpackB_write(_opb,base_mats[bmi][0][ci],8);
104 /*Now store quant ranges and their associated indices into the base matrix
105 list.
106 46 bits for VP3 matrices.*/
107 nbits=ilog(nbase_mats-1);
108 for(i=0;i<6;i++){
109 qti=i/3;
110 pli=i%3;
111 qranges=_qinfo->qi_ranges[qti]+pli;
112 if(i>0){
113 if(qti>0){
114 if(qranges->nranges==_qinfo->qi_ranges[qti-1][pli].nranges&&
115 memcmp(qranges->sizes,_qinfo->qi_ranges[qti-1][pli].sizes,
116 qranges->nranges*sizeof(qranges->sizes[0]))==0&&
117 memcmp(indices[qti][pli],indices[qti-1][pli],
118 (qranges->nranges+1)*sizeof(indices[qti][pli][0]))==0){
119 oggpackB_write(_opb,1,2);
120 continue;
123 qtj=(i-1)/3;
124 plj=(i-1)%3;
125 if(qranges->nranges==_qinfo->qi_ranges[qtj][plj].nranges&&
126 memcmp(qranges->sizes,_qinfo->qi_ranges[qtj][plj].sizes,
127 qranges->nranges*sizeof(qranges->sizes[0]))==0&&
128 memcmp(indices[qti][pli],indices[qtj][plj],
129 (qranges->nranges+1)*sizeof(indices[qti][pli][0]))==0){
130 oggpackB_write(_opb,0,1+(qti>0));
131 continue;
133 oggpackB_write(_opb,1,1);
135 oggpackB_write(_opb,indices[qti][pli][0],nbits);
136 for(qi=qri=0;qi<63;qri++){
137 oggpackB_write(_opb,qranges->sizes[qri]-1,ilog(62-qi));
138 qi+=qranges->sizes[qri];
139 oggpackB_write(_opb,indices[qti][pli][qri+1],nbits);
144 /* a copied/reconciled version of derf's theora-exp code; redundancy
145 should be eliminated at some point */
146 void InitQTables( PB_INSTANCE *pbi ){
147 int qti; /* coding mode: intra or inter */
148 int pli; /* Y U V */
149 th_quant_info *qinfo = &pbi->quant_info;
151 pbi->QThreshTable = pbi->quant_info.ac_scale;
153 for(qti=0;qti<2;qti++){
154 for(pli=0;pli<3;pli++){
155 int qi; /* quality index */
156 int qri; /* range iterator */
158 for(qi=0,qri=0; qri<=qinfo->qi_ranges[qti][pli].nranges; qri++){
159 th_quant_base base;
161 ogg_uint32_t q;
162 int qi_start;
163 int qi_end;
164 int ci;
165 memcpy(base,qinfo->qi_ranges[qti][pli].base_matrices[qri],
166 sizeof(base));
168 qi_start=qi;
169 if(qri==qinfo->qi_ranges[qti][pli].nranges)
170 qi_end=qi+1;
171 else
172 qi_end=qi+qinfo->qi_ranges[qti][pli].sizes[qri];
174 /* Iterate over quality indicies in this range */
175 for(;;){
177 /*Scale DC the coefficient from the proper table.*/
178 q=((ogg_uint32_t)qinfo->dc_scale[qi]*base[0]/100)<<2;
179 q=OC_CLAMPI(DC_QUANT_MIN[qti],q,OC_QUANT_MAX);
180 pbi->quant_tables[qti][pli][qi][0]=(ogg_uint16_t)q;
182 /*Now scale AC coefficients from the proper table.*/
183 for(ci=1;ci<64;ci++){
184 q=((ogg_uint32_t)qinfo->ac_scale[qi]*base[ci]/100)<<2;
185 q=OC_CLAMPI(AC_QUANT_MIN[qti],q,OC_QUANT_MAX);
186 pbi->quant_tables[qti][pli][qi][ci]=(ogg_uint16_t)q;
189 if(++qi>=qi_end)break;
191 /*Interpolate the next base matrix.*/
192 for(ci=0;ci<64;ci++){
193 base[ci]=(unsigned char)
194 ((2*((qi_end-qi)*qinfo->qi_ranges[qti][pli].base_matrices[qri][ci]+
195 (qi-qi_start)*qinfo->qi_ranges[qti][pli].base_matrices[qri+1][ci])
196 +qinfo->qi_ranges[qti][pli].sizes[qri])/
197 (2*qinfo->qi_ranges[qti][pli].sizes[qri]));
204 #ifdef _TH_DEBUG_
205 int i, j, k, l;
207 /* dump the static tables */
209 int i, j, k, l, m;
210 TH_DEBUG("loop filter limits = {");
211 for(i=0;i<64;){
212 TH_DEBUG("\n ");
213 for(j=0;j<16;i++,j++)
214 TH_DEBUG("%3d ",qinfo->loop_filter_limits[i]);
216 TH_DEBUG("\n}\n\n");
218 TH_DEBUG("ac scale = {");
219 for(i=0;i<64;){
220 TH_DEBUG("\n ");
221 for(j=0;j<16;i++,j++)
222 TH_DEBUG("%3d ",qinfo->ac_scale[i]);
224 TH_DEBUG("\n}\n\n");
226 TH_DEBUG("dc scale = {");
227 for(i=0;i<64;){
228 TH_DEBUG("\n ");
229 for(j=0;j<16;i++,j++)
230 TH_DEBUG("%3d ",qinfo->dc_scale[i]);
232 TH_DEBUG("\n}\n\n");
234 for(k=0;k<2;k++)
235 for(l=0;l<3;l++){
236 char *name[2][3]={
237 {"intra Y bases","intra U bases", "intra V bases"},
238 {"inter Y bases","inter U bases", "inter V bases"}
241 th_quant_ranges *r = &qinfo->qi_ranges[k][l];
242 TH_DEBUG("%s = {\n",name[k][l]);
243 TH_DEBUG(" ranges = %d\n",r->nranges);
244 TH_DEBUG(" intervals = { ");
245 for(i=0;i<r->nranges;i++)
246 TH_DEBUG("%3d ",r->sizes[i]);
247 TH_DEBUG("}\n");
248 TH_DEBUG("\n matricies = { ");
249 for(m=0;m<r->nranges+1;m++){
250 TH_DEBUG("\n { ");
251 for(i=0;i<64;){
252 TH_DEBUG("\n ");
253 for(j=0;j<8;i++,j++)
254 TH_DEBUG("%3d ",r->base_matrices[m][i]);
256 TH_DEBUG("\n }");
258 TH_DEBUG("\n }\n");
262 /* dump the calculated quantizer tables */
263 for(i=0;i<2;i++){
264 for(j=0;j<3;j++){
265 for(k=0;k<64;k++){
266 TH_DEBUG("quantizer table [%s][%s][Q%d] = {",
267 (i==0?"intra":"inter"),(j==0?"Y":(j==1?"U":"V")),k);
268 for(l=0;l<64;l++){
269 if((l&7)==0)
270 TH_DEBUG("\n ");
271 TH_DEBUG("%4d ",pbi->quant_tables[i][j][k][l]);
273 TH_DEBUG("}\n");
277 #endif
281 static void BuildZigZagIndex(PB_INSTANCE *pbi){
282 ogg_int32_t i,j;
284 /* invert the row to zigzag coeffient order lookup table */
285 for ( i = 0; i < BLOCK_SIZE; i++ ){
286 j = dezigzag_index[i];
287 pbi->zigzag_index[j] = i;
291 static void init_quantizer ( CP_INSTANCE *cpi,
292 unsigned char QIndex ){
293 int i;
294 double ZBinFactor;
295 double RoundingFactor;
297 double temp_fp_quant_coeffs;
298 double temp_fp_quant_round;
299 double temp_fp_ZeroBinSize;
300 PB_INSTANCE *pbi = &cpi->pb;
303 const ogg_uint16_t * temp_Y_coeffs;
304 const ogg_uint16_t * temp_U_coeffs;
305 const ogg_uint16_t * temp_V_coeffs;
306 const ogg_uint16_t * temp_Inter_Y_coeffs;
307 const ogg_uint16_t * temp_Inter_U_coeffs;
308 const ogg_uint16_t * temp_Inter_V_coeffs;
309 ogg_uint16_t scale_factor = cpi->pb.quant_info.ac_scale[QIndex];
311 /* Notes on setup of quantisers. The initial multiplication by
312 the scale factor is done in the ogg_int32_t domain to insure that the
313 precision in the quantiser is the same as in the inverse
314 quantiser where all calculations are integer. The "<< 2" is a
315 normalisation factor for the forward DCT transform. */
317 temp_Y_coeffs = pbi->quant_tables[0][0][QIndex];
318 temp_U_coeffs = pbi->quant_tables[0][1][QIndex];
319 temp_V_coeffs = pbi->quant_tables[0][2][QIndex];
320 temp_Inter_Y_coeffs = pbi->quant_tables[1][0][QIndex];
321 temp_Inter_U_coeffs = pbi->quant_tables[1][1][QIndex];
322 temp_Inter_V_coeffs = pbi->quant_tables[1][2][QIndex];
324 ZBinFactor = 0.9;
326 switch(cpi->pb.info.sharpness){
327 case 0:
328 ZBinFactor = 0.65;
329 if ( scale_factor <= 50 )
330 RoundingFactor = 0.499;
331 else
332 RoundingFactor = 0.46;
333 break;
334 case 1:
335 ZBinFactor = 0.75;
336 if ( scale_factor <= 50 )
337 RoundingFactor = 0.476;
338 else
339 RoundingFactor = 0.400;
340 break;
342 default:
343 ZBinFactor = 0.9;
344 if ( scale_factor <= 50 )
345 RoundingFactor = 0.476;
346 else
347 RoundingFactor = 0.333;
348 break;
351 /* Use fixed multiplier for intra Y DC */
352 temp_fp_quant_coeffs = temp_Y_coeffs[0];
353 temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
354 pbi->fp_quant_Y_round[0] = (ogg_int32_t) (0.5 + temp_fp_quant_round);
355 temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
356 pbi->fp_ZeroBinSize_Y[0] = (ogg_int32_t) (0.5 + temp_fp_ZeroBinSize);
357 temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
358 pbi->fp_quant_Y_coeffs[0] = (0.5 + SHIFT16 * temp_fp_quant_coeffs);
360 /* Intra U */
361 temp_fp_quant_coeffs = temp_U_coeffs[0];
362 temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
363 pbi->fp_quant_U_round[0] = (0.5 + temp_fp_quant_round);
364 temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
365 pbi->fp_ZeroBinSize_U[0] = (0.5 + temp_fp_ZeroBinSize);
366 temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
367 pbi->fp_quant_U_coeffs[0]= (0.5 + SHIFT16 * temp_fp_quant_coeffs);
369 /* Intra V */
370 temp_fp_quant_coeffs = temp_V_coeffs[0];
371 temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
372 pbi->fp_quant_V_round[0] = (0.5 + temp_fp_quant_round);
373 temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
374 pbi->fp_ZeroBinSize_V[0] = (0.5 + temp_fp_ZeroBinSize);
375 temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
376 pbi->fp_quant_V_coeffs[0]= (0.5 + SHIFT16 * temp_fp_quant_coeffs);
379 /* Inter Y */
380 temp_fp_quant_coeffs = temp_Inter_Y_coeffs[0];
381 temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
382 pbi->fp_quant_Inter_Y_round[0]= (0.5 + temp_fp_quant_round);
383 temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
384 pbi->fp_ZeroBinSize_Inter_Y[0]= (0.5 + temp_fp_ZeroBinSize);
385 temp_fp_quant_coeffs= 1.0 / temp_fp_quant_coeffs;
386 pbi->fp_quant_Inter_Y_coeffs[0]= (0.5 + SHIFT16 * temp_fp_quant_coeffs);
388 /* Inter U */
389 temp_fp_quant_coeffs = temp_Inter_U_coeffs[0];
390 temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
391 pbi->fp_quant_Inter_U_round[0]= (0.5 + temp_fp_quant_round);
392 temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
393 pbi->fp_ZeroBinSize_Inter_U[0]= (0.5 + temp_fp_ZeroBinSize);
394 temp_fp_quant_coeffs= 1.0 / temp_fp_quant_coeffs;
395 pbi->fp_quant_Inter_U_coeffs[0]= (0.5 + SHIFT16 * temp_fp_quant_coeffs);
397 /* Inter V */
398 temp_fp_quant_coeffs = temp_Inter_V_coeffs[0];
399 temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
400 pbi->fp_quant_Inter_V_round[0]= (0.5 + temp_fp_quant_round);
401 temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
402 pbi->fp_ZeroBinSize_Inter_V[0]= (0.5 + temp_fp_ZeroBinSize);
403 temp_fp_quant_coeffs= 1.0 / temp_fp_quant_coeffs;
404 pbi->fp_quant_Inter_V_coeffs[0]= (0.5 + SHIFT16 * temp_fp_quant_coeffs);
407 for ( i = 1; i < 64; i++ ){
408 /* Intra Y */
409 temp_fp_quant_coeffs = temp_Y_coeffs[i];
410 temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
411 pbi->fp_quant_Y_round[i] = (0.5 + temp_fp_quant_round);
412 temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
413 pbi->fp_ZeroBinSize_Y[i] = (0.5 + temp_fp_ZeroBinSize);
414 temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
415 pbi->fp_quant_Y_coeffs[i] = (0.5 + SHIFT16 * temp_fp_quant_coeffs);
417 /* Intra U */
418 temp_fp_quant_coeffs = temp_U_coeffs[i];
419 temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
420 pbi->fp_quant_U_round[i] = (0.5 + temp_fp_quant_round);
421 temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
422 pbi->fp_ZeroBinSize_U[i] = (0.5 + temp_fp_ZeroBinSize);
423 temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
424 pbi->fp_quant_U_coeffs[i]= (0.5 + SHIFT16 * temp_fp_quant_coeffs);
426 /* Intra V */
427 temp_fp_quant_coeffs = temp_V_coeffs[i];
428 temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
429 pbi->fp_quant_V_round[i] = (0.5 + temp_fp_quant_round);
430 temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
431 pbi->fp_ZeroBinSize_V[i] = (0.5 + temp_fp_ZeroBinSize);
432 temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
433 pbi->fp_quant_V_coeffs[i]= (0.5 + SHIFT16 * temp_fp_quant_coeffs);
435 /* Inter Y */
436 temp_fp_quant_coeffs = temp_Inter_Y_coeffs[i];
437 temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
438 pbi->fp_quant_Inter_Y_round[i]= (0.5 + temp_fp_quant_round);
439 temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
440 pbi->fp_ZeroBinSize_Inter_Y[i]= (0.5 + temp_fp_ZeroBinSize);
441 temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
442 pbi->fp_quant_Inter_Y_coeffs[i]= (0.5 + SHIFT16 * temp_fp_quant_coeffs);
444 /* Inter U */
445 temp_fp_quant_coeffs = temp_Inter_U_coeffs[i];
446 temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
447 pbi->fp_quant_Inter_U_round[i]= (0.5 + temp_fp_quant_round);
448 temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
449 pbi->fp_ZeroBinSize_Inter_U[i]= (0.5 + temp_fp_ZeroBinSize);
450 temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
451 pbi->fp_quant_Inter_U_coeffs[i]= (0.5 + SHIFT16 * temp_fp_quant_coeffs);
453 /* Inter V */
454 temp_fp_quant_coeffs = temp_Inter_V_coeffs[i];
455 temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
456 pbi->fp_quant_Inter_V_round[i]= (0.5 + temp_fp_quant_round);
457 temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
458 pbi->fp_ZeroBinSize_Inter_V[i]= (0.5 + temp_fp_ZeroBinSize);
459 temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
460 pbi->fp_quant_Inter_V_coeffs[i]= (0.5 + SHIFT16 * temp_fp_quant_coeffs);
465 pbi->fquant_coeffs = pbi->fp_quant_Y_coeffs;
469 void select_quantiser(PB_INSTANCE *pbi, int type) {
470 /* select a quantiser according to what plane has to be coded in what
471 * mode. Could be extended to a more sophisticated scheme. */
473 switch(type) {
474 case BLOCK_Y:
475 pbi->fquant_coeffs = pbi->fp_quant_Y_coeffs;
476 pbi->fquant_round = pbi->fp_quant_Y_round;
477 pbi->fquant_ZbSize = pbi->fp_ZeroBinSize_Y;
478 break;
479 case BLOCK_U:
480 pbi->fquant_coeffs = pbi->fp_quant_U_coeffs;
481 pbi->fquant_round = pbi->fp_quant_U_round;
482 pbi->fquant_ZbSize = pbi->fp_ZeroBinSize_U;
483 break;
484 case BLOCK_V:
485 pbi->fquant_coeffs = pbi->fp_quant_V_coeffs;
486 pbi->fquant_round = pbi->fp_quant_V_round;
487 pbi->fquant_ZbSize = pbi->fp_ZeroBinSize_V;
488 break;
489 case BLOCK_INTER_Y:
490 pbi->fquant_coeffs = pbi->fp_quant_Inter_Y_coeffs;
491 pbi->fquant_round = pbi->fp_quant_Inter_Y_round;
492 pbi->fquant_ZbSize = pbi->fp_ZeroBinSize_Inter_Y;
493 break;
494 case BLOCK_INTER_U:
495 pbi->fquant_coeffs = pbi->fp_quant_Inter_U_coeffs;
496 pbi->fquant_round = pbi->fp_quant_Inter_U_round;
497 pbi->fquant_ZbSize = pbi->fp_ZeroBinSize_Inter_U;
498 break;
499 case BLOCK_INTER_V:
500 pbi->fquant_coeffs = pbi->fp_quant_Inter_V_coeffs;
501 pbi->fquant_round = pbi->fp_quant_Inter_V_round;
502 pbi->fquant_ZbSize = pbi->fp_ZeroBinSize_Inter_V;
503 break;
508 void quantize( PB_INSTANCE *pbi,
509 ogg_int16_t * DCT_block,
510 Q_LIST_ENTRY * quantized_list){
511 ogg_uint32_t i; /* Row index */
512 Q_LIST_ENTRY val; /* Quantised value. */
514 ogg_int32_t * FquantRoundPtr = pbi->fquant_round;
515 ogg_int32_t * FquantCoeffsPtr = pbi->fquant_coeffs;
516 ogg_int32_t * FquantZBinSizePtr = pbi->fquant_ZbSize;
517 ogg_int16_t * DCT_blockPtr = DCT_block;
518 ogg_uint32_t * ZigZagPtr = (ogg_uint32_t *)pbi->zigzag_index;
519 ogg_int32_t temp;
521 /* Set the quantized_list to default to 0 */
522 memset( quantized_list, 0, 64 * sizeof(Q_LIST_ENTRY) );
524 /* Note that we add half divisor to effect rounding on positive number */
525 for( i = 0; i < VFRAGPIXELS; i++) {
527 int col;
528 /* Iterate through columns */
529 for( col = 0; col < 8; col++) {
530 if ( DCT_blockPtr[col] >= FquantZBinSizePtr[col] ) {
531 temp = FquantCoeffsPtr[col] * ( DCT_blockPtr[col] + FquantRoundPtr[col] ) ;
532 val = (Q_LIST_ENTRY) (temp>>16);
533 quantized_list[ZigZagPtr[col]] = ( val > 511 ) ? 511 : val;
534 } else if ( DCT_blockPtr[col] <= -FquantZBinSizePtr[col] ) {
535 temp = FquantCoeffsPtr[col] *
536 ( DCT_blockPtr[col] - FquantRoundPtr[col] ) + MIN16;
537 val = (Q_LIST_ENTRY) (temp>>16);
538 quantized_list[ZigZagPtr[col]] = ( val < -511 ) ? -511 : val;
542 FquantRoundPtr += 8;
543 FquantCoeffsPtr += 8;
544 FquantZBinSizePtr += 8;
545 DCT_blockPtr += 8;
546 ZigZagPtr += 8;
550 static void init_dequantizer ( PB_INSTANCE *pbi,
551 unsigned char QIndex ){
552 int i, j;
554 ogg_uint16_t * InterY_coeffs;
555 ogg_uint16_t * InterU_coeffs;
556 ogg_uint16_t * InterV_coeffs;
557 ogg_uint16_t * Y_coeffs;
558 ogg_uint16_t * U_coeffs;
559 ogg_uint16_t * V_coeffs;
561 Y_coeffs = pbi->quant_tables[0][0][QIndex];
562 U_coeffs = pbi->quant_tables[0][1][QIndex];
563 V_coeffs = pbi->quant_tables[0][2][QIndex];
564 InterY_coeffs = pbi->quant_tables[1][0][QIndex];
565 InterU_coeffs = pbi->quant_tables[1][1][QIndex];
566 InterV_coeffs = pbi->quant_tables[1][2][QIndex];
568 /* invert the dequant index into the quant index
569 the dxer has a different order than the cxer. */
570 BuildZigZagIndex(pbi);
572 /* Reorder dequantisation coefficients into dct zigzag order. */
573 for ( i = 0; i < BLOCK_SIZE; i++ ) {
574 j = pbi->zigzag_index[i];
575 pbi->dequant_Y_coeffs[j] = Y_coeffs[i];
577 for ( i = 0; i < BLOCK_SIZE; i++ ) {
578 j = pbi->zigzag_index[i];
579 pbi->dequant_U_coeffs[j] = U_coeffs[i];
581 for ( i = 0; i < BLOCK_SIZE; i++ ) {
582 j = pbi->zigzag_index[i];
583 pbi->dequant_V_coeffs[j] = V_coeffs[i];
585 for ( i = 0; i < BLOCK_SIZE; i++ ){
586 j = pbi->zigzag_index[i];
587 pbi->dequant_InterY_coeffs[j] = InterY_coeffs[i];
589 for ( i = 0; i < BLOCK_SIZE; i++ ){
590 j = pbi->zigzag_index[i];
591 pbi->dequant_InterU_coeffs[j] = InterU_coeffs[i];
593 for ( i = 0; i < BLOCK_SIZE; i++ ){
594 j = pbi->zigzag_index[i];
595 pbi->dequant_InterV_coeffs[j] = InterV_coeffs[i];
598 pbi->dequant_coeffs = pbi->dequant_Y_coeffs;
601 void UpdateQ( PB_INSTANCE *pbi, int NewQIndex ){
602 ogg_uint32_t qscale;
604 /* clamp to legal bounds */
605 if (NewQIndex >= Q_TABLE_SIZE) NewQIndex = Q_TABLE_SIZE - 1;
606 else if (NewQIndex < 0) NewQIndex = 0;
608 pbi->FrameQIndex = NewQIndex;
610 qscale = pbi->quant_info.ac_scale[NewQIndex];
611 pbi->ThisFrameQualityValue = qscale;
613 /* Re-initialise the Q tables for forward and reverse transforms. */
614 init_dequantizer ( pbi, (unsigned char) pbi->FrameQIndex );
617 void UpdateQC( CP_INSTANCE *cpi, ogg_uint32_t NewQ ){
618 ogg_uint32_t qscale;
619 PB_INSTANCE *pbi = &cpi->pb;
621 /* Do bounds checking and convert to a float. */
622 qscale = NewQ;
623 if ( qscale < pbi->quant_info.ac_scale[Q_TABLE_SIZE-1] )
624 qscale = pbi->quant_info.ac_scale[Q_TABLE_SIZE-1];
625 else if ( qscale > pbi->quant_info.ac_scale[0] )
626 qscale = pbi->quant_info.ac_scale[0];
628 /* Set the inter/intra descision control variables. */
629 pbi->FrameQIndex = Q_TABLE_SIZE - 1;
630 while ((ogg_int32_t) pbi->FrameQIndex >= 0 ) {
631 if ( (pbi->FrameQIndex == 0) ||
632 ( pbi->quant_info.ac_scale[pbi->FrameQIndex] >= NewQ) )
633 break;
634 pbi->FrameQIndex --;
637 /* Re-initialise the Q tables for forward and reverse transforms. */
638 init_quantizer ( cpi, pbi->FrameQIndex );
639 init_dequantizer ( pbi, pbi->FrameQIndex );