don't crash when loading images > 65kB (fixes #13529)
[swfdec.git] / libswfdec / swfdec_codec_mad.c
blobec15231592893fb392dc5221b7a19cd218123595
1 /* Swfdec
2 * Copyright (C) 2006-2007 Benjamin Otte <otte@gnome.org>
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.
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 Street, Fifth Floor,
17 * Boston, MA 02110-1301 USA
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23 #include <string.h>
24 #include <config.h>
25 #include <liboil/liboil.h>
26 #include <mad.h>
28 #include "swfdec_codec_audio.h"
29 #include "swfdec_debug.h"
30 #include "swfdec_internal.h"
32 typedef struct {
33 SwfdecAudioDecoder decoder;
35 struct mad_stream stream;
36 struct mad_frame frame;
37 struct mad_synth synth;
38 guint8 data[MAD_BUFFER_MDLEN * 3];
39 guint data_len;
40 SwfdecBufferQueue * queue;
41 } MadData;
43 static SwfdecBuffer *
44 convert_synth_to_buffer (MadData *mdata)
46 SwfdecBuffer *buffer;
47 int n_samples;
48 short *data;
49 int i;
50 short c0,c1;
51 #define MAD_F_TO_S16(x) (CLAMP (x, -MAD_F_ONE, MAD_F_ONE) >> (MAD_F_FRACBITS - 14))
53 n_samples = mdata->synth.pcm.length;
54 if (n_samples == 0) {
55 return NULL;
58 switch (mdata->synth.pcm.samplerate) {
59 case 11025:
60 n_samples *= 4;
61 break;
62 case 22050:
63 n_samples *= 2;
64 break;
65 case 44100:
66 break;
67 default:
68 SWFDEC_ERROR ("sample rate not handled (%d)",
69 mdata->synth.pcm.samplerate);
70 return NULL;
73 buffer = swfdec_buffer_new_and_alloc (n_samples * 2 * 2);
74 data = (gint16 *) buffer->data;
76 if (mdata->synth.pcm.samplerate == 11025) {
77 if (mdata->synth.pcm.channels == 2) {
78 for (i = 0; i < mdata->synth.pcm.length; i++) {
79 c0 = MAD_F_TO_S16 (mdata->synth.pcm.samples[0][i]);
80 c1 = MAD_F_TO_S16 (mdata->synth.pcm.samples[1][i]);
81 *data++ = c0;
82 *data++ = c1;
83 *data++ = c0;
84 *data++ = c1;
85 *data++ = c0;
86 *data++ = c1;
87 *data++ = c0;
88 *data++ = c1;
90 } else {
91 for (i = 0; i < mdata->synth.pcm.length; i++) {
92 c0 = MAD_F_TO_S16( mdata->synth.pcm.samples[0][i]);
93 *data++ = c0;
94 *data++ = c0;
95 *data++ = c0;
96 *data++ = c0;
97 *data++ = c0;
98 *data++ = c0;
99 *data++ = c0;
100 *data++ = c0;
103 } else if (mdata->synth.pcm.samplerate == 22050) {
104 if (mdata->synth.pcm.channels == 2) {
105 for (i = 0; i < mdata->synth.pcm.length; i++) {
106 c0 = MAD_F_TO_S16 (mdata->synth.pcm.samples[0][i]);
107 c1 = MAD_F_TO_S16 (mdata->synth.pcm.samples[1][i]);
108 *data++ = c0;
109 *data++ = c1;
110 *data++ = c0;
111 *data++ = c1;
113 } else {
114 for (i = 0; i < mdata->synth.pcm.length; i++) {
115 c0 = MAD_F_TO_S16 (mdata->synth.pcm.samples[0][i]);
116 *data++ = c0;
117 *data++ = c0;
118 *data++ = c0;
119 *data++ = c0;
122 } else if (mdata->synth.pcm.samplerate == 44100) {
123 if (mdata->synth.pcm.channels == 2) {
124 for (i = 0; i < mdata->synth.pcm.length; i++) {
125 c0 = MAD_F_TO_S16 (mdata->synth.pcm.samples[0][i]);
126 c1 = MAD_F_TO_S16 (mdata->synth.pcm.samples[1][i]);
127 *data++ = c0;
128 *data++ = c1;
130 } else {
131 for (i = 0; i < mdata->synth.pcm.length; i++) {
132 c0 = MAD_F_TO_S16 (mdata->synth.pcm.samples[0][i]);
133 *data++ = c0;
134 *data++ = c0;
137 } else {
138 SWFDEC_ERROR ("sample rate not handled (%d)",
139 mdata->synth.pcm.samplerate);
141 return buffer;
144 static void
145 swfdec_audio_decoder_mad_push (SwfdecAudioDecoder *dec, SwfdecBuffer *buffer)
147 MadData *data = (MadData *) dec;
148 SwfdecBuffer *out, *empty = NULL;
149 guint amount = 0, size;
151 if (buffer == NULL) {
152 buffer = empty = swfdec_buffer_new ();
153 empty->data = g_malloc0 (MAD_BUFFER_GUARD * 3);
154 empty->length = MAD_BUFFER_GUARD * 3;
157 //write (1, buffer->data, buffer->length);
158 //g_print ("buffer %p gave us %u bytes\n", buffer, buffer->length);
159 while (amount < buffer->length) {
160 size = MIN (buffer->length - amount, MAD_BUFFER_MDLEN * 3 - data->data_len);
161 memcpy (&data->data[data->data_len], buffer->data + amount, size);
162 //write (1, buffer->data + amount, size);
163 amount += size;
164 data->data_len += size;
165 mad_stream_buffer (&data->stream, data->data, data->data_len);
166 while (1) {
167 if (mad_frame_decode (&data->frame, &data->stream)) {
168 if (data->stream.error == MAD_ERROR_BUFLEN)
169 break;
170 if (MAD_RECOVERABLE (data->stream.error)) {
171 SWFDEC_LOG ("recoverable error 0x%04x", data->stream.error);
172 continue;
174 SWFDEC_ERROR ("stream error 0x%04x", data->stream.error);
175 break;
178 mad_synth_frame (&data->synth, &data->frame);
179 out = convert_synth_to_buffer (data);
180 if (out)
181 swfdec_buffer_queue_push (data->queue, out);
183 if (data->stream.next_frame == NULL) {
184 data->data_len = 0;
185 } else {
186 data->data_len = data->stream.bufend - data->stream.next_frame;
187 memmove (data->data, data->stream.next_frame, data->data_len);
190 //g_print ("%u bytes left\n", data->data_len);
192 if (empty)
193 swfdec_buffer_unref (empty);
196 static void
197 swfdec_audio_decoder_mad_free (SwfdecAudioDecoder *dec)
199 MadData *data = (MadData *) dec;
201 mad_synth_finish (&data->synth);
202 mad_frame_finish (&data->frame);
203 mad_stream_finish (&data->stream);
204 swfdec_buffer_queue_unref (data->queue);
205 g_slice_free (MadData, data);
208 static SwfdecBuffer *
209 swfdec_audio_decoder_mad_pull (SwfdecAudioDecoder *dec)
211 return swfdec_buffer_queue_pull_buffer (((MadData *) dec)->queue);
214 SwfdecAudioDecoder *
215 swfdec_audio_decoder_mad_new (guint type, SwfdecAudioFormat format)
217 MadData *data;
219 if (type != SWFDEC_AUDIO_CODEC_MP3)
220 return NULL;
222 data = g_slice_new (MadData);
223 data->decoder.format = swfdec_audio_format_new (44100, 2, TRUE);
224 data->decoder.push = swfdec_audio_decoder_mad_push;
225 data->decoder.pull = swfdec_audio_decoder_mad_pull;
226 data->decoder.free = swfdec_audio_decoder_mad_free;
227 mad_stream_init (&data->stream);
228 mad_frame_init (&data->frame);
229 mad_synth_init (&data->synth);
230 data->data_len = 0;
231 data->queue = swfdec_buffer_queue_new ();
233 return &data->decoder;