1bf941f8fac7a6da8539de96951bf1ec4850653a
[goodguy/history.git] / cinelerra-5.1 / mpeg2enc / putbits.c
1 /* putbits.c, bit-level output                                              */
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 <string.h>
32 #include <stdlib.h>
33 #include "config.h"
34 #include "global.h"
35
36 extern FILE *outfile; /* the only global var we need here */
37
38 /* private data */
39 static unsigned char outbfr;
40 static int outcnt;
41 static int bytecnt;
42
43 void slice_initbits(slice_engine_t *engine)
44 {
45         engine->outcnt = 8;
46         engine->slice_size = 0;
47 }
48
49 void slice_testbits(slice_engine_t *engine)
50 {
51         printf("slice test size %lx outcnt %d outbfr %x\n", engine->slice_size, engine->outcnt, engine->outbfr << engine->outcnt);
52 /* { int i;
53  *      for(i = 0; i < engine->slice_size; i++)
54  *              printf("%02x ", engine->slice_buffer[i]);
55  *      printf("%x\n", engine->outbfr << engine->outcnt); }
56  */
57 }
58
59 void slice_putc(slice_engine_t *engine, unsigned char c)
60 {
61         if(engine->slice_size >= engine->slice_allocated)
62         {
63                 long new_allocation = (engine->slice_allocated > 0) ? (engine->slice_allocated * 2) : 64;
64                 unsigned char *new_buffer = calloc(1, new_allocation);
65                 if(engine->slice_buffer)
66                 {
67                         memcpy(new_buffer, engine->slice_buffer, engine->slice_size);
68                         free(engine->slice_buffer);
69                 }
70                 engine->slice_buffer = new_buffer;
71                 engine->slice_allocated = new_allocation;
72         }
73         engine->slice_buffer[engine->slice_size++] = c;
74 }
75
76 void slice_putbits(slice_engine_t *engine, long val, int n)
77 {
78         int i;
79         unsigned int mask;
80
81         mask = 1 << (n - 1); /* selects first (leftmost) bit */
82
83         for(i = 0; i < n; i++)
84         {
85         engine->outbfr <<= 1;
86
87         if(val & mask)
88                 engine->outbfr |= 1;
89
90         mask >>= 1; /* select next bit */
91         engine->outcnt--;
92
93         if(engine->outcnt == 0) /* 8 bit buffer full */
94         {
95                 slice_putc(engine, engine->outbfr);
96                 engine->outcnt = 8;
97                         engine->outbfr = 0;
98         }
99         }
100 }
101
102 /* zero bit stuffing to next byte boundary (5.2.3, 6.2.1) */
103 void slice_alignbits(slice_engine_t *engine)
104 {
105     if(engine->outcnt != 8)
106         slice_putbits(engine, 0, engine->outcnt);
107 }
108
109 void slice_finishslice(slice_engine_t *engine)
110 {
111         slice_alignbits(engine);
112         if( !engine->slice_size ) return;
113
114         if(!fwrite(engine->slice_buffer, 1, engine->slice_size, outfile))
115         {
116                 perror("Write error");
117         }
118         bytecnt += engine->slice_size;
119 }
120
121
122
123 /* initialize buffer, call once before first putbits or alignbits */
124 void mpeg2_initbits()
125 {
126         outcnt = 8;
127         bytecnt = 0;
128 }
129
130
131 /* write rightmost n (0<=n<=32) bits of val to outfile */
132 void mpeg2enc_putbits(val,n)
133 int val;
134 int n;
135 {
136   int i;
137   unsigned int mask;
138
139   mask = 1 << (n-1); /* selects first (leftmost) bit */
140
141   for (i=0; i<n; i++)
142   {
143     outbfr <<= 1;
144
145     if (val & mask)
146       outbfr|= 1;
147
148     mask >>= 1; /* select next bit */
149     outcnt--;
150
151     if (outcnt==0) /* 8 bit buffer full */
152     {
153       putc(outbfr,outfile);
154       outcnt = 8;
155       bytecnt++;
156     }
157   }
158 }
159
160 /* zero bit stuffing to next byte boundary (5.2.3, 6.2.1) */
161 void alignbits()
162 {
163   if (outcnt!=8)
164     mpeg2enc_putbits(0,outcnt);
165 }
166
167 /* return total number of generated bits */
168 double bitcount()
169 {
170         return (double)8 * bytecnt + (8 - outcnt);
171 }