Bug Summary

File:build-analysis/../src/plugins/wavpack/wavpack.c
Warning:line 325, column 25
The left operand of '/' is a garbage value

Annotated Source Code

1/* XMMS2 - X Music Multiplexer System
2 * Copyright (C) 2006-2017 XMMS2 Team
3 *
4 * PLUGINS ARE NOT CONSIDERED TO BE DERIVED WORK !!!
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 */
16
17/**
18 * @file WavPack decoder
19 * @url http://wavpack.com
20 */
21
22#include <xmms/xmms_xformplugin.h>
23#include <xmms/xmms_log.h>
24#include <xmms/xmms_medialib.h>
25
26#include <glib.h>
27#include <math.h>
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31#include <wavpack/wavpack.h>
32
33#include "../apev2_common/apev2.c"
34
35typedef struct xmms_wavpack_data_St {
36 WavpackContext *ctx;
37 WavpackStreamReader reader;
38
39 gint channels;
40 gint bits_per_sample;
41 gint num_samples;
42
43 guint8 pushback_byte;
44 gboolean pushback_set;
45
46 xmms_samples32_t *buf;
47 gint buf_mono_samples;
48} xmms_wavpack_data_t;
49
50/** These are the properties that we extract from the comments */
51static const xmms_xform_metadata_basic_mapping_t basic_mappings[] = {
52 { "Album", XMMS_MEDIALIB_ENTRY_PROPERTY_ALBUM"album" },
53 { "Title", XMMS_MEDIALIB_ENTRY_PROPERTY_TITLE"title" },
54 { "Artist", XMMS_MEDIALIB_ENTRY_PROPERTY_ARTIST"artist" },
55 { "Album Artist", XMMS_MEDIALIB_ENTRY_PROPERTY_ALBUM_ARTIST"album_artist" },
56 { "Track", XMMS_MEDIALIB_ENTRY_PROPERTY_TRACKNR"tracknr" },
57 { "Disc", XMMS_MEDIALIB_ENTRY_PROPERTY_PARTOFSET"partofset" },
58 { "Year", XMMS_MEDIALIB_ENTRY_PROPERTY_YEAR"date" },
59 { "Composer", XMMS_MEDIALIB_ENTRY_PROPERTY_COMPOSER"composer" },
60 { "Lyricist", XMMS_MEDIALIB_ENTRY_PROPERTY_LYRICIST"lyricist" },
61 { "Conductor", XMMS_MEDIALIB_ENTRY_PROPERTY_CONDUCTOR"conductor" },
62 { "Performer", XMMS_MEDIALIB_ENTRY_PROPERTY_PERFORMER"performer" },
63 { "MixArtist", XMMS_MEDIALIB_ENTRY_PROPERTY_REMIXER"remixer" },
64 { "Arranger", XMMS_MEDIALIB_ENTRY_PROPERTY_ARRANGER"arranger" },
65 { "Producer", XMMS_MEDIALIB_ENTRY_PROPERTY_PRODUCER"producer" },
66 { "Mixer", XMMS_MEDIALIB_ENTRY_PROPERTY_MIXER"mixer" },
67 { "Grouping", XMMS_MEDIALIB_ENTRY_PROPERTY_GROUPING"grouping" },
68 { "Compilation", XMMS_MEDIALIB_ENTRY_PROPERTY_COMPILATION"compilation" },
69 { "Comment", XMMS_MEDIALIB_ENTRY_PROPERTY_COMMENT"comment" },
70 { "Genre", XMMS_MEDIALIB_ENTRY_PROPERTY_GENRE"genre" },
71 { "BPM", XMMS_MEDIALIB_ENTRY_PROPERTY_BPM"bpm" },
72 { "ASIN", XMMS_MEDIALIB_ENTRY_PROPERTY_ASIN"asin" },
73 { "ISRC", XMMS_MEDIALIB_ENTRY_PROPERTY_ISRC"isrc" },
74 { "Label", XMMS_MEDIALIB_ENTRY_PROPERTY_PUBLISHER"publisher" },
75 { "Copyright", XMMS_MEDIALIB_ENTRY_PROPERTY_COPYRIGHT"copyright" },
76 { "CatalogNumber", XMMS_MEDIALIB_ENTRY_PROPERTY_CATALOGNUMBER"catalognumber" },
77 { "Barcode", XMMS_MEDIALIB_ENTRY_PROPERTY_BARCODE"barcode" },
78 { "ALBUMSORT", XMMS_MEDIALIB_ENTRY_PROPERTY_ALBUM_SORT"album_sort" },
79 { "ALBUMARTISTSORT", XMMS_MEDIALIB_ENTRY_PROPERTY_ALBUM_ARTIST_SORT"album_artist_sort" },
80 { "ARTISTSORT", XMMS_MEDIALIB_ENTRY_PROPERTY_ARTIST_SORT"artist_sort" },
81 { "MUSICBRAINZ_TRACKID", XMMS_MEDIALIB_ENTRY_PROPERTY_TRACK_ID"track_id" },
82 { "MUSICBRAINZ_ALBUMID", XMMS_MEDIALIB_ENTRY_PROPERTY_ALBUM_ID"album_id" },
83 { "MUSICBRAINZ_ARTISTID", XMMS_MEDIALIB_ENTRY_PROPERTY_ARTIST_ID"artist_id" },
84 { "MUSICBRAINZ_ALBUMARTISTID", XMMS_MEDIALIB_ENTRY_PROPERTY_COMPILATION"compilation" },
85
86 /* foobar2000 free-form strings (not in APEv2 spec) */
87 { "tracknumber", XMMS_MEDIALIB_ENTRY_PROPERTY_TRACKNR"tracknr", },
88 { "discnumber", XMMS_MEDIALIB_ENTRY_PROPERTY_PARTOFSET"partofset", },
89
90 /* ReplayGain (including obsolete tag names - priority to new style tags) */
91 { "rg_audiophile", XMMS_MEDIALIB_ENTRY_PROPERTY_GAIN_ALBUM"gain_album", },
92 { "replaygain_album_gain", XMMS_MEDIALIB_ENTRY_PROPERTY_GAIN_ALBUM"gain_album", },
93 { "replaygain_album_peak", XMMS_MEDIALIB_ENTRY_PROPERTY_PEAK_ALBUM"peak_album", },
94 { "rg_radio", XMMS_MEDIALIB_ENTRY_PROPERTY_GAIN_TRACK"gain_track", },
95 { "replaygain_track_gain", XMMS_MEDIALIB_ENTRY_PROPERTY_GAIN_TRACK"gain_track", },
96 { "rg_peak", XMMS_MEDIALIB_ENTRY_PROPERTY_PEAK_TRACK"peak_track", },
97 { "replaygain_track_peak", XMMS_MEDIALIB_ENTRY_PROPERTY_PEAK_TRACK"peak_track", }
98};
99
100static const xmms_xform_metadata_mapping_t mappings[] = {
101 { "Cover Art (Front)", xmms_apetag_handle_tag_coverart }
102};
103
104/*
105 * Function prototypes
106 */
107
108static gboolean xmms_wavpack_plugin_setup (xmms_xform_plugin_t *xform_plugin);
109static gboolean xmms_wavpack_init (xmms_xform_t *xform);
110static gint64 xmms_wavpack_seek (xmms_xform_t *xform, gint64 samples,
111 xmms_xform_seek_mode_t whence, xmms_error_t *error);
112static gint xmms_wavpack_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len,
113 xmms_error_t *error);
114static void xmms_wavpack_destroy (xmms_xform_t *xform);
115
116static void xmms_wavpack_free_data (xmms_wavpack_data_t *data);
117static int32_t wavpack_read_bytes (void *id, void *data, int32_t bcount);
118static uint32_t wavpack_get_pos (void *id);
119static int wavpack_set_pos_abs (void *id, uint32_t pos);
120static int wavpack_set_pos_rel (void *id, int32_t pos, int whence);
121static int wavpack_push_back_byte (void *id, int c);
122static uint32_t wavpack_get_length (void *id);
123static int wavpack_can_seek (void *id);
124
125/*
126 * Plugin header
127 */
128
129XMMS_XFORM_PLUGIN_DEFINE ("wavpack",xmms_plugin_desc_t __attribute__((visibility ("default"))) XMMS_PLUGIN_DESC
= { XMMS_PLUGIN_TYPE_XFORM, 7, "wavpack", "WavPack Decoder",
"clang-analysis", "WavPack decoder", (gboolean (*)(gpointer)
)xmms_wavpack_plugin_setup };
130 "WavPack Decoder", XMMS_VERSION,xmms_plugin_desc_t __attribute__((visibility ("default"))) XMMS_PLUGIN_DESC
= { XMMS_PLUGIN_TYPE_XFORM, 7, "wavpack", "WavPack Decoder",
"clang-analysis", "WavPack decoder", (gboolean (*)(gpointer)
)xmms_wavpack_plugin_setup };
131 "WavPack decoder",xmms_plugin_desc_t __attribute__((visibility ("default"))) XMMS_PLUGIN_DESC
= { XMMS_PLUGIN_TYPE_XFORM, 7, "wavpack", "WavPack Decoder",
"clang-analysis", "WavPack decoder", (gboolean (*)(gpointer)
)xmms_wavpack_plugin_setup };
132 xmms_wavpack_plugin_setup)xmms_plugin_desc_t __attribute__((visibility ("default"))) XMMS_PLUGIN_DESC
= { XMMS_PLUGIN_TYPE_XFORM, 7, "wavpack", "WavPack Decoder",
"clang-analysis", "WavPack decoder", (gboolean (*)(gpointer)
)xmms_wavpack_plugin_setup };
;
133
134static gboolean
135xmms_wavpack_plugin_setup (xmms_xform_plugin_t *xform_plugin)
136{
137 xmms_xform_methods_t methods;
138
139 XMMS_XFORM_METHODS_INIT (methods)memset (&methods, 0, sizeof (xmms_xform_methods_t));
140
141 methods.init = xmms_wavpack_init;
142 methods.destroy = xmms_wavpack_destroy;
143 methods.read = xmms_wavpack_read;
144 methods.seek = xmms_wavpack_seek;
145
146 xmms_xform_plugin_methods_set (xform_plugin, &methods);
147
148 xmms_xform_plugin_metadata_mapper_init (xform_plugin,
149 basic_mappings,
150 G_N_ELEMENTS (basic_mappings)(sizeof (basic_mappings) / sizeof ((basic_mappings)[0])),
151 mappings,
152 G_N_ELEMENTS (mappings)(sizeof (mappings) / sizeof ((mappings)[0])));
153
154 xmms_xform_plugin_indata_add (xform_plugin,
155 XMMS_STREAM_TYPE_MIMETYPE,
156 "audio/x-wavpack",
157 XMMS_STREAM_TYPE_END);
158
159 xmms_magic_add ("wavpack header v4", "audio/x-wavpack",
160 "0 string wvpk", NULL((void*)0));
161
162 xmms_magic_extension_add ("audio/x-wavpack", "*.wv");
163
164 return TRUE(!(0));
165}
166
167static gboolean
168xmms_wavpack_init (xmms_xform_t *xform)
169{
170 xmms_wavpack_data_t *data;
171 xmms_sample_format_t sample_format;
172 gint samplerate;
173 /* the maximum length of error really isn't defined... stupid */
174 gchar error[1024];
175
176 g_return_val_if_fail (xform, FALSE)do{ if (xform) { } else { g_return_if_fail_warning (((gchar*)
0), ((const char*) (__func__)), "xform"); return ((0)); }; }
while (0)
;
177
178 if (!xmms_apetag_read (xform)) {
179 XMMS_DBG ("Failed to read APEv2 tag")g_debug ("../src/plugins/wavpack/wavpack.c" ":" "179" ": " "Failed to read APEv2 tag"
)
;
180 }
181
182 data = g_new0 (xmms_wavpack_data_t, 1)((xmms_wavpack_data_t *) g_malloc0_n ((1), sizeof (xmms_wavpack_data_t
)))
;
183 g_return_val_if_fail (data, FALSE)do{ if (data) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "data"); return ((0)); }; }while
(0)
;
184
185 xmms_xform_private_data_set (xform, data);
186
187 data->reader.read_bytes = wavpack_read_bytes;
188 data->reader.get_pos = wavpack_get_pos;
189 data->reader.set_pos_abs = wavpack_set_pos_abs;
190 data->reader.set_pos_rel = wavpack_set_pos_rel;
191 data->reader.push_back_byte = wavpack_push_back_byte;
192 data->reader.get_length = wavpack_get_length;
193 data->reader.can_seek = wavpack_can_seek;
194
195 data->ctx = WavpackOpenFileInputEx (&data->reader,
196 xform, xform,
197 error, OPEN_TAGS0x2, 0);
198
199 if (!data->ctx) {
200 xmms_log_error ("Unable to open wavpack file: %s", error)g_warning ("../src/plugins/wavpack/wavpack.c" ":" "200" ": " "Unable to open wavpack file: %s"
, error)
;
201 xmms_xform_private_data_set (xform, NULL((void*)0));
202 xmms_wavpack_free_data (data);
203 return FALSE(0);
204 }
205
206 data->channels = WavpackGetNumChannels (data->ctx);
207 data->bits_per_sample = WavpackGetBitsPerSample (data->ctx);
208 data->num_samples = WavpackGetNumSamples (data->ctx);
209 samplerate = WavpackGetSampleRate (data->ctx);
210
211 xmms_xform_metadata_set_int (xform,
212 XMMS_MEDIALIB_ENTRY_PROPERTY_DURATION"duration",
213 (int) (1000.0 * data->num_samples / samplerate));
214 xmms_xform_metadata_set_int (xform,
215 XMMS_MEDIALIB_ENTRY_PROPERTY_SAMPLERATE"samplerate",
216 samplerate);
217 xmms_xform_metadata_set_int (xform,
218 XMMS_MEDIALIB_ENTRY_PROPERTY_BITRATE"bitrate",
219 (int) WavpackGetAverageBitrate (data->ctx, FALSE(0)));
220
221 switch (data->bits_per_sample) {
222 case 8:
223 sample_format = XMMS_SAMPLE_FORMAT_S8;
224 break;
225 case 12:
226 case 16:
227 sample_format = XMMS_SAMPLE_FORMAT_S16;
228 break;
229 case 24:
230 case 32:
231 sample_format = XMMS_SAMPLE_FORMAT_S32;
232 break;
233 default:
234 xmms_log_error ("Unsupported bits-per-sample in wavpack file: %d",g_warning ("../src/plugins/wavpack/wavpack.c" ":" "235" ": " "Unsupported bits-per-sample in wavpack file: %d"
, data->bits_per_sample)
235 data->bits_per_sample)g_warning ("../src/plugins/wavpack/wavpack.c" ":" "235" ": " "Unsupported bits-per-sample in wavpack file: %d"
, data->bits_per_sample)
;
236 xmms_xform_private_data_set (xform, NULL((void*)0));
237 xmms_wavpack_free_data (data);
238 return FALSE(0);
239 }
240
241 xmms_xform_outdata_type_add (xform,
242 XMMS_STREAM_TYPE_MIMETYPE,
243 "audio/pcm",
244 XMMS_STREAM_TYPE_FMT_FORMAT,
245 sample_format,
246 XMMS_STREAM_TYPE_FMT_CHANNELS,
247 data->channels,
248 XMMS_STREAM_TYPE_FMT_SAMPLERATE,
249 samplerate,
250 XMMS_STREAM_TYPE_END);
251
252 return TRUE(!(0));
253}
254
255static gint64
256xmms_wavpack_seek (xmms_xform_t *xform, gint64 samples,
257 xmms_xform_seek_mode_t whence, xmms_error_t *error)
258{
259 xmms_wavpack_data_t *data;
260 gint ret;
261
262 g_return_val_if_fail (xform, -1)do{ if (xform) { } else { g_return_if_fail_warning (((gchar*)
0), ((const char*) (__func__)), "xform"); return (-1); }; }while
(0)
;
263 g_return_val_if_fail (samples >= 0, -1)do{ if (samples >= 0) { } else { g_return_if_fail_warning (
((gchar*) 0), ((const char*) (__func__)), "samples >= 0");
return (-1); }; }while (0)
;
264 g_return_val_if_fail (whence == XMMS_XFORM_SEEK_SET, -1)do{ if (whence == XMMS_XFORM_SEEK_SET) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "whence == XMMS_XFORM_SEEK_SET"
); return (-1); }; }while (0)
;
265
266 data = xmms_xform_private_data_get (xform);
267 g_return_val_if_fail (data, -1)do{ if (data) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "data"); return (-1); }; }while
(0)
;
268
269 ret = WavpackSeekSample (data->ctx, (uint32_t)samples);
270
271 if (ret) {
272 /* success */
273 return samples;
274 } else {
275 return -1;
276 }
277}
278
279static void
280xmms_wavpack_ensure_buf (xmms_wavpack_data_t *data, gint mono_samples)
281{
282 if (data->buf_mono_samples < mono_samples) {
283 data->buf = g_realloc (data->buf,
284 mono_samples * sizeof (xmms_samples32_t));
285 data->buf_mono_samples = mono_samples;
286 }
287}
288
289static gint
290xmms_wavpack_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len,
291 xmms_error_t *error)
292{
293 xmms_wavpack_data_t *data;
294 gint mono_samples, samples;
1
'mono_samples' declared without an initial value
295 xmms_samples32_t *buf32;
296 gint i;
297
298 g_return_val_if_fail (xform, -1)do{ if (xform) { } else { g_return_if_fail_warning (((gchar*)
0), ((const char*) (__func__)), "xform"); return (-1); }; }while
(0)
;
299
300 data = xmms_xform_private_data_get (xform);
301 g_return_val_if_fail (data, -1)do{ if (data) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "data"); return (-1); }; }while
(0)
;
302
303 switch (data->bits_per_sample) {
2
'Default' branch taken. Execution continues on line 325
304 case 8:
305 mono_samples = len;
306 xmms_wavpack_ensure_buf (data, mono_samples);
307 buf32 = data->buf;
308 break;
309 case 12:
310 case 16:
311 mono_samples = len / 2;
312 xmms_wavpack_ensure_buf (data, mono_samples);
313 buf32 = data->buf;
314 break;
315 case 24:
316 mono_samples = len / 4;
317 buf32 = buf;
318 break;
319 case 32:
320 mono_samples = len / 4;
321 buf32 = buf;
322 break;
323 }
324
325 samples = mono_samples / data->channels;
3
The left operand of '/' is a garbage value
326
327 samples = WavpackUnpackSamples (data->ctx, buf32, samples);
328
329 mono_samples = samples * data->channels;
330
331 switch (data->bits_per_sample) {
332 case 8:
333 len = mono_samples;
334 for (i=0; i<mono_samples; ++i) {
335 ((xmms_samples8_t *) buf)[i] = data->buf[i];
336 }
337 break;
338 case 12:
339 len = mono_samples * 2;
340 for (i=0; i<mono_samples; ++i) {
341 ((xmms_samples16_t *) buf)[i] = data->buf[i] << 4;
342 }
343 break;
344 case 16:
345 len = mono_samples * 2;
346 for (i=0; i<mono_samples; ++i) {
347 ((xmms_samples16_t *) buf)[i] = data->buf[i];
348 }
349 break;
350 case 24:
351 len = mono_samples * 4;
352 for (i=0; i<mono_samples; ++i) {
353 ((xmms_samples32_t *) buf)[i] <<= 8;
354 }
355 break;
356 case 32:
357 len = mono_samples * 4;
358 break;
359 }
360
361 return len;
362}
363
364static void
365xmms_wavpack_destroy (xmms_xform_t *xform)
366{
367 xmms_wavpack_data_t *data;
368
369 g_return_if_fail (xform)do{ if (xform) { } else { g_return_if_fail_warning (((gchar*)
0), ((const char*) (__func__)), "xform"); return; }; }while (
0)
;
370
371 data = xmms_xform_private_data_get (xform);
372 g_return_if_fail (data)do{ if (data) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "data"); return; }; }while (0)
;
373
374 xmms_wavpack_free_data (data);
375}
376
377static int32_t
378wavpack_read_bytes (void *id, void *buf, int32_t bcount)
379{
380 xmms_xform_t *xform = id;
381 xmms_wavpack_data_t *data;
382 xmms_error_t error;
383 gint64 ret;
384 gboolean did_pushback = FALSE(0);
385
386 g_return_val_if_fail (xform, -1)do{ if (xform) { } else { g_return_if_fail_warning (((gchar*)
0), ((const char*) (__func__)), "xform"); return (-1); }; }while
(0)
;
387
388 data = xmms_xform_private_data_get (xform);
389 g_return_val_if_fail (data, -1)do{ if (data) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "data"); return (-1); }; }while
(0)
;
390
391 /* if we have pushback data, consume it */
392 if (data->pushback_set && bcount > 0) {
393 ((guint8 *)buf)[0] = data->pushback_byte;
394 buf++;
395 bcount--;
396
397 data->pushback_set = FALSE(0);
398
399 did_pushback = TRUE(!(0));
400
401 if (bcount == 0) {
402 return 1;
403 }
404 }
405
406 ret = xmms_xform_read (xform, buf, bcount, &error);
407
408 if (ret != -1 && did_pushback) {
409 /* adjust return value if we consumed the pushback byte */
410 ret++;
411 }
412
413 return ret;
414}
415
416static uint32_t
417wavpack_get_pos (void *id)
418{
419 xmms_xform_t *xform = id;
420 xmms_wavpack_data_t *data;
421 xmms_error_t error;
422
423 g_return_val_if_fail (xform, (uint32_t)-1)do{ if (xform) { } else { g_return_if_fail_warning (((gchar*)
0), ((const char*) (__func__)), "xform"); return ((uint32_t)
-1); }; }while (0)
;
424
425 data = xmms_xform_private_data_get (xform);
426 g_return_val_if_fail (data, (uint32_t)-1)do{ if (data) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "data"); return ((uint32_t)-1)
; }; }while (0)
;
427
428 gint64 pos = xmms_xform_seek (xform, 0, XMMS_XFORM_SEEK_CUR, &error);
429
430 if (data->pushback_set) {
431 /* we didn't actually perform the pushback on the
432 underlying stream so adjust offset accordingly */
433 pos--;
434 }
435
436 return (uint32_t)pos;
437}
438
439/* return 0 on success, -1 on error */
440static int
441wavpack_set_pos_abs (void *id, uint32_t pos)
442{
443 xmms_xform_t *xform = id;
444 xmms_wavpack_data_t *data;
445 xmms_error_t error;
446 gint ret;
447
448 g_return_val_if_fail (xform, -1)do{ if (xform) { } else { g_return_if_fail_warning (((gchar*)
0), ((const char*) (__func__)), "xform"); return (-1); }; }while
(0)
;
449
450 data = xmms_xform_private_data_get (xform);
451 g_return_val_if_fail (data, -1)do{ if (data) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "data"); return (-1); }; }while
(0)
;
452
453 ret = xmms_xform_seek (xform, pos, XMMS_XFORM_SEEK_SET, &error);
454
455 if (ret == -1) {
456 return -1;
457 }
458
459 data->pushback_set = FALSE(0);
460
461 return 0;
462}
463
464/* return 0 on success, -1 on error */
465static int
466wavpack_set_pos_rel (void *id, int32_t pos, int whence)
467{
468 xmms_xform_t *xform = id;
469 xmms_wavpack_data_t *data;
470 xmms_error_t error;
471 gint ret;
472
473 g_return_val_if_fail (xform, -1)do{ if (xform) { } else { g_return_if_fail_warning (((gchar*)
0), ((const char*) (__func__)), "xform"); return (-1); }; }while
(0)
;
474
475 data = xmms_xform_private_data_get (xform);
476 g_return_val_if_fail (data, -1)do{ if (data) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "data"); return (-1); }; }while
(0)
;
477
478 if (whence == SEEK_CUR1) {
479 whence = XMMS_XFORM_SEEK_CUR;
480
481 if (data->pushback_set) {
482 /* we didn't actually perform the pushback on the
483 underlying stream so adjust offset accordingly */
484 pos--;
485 }
486 } else if (whence == SEEK_SET0) {
487 whence = XMMS_XFORM_SEEK_SET;
488 } else if (whence == SEEK_END2) {
489 whence = XMMS_XFORM_SEEK_END;
490 }
491
492 ret = xmms_xform_seek (xform, pos, whence, &error);
493
494 data->pushback_set = FALSE(0);
495
496 return ((ret != -1) ? 0 : -1);
497}
498
499static int
500wavpack_push_back_byte (void *id, int c)
501{
502 xmms_xform_t *xform = id;
503 xmms_wavpack_data_t *data;
504
505 g_return_val_if_fail (xform, EOF)do{ if (xform) { } else { g_return_if_fail_warning (((gchar*)
0), ((const char*) (__func__)), "xform"); return ((-1)); }; }
while (0)
;
506
507 data = xmms_xform_private_data_get (xform);
508 g_return_val_if_fail (data, EOF)do{ if (data) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "data"); return ((-1)); }; }while
(0)
;
509
510 if (data->pushback_set) {
511 /* current implementation only supports pushing back one byte,
512 and in wavpack-4.31 this is enough */
513 /* => return failure */
514 return EOF(-1);
515 }
516
517 data->pushback_byte = c;
518 data->pushback_set = TRUE(!(0));
519
520 return c;
521}
522
523static uint32_t
524wavpack_get_length (void *id)
525{
526 xmms_xform_t *xform = id;
527 gint filesize;
528 const gchar *metakey;
529
530 metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_SIZE"size";
531 if (!xmms_xform_metadata_get_int (xform, metakey, &filesize)) {
532 filesize = 0;
533 }
534
535 return filesize;
536}
537
538static int
539wavpack_can_seek (void *id)
540{
541 xmms_xform_t *xform = id;
542 xmms_error_t error;
543 int ret;
544
545 ret = xmms_xform_seek (xform, 0, XMMS_XFORM_SEEK_CUR, &error);
546
547 return (ret != -1);
548}
549
550static void
551xmms_wavpack_free_data (xmms_wavpack_data_t *data)
552{
553 if (!data) {
554 return;
555 }
556
557 if (data->buf) {
558 g_free (data->buf);
559 }
560
561 if (data->ctx) {
562 WavpackCloseFile (data->ctx);
563 }
564
565 g_free (data);
566}