]> Creatis software - gdcm.git/blob - src/gdcmmpeg2/src/mpeg2enc/putvlc.c
ENH: Continue cleaning of open/write/seek ...
[gdcm.git] / src / gdcmmpeg2 / src / mpeg2enc / putvlc.c
1 /* putvlc.c, generation of variable length codes                            */
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
32 #include "config.h"
33 #include "global.h"
34 #include "vlc.h"
35
36 /* private prototypes */
37 static void putDC _ANSI_ARGS_((sVLCtable *tab, int val));
38
39 /* generate variable length code for luminance DC coefficient */
40 void putDClum(val)
41 int val;
42 {
43   putDC(DClumtab,val);
44 }
45
46 /* generate variable length code for chrominance DC coefficient */
47 void putDCchrom(val)
48 int val;
49 {
50   putDC(DCchromtab,val);
51 }
52
53 /* generate variable length code for DC coefficient (7.2.1) */
54 static void putDC(tab,val)
55 sVLCtable *tab;
56 int val;
57 {
58   int absval, size;
59
60   absval = (val<0) ? -val : val; /* abs(val) */
61
62   if (absval>2047 || (mpeg1 && absval>255))
63   {
64     /* should never happen */
65     sprintf(errortext,"DC value out of range (%d)\n",val);
66     error(errortext);
67   }
68
69   /* compute dct_dc_size */
70   size = 0;
71
72   while (absval)
73   {
74     absval >>= 1;
75     size++;
76   }
77
78   /* generate VLC for dct_dc_size (Table B-12 or B-13) */
79   putbits(tab[size].code,tab[size].len);
80
81   /* append fixed length code (dc_dct_differential) */
82   if (size!=0)
83   {
84     if (val>=0)
85       absval = val;
86     else
87       absval = val + (1<<size) - 1; /* val + (2 ^ size) - 1 */
88     putbits(absval,size);
89   }
90 }
91
92 /* generate variable length code for first coefficient
93  * of a non-intra block (7.2.2.2) */
94 void putACfirst(run,val)
95 int run,val;
96 {
97   if (run==0 && (val==1 || val==-1)) /* these are treated differently */
98     putbits(2|(val<0),2); /* generate '1s' (s=sign), (Table B-14, line 2) */
99   else
100     putAC(run,val,0); /* no difference for all others */
101 }
102
103 /* generate variable length code for other DCT coefficients (7.2.2) */
104 void putAC(run,signed_level,vlcformat)
105 int run,signed_level,vlcformat;
106 {
107   int level, len;
108   VLCtable *ptab;
109
110   level = (signed_level<0) ? -signed_level : signed_level; /* abs(signed_level) */
111
112   /* make sure run and level are valid */
113   if (run<0 || run>63 || level==0 || level>2047 || (mpeg1 && level>255))
114   {
115     sprintf(errortext,"AC value out of range (run=%d, signed_level=%d)\n",
116       run,signed_level);
117     error(errortext);
118   }
119
120   len = 0;
121
122   if (run<2 && level<41)
123   {
124     /* vlcformat selects either of Table B-14 / B-15 */
125     if (vlcformat)
126       ptab = &dct_code_tab1a[run][level-1];
127     else
128       ptab = &dct_code_tab1[run][level-1];
129
130     len = ptab->len;
131   }
132   else if (run<32 && level<6)
133   {
134     /* vlcformat selects either of Table B-14 / B-15 */
135     if (vlcformat)
136       ptab = &dct_code_tab2a[run-2][level-1];
137     else
138       ptab = &dct_code_tab2[run-2][level-1];
139
140     len = ptab->len;
141   }
142
143   if (len!=0) /* a VLC code exists */
144   {
145     putbits(ptab->code,len);
146     putbits(signed_level<0,1); /* sign */
147   }
148   else
149   {
150     /* no VLC for this (run, level) combination: use escape coding (7.2.2.3) */
151     putbits(1l,6); /* Escape */
152     putbits(run,6); /* 6 bit code for run */
153     if (mpeg1)
154     {
155       /* ISO/IEC 11172-2 uses a 8 or 16 bit code */
156       if (signed_level>127)
157         putbits(0,8);
158       if (signed_level<-127)
159         putbits(128,8);
160       putbits(signed_level,8);
161     }
162     else
163     {
164       /* ISO/IEC 13818-2 uses a 12 bit code, Table B-16 */
165       putbits(signed_level,12);
166     }
167   }
168 }
169
170 /* generate variable length code for macroblock_address_increment (6.3.16) */
171 void putaddrinc(addrinc)
172 int addrinc;
173 {
174   while (addrinc>33)
175   {
176     putbits(0x08,11); /* macroblock_escape */
177     addrinc-= 33;
178   }
179
180   putbits(addrinctab[addrinc-1].code,addrinctab[addrinc-1].len);
181 }
182
183 /* generate variable length code for macroblock_type (6.3.16.1) */
184 void putmbtype(pict_type,mb_type)
185 int pict_type,mb_type;
186 {
187   putbits(mbtypetab[pict_type-1][mb_type].code,
188           mbtypetab[pict_type-1][mb_type].len);
189 }
190
191 /* generate variable length code for motion_code (6.3.16.3) */
192 void putmotioncode(motion_code)
193 int motion_code;
194 {
195   int abscode;
196
197   abscode = (motion_code>=0) ? motion_code : -motion_code; /* abs(motion_code) */
198   putbits(motionvectab[abscode].code,motionvectab[abscode].len);
199   if (motion_code!=0)
200     putbits(motion_code<0,1); /* sign, 0=positive, 1=negative */
201 }
202
203 /* generate variable length code for dmvector[t] (6.3.16.3), Table B-11 */
204 void putdmv(dmv)
205 int dmv;
206 {
207   if (dmv==0)
208     putbits(0,1);
209   else if (dmv>0)
210     putbits(2,2);
211   else
212     putbits(3,2);
213 }
214
215 /* generate variable length code for coded_block_pattern (6.3.16.4)
216  *
217  * 4:2:2, 4:4:4 not implemented
218  */
219 void putcbp(cbp)
220 int cbp;
221 {
222   putbits(cbptable[cbp].code,cbptable[cbp].len);
223 }