ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/freemol/trunk/src/mpeg_encode/src/moutput.c
Revision: 22
Committed: Mon Jul 7 22:16:37 2008 UTC (11 years ago) by wdelano
File size: 10284 byte(s)
Log Message:
initial checkin of mpeg_encode source
Line File contents
1 /*===========================================================================*
2 * moutput.c *
3 * *
4 * Procedures concerned with quantization and RLE *
5 * *
6 * EXPORTED PROCEDURES: *
7 * mp_quant_zig_block *
8 * mp_rle_huff_block *
9 * mp_rle_huff_pblock *
10 * *
11 *===========================================================================*/
12
13 /*
14 * Copyright (c) 1995 The Regents of the University of California.
15 * All rights reserved.
16 *
17 * Permission to use, copy, modify, and distribute this software and its
18 * documentation for any purpose, without fee, and without written agreement is
19 * hereby granted, provided that the above copyright notice and the following
20 * two paragraphs appear in all copies of this software.
21 *
22 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
23 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
24 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
25 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
28 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
29 * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
30 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
31 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
32 */
33
34 /*
35 * $Header: /n/charlie-brown/project/mm/mpeg/mpeg_dist/mpeg_encode/RCS/moutput.c,v 1.12 1995/01/19 23:08:49 eyhung Exp $
36 * $Log: moutput.c,v $
37 * Revision 1.12 1995/01/19 23:08:49 eyhung
38 * Changed copyrights
39 *
40 * Revision 1.11 1993/07/22 22:23:43 keving
41 * nothing
42 *
43 * Revision 1.10 1993/06/30 20:06:09 keving
44 * nothing
45 *
46 * Revision 1.9 1993/06/03 21:08:08 keving
47 * nothing
48 *
49 * Revision 1.8 1993/02/24 18:57:19 keving
50 * nothing
51 *
52 * Revision 1.7 1993/02/23 22:58:36 keving
53 * nothing
54 *
55 * Revision 1.6 1993/02/23 22:54:56 keving
56 * nothing
57 *
58 * Revision 1.5 1993/02/17 23:18:20 dwallach
59 * checkin prior to keving's joining the project
60 *
61 * Revision 1.4 1993/01/18 10:20:02 dwallach
62 * *** empty log message ***
63 *
64 * Revision 1.3 1993/01/18 10:17:29 dwallach
65 * RCS headers installed, code indented uniformly
66 *
67 * Revision 1.3 1993/01/18 10:17:29 dwallach
68 * RCS headers installed, code indented uniformly
69 *
70 */
71
72
73 /*==============*
74 * HEADER FILES *
75 *==============*/
76
77 #include "all.h"
78 #include "mtypes.h"
79 #include "mproto.h"
80 #include "huff.h"
81
82
83 /*==================*
84 * STATIC VARIABLES *
85 *==================*/
86
87 /* ZAG[i] is the natural-order position of the i'th element of zigzag order. */
88 static int ZAG[] =
89 {
90 0, 1, 8, 16, 9, 2, 3, 10,
91 17, 24, 32, 25, 18, 11, 4, 5,
92 12, 19, 26, 33, 40, 48, 41, 34,
93 27, 20, 13, 6, 7, 14, 21, 28,
94 35, 42, 49, 56, 57, 50, 43, 36,
95 29, 22, 15, 23, 30, 37, 44, 51,
96 58, 59, 52, 45, 38, 31, 39, 46,
97 53, 60, 61, 54, 47, 55, 62, 63
98 };
99
100
101 /*
102 * possible optimization: reorder the qtable in the correct zigzag order, to
103 * reduce the number of necessary lookups
104 *
105 * this table comes from the MPEG draft, p. D-16, Fig. 2-D.15.
106 */
107 static int qtable[] =
108 {
109 8, 16, 19, 22, 26, 27, 29, 34,
110 16, 16, 22, 24, 27, 29, 34, 37,
111 19, 22, 26, 27, 29, 34, 34, 38,
112 22, 22, 26, 27, 29, 34, 37, 40,
113 22, 26, 27, 29, 32, 35, 40, 48,
114 26, 27, 29, 32, 35, 40, 48, 58,
115 26, 27, 29, 34, 38, 46, 56, 69,
116 27, 29, 35, 38, 46, 56, 69, 83};
117
118
119 /*=====================*
120 * EXPORTED PROCEDURES *
121 *=====================*/
122
123
124 void UnQuantZig(FlatBlock in, Block out, int qscale, boolean iblock)
125 {
126 register int index;
127 int start;
128 int position;
129 register int qentry;
130 int level, coeff;
131 register int16 temp;
132
133 if ( iblock )
134 {
135 ((int16 *)out)[0] = (int16)(in[0]*qtable[0]);
136
137 start = 1;
138 }
139 else
140 start = 0;
141
142 for ( index = start; index < DCTSIZE_SQ; index++ )
143 {
144 position = ZAG[index];
145
146 if (iblock)
147 qentry = qtable[position] * qscale;
148 else
149 qentry = 16 * qscale;
150
151 level = in[index];
152 coeff = (level * qentry) >> 3;
153 if (level < 0) {
154 coeff += (coeff & 1);
155 } else {
156 coeff -= (coeff & 1);
157 }
158
159 ((int16 *)out)[position] = coeff;
160 }
161
162 #ifdef BLEAH
163 for ( index = 0; index < 64; index++ )
164 fprintf(stdout, "DCT[%d] = %d\n", index,
165 ((int16 *)out)[index]);
166 #endif
167 }
168
169
170 /*
171 * --------------------------------------------------------------
172 *
173 * mp_quant_zig_block --
174 *
175 * Quantizes and zigzags a block -- removing information
176 *
177 * Results: TRUE iff resulting 'out' is non-zero, FALSE if all
178 * zero
179 *
180 * Side effects: Modifies the out block.
181 *
182 * --------------------------------------------------------------
183 */
184 boolean mp_quant_zig_block(Block in, FlatBlock out, int qscale, int iblock)
185 {
186 register int i;
187 register int y, x;
188 register int16 temp;
189 register int qentry;
190 int start;
191 boolean nonZero = FALSE;
192
193 DBG_PRINT(("mp_quant_zig_block...\n"));
194 if (iblock) {
195 /*
196 * the DC coefficient is handled specially -- it's not
197 * sensitive to qscale, but everything else is
198 */
199 temp = ((int16 *) in)[ZAG[0]];
200 qentry = qtable[ZAG[0]];
201 if (temp < 0) {
202 temp = -temp;
203 temp += qentry >> 1;
204 temp /= qentry;
205 temp = -temp;
206 } else {
207 temp += qentry >> 1;
208 temp /= qentry;
209 }
210 if ( temp != 0 )
211 nonZero = TRUE;
212 out[0] = temp;
213 start = 1;
214 } else
215 start = 0;
216
217 for (i = start; i < DCTSIZE_SQ; i++) {
218 x = ZAG[i] % 8;
219 y = ZAG[i] / 8;
220 temp = in[y][x];
221 DBG_PRINT((" in[%d][%d] = %d; ", y, x, temp));
222
223 if (iblock)
224 qentry = qtable[ZAG[i]] * qscale;
225 else
226 qentry = 16 * qscale;
227
228 DBG_PRINT(("quantized with %d = ", qentry));
229
230 if (temp < 0) {
231 temp = -temp;
232 temp *= 8;
233 temp += qentry >> 1;
234 temp /= qentry;
235 temp = -temp;
236 } else {
237 temp *= 8;
238 temp += qentry >> 1;
239 temp /= qentry;
240 }
241 if ( temp != 0 )
242 nonZero = TRUE;
243 out[i] = temp;
244 DBG_PRINT(("%d\n", temp));
245 }
246
247 return nonZero;
248 }
249
250
251
252 /*
253 * --------------------------------------------------------------
254 *
255 * mp_rle_huff_block --
256 *
257 * Given a FlatBlock, generates the Huffman bits
258 *
259 * Results: None.
260 *
261 * Side effects: Output bits changed
262 *
263 * --------------------------------------------------------------
264 */
265
266 void mp_rle_huff_block(FlatBlock in, BitBucket *out)
267 {
268 register int i;
269 register int nzeros = 0;
270 register int16 cur;
271 register int16 acur;
272 register uint32 code;
273 register int nbits;
274
275 /*
276 * yes, Virginia, we start at 1. The DC coefficient is handled
277 * specially, elsewhere. Not here.
278 */
279 for (i = 1; i < DCTSIZE_SQ; i++) {
280 cur = in[i];
281 acur = ABS(cur);
282 if (cur) {
283 if (nzeros < HUFF_MAXRUN && acur < huff_maxlevel[nzeros]) {
284 /*
285 * encode using the Huffman tables
286 */
287
288 DBG_PRINT(("rle_huff %02d: Run %02d, Level %02d\n", i, nzeros, cur));
289 assert(cur);
290
291 code = (huff_table[nzeros])[acur];
292 nbits = (huff_bits[nzeros])[acur];
293
294 assert(nbits);
295
296 if (cur < 0)
297 code |= 1; /* the sign bit */
298 Bitio_Write(out, code, nbits);
299 } else {
300 /*
301 * encode using the escape code
302 */
303 DBG_PRINT(("Escape\n"));
304 Bitio_Write(out, 0x1, 6); /* ESCAPE */
305 DBG_PRINT(("Run Length\n"));
306 Bitio_Write(out, nzeros, 6); /* Run-Length */
307
308 assert(cur != 0);
309
310 /*
311 * this shouldn't happen, but the other
312 * choice is to bomb out and dump core...
313 */
314 if (cur < -255)
315 cur = -255;
316 else if (cur > 255)
317 cur = 255;
318
319 DBG_PRINT(("Level\n"));
320 if (acur < 128) {
321 Bitio_Write(out, cur, 8);
322 } else {
323 if (cur < 0) {
324 Bitio_Write(out, 0x8001 + cur + 255, 16);
325 } else
326 Bitio_Write(out, cur, 16);
327 }
328 }
329 nzeros = 0;
330 } else
331 nzeros++;
332 }
333 DBG_PRINT(("End of block\n"));
334 Bitio_Write(out, 0x2, 2); /* end of block marker */
335 }
336
337
338 /*
339 * --------------------------------------------------------------
340 *
341 * mp_rle_huff_pblock --
342 *
343 * Given a FlatBlock, generates the Huffman bits for P DCT
344 *
345 * Results: None.
346 *
347 * Side effects: Output bits changed
348 *
349 * --------------------------------------------------------------
350 */
351
352 void mp_rle_huff_pblock(FlatBlock in, BitBucket *out)
353 {
354 register int i;
355 register int nzeros = 0;
356 register int16 cur;
357 register int16 acur;
358 register uint32 code;
359 register int nbits;
360 boolean first_dct = TRUE;
361
362 /*
363 * yes, Virginia, we start at 0.
364 */
365 for (i = 0; i < DCTSIZE_SQ; i++) {
366 cur = in[i];
367 acur = ABS(cur);
368 if (cur) {
369 if (nzeros < HUFF_MAXRUN && acur < huff_maxlevel[nzeros]) {
370 /*
371 * encode using the Huffman tables
372 */
373
374 DBG_PRINT(("rle_huff %02d: Run %02d, Level %02d\n", i, nzeros, cur));
375 assert(cur);
376
377 if ( first_dct && (nzeros == 0) && (acur == 1) )
378 {
379 /* actually, only needs = 0x2 */
380 code = (cur == 1) ? 0x2 : 0x3;
381 nbits = 2;
382 }
383 else
384 {
385 code = (huff_table[nzeros])[acur];
386 nbits = (huff_bits[nzeros])[acur];
387 }
388
389 assert(nbits);
390
391 if (cur < 0)
392 code |= 1; /* the sign bit */
393 Bitio_Write(out, code, nbits);
394 first_dct = FALSE;
395 } else {
396 /*
397 * encode using the escape code
398 */
399 DBG_PRINT(("Escape\n"));
400 Bitio_Write(out, 0x1, 6); /* ESCAPE */
401 DBG_PRINT(("Run Length\n"));
402 Bitio_Write(out, nzeros, 6); /* Run-Length */
403
404 assert(cur != 0);
405
406 /*
407 * this shouldn't happen, but the other
408 * choice is to bomb out and dump core...
409 */
410 if (cur < -255)
411 cur = -255;
412 else if (cur > 255)
413 cur = 255;
414
415 DBG_PRINT(("Level\n"));
416 if (acur < 128) {
417 Bitio_Write(out, cur, 8);
418 } else {
419 if (cur < 0) {
420 Bitio_Write(out, 0x8001 + cur + 255, 16);
421 } else
422 Bitio_Write(out, cur, 16);
423 }
424
425 first_dct = FALSE;
426 }
427 nzeros = 0;
428 } else
429 nzeros++;
430 }
431
432 /* actually, should REALLY return FALSE and not use this! */
433 if ( first_dct ) /* have to give a first_dct even if all 0's */
434 {
435 fprintf(stdout, "HUFF called with all-zero coefficients\n");
436 fprintf(stdout, "exiting...\n");
437 exit(1);
438 }
439
440 DBG_PRINT(("End of block\n"));
441 Bitio_Write(out, 0x2, 2); /* end of block marker */
442 }