r1009: Move the dependencies to newer package names
[cinelerra_cv/mob.git] / quicktime / encore50 / text_code_mb.c
blob305c8ebb09ef7d55d2f59c3257d577efb85697e8
2 /**************************************************************************
3 * *
4 * This code is developed by Adam Li. This software is an *
5 * implementation of a part of one or more MPEG-4 Video tools as *
6 * specified in ISO/IEC 14496-2 standard. Those intending to use this *
7 * software module in hardware or software products are advised that its *
8 * use may infringe existing patents or copyrights, and any such use *
9 * would be at such party's own risk. The original developer of this *
10 * software module and his/her company, and subsequent editors and their *
11 * companies (including Project Mayo), will have no liability for use of *
12 * this software or modifications or derivatives thereof. *
13 * *
14 * Project Mayo gives users of the Codec a license to this software *
15 * module or modifications thereof for use in hardware or software *
16 * products claiming conformance to the MPEG-4 Video Standard as *
17 * described in the Open DivX license. *
18 * *
19 * The complete Open DivX license can be found at *
20 * http://www.projectmayo.com/opendivx/license.php . *
21 * *
22 **************************************************************************/
24 /**************************************************************************
26 * text_code_mb.c
28 * Copyright (C) 2001 Project Mayo
30 * Adam Li
31 * Juice
33 * DivX Advance Research Center <darc@projectmayo.com>
35 **************************************************************************/
37 /* This file contains some functions for text coding of MacroBlocks. */
38 /* Some codes of this project come from MoMuSys MPEG-4 implementation. */
39 /* Please see seperate acknowledgement file for a list of contributors. */
41 #include "text_code.h"
42 #include "text_dct.h"
44 #define BLOCK_SIZE 8
46 Void BlockPredict (SInt *curr, /*SInt *rec_curr,*/
47 Int x_pos, Int y_pos, UInt width, Int fblock[][8]);
48 Void BlockRebuild (SInt *rec_curr, SInt *comp, Int pred_type, Int max,
49 Int x_pos, Int y_pos, UInt width, UInt edge, Int fblock[][8]);
50 Void BlockQuantH263 (Int *coeff, Int QP, Int mode, Int type,
51 Int *qcoeff, Int maxDC, Int image_type);
52 Void BlockDequantH263 (Int *qcoeff, Int QP, Int mode, Int type,
53 Int *rcoeff, Int image_type, Int short_video_header, Int bits_per_pixel);
56 /***********************************************************CommentBegin******
58 * -- CodeMB -- Code, decode and reconstruct Macroblock
59 * combined with substraction and addition operation
61 * Arguments in :
62 * Int x_pos x_position of Macroblock
63 * Int y_pos y_position of Macroblock
64 * UInt width width of Vop bounding box (unpadded size)
65 * Int QP Quantization parameter
66 * Int Mode Macroblock coding mode
68 * Arguments in/out :
69 * Vop *curr current Vop, uncoded
70 * Vop *rec_curr current Vop, decoded and reconstructed
71 * Vop *comp current Vop, motion compensated
72 * Int *qcoeff coefficient block (384 * sizeof(Int))
74 ***********************************************************CommentEnd********/
76 Void CodeMB(Vop *curr, Vop *rec_curr, Vop *comp, Int x_pos, Int y_pos, UInt width,
77 Int QP, Int Mode, Int *qcoeff)
79 Int k;
80 Int fblock[6][8][8];
81 Int coeff[384];
82 Int *coeff_ind;
83 Int *qcoeff_ind;
84 Int* rcoeff_ind;
85 Int x, y;
86 SInt *current, *recon, *compensated = NULL;
87 UInt xwidth;
88 Int iblock[6][8][8];
89 Int rcoeff[6*64];
90 Int i, j;
91 Int type; /* luma = 1, chroma = 2 */
92 // Int *qmat;
93 SInt tmp[64];
94 Int s;
96 int operation = curr->prediction_type;
97 /* This variable is for combined operation.
98 If it is an I_VOP, then MB in curr is reconstruct into rec_curr,
99 and comp is not used at all (i.e., it can be set to NULL).
100 If it is a P_VOP, then MB in curr is reconstructed, and the result
101 added with MB_comp is written into rec_curr.
102 - adamli 11/19/2000 */
104 Int max = GetVopBrightWhite(curr);
105 /* This variable is the max value for the clipping of the reconstructed image. */
107 coeff_ind = coeff;
108 qcoeff_ind = qcoeff;
109 rcoeff_ind = rcoeff;
111 for (k = 0; k < 6; k++)
113 switch (k)
115 case 0:
116 x = x_pos;
117 y = y_pos;
118 xwidth = width;
119 current = (SInt *) GetImageData (GetVopY (curr));
120 break;
121 case 1:
122 x = x_pos + 8;
123 y = y_pos;
124 xwidth = width;
125 current = (SInt *) GetImageData (GetVopY (curr));
126 break;
127 case 2:
128 x = x_pos;
129 y = y_pos + 8;
130 xwidth = width;
131 current = (SInt *) GetImageData (GetVopY (curr));
132 break;
133 case 3:
134 x = x_pos + 8;
135 y = y_pos + 8;
136 xwidth = width;
137 current = (SInt *) GetImageData (GetVopY (curr));
138 break;
139 case 4:
140 x = x_pos / 2;
141 y = y_pos / 2;
142 xwidth = width / 2;
143 current = (SInt *) GetImageData (GetVopU (curr));
144 break;
145 case 5:
146 x = x_pos / 2;
147 y = y_pos / 2;
148 xwidth = width / 2;
149 current = (SInt *) GetImageData (GetVopV (curr));
150 break;
151 default:
152 break;
154 BlockPredict (current, x, y, xwidth, fblock[k]);
157 for (k = 0; k < 6; k++)
159 s = 0;
160 for (i = 0; i < 8; i++)
161 for (j = 0; j < 8; j++)
162 tmp[s++] = (SInt) fblock[k][i][j];
163 #ifndef _MMX_
164 fdct_enc(tmp);
165 #else
166 fdct_mm32(tmp);
167 #endif
168 for (s = 0; s < 64; s++)
169 coeff_ind[s] = (Int) tmp[s];
171 if (k < 4) type = 1;
172 else type = 2;
174 /* For this release, only H263 quantization is supported. - adamli */
175 BlockQuantH263(coeff_ind,QP,Mode,type,qcoeff_ind,
176 GetVopBrightWhite(curr),1);
177 BlockDequantH263(qcoeff_ind,QP,Mode,type,rcoeff_ind,1, 0, GetVopBitsPerPixel(curr));
179 for (s = 0; s < 64; s++)
180 tmp[s] = (SInt) rcoeff_ind[s];
181 #ifndef _MMX_
182 idct_enc(tmp);
183 #else
184 Fast_IDCT(tmp);
185 #endif
186 s = 0;
187 for (i = 0; i < 8; i++)
188 for (j = 0; j < 8; j++)
189 iblock[k][i][j] = (Int)tmp[s++];
191 coeff_ind += 64;
192 qcoeff_ind += 64;
193 rcoeff_ind += 64;
195 if (Mode == MODE_INTRA||Mode==MODE_INTRA_Q)
196 for (i = 0; i < 8; i++)
197 for (j = 0; j < 8; j ++)
198 iblock[k][i][j] = MIN (GetVopBrightWhite(curr), MAX (0, iblock[k][i][j]));
200 switch (k)
202 case 0:
203 case 1:
204 case 2:
205 continue;
207 case 3:
208 recon = (SInt *) GetImageData (GetVopY (rec_curr));
209 if (operation == P_VOP) compensated = (SInt *) GetImageData (GetVopY (comp));
210 BlockRebuild (recon, compensated, operation, max, x_pos, y_pos, width, 16, iblock[0]);
211 BlockRebuild (recon, compensated, operation, max, x_pos + 8, y_pos, width, 16, iblock[1]);
212 BlockRebuild (recon, compensated, operation, max, x_pos, y_pos + 8, width, 16, iblock[2]);
213 BlockRebuild (recon, compensated, operation, max, x_pos + 8, y_pos + 8, width, 16, iblock[3]);
214 continue;
216 case 4:
217 recon = (SInt *) GetImageData (GetVopU (rec_curr));
218 if (operation == P_VOP) compensated = (SInt *) GetImageData (GetVopU (comp));
219 BlockRebuild (recon, compensated, operation, max,
220 x_pos/2, y_pos/2, width/2, 8, iblock[4]);
221 continue;
223 case 5:
224 recon = (SInt *) GetImageData (GetVopV (rec_curr));
225 if (operation == P_VOP) compensated = (SInt *) GetImageData (GetVopV (comp));
226 BlockRebuild (recon, compensated, operation, max,
227 x_pos/2, y_pos/2, width/2, 8, iblock[5]);
228 continue;
232 return;
236 /***********************************************************CommentBegin******
238 * -- BlockPredict -- Get prediction for an Intra block
240 * Purpose :
241 * Get prediction for an Intra block
243 * Arguments in :
244 * Int x_pos x_position of Macroblock
245 * Int y_pos y_position of Macroblock
246 * UInt width width of Vop bounding box
248 * Arguments in/out :
249 * SInt *curr current uncoded Vop data
250 * SInt *rec_curr reconstructed Vop data area
252 * Arguments out :
253 * Int fblock[][8] the prediction block to be coded for bitstream
255 ***********************************************************CommentEnd********/
256 Void
257 BlockPredict (SInt *curr, /*SInt *rec_curr,*/ Int x_pos, Int y_pos,
258 UInt width, Int fblock[][8])
260 Int i, j;
262 for (i = 0; i < 8; i++)
264 for (j = 0; j < 8; j++)
266 fblock[i][j] = curr[(y_pos+i)*width + x_pos+j];
272 /***********************************************************CommentBegin******
274 * -- BlockRebuild -- Reconstructs a block into data area of Vop
276 * Purpose :
277 * Reconstructs a block into data area of Vop
279 * Arguments in :
280 * Int x_pos x_position of Macroblock
281 * Int y_pos y_position of Macroblock
282 * UInt width width of Vop bounding box
284 * Arguments in/out :
285 * SInt *rec_curr current Vop data area to be reconstructed
287 * Description :
288 * Does reconstruction for Intra predicted blocks also
290 ***********************************************************CommentEnd********/
292 Void
293 BlockRebuild (SInt *rec_curr, SInt *comp, Int pred_type, Int max,
294 Int x_pos, Int y_pos, UInt width, UInt edge, Int fblock[][8])
296 /* this function now does rebuild and generating error at the same time */
297 Int i, j;
298 SInt *rec;
299 Int padded_width;
301 padded_width = width + 2 * edge;
302 rec = rec_curr + edge * padded_width + edge;
304 if (pred_type == I_VOP)
306 SInt *p;
307 p = rec + y_pos * padded_width + x_pos;
309 for (i = 0; i < 8; i++)
311 for (j = 0; j < 8; j++)
313 SInt temp = fblock[i][j];
314 *(p++) = CLIP(temp, 0, max);
317 p += padded_width - 8;
320 else if (pred_type == P_VOP)
322 SInt *p, *pc;
323 p = rec + y_pos * padded_width + x_pos;
324 pc = comp + y_pos * width + x_pos;
326 for (i = 0; i < 8; i++)
328 for (j = 0; j < 8; j++)
330 SInt temp = *(pc++) + fblock[i][j];
331 *(p++) = CLIP(temp, 0, max);
334 p += padded_width - 8;
335 pc += width - 8;
342 /***********************************************************CommentBegin******
344 * -- BlockQuantH263 -- 8x8 block level quantization
346 * Purpose :
347 * 8x8 block level quantization
349 * Arguments in :
350 * Int *coeff non-quantized coefficients
351 * Int QP quantization parameter
352 * Int Mode Macroblock coding mode
354 * Arguments out :
355 * Int *qcoeff quantized coefficients
357 ***********************************************************CommentEnd********/
358 Void
359 BlockQuantH263 (Int *coeff,
360 Int QP,
361 Int mode,
362 Int type,
363 Int *qcoeff,
364 Int maxDC,
365 Int image_type)
367 Int i;
368 Int level, result;
369 Int step, offset;
370 Int dc_scaler;
378 //if(QP != 5) printf("BlockQuantH263 %d\n", QP);
379 if (!(QP > 0 && (QP < 32*image_type))) return;
380 if (!(type == 1 || type == 2)) return;
382 if (mode == MODE_INTRA || mode == MODE_INTRA_Q)
383 { /* Intra */
384 dc_scaler = cal_dc_scaler(QP,type);
385 qcoeff[0] = MAX(1,MIN(maxDC-1, (coeff[0] + dc_scaler/2)/dc_scaler));
387 step = 2 * QP;
388 for (i = 1; i < 64; i++)
390 level = (abs(coeff[i])) / step;
391 result = (coeff[i] >= 0) ? level : -level;
392 qcoeff[i] = MIN(2047, MAX(-2048, result));
395 else
396 { /* non Intra */
397 step = 2 * QP;
398 offset = QP / 2;
399 for (i = 0; i < 64; i++)
401 level = (abs(coeff[i]) - offset) / step;
402 result = (coeff[i] >= 0) ? level : -level;
403 qcoeff[i] = MIN(2047, MAX(-2048, result));
407 return;
411 /***********************************************************CommentBegin******
413 * -- BlockDequantH263 -- 8x8 block dequantization
415 * Purpose :
416 * 8x8 block dequantization
418 * Arguments in :
419 * Int *qcoeff quantized coefficients
420 * Int QP quantization parameter
421 * Int mode Macroblock coding mode
422 * Int short_video_header Flag to signal short video header bitstreams (H.263)
424 * Arguments out :
425 * Int *rcoeff reconstructed (dequantized) coefficients
427 ***********************************************************CommentEnd********/
428 Void
429 BlockDequantH263 (Int *qcoeff, Int QP, Int mode, Int type, Int *rcoeff,
430 Int image_type, Int short_video_header, Int bits_per_pixel)
432 Int i;
433 Int dc_scaler;
434 Int lim;
436 lim = (1 << (bits_per_pixel + 3));
438 if (QP)
440 for (i = 0; i < 64; i++)
442 if (qcoeff[i])
444 /* 16.11.98 Sven Brandau: "correct saturation" due to N2470, Clause 2.1.6 */
445 qcoeff[i] = MIN(2047, MAX(-2048, qcoeff[i] ));
446 if ((QP % 2) == 1)
447 rcoeff[i] = QP * (2*ABS(qcoeff[i]) + 1);
448 else
449 rcoeff[i] = QP * (2*ABS(qcoeff[i]) + 1) - 1;
450 rcoeff[i] = SIGN(qcoeff[i]) * rcoeff[i];
452 else
453 rcoeff[i] = 0;
455 if (mode == MODE_INTRA || mode == MODE_INTRA_Q)
456 { /* Intra */
458 MOMCHECK(QP > 0 && (QP < 32*image_type));
459 MOMCHECK(type == 1 || type == 2);
461 if (short_video_header)
462 dc_scaler = 8;
463 else
464 dc_scaler = cal_dc_scaler(QP,type);
466 rcoeff[0] = qcoeff[0] * dc_scaler;
469 else
471 /* No quantizing at all */
472 for (i = 0; i < 64; i++)
474 rcoeff[i] = qcoeff[i];
477 if (mode == MODE_INTRA || mode == MODE_INTRA_Q)
478 { /* Intra */
479 rcoeff[0] = qcoeff[0]*8;
482 for (i=0;i<64;i++)
483 if (rcoeff[i]>(lim-1)) rcoeff[i]=(lim-1);
484 else if (rcoeff[i]<(-lim)) rcoeff[i]=(-lim);
486 return;