configure.ac: Check for wavpack version and define WAVPACK_OLD_API if necessary.
[platform/upstream/gst-plugins-good.git] / ext / wavpack / gstwavpackcommon.c
1 /* GStreamer Wavpack plugin
2  * Copyright (c) 2005 Arwed v. Merkatz <v.merkatz@gmx.net>
3  * Copyright (c) 1998 - 2005 Conifer Software
4  * Copyright (c) 2006 Sebastian Dröge <slomo@circular-chaos.org>
5  *
6  * gstwavpackcommon.c: common helper functions
7  * 
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include "gstwavpackcommon.h"
29 #include <string.h>
30
31 gboolean
32 gst_wavpack_read_header (WavpackHeader * header, guint8 * buf)
33 {
34   g_memmove (header, buf, sizeof (WavpackHeader));
35
36 #ifndef WAVPACK_OLD_API
37   WavpackLittleEndianToNative (header, WavpackHeaderFormat);
38 #else
39   little_endian_to_native (header, WavpackHeaderFormat);
40 #endif
41
42   return (memcmp (header->ckID, "wvpk", 4) == 0);
43 }
44
45 /* inspired by the original one in wavpack */
46 gboolean
47 gst_wavpack_read_metadata (GstWavpackMetadata * wpmd, guint8 * header_data,
48     guint8 ** p_data)
49 {
50   WavpackHeader hdr;
51   guint8 *end;
52
53   gst_wavpack_read_header (&hdr, header_data);
54   end = header_data + hdr.ckSize + 8;
55
56   if (end - *p_data < 2)
57     return FALSE;
58
59   wpmd->id = GST_READ_UINT8 (*p_data);
60   wpmd->byte_length = 2 * (guint) GST_READ_UINT8 (*p_data + 1);
61
62   *p_data += 2;
63
64   if ((wpmd->id & ID_LARGE) == ID_LARGE) {
65     guint extra;
66
67     wpmd->id &= ~ID_LARGE;
68
69     if (end - *p_data < 2)
70       return FALSE;
71
72     extra = GST_READ_UINT16_LE (*p_data);
73     wpmd->byte_length += (extra << 9);
74     *p_data += 2;
75   }
76
77   if ((wpmd->id & ID_ODD_SIZE) == ID_ODD_SIZE) {
78     wpmd->id &= ~ID_ODD_SIZE;
79     --wpmd->byte_length;
80   }
81
82   if (wpmd->byte_length > 0) {
83     if (end - *p_data < wpmd->byte_length + (wpmd->byte_length & 1)) {
84       wpmd->data = NULL;
85       return FALSE;
86     }
87
88     wpmd->data = *p_data;
89     *p_data += wpmd->byte_length + (wpmd->byte_length & 1);
90   } else {
91     wpmd->data = NULL;
92   }
93
94   return TRUE;
95 }