1 /*
2  * libmad - MPEG audio decoder library
3  * Copyright (C) 2000-2004 Underbit Technologies, Inc.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  * $Id: stream.c,v 1.12 2004/02/05 09:02:39 rob Exp $
20  */
21 
22 # include "global.h"
23 
24 # include <stdlib.h>
25 
26 # include "bit.h"
27 # include "stream.h"
28 
29 /*
30  * NAME:	stream->init()
31  * DESCRIPTION:	initialize stream struct
32  */
mad_stream_init(struct mad_stream * stream)33 void mad_stream_init(struct mad_stream *stream)
34 {
35   stream->buffer     = 0;
36   stream->bufend     = 0;
37   stream->skiplen    = 0;
38 
39   stream->sync       = 0;
40   stream->freerate   = 0;
41 
42   stream->this_frame = 0;
43   stream->next_frame = 0;
44   mad_bit_init(&stream->ptr, 0);
45 
46   mad_bit_init(&stream->anc_ptr, 0);
47   stream->anc_bitlen = 0;
48 
49   stream->main_data  = 0;
50   stream->md_len     = 0;
51 
52   stream->options    = 0;
53   stream->error      = MAD_ERROR_NONE;
54 }
55 
56 /*
57  * NAME:	stream->finish()
58  * DESCRIPTION:	deallocate any dynamic memory associated with stream
59  */
mad_stream_finish(struct mad_stream * stream)60 void mad_stream_finish(struct mad_stream *stream)
61 {
62   if (stream->main_data) {
63     free(stream->main_data);
64     stream->main_data = 0;
65   }
66 
67   mad_bit_finish(&stream->anc_ptr);
68   mad_bit_finish(&stream->ptr);
69 }
70 
71 /*
72  * NAME:	stream->buffer()
73  * DESCRIPTION:	set stream buffer pointers
74  */
mad_stream_buffer(struct mad_stream * stream,unsigned char const * buffer,unsigned long length)75 void mad_stream_buffer(struct mad_stream *stream,
76 		       unsigned char const *buffer, unsigned long length)
77 {
78   stream->buffer = buffer;
79   stream->bufend = buffer + length;
80 
81   stream->this_frame = buffer;
82   stream->next_frame = buffer;
83 
84   stream->sync = 1;
85 
86   mad_bit_init(&stream->ptr, buffer);
87 }
88 
89 /*
90  * NAME:	stream->skip()
91  * DESCRIPTION:	arrange to skip bytes before the next frame
92  */
mad_stream_skip(struct mad_stream * stream,unsigned long length)93 void mad_stream_skip(struct mad_stream *stream, unsigned long length)
94 {
95   stream->skiplen += length;
96 }
97 
98 /*
99  * NAME:	stream->sync()
100  * DESCRIPTION:	locate the next stream sync word
101  */
mad_stream_sync(struct mad_stream * stream)102 int mad_stream_sync(struct mad_stream *stream)
103 {
104   register unsigned char const *ptr, *end;
105 
106   ptr = mad_bit_nextbyte(&stream->ptr);
107   end = stream->bufend;
108 
109   while (ptr < end - 1 &&
110 	 !(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0))
111     ++ptr;
112 
113   if (end - ptr < MAD_BUFFER_GUARD)
114     return -1;
115 
116   mad_bit_init(&stream->ptr, ptr);
117 
118   return 0;
119 }
120 
121 /*
122  * NAME:	stream->errorstr()
123  * DESCRIPTION:	return a string description of the current error condition
124  */
mad_stream_errorstr(struct mad_stream const * stream)125 char const *mad_stream_errorstr(struct mad_stream const *stream)
126 {
127   switch (stream->error) {
128   case MAD_ERROR_NONE:		 return "no error";
129 
130   case MAD_ERROR_BUFLEN:	 return "input buffer too small (or EOF)";
131   case MAD_ERROR_BUFPTR:	 return "invalid (null) buffer pointer";
132 
133   case MAD_ERROR_NOMEM:		 return "not enough memory";
134 
135   case MAD_ERROR_LOSTSYNC:	 return "lost synchronization";
136   case MAD_ERROR_BADLAYER:	 return "reserved header layer value";
137   case MAD_ERROR_BADBITRATE:	 return "forbidden bitrate value";
138   case MAD_ERROR_BADSAMPLERATE:	 return "reserved sample frequency value";
139   case MAD_ERROR_BADEMPHASIS:	 return "reserved emphasis value";
140 
141   case MAD_ERROR_BADCRC:	 return "CRC check failed";
142   case MAD_ERROR_BADBITALLOC:	 return "forbidden bit allocation value";
143   case MAD_ERROR_BADSCALEFACTOR: return "bad scalefactor index";
144   case MAD_ERROR_BADMODE:	 return "bad bitrate/mode combination";
145   case MAD_ERROR_BADFRAMELEN:	 return "bad frame length";
146   case MAD_ERROR_BADBIGVALUES:	 return "bad big_values count";
147   case MAD_ERROR_BADBLOCKTYPE:	 return "reserved block_type";
148   case MAD_ERROR_BADSCFSI:	 return "bad scalefactor selection info";
149   case MAD_ERROR_BADDATAPTR:	 return "bad main_data_begin pointer";
150   case MAD_ERROR_BADPART3LEN:	 return "bad audio data length";
151   case MAD_ERROR_BADHUFFTABLE:	 return "bad Huffman table select";
152   case MAD_ERROR_BADHUFFDATA:	 return "Huffman data overrun";
153   case MAD_ERROR_BADSTEREO:	 return "incompatible block_type for JS";
154   }
155 
156   return 0;
157 }
158