]> Creatis software - gdcm.git/blob - src/gdcmmpeg2/src/mpeg2enc/quantize.c
ENH: Continue cleaning of open/write/seek ...
[gdcm.git] / src / gdcmmpeg2 / src / mpeg2enc / quantize.c
1 /* quantize.c, quantization / inverse quantization                          */
2
3 /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
4
5 /*
6  * Disclaimer of Warranty
7  *
8  * These software programs are available to the user without any license fee or
9  * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
10  * any and all warranties, whether express, implied, or statuary, including any
11  * implied warranties or merchantability or of fitness for a particular
12  * purpose.  In no event shall the copyright-holder be liable for any
13  * incidental, punitive, or consequential damages of any kind whatsoever
14  * arising from the use of these programs.
15  *
16  * This disclaimer of warranty extends to the user of these programs and user's
17  * customers, employees, agents, transferees, successors, and assigns.
18  *
19  * The MPEG Software Simulation Group does not represent or warrant that the
20  * programs furnished hereunder are free of infringement of any third-party
21  * patents.
22  *
23  * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
24  * are subject to royalty fees to patent holders.  Many of these patents are
25  * general enough such that they are unavoidable regardless of implementation
26  * design.
27  *
28  */
29
30 #include <stdio.h>
31 #include "config.h"
32 #include "global.h"
33
34 static void iquant1_intra _ANSI_ARGS_((short *src, short *dst,
35   int dc_prec, unsigned char *quant_mat, int mquant));
36 static void iquant1_non_intra _ANSI_ARGS_((short *src, short *dst,
37   unsigned char *quant_mat, int mquant));
38
39 /* Test Model 5 quantization
40  *
41  * this quantizer has a bias of 1/8 stepsize towards zero
42  * (except for the DC coefficient)
43  */
44 int quant_intra(src,dst,dc_prec,quant_mat,mquant)
45 short *src, *dst;
46 int dc_prec;
47 unsigned char *quant_mat;
48 int mquant;
49 {
50   int i;
51   int x, y, d;
52
53   x = src[0];
54   d = 8>>dc_prec; /* intra_dc_mult */
55   dst[0] = (x>=0) ? (x+(d>>1))/d : -((-x+(d>>1))/d); /* round(x/d) */
56
57   for (i=1; i<64; i++)
58   {
59     x = src[i];
60     d = quant_mat[i];
61     y = (32*(x>=0 ? x : -x) + (d>>1))/d; /* round(32*x/quant_mat) */
62     d = (3*mquant+2)>>2;
63     y = (y+d)/(2*mquant); /* (y+0.75*mquant) / (2*mquant) */
64
65     /* clip to syntax limits */
66     if (y > 255)
67     {
68       if (mpeg1)
69         y = 255;
70       else if (y > 2047)
71         y = 2047;
72     }
73
74     dst[i] = (x>=0) ? y : -y;
75
76 #if 0
77     /* this quantizer is virtually identical to the above */
78     if (x<0)
79       x = -x;
80     d = mquant*quant_mat[i];
81     y = (16*x + ((3*d)>>3)) / d;
82     dst[i] = (src[i]<0) ? -y : y;
83 #endif
84   }
85
86   return 1;
87 }
88
89 int quant_non_intra(src,dst,quant_mat,mquant)
90 short *src, *dst;
91 unsigned char *quant_mat;
92 int mquant;
93 {
94   int i;
95   int x, y, d;
96   int nzflag;
97
98   nzflag = 0;
99
100   for (i=0; i<64; i++)
101   {
102     x = src[i];
103     d = quant_mat[i];
104     y = (32*(x>=0 ? x : -x) + (d>>1))/d; /* round(32*x/quant_mat) */
105     y /= (2*mquant);
106
107     /* clip to syntax limits */
108     if (y > 255)
109     {
110       if (mpeg1)
111         y = 255;
112       else if (y > 2047)
113         y = 2047;
114     }
115
116     if ((dst[i] = (x>=0 ? y : -y)) != 0)
117       nzflag=1;
118   }
119
120   return nzflag;
121 }
122
123 /* MPEG-2 inverse quantization */
124 void iquant_intra(src,dst,dc_prec,quant_mat,mquant)
125 short *src, *dst;
126 int dc_prec;
127 unsigned char *quant_mat;
128 int mquant;
129 {
130   int i, val, sum;
131
132   if (mpeg1)
133     iquant1_intra(src,dst,dc_prec,quant_mat,mquant);
134   else
135   {
136     sum = dst[0] = src[0] << (3-dc_prec);
137     for (i=1; i<64; i++)
138     {
139       val = (int)(src[i]*quant_mat[i]*mquant)/16;
140       sum+= dst[i] = (val>2047) ? 2047 : ((val<-2048) ? -2048 : val);
141     }
142
143     /* mismatch control */
144     if ((sum&1)==0)
145       dst[63]^= 1;
146   }
147 }
148
149 void iquant_non_intra(src,dst,quant_mat,mquant)
150 short *src, *dst;
151 unsigned char *quant_mat;
152 int mquant;
153 {
154   int i, val, sum;
155
156   if (mpeg1)
157     iquant1_non_intra(src,dst,quant_mat,mquant);
158   else
159   {
160     sum = 0;
161     for (i=0; i<64; i++)
162     {
163       val = src[i];
164       if (val!=0)
165         val = (int)((2*val+(val>0 ? 1 : -1))*quant_mat[i]*mquant)/32;
166       sum+= dst[i] = (val>2047) ? 2047 : ((val<-2048) ? -2048 : val);
167     }
168
169     /* mismatch control */
170     if ((sum&1)==0)
171       dst[63]^= 1;
172   }
173 }
174
175 /* MPEG-1 inverse quantization */
176 static void iquant1_intra(src,dst,dc_prec,quant_mat,mquant)
177 short *src, *dst;
178 int dc_prec;
179 unsigned char *quant_mat;
180 int mquant;
181 {
182   int i, val;
183
184   dst[0] = src[0] << (3-dc_prec);
185   for (i=1; i<64; i++)
186   {
187     val = (int)(src[i]*quant_mat[i]*mquant)/16;
188
189     /* mismatch control */
190     if ((val&1)==0 && val!=0)
191       val+= (val>0) ? -1 : 1;
192
193     /* saturation */
194     dst[i] = (val>2047) ? 2047 : ((val<-2048) ? -2048 : val);
195   }
196 }
197
198 static void iquant1_non_intra(src,dst,quant_mat,mquant)
199 short *src, *dst;
200 unsigned char *quant_mat;
201 int mquant;
202 {
203   int i, val;
204
205   for (i=0; i<64; i++)
206   {
207     val = src[i];
208     if (val!=0)
209     {
210       val = (int)((2*val+(val>0 ? 1 : -1))*quant_mat[i]*mquant)/32;
211
212       /* mismatch control */
213       if ((val&1)==0 && val!=0)
214         val+= (val>0) ? -1 : 1;
215     }
216
217     /* saturation */
218     dst[i] = (val>2047) ? 2047 : ((val<-2048) ? -2048 : val);
219   }
220 }