winecfg: Move controls on "Desktop Integration" tab to make more room for the next...
[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                 if(!mp->tail) {
126                         fprintf(stderr,"Fatal error!\n");
127                         exit(1);
128                 }
129         }
130
131         b = mp->tail->pnt[pos];
132         mp->bsize--;
133         mp->tail->pos++;
134
135
136         return b;
137 }
138
139 static void read_head(struct mpstr *mp)
140 {
141         unsigned long head;
142
143         head = read_buf_byte(mp);
144         head <<= 8;
145         head |= read_buf_byte(mp);
146         head <<= 8;
147         head |= read_buf_byte(mp);
148         head <<= 8;
149         head |= read_buf_byte(mp);
150
151         mp->header = head;
152 }
153
154 int decodeMP3(struct mpstr *mp,const unsigned char *in,int isize,unsigned char *out,
155                 int osize,int *done)
156 {
157         int len;
158
159         gmp = mp;
160
161         if(osize < 4608) {
162                 fprintf(stderr,"To less out space\n");
163                 return MP3_ERR;
164         }
165
166         if(in) {
167                 if(addbuf(mp,in,isize) == NULL) {
168                         return MP3_ERR;
169                 }
170         }
171
172         /* First decode header */
173         if(mp->framesize == 0) {
174                 if(mp->bsize < 4) {
175                         return MP3_NEED_MORE;
176                 }
177                 read_head(mp);
178                 if (decode_header(&mp->fr,mp->header) == 0) {
179                         return MP3_ERR;
180                 }
181                 mp->framesize = mp->fr.framesize;
182         }
183
184         if(mp->fr.framesize > mp->bsize)
185                 return MP3_NEED_MORE;
186
187         wordpointer = mp->bsspace[mp->bsnum] + 512;
188         mp->bsnum = (mp->bsnum + 1) & 0x1;
189         bitindex = 0;
190
191         len = 0;
192         while(len < mp->framesize) {
193                 int nlen;
194                 int blen = mp->tail->size - mp->tail->pos;
195                 if( (mp->framesize - len) <= blen) {
196                   nlen = mp->framesize-len;
197                 }
198                 else {
199                   nlen = blen;
200                 }
201                 memcpy(wordpointer+len,mp->tail->pnt+mp->tail->pos,nlen);
202                 len += nlen;
203                 mp->tail->pos += nlen;
204                 mp->bsize -= nlen;
205                 if(mp->tail->pos == mp->tail->size) {
206                    remove_buf(mp);
207                 }
208         }
209
210         *done = 0;
211         if(mp->fr.error_protection)
212            getbits(16);
213         switch(mp->fr.lay) {
214           case 1:
215             do_layer1(&mp->fr,(unsigned char *) out,done);
216             break;
217           case 2:
218             do_layer2(&mp->fr,(unsigned char *) out,done);
219             break;
220           case 3:
221             do_layer3(&mp->fr,(unsigned char *) out,done);
222             break;
223         }
224
225         mp->fsizeold = mp->framesize;
226         mp->framesize = 0;
227
228         return MP3_OK;
229 }
230
231 int set_pointer(long backstep)
232 {
233   unsigned char *bsbufold;
234   if(gmp->fsizeold < 0 && backstep > 0) {
235     fprintf(stderr,"Can't step back %ld!\n",backstep);
236     return MP3_ERR;
237   }
238   bsbufold = gmp->bsspace[gmp->bsnum] + 512;
239   wordpointer -= backstep;
240   if (backstep)
241     memcpy(wordpointer,bsbufold+gmp->fsizeold-backstep,backstep);
242   bitindex = 0;
243   return MP3_OK;
244 }