]> Creatis software - gdcm.git/blob - src/gdcmmpeg2/src/mpeg2dec/getbits.c
ENH: Start working again on the MPEG2 stuff. Gather the stdio mess in a single place
[gdcm.git] / src / gdcmmpeg2 / src / mpeg2dec / getbits.c
1 /* getbits.c, bit level routines                                            */
2
3 /*
4  * All modifications (mpeg2decode -> mpeg2play) are
5  * Copyright (C) 1996, Stefan Eckart. All Rights Reserved.
6  */
7
8 /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
9
10 /*
11  * Disclaimer of Warranty
12  *
13  * These software programs are available to the user without any license fee or
14  * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
15  * any and all warranties, whether express, implied, or statuary, including any
16  * implied warranties or merchantability or of fitness for a particular
17  * purpose.  In no event shall the copyright-holder be liable for any
18  * incidental, punitive, or consequential damages of any kind whatsoever
19  * arising from the use of these programs.
20  *
21  * This disclaimer of warranty extends to the user of these programs and user's
22  * customers, employees, agents, transferees, successors, and assigns.
23  *
24  * The MPEG Software Simulation Group does not represent or warrant that the
25  * programs furnished hereunder are free of infringement of any third-party
26  * patents.
27  *
28  * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
29  * are subject to royalty fees to patent holders.  Many of these patents are
30  * general enough such that they are unavoidable regardless of implementation
31  * design.
32  *
33  */
34
35 #include "config.h"
36 #include "global.h"
37
38 /* initialize buffer, call once before first getbits or showbits */
39
40 void Initialize_Buffer()
41 {
42   ld->Incnt = 0;
43   ld->Rdptr = ld->Rdbfr + 2048;
44   ld->Rdmax = ld->Rdptr;
45
46 #ifdef VERIFY
47   /*  only the verifier uses this particular bit counter 
48    *  Bitcnt keeps track of the current parser position with respect
49    *  to the video elementary stream being decoded, regardless 
50    *  of whether or not it is wrapped within a systems layer stream 
51    */
52   ld->Bitcnt = 0;
53 #endif
54
55   ld->Bfr = 0;
56   Flush_Buffer(0); /* fills valid data into bfr */
57 }
58
59 void Fill_Buffer()
60 {
61   int Buffer_Level;
62
63   /*Buffer_Level = read(ld->Infile,ld->Rdbfr,2048);*/
64   Buffer_Level = ld->read_stream(ld->Infile,ld->Rdbfr,2048);
65   ld->Rdptr = ld->Rdbfr;
66
67   if (System_Stream_Flag)
68     ld->Rdmax -= 2048;
69
70   
71   /* end of the bitstream file */
72   if (Buffer_Level < 2048)
73   {
74     /* just to be safe */
75     if (Buffer_Level < 0)
76       Buffer_Level = 0;
77
78     /* pad until the next to the next 32-bit word boundary */
79     while (Buffer_Level & 3)
80       ld->Rdbfr[Buffer_Level++] = 0;
81
82     /* pad the buffer with sequence end codes */
83     while (Buffer_Level < 2048)
84     {
85       ld->Rdbfr[Buffer_Level++] = SEQUENCE_END_CODE>>24;
86       ld->Rdbfr[Buffer_Level++] = SEQUENCE_END_CODE>>16;
87       ld->Rdbfr[Buffer_Level++] = SEQUENCE_END_CODE>>8;
88       ld->Rdbfr[Buffer_Level++] = SEQUENCE_END_CODE&0xff;
89     }
90   }
91 }
92
93
94 /* MPEG-1 system layer demultiplexer */
95
96 int Get_Byte()
97 {
98   while(ld->Rdptr >= ld->Rdbfr+2048)
99   {
100     /*read(ld->Infile,ld->Rdbfr,2048);*/
101     ld->read_stream(ld->Infile,ld->Rdbfr,2048);
102     ld->Rdptr -= 2048;
103     ld->Rdmax -= 2048;
104   }
105   return *ld->Rdptr++;
106 }
107
108 /* extract a 16-bit word from the bitstream buffer */
109 int Get_Word()
110 {
111   int Val;
112
113   Val = Get_Byte();
114   return (Val<<8) | Get_Byte();
115 }
116
117
118 /* return next n bits (right adjusted) without advancing */
119
120 unsigned int Show_Bits(N)
121 int N;
122 {
123   return ld->Bfr >> (32-N);
124 }
125
126
127 /* return next bit (could be made faster than Get_Bits(1)) */
128
129 unsigned int Get_Bits1()
130 {
131   return Get_Bits(1);
132 }
133
134
135 /* advance by n bits */
136
137 void Flush_Buffer(N)
138 int N;
139 {
140   int Incnt;
141
142   ld->Bfr <<= N;
143
144   Incnt = ld->Incnt -= N;
145
146   if (Incnt <= 24)
147   {
148     if (System_Stream_Flag && (ld->Rdptr >= ld->Rdmax-4))
149     {
150       do
151       {
152         if (ld->Rdptr >= ld->Rdmax)
153           Next_Packet();
154         ld->Bfr |= Get_Byte() << (24 - Incnt);
155         Incnt += 8;
156       }
157       while (Incnt <= 24);
158     }
159     else if (ld->Rdptr < ld->Rdbfr+2044)
160     {
161       do
162       {
163         ld->Bfr |= *ld->Rdptr++ << (24 - Incnt);
164         Incnt += 8;
165       }
166       while (Incnt <= 24);
167     }
168     else
169     {
170       do
171       {
172         if (ld->Rdptr >= ld->Rdbfr+2048)
173           Fill_Buffer();
174         ld->Bfr |= *ld->Rdptr++ << (24 - Incnt);
175         Incnt += 8;
176       }
177       while (Incnt <= 24);
178     }
179     ld->Incnt = Incnt;
180   }
181
182 #ifdef VERIFY 
183   ld->Bitcnt += N;
184 #endif /* VERIFY */
185
186 }
187
188
189 /* return next n bits (right adjusted) */
190
191 unsigned int Get_Bits(N)
192 int N;
193 {
194   unsigned int Val;
195
196   Val = Show_Bits(N);
197   Flush_Buffer(N);
198
199   return Val;
200 }
201