wined3d: Only copy front buffer to screen in gdi RealizePalette.
[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 "config.h"
20 #include <stdlib.h>
21 #include <stdio.h>
22
23 #include "wine/debug.h"
24 #include "mpg123.h"
25 #include "mpglib.h"
26
27 WINE_DEFAULT_DEBUG_CHANNEL(mpeg3);
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         mp->fr.mp = mp;
43
44         if(!init) {
45                 init = 1;
46                 make_decode_tables(32767);
47                 init_layer2();
48                 init_layer3(SBLIMIT);
49         }
50
51         return !0;
52 }
53
54 void ClearMP3Buffer(struct mpstr *mp)
55 {
56         struct buf *b,*bn;
57
58         b = mp->tail;
59         while(b) {
60                 free(b->pnt);
61                 bn = b->next;
62                 free(b);
63                 b = bn;
64         }
65         mp->tail = NULL;
66         mp->head = NULL;
67         mp->bsize = 0;
68 }
69
70 static struct buf *addbuf(struct mpstr *mp,const unsigned char *buf,int size)
71 {
72         struct buf *nbuf;
73
74         nbuf = malloc( sizeof(struct buf) );
75         if(!nbuf) {
76                 WARN("Out of memory!\n");
77                 return NULL;
78         }
79         nbuf->pnt = malloc(size);
80         if(!nbuf->pnt) {
81                 free(nbuf);
82                 WARN("Out of memory!\n");
83                 return NULL;
84         }
85         nbuf->size = size;
86         memcpy(nbuf->pnt,buf,size);
87         nbuf->next = NULL;
88         nbuf->prev = mp->head;
89         nbuf->pos = 0;
90
91         if(!mp->tail) {
92                 mp->tail = nbuf;
93         }
94         else {
95           mp->head->next = nbuf;
96         }
97
98         mp->head = nbuf;
99         mp->bsize += size;
100
101         return nbuf;
102 }
103
104 static void remove_buf(struct mpstr *mp)
105 {
106   struct buf *buf = mp->tail;
107
108   mp->tail = buf->next;
109   if(mp->tail)
110     mp->tail->prev = NULL;
111   else {
112     mp->tail = mp->head = NULL;
113   }
114
115   free(buf->pnt);
116   free(buf);
117
118 }
119
120 static int read_buf_byte(struct mpstr *mp)
121 {
122         unsigned int b;
123
124         int pos;
125
126         pos = mp->tail->pos;
127         while(pos >= mp->tail->size) {
128                 remove_buf(mp);
129                 pos = mp->tail->pos;
130         }
131
132         b = mp->tail->pnt[pos];
133         mp->bsize--;
134         mp->tail->pos++;
135
136
137         return b;
138 }
139
140 static void read_head(struct mpstr *mp)
141 {
142         unsigned long head;
143
144         head = read_buf_byte(mp);
145         head <<= 8;
146         head |= read_buf_byte(mp);
147         head <<= 8;
148         head |= read_buf_byte(mp);
149         head <<= 8;
150         head |= read_buf_byte(mp);
151
152         mp->header = head;
153 }
154
155 int decodeMP3(struct mpstr *mp,const unsigned char *in,int isize,unsigned char *out,
156                 int osize,int *done)
157 {
158         int len;
159
160         if(osize < 4608) {
161                 ERR("Output buffer too small\n");
162                 return MP3_ERR;
163         }
164
165         if(in) {
166                 if(addbuf(mp,in,isize) == NULL) {
167                         return MP3_ERR;
168                 }
169         }
170
171         /* First decode header */
172         if(mp->framesize == 0) {
173                 if(mp->bsize < 4) {
174                         return MP3_NEED_MORE;
175                 }
176                 read_head(mp);
177                 if (decode_header(&mp->fr,mp->header) == 0) {
178                         return MP3_ERR;
179                 }
180                 mp->framesize = mp->fr.framesize;
181         }
182
183         if(mp->fr.framesize > mp->bsize)
184                 return MP3_NEED_MORE;
185
186         wordpointer = mp->bsspace[mp->bsnum] + 512;
187         mp->bsnum = (mp->bsnum + 1) & 0x1;
188         bitindex = 0;
189
190         len = 0;
191         while(len < mp->framesize) {
192                 int nlen;
193                 int blen = mp->tail->size - mp->tail->pos;
194                 if( (mp->framesize - len) <= blen) {
195                   nlen = mp->framesize-len;
196                 }
197                 else {
198                   nlen = blen;
199                 }
200                 memcpy(wordpointer+len,mp->tail->pnt+mp->tail->pos,nlen);
201                 len += nlen;
202                 mp->tail->pos += nlen;
203                 mp->bsize -= nlen;
204                 if(mp->tail->pos == mp->tail->size) {
205                    remove_buf(mp);
206                 }
207         }
208
209         *done = 0;
210         if(mp->fr.error_protection)
211            getbits(16);
212         switch(mp->fr.lay) {
213           case 1:
214             do_layer1(&mp->fr,out,done);
215             break;
216           case 2:
217             do_layer2(&mp->fr,out,done);
218             break;
219           case 3:
220             do_layer3(&mp->fr,out,done);
221             break;
222         }
223
224         mp->fsizeold = mp->framesize;
225         mp->framesize = 0;
226
227         return MP3_OK;
228 }
229
230 int set_pointer(struct mpstr *mp, long backstep)
231 {
232   unsigned char *bsbufold;
233   if(mp->fsizeold < 0 && backstep > 0) {
234     /* This is not a bug if we just did seeking, the first frame is dropped then */
235     WARN("Can't step back %ld!\n",backstep);
236     return MP3_ERR;
237   }
238   bsbufold = mp->bsspace[mp->bsnum] + 512;
239   wordpointer -= backstep;
240   if (backstep)
241     memcpy(wordpointer,bsbufold+mp->fsizeold-backstep,backstep);
242   bitindex = 0;
243   return MP3_OK;
244 }