ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/freemol/trunk/src/mpeg_encode/src/postdct.c
Revision: 22
Committed: Mon Jul 7 22:16:37 2008 UTC (11 years ago) by wdelano
File size: 14804 byte(s)
Log Message:
initial checkin of mpeg_encode source
Line File contents
1 /*===========================================================================*
2 * postdct.c *
3 * *
4 * Procedures concerned with MPEG post-DCT processing: *
5 * quantization and RLE Huffman encoding *
6 * *
7 * EXPORTED PROCEDURES: *
8 * Mpost_QuantZigBlock *
9 * Mpost_RLEHuffIBlock *
10 * Mpost_RLEHuffPBlock *
11 * Mpost_UnQuantZigBlock *
12 * *
13 *===========================================================================*/
14
15 /*
16 * Copyright (c) 1995 The Regents of the University of California.
17 * All rights reserved.
18 *
19 * Permission to use, copy, modify, and distribute this software and its
20 * documentation for any purpose, without fee, and without written agreement is
21 * hereby granted, provided that the above copyright notice and the following
22 * two paragraphs appear in all copies of this software.
23 *
24 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
25 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
26 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
27 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
30 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
31 * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
32 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
33 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
34 */
35
36 /*
37 * $Header: /n/picasso/project/mm/mpeg/mpeg_dist/mpeg_encode/RCS/postdct.c,v 1.12 1995/06/21 18:26:39 smoot Exp $
38 * $Log: postdct.c,v $
39 * Revision 1.12 1995/06/21 18:26:39 smoot
40 * added length estimator for P-blocks
41 *
42 * Revision 1.11 1995/04/23 23:22:59 eyhung
43 * nothing changed
44 *
45 * Revision 1.10 1995/04/14 23:10:46 smoot
46 * Added overflow detection to MPOST_DCT so it will adjust Qscales (above)
47 *
48 * Revision 1.9 1995/02/15 23:15:32 smoot
49 * killed useless asserts
50 *
51 * Revision 1.8 1995/02/01 21:48:41 smoot
52 * assure out is set properly, short circuit 0 revquant
53 *
54 * Revision 1.7 1995/01/30 19:56:37 smoot
55 * Killed a <0 shift
56 *
57 * Revision 1.6 1995/01/25 23:07:33 smoot
58 * Better DBG_PRINTs, multiply/divide instead of shifts
59 *
60 * Revision 1.5 1995/01/19 23:09:10 eyhung
61 * Changed copyrights
62 *
63 * Revision 1.4 1995/01/16 08:17:08 eyhung
64 * added realQuiet
65 *
66 * Revision 1.3 1994/11/12 02:11:58 keving
67 * nothing
68 *
69 * Revision 1.2 1994/03/15 00:27:11 keving
70 * nothing
71 *
72 * Revision 1.2 1994/03/15 00:27:11 keving
73 * nothing
74 *
75 * Revision 1.1 1993/12/22 19:19:01 keving
76 * nothing
77 *
78 * Revision 1.11 1993/07/22 22:23:43 keving
79 * nothing
80 *
81 * Revision 1.10 1993/06/30 20:06:09 keving
82 * nothing
83 *
84 * Revision 1.9 1993/06/03 21:08:08 keving
85 * nothing
86 *
87 * Revision 1.8 1993/02/24 18:57:19 keving
88 * nothing
89 *
90 * Revision 1.7 1993/02/23 22:58:36 keving
91 * nothing
92 *
93 * Revision 1.6 1993/02/23 22:54:56 keving
94 * nothing
95 *
96 * Revision 1.5 1993/02/17 23:18:20 dwallach
97 * checkin prior to keving's joining the project
98 *
99 * Revision 1.4 1993/01/18 10:20:02 dwallach
100 * *** empty log message ***
101 *
102 * Revision 1.3 1993/01/18 10:17:29 dwallach
103 * RCS headers installed, code indented uniformly
104 *
105 * Revision 1.3 1993/01/18 10:17:29 dwallach
106 * RCS headers installed, code indented uniformly
107 *
108 */
109
110
111 /*==============*
112 * HEADER FILES *
113 *==============*/
114
115 #include <assert.h>
116 #include "all.h"
117 #include "mtypes.h"
118 #include "bitio.h"
119 #include "huff.h"
120 #include "postdct.h"
121 #include "opts.h"
122
123 /*==================*
124 * STATIC VARIABLES *
125 *==================*/
126
127 /* ZAG[i] is the natural-order position of the i'th element of zigzag order. */
128 int ZAG[] = {
129 0, 1, 8, 16, 9, 2, 3, 10,
130 17, 24, 32, 25, 18, 11, 4, 5,
131 12, 19, 26, 33, 40, 48, 41, 34,
132 27, 20, 13, 6, 7, 14, 21, 28,
133 35, 42, 49, 56, 57, 50, 43, 36,
134 29, 22, 15, 23, 30, 37, 44, 51,
135 58, 59, 52, 45, 38, 31, 39, 46,
136 53, 60, 61, 54, 47, 55, 62, 63
137 };
138
139 /*
140 * possible optimization: reorder the qtable in the correct zigzag order, to
141 * reduce the number of necessary lookups
142 *
143 * this table comes from the MPEG draft, p. D-16, Fig. 2-D.15.
144 */
145 int32 qtable[] = {
146 8, 16, 19, 22, 26, 27, 29, 34,
147 16, 16, 22, 24, 27, 29, 34, 37,
148 19, 22, 26, 27, 29, 34, 34, 38,
149 22, 22, 26, 27, 29, 34, 37, 40,
150 22, 26, 27, 29, 32, 35, 40, 48,
151 26, 27, 29, 32, 35, 40, 48, 58,
152 26, 27, 29, 34, 38, 46, 56, 69,
153 27, 29, 35, 38, 46, 56, 69, 83
154 };
155
156 int32 niqtable[] = {
157 16, 16, 16, 16, 16, 16, 16, 16,
158 16, 16, 16, 16, 16, 16, 16, 16,
159 16, 16, 16, 16, 16, 16, 16, 16,
160 16, 16, 16, 16, 16, 16, 16, 16,
161 16, 16, 16, 16, 16, 16, 16, 16,
162 16, 16, 16, 16, 16, 16, 16, 16,
163 16, 16, 16, 16, 16, 16, 16, 16,
164 16, 16, 16, 16, 16, 16, 16, 16
165 };
166
167 int32 *customQtable = NULL;
168 int32 *customNIQtable = NULL;
169
170 /*==================*
171 * GLOBAL VARIABLES *
172 *==================*/
173
174 extern boolean realQuiet;
175
176 /*=====================*
177 * EXPORTED PROCEDURES *
178 *=====================*/
179
180 /*===========================================================================*
181 *
182 * Mpost_UnQuantZigBlock
183 *
184 * unquantize and zig-zag (decode) a single block
185 * see section 2.4.4.1 of MPEG standard
186 *
187 * RETURNS: nothing
188 *
189 * SIDE EFFECTS: none
190 *
191 *===========================================================================*/
192 void
193 Mpost_UnQuantZigBlock(in, out, qscale, iblock)
194 FlatBlock in;
195 Block out;
196 int qscale;
197 boolean iblock;
198 {
199 register int index;
200 int start;
201 int position;
202 register int qentry;
203 int level, coeff;
204
205 if ( iblock ) {
206 /* qtable[0] must be 8 */
207 out[0][0] = (int16)(in[0] * 8);
208
209 /* don't need to do anything fancy here, because we saved orig
210 value, not encoded dc value */
211 start = 1;
212 } else {
213 start = 0;
214 }
215
216 for ( index = start; index < DCTSIZE_SQ; index++ ) {
217 position = ZAG[index];
218 level = in[index];
219
220 if (level == 0) {
221 ((int16 *)out)[position] = 0;
222 continue;
223 }
224
225
226 if ( iblock ) {
227 qentry = qtable[position] * qscale;
228 coeff = (level*qentry)/8;
229 if ( (coeff & 1) == 0 ) {
230 if ( coeff < 0 ) {
231 coeff++;
232 } else if ( coeff > 0 ) {
233 coeff--;
234 }
235 }
236 } else {
237 qentry = niqtable[position] * qscale;
238 if ( level == 0 ) {
239 coeff = 0;
240 } else if ( level < 0 ) {
241 coeff = (((2*level)-1)*qentry) / 16;
242 if ( (coeff & 1) == 0 ) {
243 coeff++;
244 }
245 } else {
246 coeff = (((2*level)+1)*qentry) >> 4;
247 if ( (coeff & 1) == 0 ) {
248 coeff--;
249 }
250 }
251
252 if ( coeff > 2047 ) {
253 coeff = 2047;
254 } else if ( coeff < -2048 ) {
255 coeff = -2048;
256 }
257 }
258
259 ((int16 *)out)[position] = coeff;
260 }
261 }
262
263
264 /*===========================================================================*
265 *
266 * Mpost_QuantZigBlock
267 *
268 * quantize and zigzags a block
269 *
270 * RETURNS: MPOST_OVERFLOW if a generated value is outside |255|
271 * MPOST_ZERO if all coeffs are zero
272 * MPOST_NON_ZERO otherwisw
273 *
274 * SIDE EFFECTS: none
275 *
276 *===========================================================================*/
277 int
278 Mpost_QuantZigBlock(in, out, qscale, iblock)
279 Block in;
280 FlatBlock out;
281 register int qscale;
282 int iblock;
283 {
284 register int i;
285 register int16 temp;
286 register int qentry;
287 register int position;
288 boolean nonZero = FALSE;
289 boolean overflow = FALSE;
290
291 DBG_PRINT(("Mpost_QuantZigBlock...\n"));
292 if (iblock) {
293 /*
294 * the DC coefficient is handled specially -- it's not
295 * sensitive to qscale, but everything else is
296 */
297 temp = ((int16 *) in)[ZAG[0]];
298 qentry = qtable[ZAG[0]];
299
300 if (temp < 0) {
301 temp = -temp;
302 temp += (qentry >> 1);
303 temp /= qentry;
304 temp = -temp;
305 } else {
306 temp += (qentry >> 1);
307 temp /= qentry;
308 }
309 if ( temp != 0 ) {
310 nonZero = TRUE;
311 }
312 out[0] = temp;
313
314 for (i = 1; i < DCTSIZE_SQ; i++) {
315 position = ZAG[i];
316 temp = ((int16 *) in)[position];
317 qentry = qtable[position] * qscale;
318
319 /* see 1993 MPEG doc, section D.6.3.4 */
320 if (temp < 0) {
321 temp = -temp;
322 temp = (temp << 3); /* temp > 0 */
323 temp += (qentry >> 1);
324 temp /= qentry;
325 temp = -temp;
326 } else {
327 temp = (temp << 3); /* temp > 0 */
328 temp += (qentry >> 1);
329 temp /= qentry;
330 }
331
332 if ( temp != 0 ) {
333 nonZero = TRUE;
334 out[i] = temp;
335 if (temp < -255) {
336 temp = -255;
337 overflow = TRUE;
338 } else if (temp > 255) {
339 temp = 255;
340 overflow = TRUE;
341 }
342 } else out[i]=0;
343 }
344 } else {
345 for (i = 0; i < DCTSIZE_SQ; i++) {
346 position = ZAG[i];
347 temp = ((int16 *) in)[position];
348
349 /* multiply by non-intra qtable */
350 qentry = qscale * niqtable[position];
351
352 /* see 1993 MPEG doc, D.6.4.5 */
353 temp *= 8;
354 temp /= qentry; /* truncation toward 0 -- correct */
355
356 if ( temp != 0 ) {
357 nonZero = TRUE;
358 out[i] = temp;
359 if (temp < -255) {
360 temp = -255;
361 overflow = TRUE;
362 } else if (temp > 255) {
363 temp = 255;
364 overflow = TRUE;
365 }
366
367 } else out[i]=0;
368 }
369 }
370
371 if (overflow) return MPOST_OVERFLOW;
372 if (nonZero) return MPOST_NON_ZERO;
373 return MPOST_ZERO;
374 }
375
376
377
378 /*===========================================================================*
379 *
380 * Mpost_RLEHuffIBlock
381 *
382 * generate the huffman bits from an I-block
383 *
384 * RETURNS: nothing
385 *
386 * SIDE EFFECTS: none
387 *
388 *===========================================================================*/
389 void
390 Mpost_RLEHuffIBlock(in, out)
391 FlatBlock in;
392 BitBucket *out;
393 {
394 register int i;
395 register int nzeros = 0;
396 register int16 cur;
397 register int16 acur;
398 register uint32 code;
399 register int nbits;
400
401 /*
402 * yes, Virginia, we start at 1. The DC coefficient is handled
403 * specially, elsewhere. Not here.
404 */
405 for (i = 1; i < DCTSIZE_SQ; i++) {
406 cur = in[i];
407 acur = ABS(cur);
408 if (cur) {
409 if ( (nzeros < HUFF_MAXRUN) && (acur < huff_maxlevel[nzeros])) {
410 /*
411 * encode using the Huffman tables
412 */
413
414 DBG_PRINT(("rle_huff %02d.%02d: Run %02d, Level %4d\n", i, ZAG[i], nzeros, cur));
415 code = (huff_table[nzeros])[acur];
416 nbits = (huff_bits[nzeros])[acur];
417
418 if (cur < 0) {
419 code |= 1; /* the sign bit */
420 }
421 Bitio_Write(out, code, nbits);
422 } else {
423 /*
424 * encode using the escape code
425 */
426 DBG_PRINT(("Escape\n"));
427 Bitio_Write(out, 0x1, 6); /* ESCAPE */
428 DBG_PRINT(("Run Length\n"));
429 Bitio_Write(out, nzeros, 6); /* Run-Length */
430
431 /*
432 * this shouldn't happen, but the other
433 * choice is to bomb out and dump core...
434 * Hmmm, seems to happen with small Qtable entries (1) -srs
435 */
436 if (cur < -255) {
437 cur = -255;
438 } else if (cur > 255) {
439 cur = 255;
440 }
441
442 DBG_PRINT(("Level\n"));
443 if (acur < 128) {
444 Bitio_Write(out, cur, 8);
445 } else {
446 if (cur < 0) {
447 Bitio_Write(out, 0x8001 + cur + 255, 16);
448 } else {
449 Bitio_Write(out, cur, 16);
450 }
451 }
452 }
453 nzeros = 0;
454 } else {
455 nzeros++;
456 }
457 }
458 DBG_PRINT(("End of block\n"));
459 Bitio_Write(out, 0x2, 2); /* end of block marker */
460 }
461
462
463 /*===========================================================================*
464 *
465 * Mpost_RLEHuffPBlock
466 *
467 * generate the huffman bits from an P-block
468 *
469 * RETURNS: nothing
470 *
471 * SIDE EFFECTS: none
472 *
473 *===========================================================================*/
474 void
475 Mpost_RLEHuffPBlock(in, out)
476 FlatBlock in;
477 BitBucket *out;
478 {
479 register int i;
480 register int nzeros = 0;
481 register int16 cur;
482 register int16 acur;
483 register uint32 code;
484 register int nbits;
485 boolean first_dct = TRUE;
486
487 /*
488 * yes, Virginia, we start at 0.
489 */
490 for (i = 0; i < DCTSIZE_SQ; i++) {
491 cur = in[i];
492 acur = ABS(cur);
493 if (cur) {
494 if ((nzeros < HUFF_MAXRUN) && (acur < huff_maxlevel[nzeros])) {
495 /*
496 * encode using the Huffman tables
497 */
498
499 DBG_PRINT(("rle_huff %02d.%02d: Run %02d, Level %4d\n", i, ZAG[i], nzeros, cur));
500 if ( first_dct && (nzeros == 0) && (acur == 1) ) {
501 /* actually, only needs = 0x2 */
502 code = (cur == 1) ? 0x2 : 0x3;
503 nbits = 2;
504 } else {
505 code = (huff_table[nzeros])[acur];
506 nbits = (huff_bits[nzeros])[acur];
507 }
508
509 assert(nbits);
510
511 if (cur < 0) {
512 code |= 1; /* the sign bit */
513 }
514 Bitio_Write(out, code, nbits);
515 first_dct = FALSE;
516 } else {
517 /*
518 * encode using the escape code
519 */
520 DBG_PRINT(("Escape\n"));
521 Bitio_Write(out, 0x1, 6); /* ESCAPE */
522 DBG_PRINT(("Run Length\n"));
523 Bitio_Write(out, nzeros, 6); /* Run-Length */
524
525 /*
526 * this shouldn't happen, but the other
527 * choice is to bomb out and dump core...
528 * Hmmm, seems to happen with small Qtable entries (1) -srs
529 */
530 if (cur < -255) {
531 cur = -255;
532 } else if (cur > 255) {
533 cur = 255;
534 }
535
536 DBG_PRINT(("Level\n"));
537 if (acur < 128) {
538 Bitio_Write(out, cur, 8);
539 } else {
540 if (cur < 0) {
541 Bitio_Write(out, 0x8001 + cur + 255, 16);
542 } else {
543 Bitio_Write(out, cur, 16);
544 }
545 }
546
547 first_dct = FALSE;
548 }
549 nzeros = 0;
550 } else {
551 nzeros++;
552 }
553 }
554
555 /* actually, should REALLY return FALSE and not use this! */
556
557 if ( first_dct ) { /* have to give a first_dct even if all 0's */
558 fprintf(stderr, "HUFF called with all-zero coefficients\n");
559 fprintf(stderr, "exiting...\n");
560 exit(1);
561 }
562
563 DBG_PRINT(("End of block\n"));
564 Bitio_Write(out, 0x2, 2); /* end of block marker */
565 }
566
567
568 /*===========================================================================*
569 *
570 * CalcRLEHuffLength
571 *
572 * count the huffman bits for an P-block
573 *
574 * RETURNS: number of bits
575 *
576 * SIDE EFFECTS: none
577 *
578 *===========================================================================*/
579 int
580 CalcRLEHuffLength(in)
581 FlatBlock in;
582 {
583 register int i;
584 register int nzeros = 0;
585 register int16 cur;
586 register int16 acur;
587 register int nbits;
588 register int countbits=0;
589 boolean first_dct = TRUE;
590
591 for (i = 0; i < DCTSIZE_SQ; i++) {
592 cur = in[i];
593 acur = ABS(cur);
594 if (cur) {
595 if ((nzeros < HUFF_MAXRUN) && (acur < huff_maxlevel[nzeros])) {
596 /*
597 * encode using the Huffman tables
598 */
599
600 if ( first_dct && (nzeros == 0) && (acur == 1) ) {
601 nbits = 2;
602 } else {
603 nbits = (huff_bits[nzeros])[acur];
604 }
605 countbits += nbits;
606 first_dct = FALSE;
607 } else {
608 countbits += 12; /* ESCAPE + runlength */
609
610 if (acur < 128) {
611 countbits += 8;
612 } else {
613 countbits += 16;
614 }
615
616 first_dct = FALSE;
617 }
618 nzeros = 0;
619 } else {
620 nzeros++;
621 }
622 }
623
624 countbits += 2; /* end of block marker */
625 return countbits;
626 }