w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

postdct.c
Go to the documentation of this file.
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  */
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 
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 
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
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  }
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
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  }
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
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 }
int level
Definition: afm2pl.c:1694
int code
Definition: aftopl.c:52
static point_t cur
Definition: backend_eps.c:108
#define DCTSIZE_SQ
Definition: dct.h:39
@ FALSE
Definition: dd.h:101
@ TRUE
Definition: dd.h:102
char * temp
Definition: dvidvi.c:137
FILE * out
Definition: hbf2gf.c:286
#define HUFF_MAXRUN
Definition: huff.h:29
int * huff_bits[]
Definition: huff.c:131
uint32 * huff_table[]
Definition: huff.c:130
int huff_maxlevel[]
Definition: huff.c:32
assert(pcxLoadImage24((char *)((void *) 0), fp, pinfo, hdr))
register bit_buf_type register int int nbits
Definition: jdhuff.h:156
#define ABS(a)
Definition: tttypes.h:126
#define NULL
Definition: ftobjs.h:61
small capitals from c petite p scientific i
Definition: afcover.h:80
void exit()
#define fprintf
Definition: mendex.h:64
void overflow(const char *)
Definition: cwebboot.c:1385
short int16
Definition: tiff.h:61
unsigned long uint32
Definition: tiff.h:68
long int32
Definition: tiff.h:67
#define int16
Definition: unibasics.h:52
int16 FlatBlock[64]
Definition: mtypes.h:100
int16 Block[8][8]
Definition: mtypes.h:99
#define DBG_PRINT(x)
Definition: mtypes.h:117
#define index(s, c)
Definition: plain2.h:351
void Mpost_RLEHuffPBlock(FlatBlock in, BitBucket *out)
Definition: postdct.c:475
int CalcRLEHuffLength(FlatBlock in)
Definition: postdct.c:580
boolean realQuiet
Definition: main.c:155
int Mpost_QuantZigBlock(Block in, FlatBlock out, int qscale, int iblock)
Definition: postdct.c:278
void Mpost_RLEHuffIBlock(FlatBlock in, BitBucket *out)
Definition: postdct.c:390
int32 qtable[]
Definition: postdct.c:145
int ZAG[]
Definition: postdct.c:128
void Mpost_UnQuantZigBlock(FlatBlock in, Block out, int qscale, boolean iblock)
Definition: postdct.c:193
int32 niqtable[]
Definition: postdct.c:156
int32 * customQtable
Definition: postdct.c:167
int32 * customNIQtable
Definition: postdct.c:168
#define MPOST_NON_ZERO
Definition: postdct.h:39
#define MPOST_ZERO
Definition: postdct.h:38
#define MPOST_OVERFLOW
Definition: postdct.h:40
void Bitio_Write(BitBucket *bbPtr, uint32 bits, int nbits)
Definition: bitio.c:202
static FILE * in
Definition: squeeze.c:36
Definition: inftrees.h:24
Definition: mendex.h:20
@ start
Definition: preamble.c:52
#define position
Definition: xmlparse.c:605