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