winedos: Remove superfluous casts of void pointers to other pointer types.
[wine] / dlls / winemp3.acm / interface.c
1 /*
2  * Copyright (c) Michael Hipp and other authors of the mpglib project.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include <stdlib.h>
20 #include <stdio.h>
21
22 #include "mpg123.h"
23 #include "mpglib.h"
24
25 /* Global mp .. it's a hack */
26 struct mpstr *gmp;
27
28
29 BOOL InitMP3(struct mpstr *mp)
30 {
31         static int init = 0;
32
33         memset(mp,0,sizeof(struct mpstr));
34
35         mp->framesize = 0;
36         mp->fsizeold = -1;
37         mp->bsize = 0;
38         mp->head = mp->tail = NULL;
39         mp->fr.single = -1;
40         mp->bsnum = 0;
41         mp->synth_bo = 1;
42
43         if(!init) {
44                 init = 1;
45                 make_decode_tables(32767);
46                 init_layer2();
47                 init_layer3(SBLIMIT);
48         }
49
50         return !0;
51 }
52
53 void ExitMP3(struct mpstr *mp)
54 {
55         struct buf *b,*bn;
56
57         b = mp->tail;
58         while(b) {
59                 free(b->pnt);
60                 bn = b->next;
61                 free(b);
62                 b = bn;
63         }
64 }
65
66 static struct buf *addbuf(struct mpstr *mp,const unsigned char *buf,int size)
67 {
68         struct buf *nbuf;
69
70         nbuf = malloc( sizeof(struct buf) );
71         if(!nbuf) {
72                 fprintf(stderr,"Out of memory!\n");
73                 return NULL;
74         }
75         nbuf->pnt = malloc(size);
76         if(!nbuf->pnt) {
77                 free(nbuf);
78                 return NULL;
79         }
80         nbuf->size = size;
81         memcpy(nbuf->pnt,buf,size);
82         nbuf->next = NULL;
83         nbuf->prev = mp->head;
84         nbuf->pos = 0;
85
86         if(!mp->tail) {
87                 mp->tail = nbuf;
88         }
89         else {
90           mp->head->next = nbuf;
91         }
92
93         mp->head = nbuf;
94         mp->bsize += size;
95
96         return nbuf;
97 }
98
99 static void remove_buf(struct mpstr *mp)
100 {
101   struct buf *buf = mp->tail;
102
103   mp->tail = buf->next;
104   if(mp->tail)
105     mp->tail->prev = NULL;
106   else {
107     mp->tail = mp->head = NULL;
108   }
109
110   free(buf->pnt);
111   free(buf);
112
113 }
114
115 static int read_buf_byte(struct mpstr *mp)
116 {
117         unsigned int b;
118
119         int pos;
120
121         pos = mp->tail->pos;
122         while(pos >= mp->tail->size) {
123                 remove_buf(mp);
124                 pos = mp->tail->pos;
125         }
126
127         b = mp->tail->pnt[pos];
128         mp->bsize--;
129         mp->tail->pos++;
130
131
132         return b;
133 }
134
135 static void read_head(struct mpstr *mp)
136 {
137         unsigned long head;
138
139         head = read_buf_byte(mp);
140         head <<= 8;
141         head |= read_buf_byte(mp);
142         head <<= 8;
143         head |= read_buf_byte(mp);
144         head <<= 8;
145         head |= read_buf_byte(mp);
146
147         mp->header = head;
148 }
149
150 int decodeMP3(struct mpstr *mp,const unsigned char *in,int isize,unsigned char *out,
151                 int osize,int *done)
152 {
153         int len;
154
155         gmp = mp;
156
157         if(osize < 4608) {
158                 fprintf(stderr,"To less out space\n");
159                 return MP3_ERR;
160         }
161
162         if(in) {
163                 if(addbuf(mp,in,isize) == NULL) {
164                         return MP3_ERR;
165                 }
166         }
167
168         /* First decode header */
169         if(mp->framesize == 0) {
170                 if(mp->bsize < 4) {
171                         return MP3_NEED_MORE;
172                 }
173                 read_head(mp);
174                 if (decode_header(&mp->fr,mp->header) == 0) {
175                         return MP3_ERR;
176                 }
177                 mp->framesize = mp->fr.framesize;
178         }
179
180         if(mp->fr.framesize > mp->bsize)
181                 return MP3_NEED_MORE;
182
183         wordpointer = mp->bsspace[mp->bsnum] + 512;
184         mp->bsnum = (mp->bsnum + 1) & 0x1;
185         bitindex = 0;
186
187         len = 0;
188         while(len < mp->framesize) {
189                 int nlen;
190                 int blen = mp->tail->size - mp->tail->pos;
191                 if( (mp->framesize - len) <= blen) {
192                   nlen = mp->framesize-len;
193                 }
194                 else {
195                   nlen = blen;
196                 }
197                 memcpy(wordpointer+len,mp->tail->pnt+mp->tail->pos,nlen);
198                 len += nlen;
199                 mp->tail->pos += nlen;
200                 mp->bsize -= nlen;
201                 if(mp->tail->pos == mp->tail->size) {
202                    remove_buf(mp);
203                 }
204         }
205
206         *done = 0;
207         if(mp->fr.error_protection)
208            getbits(16);
209         switch(mp->fr.lay) {
210           case 1:
211             do_layer1(&mp->fr,(unsigned char *) out,done);
212             break;
213           case 2:
214             do_layer2(&mp->fr,(unsigned char *) out,done);
215             break;
216           case 3:
217             do_layer3(&mp->fr,(unsigned char *) out,done);
218             break;
219         }
220
221         mp->fsizeold = mp->framesize;
222         mp->framesize = 0;
223
224         return MP3_OK;
225 }
226
227 int set_pointer(long backstep)
228 {
229   unsigned char *bsbufold;
230   if(gmp->fsizeold < 0 && backstep > 0) {
231     fprintf(stderr,"Can't step back %ld!\n",backstep);
232     return MP3_ERR;
233   }
234   bsbufold = gmp->bsspace[gmp->bsnum] + 512;
235   wordpointer -= backstep;
236   if (backstep)
237     memcpy(wordpointer,bsbufold+gmp->fsizeold-backstep,backstep);
238   bitindex = 0;
239   return MP3_OK;
240 }