📄 quantize.c
字号:
/* quantize.c, quantization / inverse quantization */
/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
/*
* Disclaimer of Warranty
*
* These software programs are available to the user without any license fee or
* royalty on an "as is" basis. The MPEG Software Simulation Group disclaims
* any and all warranties, whether express, implied, or statuary, including any
* implied warranties or merchantability or of fitness for a particular
* purpose. In no event shall the copyright-holder be liable for any
* incidental, punitive, or consequential damages of any kind whatsoever
* arising from the use of these programs.
*
* This disclaimer of warranty extends to the user of these programs and user's
* customers, employees, agents, transferees, successors, and assigns.
*
* The MPEG Software Simulation Group does not represent or warrant that the
* programs furnished hereunder are free of infringement of any third-party
* patents.
*
* Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
* are subject to royalty fees to patent holders. Many of these patents are
* general enough such that they are unavoidable regardless of implementation
* design.
*
*/
#include <stdio.h>
#include "config.h"
#include "global.h"
static void iquant1_intra _ANSI_ARGS_((short *src, short *dst,
int dc_prec, unsigned char *quant_mat, int mquant));
static void iquant1_non_intra _ANSI_ARGS_((short *src, short *dst,
unsigned char *quant_mat, int mquant));
/* Test Model 5 quantization
*
* this quantizer has a bias of 1/8 stepsize towards zero
* (except for the DC coefficient)
*/
int quant_intra(src,dst,dc_prec,quant_mat,mquant)
short *src, *dst;
int dc_prec;
unsigned char *quant_mat;
int mquant;
{
int i;
int x, y, d;
x = src[0];
d = 8>>dc_prec; /* intra_dc_mult */
dst[0] = (x>=0) ? (x+(d>>1))/d : -((-x+(d>>1))/d); /* round(x/d) */
for (i=1; i<64; i++)
{
x = src[i];
d = quant_mat[i];
y = (32*(x>=0 ? x : -x) + (d>>1))/d; /* round(32*x/quant_mat) */
d = (3*mquant+2)>>2;
y = (y+d)/(2*mquant); /* (y+0.75*mquant) / (2*mquant) */
/* clip to syntax limits */
if (y > 255)
{
if (mpeg1)
y = 255;
else if (y > 2047)
y = 2047;
}
dst[i] = (x>=0) ? y : -y;
#if 0
/* this quantizer is virtually identical to the above */
if (x<0)
x = -x;
d = mquant*quant_mat[i];
y = (16*x + ((3*d)>>3)) / d;
dst[i] = (src[i]<0) ? -y : y;
#endif
}
return 1;
}
int quant_non_intra(src,dst,quant_mat,mquant)
short *src, *dst;
unsigned char *quant_mat;
int mquant;
{
int i;
int x, y, d;
int nzflag;
nzflag = 0;
for (i=0; i<64; i++)
{
x = src[i];
d = quant_mat[i];
y = (32*(x>=0 ? x : -x) + (d>>1))/d; /* round(32*x/quant_mat) */
y /= (2*mquant);
/* clip to syntax limits */
if (y > 255)
{
if (mpeg1)
y = 255;
else if (y > 2047)
y = 2047;
}
if ((dst[i] = (x>=0 ? y : -y)) != 0)
nzflag=1;
}
return nzflag;
}
/* MPEG-2 inverse quantization */
void iquant_intra(src,dst,dc_prec,quant_mat,mquant)
short *src, *dst;
int dc_prec;
unsigned char *quant_mat;
int mquant;
{
int i, val, sum;
if (mpeg1)
iquant1_intra(src,dst,dc_prec,quant_mat,mquant);
else
{
sum = dst[0] = src[0] << (3-dc_prec);
for (i=1; i<64; i++)
{
val = (int)(src[i]*quant_mat[i]*mquant)/16;
sum+= dst[i] = (val>2047) ? 2047 : ((val<-2048) ? -2048 : val);
}
/* mismatch control */
if ((sum&1)==0)
dst[63]^= 1;
}
}
void iquant_non_intra(src,dst,quant_mat,mquant)
short *src, *dst;
unsigned char *quant_mat;
int mquant;
{
int i, val, sum;
if (mpeg1)
iquant1_non_intra(src,dst,quant_mat,mquant);
else
{
sum = 0;
for (i=0; i<64; i++)
{
val = src[i];
if (val!=0)
val = (int)((2*val+(val>0 ? 1 : -1))*quant_mat[i]*mquant)/32;
sum+= dst[i] = (val>2047) ? 2047 : ((val<-2048) ? -2048 : val);
}
/* mismatch control */
if ((sum&1)==0)
dst[63]^= 1;
}
}
/* MPEG-1 inverse quantization */
static void iquant1_intra(src,dst,dc_prec,quant_mat,mquant)
short *src, *dst;
int dc_prec;
unsigned char *quant_mat;
int mquant;
{
int i, val;
dst[0] = src[0] << (3-dc_prec);
for (i=1; i<64; i++)
{
val = (int)(src[i]*quant_mat[i]*mquant)/16;
/* mismatch control */
if ((val&1)==0 && val!=0)
val+= (val>0) ? -1 : 1;
/* saturation */
dst[i] = (val>2047) ? 2047 : ((val<-2048) ? -2048 : val);
}
}
static void iquant1_non_intra(src,dst,quant_mat,mquant)
short *src, *dst;
unsigned char *quant_mat;
int mquant;
{
int i, val;
for (i=0; i<64; i++)
{
val = src[i];
if (val!=0)
{
val = (int)((2*val+(val>0 ? 1 : -1))*quant_mat[i]*mquant)/32;
/* mismatch control */
if ((val&1)==0 && val!=0)
val+= (val>0) ? -1 : 1;
}
/* saturation */
dst[i] = (val>2047) ? 2047 : ((val<-2048) ? -2048 : val);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -