Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2 | pj | 1 | #include <ctype.h> |
2 | #include <stdlib.h> |
||
3 | #include "mpg123.h" |
||
4 | #include "tables.h" |
||
5 | |||
6 | /* max = 1728 */ |
||
7 | #define MAXFRAMESIZE 1792 |
||
8 | |||
9 | #define SKIP_JUNK 1 |
||
10 | |||
11 | int tabsel_123[2][3][16] = { |
||
12 | { {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,}, |
||
13 | {0,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,}, |
||
14 | {0,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,} }, |
||
15 | |||
16 | { {0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,}, |
||
17 | {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,}, |
||
18 | {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,} } |
||
19 | }; |
||
20 | |||
21 | long freqs[7] = { 44100, 48000, 32000, 22050, 24000, 16000 , 11025 }; |
||
22 | |||
23 | #ifdef I386_ASSEM |
||
24 | int bitindex; |
||
25 | unsigned char *wordpointer; |
||
26 | #else |
||
27 | static int bitindex; |
||
28 | static unsigned char *wordpointer; |
||
29 | #endif |
||
30 | |||
31 | static int fsize=0,fsizeold=0,ssize; |
||
32 | static unsigned char bsspace[2][MAXFRAMESIZE+512]; /* MAXFRAMESIZE */ |
||
33 | static unsigned char *bsbuf=bsspace[1],*bsbufold; |
||
34 | static int bsnum=0; |
||
35 | |||
36 | struct ibuf { |
||
37 | struct ibuf *next; |
||
38 | struct ibuf *prev; |
||
39 | unsigned char *buf; |
||
40 | unsigned char *pnt; |
||
41 | int len; |
||
42 | /* skip,time stamp */ |
||
43 | }; |
||
44 | |||
45 | struct ibuf ibufs[2]; |
||
46 | struct ibuf *cibuf; |
||
47 | int ibufnum=0; |
||
48 | |||
49 | unsigned char *pcm_sample; |
||
50 | int pcm_point = 0; |
||
51 | int audiobufsize = AUDIOBUFSIZE; |
||
52 | |||
53 | #ifdef VARMODESUPPORT |
||
54 | /* |
||
55 | * This is a dirty hack! It might burn your PC and kill your cat! |
||
56 | * When in "varmode", specially formatted layer-3 mpeg files are |
||
57 | * expected as input -- it will NOT work with standard mpeg files. |
||
58 | * The reason for this: |
||
59 | * Varmode mpeg files enable my own GUI player to perform fast |
||
60 | * forward and backward functions, and to jump to an arbitrary |
||
61 | * timestamp position within the file. This would be possible |
||
62 | * with standard mpeg files, too, but it would be a lot harder to |
||
63 | * implement. |
||
64 | * A filter for converting standard mpeg to varmode mpeg is |
||
65 | * available on request, but it's really not useful on its own. |
||
66 | * |
||
67 | * Oliver Fromme <oliver.fromme@heim3.tu-clausthal.de> |
||
68 | * Mon Mar 24 00:04:24 MET 1997 |
||
69 | */ |
||
70 | int varmode = FALSE; |
||
71 | int playlimit; |
||
72 | #endif |
||
73 | |||
74 | static FILE *filept; |
||
75 | static int filept_opened; |
||
76 | |||
77 | static void get_II_stuff(struct frame *fr) |
||
78 | { |
||
79 | static int translate[3][2][16] = |
||
80 | { { { 0,2,2,2,2,2,2,0,0,0,1,1,1,1,1,0 } , |
||
81 | { 0,2,2,0,0,0,1,1,1,1,1,1,1,1,1,0 } } , |
||
82 | { { 0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0 } , |
||
83 | { 0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0 } } , |
||
84 | { { 0,3,3,3,3,3,3,0,0,0,1,1,1,1,1,0 } , |
||
85 | { 0,3,3,0,0,0,1,1,1,1,1,1,1,1,1,0 } } }; |
||
86 | |||
87 | int table,sblim; |
||
88 | static struct al_table *tables[5] = |
||
89 | { alloc_0, alloc_1, alloc_2, alloc_3 , alloc_4 }; |
||
90 | static int sblims[5] = { 27 , 30 , 8, 12 , 30 }; |
||
91 | |||
92 | if(fr->lsf) |
||
93 | table = 4; |
||
94 | else |
||
95 | table = translate[fr->sampling_frequency][2-fr->stereo][fr->bitrate_index]; |
||
96 | sblim = sblims[table]; |
||
97 | |||
98 | fr->alloc = tables[table]; |
||
99 | fr->II_sblimit = sblim; |
||
100 | } |
||
101 | |||
102 | void audio_flush(int outmode, struct audio_info_struct *ai) |
||
103 | { |
||
104 | if (pcm_point) { |
||
105 | switch (outmode) { |
||
106 | case DECODE_STDOUT: |
||
107 | write (1, pcm_sample, pcm_point); |
||
108 | break; |
||
109 | case DECODE_AUDIO: |
||
110 | audio_play_samples (ai, pcm_sample, pcm_point); |
||
111 | break; |
||
112 | case DECODE_BUFFER: |
||
113 | write (buffer_fd[1], pcm_sample, pcm_point); |
||
114 | break; |
||
115 | } |
||
116 | pcm_point = 0; |
||
117 | } |
||
118 | } |
||
119 | |||
120 | void (*catchsignal(int signum, void(*handler)()))() |
||
121 | { |
||
122 | struct sigaction new_sa; |
||
123 | struct sigaction old_sa; |
||
124 | |||
125 | new_sa.sa_handler = handler; |
||
126 | sigemptyset(&new_sa.sa_mask); |
||
127 | new_sa.sa_flags = 0; |
||
128 | if (sigaction(signum, &new_sa, &old_sa) == -1) |
||
129 | return ((void (*)()) -1); |
||
130 | return (old_sa.sa_handler); |
||
131 | } |
||
132 | |||
133 | static unsigned long oldhead = 0; |
||
134 | static unsigned long firsthead=0; |
||
135 | |||
136 | void read_frame_init (void) |
||
137 | { |
||
138 | oldhead = 0; |
||
139 | firsthead = 0; |
||
140 | } |
||
141 | |||
142 | #define HDRCMPMASK 0xfffffd00 |
||
143 | #if 0 |
||
144 | #define HDRCMPMASK 0xfffffdft |
||
145 | #endif |
||
146 | |||
147 | /* |
||
148 | * HACK,HACK,HACK |
||
149 | * step back <num> frames |
||
150 | */ |
||
151 | int back_frame(struct frame *fr,int num) |
||
152 | { |
||
153 | long bytes; |
||
154 | unsigned char buf[4]; |
||
155 | unsigned long newhead; |
||
156 | |||
157 | if(!firsthead) |
||
158 | return 0; |
||
159 | |||
160 | bytes = (fsize+8)*(num+2); |
||
161 | |||
162 | if(fseek(filept,-bytes,SEEK_CUR) < 0) |
||
163 | return -1; |
||
164 | |||
165 | if(fread(buf,1,4,filept) != 4) |
||
166 | return -1; |
||
167 | |||
168 | newhead = (buf[0]<<24) + (buf[1]<<16) + (buf[2]<<8) + buf[3]; |
||
169 | |||
170 | while( (newhead & HDRCMPMASK) != (firsthead & HDRCMPMASK) ) { |
||
171 | if(fread(buf,1,1,filept) != 1) |
||
172 | return -1; |
||
173 | newhead <<= 8; |
||
174 | newhead |= buf[0]; |
||
175 | newhead &= 0xffffffff; |
||
176 | } |
||
177 | |||
178 | if( fseek(filept,-4,SEEK_CUR) < 0) |
||
179 | return -1; |
||
180 | |||
181 | read_frame(fr); |
||
182 | read_frame(fr); |
||
183 | |||
184 | if(fr->lay == 3) { |
||
185 | set_pointer(512); |
||
186 | } |
||
187 | |||
188 | return 0; |
||
189 | } |
||
190 | |||
191 | int read_frame(struct frame *fr) |
||
192 | { |
||
193 | static unsigned long newhead; |
||
194 | |||
195 | static unsigned char ssave[34]; |
||
196 | unsigned char hbuf[8]; |
||
197 | static int framesize; |
||
198 | static int halfphase = 0; |
||
199 | int l; |
||
200 | int try = 0; |
||
201 | |||
202 | if (halfspeed) |
||
203 | if (halfphase--) { |
||
204 | bitindex = 0; |
||
205 | wordpointer = (unsigned char *) bsbuf; |
||
206 | if (fr->lay == 3) |
||
207 | memcpy (bsbuf, ssave, ssize); |
||
208 | return 1; |
||
209 | } |
||
210 | else |
||
211 | halfphase = halfspeed - 1; |
||
212 | |||
213 | #ifdef VARMODESUPPORT |
||
214 | if (varmode) { |
||
215 | if(fread(hbuf,1,8,filept) != 8) |
||
216 | return 0; |
||
217 | } |
||
218 | else |
||
219 | #endif |
||
220 | read_again: |
||
221 | if(fread(hbuf,1,4,filept) != 4) |
||
222 | return 0; |
||
223 | |||
224 | newhead = ((unsigned long) hbuf[0] << 24) | ((unsigned long) hbuf[1] << 16) | |
||
225 | ((unsigned long) hbuf[2] << 8) | (unsigned long) hbuf[3]; |
||
226 | |||
227 | if(oldhead != newhead || !oldhead) |
||
228 | { |
||
229 | fr->header_change = 1; |
||
230 | #if 0 |
||
231 | fprintf(stderr,"Major headerchange %08lx->%08lx.\n",oldhead,newhead); |
||
232 | #endif |
||
233 | |||
234 | init_resync: |
||
235 | if( (newhead & 0xffe00000) != 0xffe00000) { |
||
236 | #ifdef SKIP_JUNK |
||
237 | if(!firsthead) { |
||
238 | int i; |
||
239 | /* I even saw RIFF headers at the beginning of MPEG streams ;( */ |
||
240 | if(newhead == ('R'<<24)+('I'<<16)+('F'<<8)+'F') { |
||
241 | char buf[40]; |
||
242 | fprintf(stderr,"Skipped RIFF header\n"); |
||
243 | fread(buf,1,68,filept); |
||
244 | goto read_again; |
||
245 | } |
||
246 | /* give up after 1024 bytes */ |
||
247 | for(i=0;i<1024;i++) { |
||
248 | memmove (&hbuf[0], &hbuf[1], 3); |
||
249 | if(fread(hbuf+3,1,1,filept) != 1) |
||
250 | return 0; |
||
251 | newhead <<= 8; |
||
252 | newhead |= hbuf[3]; |
||
253 | newhead &= 0xffffffff; |
||
254 | goto init_resync; |
||
255 | } |
||
256 | fprintf(stderr,"Giving up searching valid MPEG header\n"); |
||
257 | return 0; |
||
258 | } |
||
259 | #endif |
||
260 | if (!quiet) |
||
261 | fprintf(stderr,"Illegal Audio-MPEG-Header 0x%08lx at offset 0x%lx.\n", |
||
262 | newhead,ftell(filept)-4); |
||
263 | if (tryresync) { |
||
264 | /* Read more bytes until we find something that looks |
||
265 | reasonably like a valid header. This is not a |
||
266 | perfect strategy, but it should get us back on the |
||
267 | track within a short time (and hopefully without |
||
268 | too much distortion in the audio output). */ |
||
269 | do { |
||
270 | try++; |
||
271 | memmove (&hbuf[0], &hbuf[1], 7); |
||
272 | #ifdef VARMODESUPPORT |
||
273 | if (fread(&hbuf[varmode?7:3],1,1,filept) != 1) |
||
274 | #else |
||
275 | if (fread(&hbuf[3],1,1,filept) != 1) |
||
276 | #endif |
||
277 | return 0; |
||
278 | |||
279 | /* This is faster than combining newhead from scratch */ |
||
280 | newhead = ((newhead << 8) | hbuf[3]) & 0xffffffff; |
||
281 | |||
282 | if (!oldhead) |
||
283 | goto init_resync; /* "considered harmful", eh? */ |
||
284 | |||
285 | } while ((newhead & HDRCMPMASK) != (oldhead & HDRCMPMASK) |
||
286 | && (newhead & HDRCMPMASK) != (firsthead & HDRCMPMASK)); |
||
287 | if (!quiet) |
||
288 | fprintf (stderr, "Skipped %d bytes in input.\n", try); |
||
289 | } |
||
290 | else |
||
291 | return (0); |
||
292 | } |
||
293 | if (!firsthead) |
||
294 | firsthead = newhead; |
||
295 | |||
296 | if( newhead & (1<<20) ) { |
||
297 | fr->lsf = (newhead & (1<<19)) ? 0x0 : 0x1; |
||
298 | fr->mpeg25 = 0; |
||
299 | } |
||
300 | else { |
||
301 | fr->lsf = 1; |
||
302 | fr->mpeg25 = 1; |
||
303 | } |
||
304 | |||
305 | if (!tryresync || !oldhead) { |
||
306 | /* If "tryresync" is true, assume that certain |
||
307 | parameters do not change within the stream! */ |
||
308 | fr->lay = 4-((newhead>>17)&3); |
||
309 | fr->bitrate_index = ((newhead>>12)&0xf); |
||
310 | if( ((newhead>>10)&0x3) == 0x3) { |
||
311 | fprintf(stderr,"Stream error\n"); |
||
312 | exit(1); |
||
313 | } |
||
314 | if(fr->mpeg25) |
||
315 | fr->sampling_frequency = 6; |
||
316 | else |
||
317 | fr->sampling_frequency = ((newhead>>10)&0x3) + (fr->lsf*3); |
||
318 | fr->error_protection = ((newhead>>16)&0x1)^0x1; |
||
319 | } |
||
320 | |||
321 | fr->padding = ((newhead>>9)&0x1); |
||
322 | fr->extension = ((newhead>>8)&0x1); |
||
323 | fr->mode = ((newhead>>6)&0x3); |
||
324 | fr->mode_ext = ((newhead>>4)&0x3); |
||
325 | fr->copyright = ((newhead>>3)&0x1); |
||
326 | fr->original = ((newhead>>2)&0x1); |
||
327 | fr->emphasis = newhead & 0x3; |
||
328 | |||
329 | fr->stereo = (fr->mode == MPG_MD_MONO) ? 1 : 2; |
||
330 | |||
331 | oldhead = newhead; |
||
332 | |||
333 | if(!fr->bitrate_index) |
||
334 | { |
||
335 | fprintf(stderr,"Free format not supported.\n"); |
||
336 | return (0); |
||
337 | } |
||
338 | |||
339 | switch(fr->lay) |
||
340 | { |
||
341 | case 1: |
||
342 | fr->do_layer = do_layer1; |
||
343 | #ifdef VARMODESUPPORT |
||
344 | if (varmode) { |
||
345 | fprintf(stderr,"Sorry, layer-1 not supported in varmode.\n"); |
||
346 | return (0); |
||
347 | } |
||
348 | #endif |
||
349 | fr->jsbound = (fr->mode == MPG_MD_JOINT_STEREO) ? |
||
350 | (fr->mode_ext<<2)+4 : 32; |
||
351 | framesize = (long) tabsel_123[fr->lsf][0][fr->bitrate_index] * 12000; |
||
352 | framesize /= freqs[fr->sampling_frequency]; |
||
353 | framesize = ((framesize+fr->padding)<<2)-4; |
||
354 | break; |
||
355 | case 2: |
||
356 | fr->do_layer = do_layer2; |
||
357 | #ifdef VARMODESUPPORT |
||
358 | if (varmode) { |
||
359 | fprintf(stderr,"Sorry, layer-2 not supported in varmode.\n"); |
||
360 | return (0); |
||
361 | } |
||
362 | #endif |
||
363 | get_II_stuff(fr); |
||
364 | fr->jsbound = (fr->mode == MPG_MD_JOINT_STEREO) ? |
||
365 | (fr->mode_ext<<2)+4 : fr->II_sblimit; |
||
366 | framesize = (long) tabsel_123[fr->lsf][1][fr->bitrate_index] * 144000; |
||
367 | framesize /= freqs[fr->sampling_frequency]; |
||
368 | framesize += fr->padding - 4; |
||
369 | break; |
||
370 | case 3: |
||
371 | fr->do_layer = do_layer3; |
||
372 | if(fr->lsf) |
||
373 | ssize = (fr->stereo == 1) ? 9 : 17; |
||
374 | else |
||
375 | ssize = (fr->stereo == 1) ? 17 : 32; |
||
376 | if(fr->error_protection) |
||
377 | ssize += 2; |
||
378 | #ifdef VARMODESUPPORT |
||
379 | if (varmode) |
||
380 | playlimit = ((unsigned int) hbuf[6] << 8) | (unsigned int) hbuf[7]; |
||
381 | framesize = ssize + |
||
382 | (((unsigned int) hbuf[4] << 8) | (unsigned int) hbuf[5]); |
||
383 | else { |
||
384 | #endif |
||
385 | framesize = (long) tabsel_123[fr->lsf][2][fr->bitrate_index] * 144000; |
||
386 | framesize /= freqs[fr->sampling_frequency]<<(fr->lsf); |
||
387 | framesize = framesize + fr->padding - 4; |
||
388 | #ifdef VARMODESUPPORT |
||
389 | } |
||
390 | #endif |
||
391 | break; |
||
392 | default: |
||
393 | fprintf(stderr,"Sorry, unknown layer type.\n"); |
||
394 | return (0); |
||
395 | } |
||
396 | } |
||
397 | else |
||
398 | fr->header_change = 0; |
||
399 | |||
400 | fsizeold=fsize; /* for Layer3 */ |
||
401 | bsbufold = bsbuf; |
||
402 | bsbuf = bsspace[bsnum]+512; |
||
403 | bsnum = (bsnum + 1) & 1; |
||
404 | |||
405 | fsize = framesize; |
||
406 | |||
407 | if( (l=fread(bsbuf,1,fsize,filept)) != fsize) |
||
408 | { |
||
409 | if(l <= 0) |
||
410 | return 0; |
||
411 | memset(bsbuf+l,0,fsize-l); |
||
412 | } |
||
413 | |||
414 | if (halfspeed && fr->lay == 3) |
||
415 | memcpy (ssave, bsbuf, ssize); |
||
416 | |||
417 | bitindex = 0; |
||
418 | wordpointer = (unsigned char *) bsbuf; |
||
419 | |||
420 | return 1; |
||
421 | } |
||
422 | |||
423 | #ifdef MPG123_REMOTE |
||
424 | void print_rheader(struct frame *fr) |
||
425 | { |
||
426 | static char *modes[4] = { "Stereo", "Joint-Stereo", "Dual-Channel", "Single-Channel" }; |
||
427 | static char *layers[4] = { "Unknown" , "I", "II", "III" }; |
||
428 | static char *mpeg_type[2] = { "1.0" , "2.0" }; |
||
429 | |||
430 | /* version, layer, freq, mode, channels, bitrate, BPF */ |
||
431 | fprintf(stderr,"@I %s %s %ld %s %d %d %d\n", |
||
432 | mpeg_type[fr->lsf],layers[fr->lay],freqs[fr->sampling_frequency], |
||
433 | modes[fr->mode],fr->stereo, |
||
434 | tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index], |
||
435 | fsize+4); |
||
436 | } |
||
437 | #endif |
||
438 | |||
439 | void print_header(struct frame *fr) |
||
440 | { |
||
441 | static char *modes[4] = { "Stereo", "Joint-Stereo", "Dual-Channel", "Single-Channel" }; |
||
442 | static char *layers[4] = { "Unknown" , "I", "II", "III" }; |
||
443 | |||
444 | fprintf(stderr,"MPEG %s, Layer: %s, Freq: %ld, mode: %s, modext: %d, BPF: %d\n", |
||
445 | fr->mpeg25 ? "2.5" : (fr->lsf ? "2.0" : "1.0"), |
||
446 | layers[fr->lay],freqs[fr->sampling_frequency], |
||
447 | modes[fr->mode],fr->mode_ext,fsize+4); |
||
448 | fprintf(stderr,"Channels: %d, copyright: %s, original: %s, CRC: %s, emphasis: %d.\n", |
||
449 | fr->stereo,fr->copyright?"Yes":"No", |
||
450 | fr->original?"Yes":"No",fr->error_protection?"Yes":"No", |
||
451 | fr->emphasis); |
||
452 | fprintf(stderr,"Bitrate: %d Kbits/s, Extension value: %d\n", |
||
453 | tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index],fr->extension); |
||
454 | } |
||
455 | |||
456 | void print_header_compact(struct frame *fr) |
||
457 | { |
||
458 | static char *modes[4] = { "stereo", "joint-stereo", "dual-channel", "mono" }; |
||
459 | static char *layers[4] = { "Unknown" , "I", "II", "III" }; |
||
460 | |||
461 | fprintf(stderr,"MPEG %s layer %s, %d kbit/s, %ld Hz %s\n", |
||
462 | fr->mpeg25 ? "2.5" : (fr->lsf ? "2.0" : "1.0"), |
||
463 | layers[fr->lay], |
||
464 | tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index], |
||
465 | freqs[fr->sampling_frequency], modes[fr->mode]); |
||
466 | } |
||
467 | |||
468 | /* |
||
469 | * Allocate space for a new string containing the first |
||
470 | * "num" characters of "src". The resulting string is |
||
471 | * always zero-terminated. Returns NULL if malloc fails. |
||
472 | */ |
||
473 | |||
474 | char *strndup (const char *src, int num) |
||
475 | { |
||
476 | char *dst; |
||
477 | |||
478 | if (!(dst = (char *) malloc(num+1))) |
||
479 | return (NULL); |
||
480 | dst[num] = '\0'; |
||
481 | return (strncpy(dst, src, num)); |
||
482 | } |
||
483 | |||
484 | /* |
||
485 | * Split "path" into directory and filename components. |
||
486 | * |
||
487 | * Return value is 0 if no directory was specified (i.e. |
||
488 | * "path" does not contain a '/'), OR if the directory |
||
489 | * is the same as on the previous call to this function. |
||
490 | * |
||
491 | * Return value is 1 if a directory was specified AND it |
||
492 | * is different from the previous one (if any). |
||
493 | */ |
||
494 | |||
495 | int split_dir_file (const char *path, char **dname, char **fname) |
||
496 | { |
||
497 | static char *lastdir = NULL; |
||
498 | char *slashpos; |
||
499 | |||
500 | if ((slashpos = strrchr(path, '/'))) { |
||
501 | *fname = slashpos + 1; |
||
502 | *dname = strndup(path, 1 + slashpos - path); |
||
503 | if (lastdir && !strcmp(lastdir, *dname)) { |
||
504 | /*** same as previous directory ***/ |
||
505 | free (*dname); |
||
506 | *dname = lastdir; |
||
507 | return 0; |
||
508 | } |
||
509 | else { |
||
510 | /*** different directory ***/ |
||
511 | if (lastdir) |
||
512 | free (lastdir); |
||
513 | lastdir = *dname; |
||
514 | return 1; |
||
515 | } |
||
516 | } |
||
517 | else { |
||
518 | /*** no directory specified ***/ |
||
519 | if (lastdir) { |
||
520 | free (lastdir); |
||
521 | lastdir = NULL; |
||
522 | }; |
||
523 | *dname = NULL; |
||
524 | *fname = (char *)path; |
||
525 | return 0; |
||
526 | } |
||
527 | } |
||
528 | |||
529 | /* open the device to read the bit stream from it */ |
||
530 | |||
531 | void open_stream(char *bs_filenam,int fd) |
||
532 | { |
||
533 | filept_opened = 1; |
||
534 | if (!bs_filenam) { |
||
535 | if(fd < 0) { |
||
536 | filept = stdin; |
||
537 | filept_opened = 0; |
||
538 | } |
||
539 | else |
||
540 | filept = fdopen(fd,"r"); |
||
541 | } |
||
542 | else if (!strncmp(bs_filenam, "http://", 7)) |
||
543 | filept = http_open(bs_filenam); |
||
544 | else if (!(filept = fopen(bs_filenam, "rb"))) { |
||
545 | perror (bs_filenam); |
||
546 | exit(1); |
||
547 | } |
||
548 | } |
||
549 | |||
550 | /*close the device containing the bit stream after a read process*/ |
||
551 | |||
552 | void close_stream(void) |
||
553 | { |
||
554 | if (filept_opened) |
||
555 | fclose(filept); |
||
556 | } |
||
557 | |||
558 | long tell_stream(void) |
||
559 | { |
||
560 | return ftell(filept); |
||
561 | } |
||
562 | |||
563 | #if !defined(I386_ASSEM) || defined(DEBUG_GETBITS) |
||
564 | #ifdef _gcc_ |
||
565 | inline |
||
566 | #endif |
||
567 | unsigned int getbits(int number_of_bits) |
||
568 | { |
||
569 | unsigned long rval; |
||
570 | |||
571 | #ifdef DEBUG_GETBITS |
||
572 | fprintf(stderr,"g%d",number_of_bits); |
||
573 | #endif |
||
574 | |||
575 | if(!number_of_bits) |
||
576 | return 0; |
||
577 | |||
578 | { |
||
579 | rval = wordpointer[0]; |
||
580 | rval <<= 8; |
||
581 | rval |= wordpointer[1]; |
||
582 | rval <<= 8; |
||
583 | rval |= wordpointer[2]; |
||
584 | #if 0 |
||
585 | rval = ((unsigned int) wordpointer[0] << 16)+((unsigned int) wordpointer[1]<<8)+ |
||
586 | (unsigned int) wordpointer[2]; |
||
587 | #endif |
||
588 | rval <<= bitindex; |
||
589 | rval &= 0xffffff; |
||
590 | |||
591 | bitindex += number_of_bits; |
||
592 | |||
593 | rval >>= (24-number_of_bits); |
||
594 | |||
595 | wordpointer += (bitindex>>3); |
||
596 | bitindex &= 7; |
||
597 | } |
||
598 | |||
599 | #ifdef DEBUG_GETBITS |
||
600 | fprintf(stderr,":%x ",rval); |
||
601 | #endif |
||
602 | return rval; |
||
603 | } |
||
604 | |||
605 | #ifdef _gcc_ |
||
606 | inline |
||
607 | #endif |
||
608 | unsigned int getbits_fast(int number_of_bits) |
||
609 | { |
||
610 | unsigned long rval; |
||
611 | |||
612 | #ifdef DEBUG_GETBITS |
||
613 | fprintf(stderr,"g%d",number_of_bits); |
||
614 | #endif |
||
615 | |||
616 | { |
||
617 | rval = wordpointer[0]; |
||
618 | rval <<= 8; |
||
619 | rval |= wordpointer[1]; |
||
620 | rval <<= bitindex; |
||
621 | rval &= 0xffff; |
||
622 | #if 0 |
||
623 | rval = ((unsigned int) high << (8-bitindex) )+((unsigned int) (unsigned char) wordpointer[1]); |
||
624 | #endif |
||
625 | bitindex += number_of_bits; |
||
626 | |||
627 | rval >>= (16-number_of_bits); |
||
628 | |||
629 | wordpointer += (bitindex>>3); |
||
630 | bitindex &= 7; |
||
631 | } |
||
632 | |||
633 | |||
634 | #ifdef DEBUG_GETBITS |
||
635 | fprintf(stderr,":%x ",rval); |
||
636 | #endif |
||
637 | |||
638 | |||
639 | return rval; |
||
640 | } |
||
641 | |||
642 | #ifdef _gcc_ |
||
643 | inline |
||
644 | #endif |
||
645 | unsigned int get1bit(void) |
||
646 | { |
||
647 | unsigned char rval; |
||
648 | |||
649 | #ifdef DEBUG_GETBITS |
||
650 | fprintf(stderr,"g%d",1); |
||
651 | #endif |
||
652 | |||
653 | rval = *wordpointer << bitindex; |
||
654 | |||
655 | bitindex++; |
||
656 | wordpointer += (bitindex>>3); |
||
657 | bitindex &= 7; |
||
658 | |||
659 | #ifdef DEBUG_GETBITS |
||
660 | fprintf(stderr,":%d ",rval>>7); |
||
661 | #endif |
||
662 | |||
663 | return rval>>7; |
||
664 | } |
||
665 | #endif |
||
666 | |||
667 | void set_pointer(long backstep) |
||
668 | { |
||
669 | wordpointer = bsbuf + ssize - backstep; |
||
670 | if (backstep) |
||
671 | memcpy(wordpointer,bsbufold+fsizeold-backstep,backstep); |
||
672 | bitindex = 0; |
||
673 | } |