⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 postdct.c

📁 linux下将各类格式图片转换工具
💻 C
字号:
/*===========================================================================* * postdct.c								     * *									     * *	Procedures concerned with MPEG post-DCT processing:		     * *	    quantization and RLE Huffman encoding			     * *									     * * EXPORTED PROCEDURES:							     * *	Mpost_QuantZigBlock						     * *	Mpost_RLEHuffIBlock						     * *	Mpost_RLEHuffPBlock						     * *	Mpost_UnQuantZigBlock						     * *									     * *===========================================================================*//* * Copyright (c) 1995 The Regents of the University of California. * All rights reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose, without fee, and without written agreement is * hereby granted, provided that the above copyright notice and the following * two paragraphs appear in all copies of this software. * * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. *//* *  $Header: /n/picasso/project/mm/mpeg/mpeg_dist/mpeg_encode/RCS/postdct.c,v 1.12 1995/06/21 18:26:39 smoot Exp $ *  $Log: postdct.c,v $ * Revision 1.12  1995/06/21  18:26:39  smoot * added length estimator for P-blocks * * Revision 1.11  1995/04/23  23:22:59  eyhung * nothing changed * * Revision 1.10  1995/04/14  23:10:46  smoot * Added overflow detection to MPOST_DCT so it will adjust Qscales (above) * * Revision 1.9  1995/02/15  23:15:32  smoot * killed useless asserts * * Revision 1.8  1995/02/01  21:48:41  smoot * assure out is set properly, short circuit 0 revquant * * Revision 1.7  1995/01/30  19:56:37  smoot * Killed a <0 shift * * Revision 1.6  1995/01/25  23:07:33  smoot * Better DBG_PRINTs, multiply/divide instead of shifts * * Revision 1.5  1995/01/19  23:09:10  eyhung * Changed copyrights * * Revision 1.4  1995/01/16  08:17:08  eyhung * added realQuiet * * Revision 1.3  1994/11/12  02:11:58  keving * nothing * * Revision 1.2  1994/03/15  00:27:11  keving * nothing * * Revision 1.2  1994/03/15  00:27:11  keving * nothing * * Revision 1.1  1993/12/22  19:19:01  keving * nothing * * Revision 1.11  1993/07/22  22:23:43  keving * nothing * * Revision 1.10  1993/06/30  20:06:09  keving * nothing * * Revision 1.9  1993/06/03  21:08:08  keving * nothing * * Revision 1.8  1993/02/24  18:57:19  keving * nothing * * Revision 1.7  1993/02/23  22:58:36  keving * nothing * * Revision 1.6  1993/02/23  22:54:56  keving * nothing * * Revision 1.5  1993/02/17  23:18:20  dwallach * checkin prior to keving's joining the project * * Revision 1.4  1993/01/18  10:20:02  dwallach * *** empty log message *** * * Revision 1.3  1993/01/18  10:17:29  dwallach * RCS headers installed, code indented uniformly * * Revision 1.3  1993/01/18  10:17:29  dwallach * RCS headers installed, code indented uniformly * *//*==============* * HEADER FILES * *==============*/#include <assert.h>#include "all.h"#include "mtypes.h"#include "bitio.h"#include "huff.h"#include "postdct.h"#include "opts.h"/*==================* * STATIC VARIABLES * *==================*//* ZAG[i] is the natural-order position of the i'th element of zigzag order. */int ZAG[] = {    0, 1, 8, 16, 9, 2, 3, 10,    17, 24, 32, 25, 18, 11, 4, 5,    12, 19, 26, 33, 40, 48, 41, 34,    27, 20, 13, 6, 7, 14, 21, 28,    35, 42, 49, 56, 57, 50, 43, 36,    29, 22, 15, 23, 30, 37, 44, 51,    58, 59, 52, 45, 38, 31, 39, 46,    53, 60, 61, 54, 47, 55, 62, 63};/* * possible optimization: reorder the qtable in the correct zigzag order, to * reduce the number of necessary lookups * * this table comes from the MPEG draft, p. D-16, Fig. 2-D.15. */int32 qtable[] = {    8, 16, 19, 22, 26, 27, 29, 34,    16, 16, 22, 24, 27, 29, 34, 37,    19, 22, 26, 27, 29, 34, 34, 38,    22, 22, 26, 27, 29, 34, 37, 40,    22, 26, 27, 29, 32, 35, 40, 48,    26, 27, 29, 32, 35, 40, 48, 58,    26, 27, 29, 34, 38, 46, 56, 69,    27, 29, 35, 38, 46, 56, 69, 83};int32 niqtable[] = {     16, 16, 16, 16, 16, 16, 16, 16,     16, 16, 16, 16, 16, 16, 16, 16,     16, 16, 16, 16, 16, 16, 16, 16,     16, 16, 16, 16, 16, 16, 16, 16,     16, 16, 16, 16, 16, 16, 16, 16,     16, 16, 16, 16, 16, 16, 16, 16,     16, 16, 16, 16, 16, 16, 16, 16,     16, 16, 16, 16, 16, 16, 16, 16};int32	*customQtable = NULL;int32	*customNIQtable = NULL;/*==================* * GLOBAL VARIABLES * *==================*/extern boolean realQuiet;/*=====================* * EXPORTED PROCEDURES * *=====================*//*===========================================================================* * * Mpost_UnQuantZigBlock * *	unquantize and zig-zag (decode) a single block *	see section 2.4.4.1 of MPEG standard * * RETURNS:	nothing * * SIDE EFFECTS:    none * *===========================================================================*/voidMpost_UnQuantZigBlock(in, out, qscale, iblock)    FlatBlock in;    Block out;    int qscale;    boolean iblock;{    register int index;    int	    start;    int	    position;    register int	    qentry;    int	    level, coeff;        if ( iblock ) {	/* qtable[0] must be 8 */	out[0][0] = (int16)(in[0] * 8);	/* don't need to do anything fancy here, because we saved orig	    value, not encoded dc value */	start = 1;    } else {	start = 0;    }    for ( index = start;  index < DCTSIZE_SQ;  index++ ) {	position = ZAG[index];	level = in[index];	if (level == 0) {	  ((int16 *)out)[position] = 0;	  continue;	}	if ( iblock ) {	    qentry = qtable[position] * qscale;	    coeff = (level*qentry)/8;	    if ( (coeff & 1) == 0 ) {		if ( coeff < 0 ) {		    coeff++;		} else if ( coeff > 0 ) {		    coeff--;		}	    }	} else {	    qentry = niqtable[position] * qscale;	    if ( level == 0 ) {		coeff = 0;	    } else if ( level < 0 ) {		coeff = (((2*level)-1)*qentry) / 16;		if ( (coeff & 1) == 0 ) {		    coeff++;		}	    } else {		coeff = (((2*level)+1)*qentry) >> 4;		if ( (coeff & 1) == 0 ) {		    coeff--;		}	    }	    if ( coeff > 2047 ) {		coeff = 2047;	    } else if ( coeff < -2048 ) {		coeff = -2048;	    }        }	((int16 *)out)[position] = coeff;    }}/*===========================================================================* * * Mpost_QuantZigBlock * *	quantize and zigzags a block * * RETURNS:	MPOST_OVERFLOW if a generated value is outside |255| *              MPOST_ZERO     if all coeffs are zero *              MPOST_NON_ZERO otherwisw * * SIDE EFFECTS:    none * *===========================================================================*/intMpost_QuantZigBlock(in, out, qscale, iblock)    Block in;    FlatBlock out;    register int qscale;    int iblock;{  register int i;  register int16 temp;  register int qentry;  register int position;  boolean nonZero = FALSE;  boolean overflow = FALSE;    DBG_PRINT(("Mpost_QuantZigBlock...\n"));  if (iblock) {    /*     * the DC coefficient is handled specially -- it's not     * sensitive to qscale, but everything else is     */    temp = ((int16 *) in)[ZAG[0]];    qentry = qtable[ZAG[0]];        if (temp < 0) {      temp = -temp;      temp += (qentry >> 1);      temp /= qentry;      temp = -temp;    } else {      temp += (qentry >> 1);      temp /= qentry;    }    if ( temp != 0 ) {      nonZero = TRUE;    }    out[0] = temp;        for (i = 1; i < DCTSIZE_SQ; i++) {      position = ZAG[i];      temp = ((int16 *) in)[position];      qentry = qtable[position] * qscale;            /* see 1993 MPEG doc, section D.6.3.4 */      if (temp < 0) {	temp = -temp;	temp = (temp << 3);	/* temp > 0 */	temp += (qentry >> 1);	temp /= qentry;	temp = -temp;      } else {	temp = (temp << 3);	/* temp > 0 */	temp += (qentry >> 1);	temp /= qentry;      }            if ( temp != 0 ) {	nonZero = TRUE;	out[i] = temp;	if (temp < -255) {	  temp = -255;	  overflow = TRUE;	} else if (temp > 255) {	  temp = 255;	  overflow = TRUE;	}      } else out[i]=0;    }  } else {    for (i = 0; i < DCTSIZE_SQ; i++) {      position = ZAG[i];      temp = ((int16 *) in)[position];            /* multiply by non-intra qtable */      qentry = qscale * niqtable[position];            /* see 1993 MPEG doc, D.6.4.5 */      temp *= 8;      temp /= qentry;	    /* truncation toward 0 -- correct */            if ( temp != 0 ) {	nonZero = TRUE;	out[i] = temp;	if (temp < -255) {	  temp = -255;	  overflow = TRUE;	} else if (temp > 255) {	  temp = 255;	  overflow = TRUE;	}	      } else out[i]=0;    }  } if (overflow) return MPOST_OVERFLOW; if (nonZero)  return MPOST_NON_ZERO; return MPOST_ZERO;}/*===========================================================================* * * Mpost_RLEHuffIBlock * *	generate the huffman bits from an I-block * * RETURNS:	nothing * * SIDE EFFECTS:    none * *===========================================================================*/voidMpost_RLEHuffIBlock(in, out)    FlatBlock in;    BitBucket *out;{    register int i;    register int nzeros = 0;    register int16 cur;    register int16 acur;    register uint32 code;    register int nbits;    /*     * yes, Virginia, we start at 1.  The DC coefficient is handled     * specially, elsewhere.  Not here.     */    for (i = 1; i < DCTSIZE_SQ; i++) {	cur = in[i];	acur = ABS(cur);	if (cur) {	    if ( (nzeros < HUFF_MAXRUN) && (acur < huff_maxlevel[nzeros])) {	        /*		 * encode using the Huffman tables		 */		DBG_PRINT(("rle_huff %02d.%02d: Run %02d, Level %4d\n", i,  ZAG[i], nzeros, cur));		code = (huff_table[nzeros])[acur];		nbits = (huff_bits[nzeros])[acur];		if (cur < 0) {		    code |= 1;	/* the sign bit */		}		Bitio_Write(out, code, nbits);	    } else {		/*		 * encode using the escape code		 */		DBG_PRINT(("Escape\n"));		Bitio_Write(out, 0x1, 6);	/* ESCAPE */		DBG_PRINT(("Run Length\n"));		Bitio_Write(out, nzeros, 6);	/* Run-Length */		/*	         * this shouldn't happen, but the other	         * choice is to bomb out and dump core...		 * Hmmm, seems to happen with small Qtable entries (1) -srs	         */		if (cur < -255) {		    cur = -255;		} else if (cur > 255) {		    cur = 255;		}		DBG_PRINT(("Level\n"));		if (acur < 128) {		    Bitio_Write(out, cur, 8);		} else {		    if (cur < 0) {			Bitio_Write(out, 0x8001 + cur + 255, 16);		    } else {			Bitio_Write(out, cur, 16);		    }		}	    }	    nzeros = 0;	} else {	    nzeros++;	}    }    DBG_PRINT(("End of block\n"));    Bitio_Write(out, 0x2, 2);	/* end of block marker */}/*===========================================================================* * * Mpost_RLEHuffPBlock * *	generate the huffman bits from an P-block * * RETURNS:	nothing * * SIDE EFFECTS:    none * *===========================================================================*/voidMpost_RLEHuffPBlock(in, out)    FlatBlock in;    BitBucket *out;{    register int i;    register int nzeros = 0;    register int16 cur;    register int16 acur;    register uint32 code;    register int nbits;    boolean first_dct = TRUE;    /*     * yes, Virginia, we start at 0.     */    for (i = 0; i < DCTSIZE_SQ; i++) {	cur = in[i];	acur = ABS(cur);	if (cur) {	    if ((nzeros < HUFF_MAXRUN) && (acur < huff_maxlevel[nzeros])) {	        /*		 * encode using the Huffman tables		 */		DBG_PRINT(("rle_huff %02d.%02d: Run %02d, Level %4d\n", i, ZAG[i], nzeros, cur));		if ( first_dct && (nzeros == 0) && (acur == 1) ) {		    /* actually, only needs = 0x2 */		    code = (cur == 1) ? 0x2 : 0x3;		    nbits = 2;		} else {		    code = (huff_table[nzeros])[acur];		    nbits = (huff_bits[nzeros])[acur];		  }		assert(nbits);		if (cur < 0) {		    code |= 1;	/* the sign bit */		}		Bitio_Write(out, code, nbits);		first_dct = FALSE;	    } else {		/*		 * encode using the escape code		 */		DBG_PRINT(("Escape\n"));		Bitio_Write(out, 0x1, 6);	/* ESCAPE */		DBG_PRINT(("Run Length\n"));		Bitio_Write(out, nzeros, 6);	/* Run-Length */		/*	         * this shouldn't happen, but the other	         * choice is to bomb out and dump core...		 * Hmmm, seems to happen with small Qtable entries (1) -srs	         */		if (cur < -255) {		  cur = -255;		} else if (cur > 255) {		  cur = 255;		}		DBG_PRINT(("Level\n"));		if (acur < 128) {		    Bitio_Write(out, cur, 8);		} else {		    if (cur < 0) {			Bitio_Write(out, 0x8001 + cur + 255, 16);		    } else {			Bitio_Write(out, cur, 16);		    }		}		first_dct = FALSE;	    }	    nzeros = 0;	} else {	    nzeros++;	}    }    /* actually, should REALLY return FALSE and not use this! */    if ( first_dct ) {	/* have to give a first_dct even if all 0's */	fprintf(stderr, "HUFF called with all-zero coefficients\n");	fprintf(stderr, "exiting...\n");	exit(1);    }    DBG_PRINT(("End of block\n"));    Bitio_Write(out, 0x2, 2);	/* end of block marker */}/*===========================================================================* * * CalcRLEHuffLength * *	count the huffman bits for an P-block * * RETURNS:	number of bits * * SIDE EFFECTS:    none * *===========================================================================*/intCalcRLEHuffLength(in)    FlatBlock in;{  register int i;  register int nzeros = 0;  register int16 cur;  register int16 acur;  register int nbits;  register int countbits=0;  boolean first_dct = TRUE;    for (i = 0; i < DCTSIZE_SQ; i++) {    cur = in[i];    acur = ABS(cur);    if (cur) {      if ((nzeros < HUFF_MAXRUN) && (acur < huff_maxlevel[nzeros])) {	/*	 * encode using the Huffman tables	 */	if ( first_dct && (nzeros == 0) && (acur == 1) ) {	  nbits = 2;	} else {	  nbits = (huff_bits[nzeros])[acur];	}	countbits += nbits;	first_dct = FALSE;      } else {	countbits += 12;	/* ESCAPE + runlength */	if (acur < 128) {	  countbits += 8;	} else {	  countbits += 16;	}	first_dct = FALSE;      }      nzeros = 0;    } else {      nzeros++;    }  }    countbits += 2; /* end of block marker */  return countbits;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -