summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/libwavpack/metadata.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/libwavpack/metadata.c')
-rw-r--r--lib/rbcodec/codecs/libwavpack/metadata.c171
1 files changed, 171 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libwavpack/metadata.c b/lib/rbcodec/codecs/libwavpack/metadata.c
new file mode 100644
index 0000000000..4dce10100f
--- /dev/null
+++ b/lib/rbcodec/codecs/libwavpack/metadata.c
@@ -0,0 +1,171 @@
1////////////////////////////////////////////////////////////////////////////
2// **** WAVPACK **** //
3// Hybrid Lossless Wavefile Compressor //
4// Copyright (c) 1998 - 2003 Conifer Software. //
5// All Rights Reserved. //
6// Distributed under the BSD Software License (see license.txt) //
7////////////////////////////////////////////////////////////////////////////
8
9// metadata.c
10
11// This module handles the metadata structure introduced in WavPack 4.0
12
13#include "wavpack.h"
14
15#include <string.h>
16
17int read_metadata_buff (WavpackContext *wpc, WavpackMetadata *wpmd)
18{
19 uint32_t bytes_to_read;
20 uchar tchar;
21
22 if (wpc->stream.block_bytes_left < 2 || !wpc->infile (&wpmd->id, 1) || !wpc->infile (&tchar, 1))
23 return FALSE;
24
25 wpmd->byte_length = tchar << 1;
26 wpc->stream.block_bytes_left -= 2;
27
28 if (wpmd->id & ID_LARGE) {
29 wpmd->id &= ~ID_LARGE;
30
31 if (wpc->stream.block_bytes_left < 2 || !wpc->infile (&tchar, 1))
32 return FALSE;
33
34 wpmd->byte_length += (int32_t) tchar << 9;
35
36 if (!wpc->infile (&tchar, 1))
37 return FALSE;
38
39 wpmd->byte_length += (int32_t) tchar << 17;
40 wpc->stream.block_bytes_left -= 2;
41 }
42
43 if ((wpc->stream.block_bytes_left -= wpmd->byte_length) < 0)
44 return FALSE;
45
46 if (wpmd->id & ID_ODD_SIZE) {
47 wpmd->id &= ~ID_ODD_SIZE;
48 wpmd->byte_length--;
49 }
50
51 if (!wpmd->byte_length || wpmd->id == ID_WV_BITSTREAM) {
52 wpmd->data = NULL;
53 return TRUE;
54 }
55
56 bytes_to_read = wpmd->byte_length + (wpmd->byte_length & 1);
57
58 if (bytes_to_read > sizeof (wpc->read_buffer)) {
59 wpmd->data = NULL;
60
61 while (bytes_to_read > sizeof (wpc->read_buffer))
62 if (wpc->infile (wpc->read_buffer, sizeof (wpc->read_buffer)) == sizeof (wpc->read_buffer))
63 bytes_to_read -= sizeof (wpc->read_buffer);
64 else
65 return FALSE;
66 }
67 else
68 wpmd->data = wpc->read_buffer;
69
70 if (bytes_to_read && wpc->infile (wpc->read_buffer, bytes_to_read) != (int32_t) bytes_to_read) {
71 wpmd->data = NULL;
72 return FALSE;
73 }
74
75 return TRUE;
76}
77
78int process_metadata (WavpackContext *wpc, WavpackMetadata *wpmd)
79{
80 WavpackStream *wps = &wpc->stream;
81
82 switch (wpmd->id) {
83 case ID_DUMMY:
84 return TRUE;
85
86 case ID_DECORR_TERMS:
87 return read_decorr_terms (wps, wpmd);
88
89 case ID_DECORR_WEIGHTS:
90 return read_decorr_weights (wps, wpmd);
91
92 case ID_DECORR_SAMPLES:
93 return read_decorr_samples (wps, wpmd);
94
95 case ID_ENTROPY_VARS:
96 return read_entropy_vars (wps, wpmd);
97
98 case ID_HYBRID_PROFILE:
99 return read_hybrid_profile (wps, wpmd);
100
101 case ID_FLOAT_INFO:
102 return read_float_info (wps, wpmd);
103
104 case ID_INT32_INFO:
105 return read_int32_info (wps, wpmd);
106
107 case ID_CHANNEL_INFO:
108 return read_channel_info (wpc, wpmd);
109
110 case ID_SAMPLE_RATE:
111 return read_sample_rate (wpc, wpmd);
112
113 case ID_CONFIG_BLOCK:
114 return read_config_info (wpc, wpmd);
115
116 case ID_WV_BITSTREAM:
117 return init_wv_bitstream (wpc, wpmd);
118
119 case ID_SHAPING_WEIGHTS:
120 case ID_WVC_BITSTREAM:
121 case ID_WVX_BITSTREAM:
122 return TRUE;
123
124 default:
125 return (wpmd->id & ID_OPTIONAL_DATA) ? TRUE : FALSE;
126 }
127}
128
129int copy_metadata (WavpackMetadata *wpmd, uchar *buffer_start, uchar *buffer_end)
130{
131 uint32_t mdsize = wpmd->byte_length + (wpmd->byte_length & 1);
132 WavpackHeader *wphdr = (WavpackHeader *) buffer_start;
133
134 if (wpmd->byte_length & 1)
135 ((char *) wpmd->data) [wpmd->byte_length] = 0;
136
137 mdsize += (wpmd->byte_length > 510) ? 4 : 2;
138 buffer_start += wphdr->ckSize + 8;
139
140 if (buffer_start + mdsize >= buffer_end)
141 return FALSE;
142
143 buffer_start [0] = wpmd->id | (wpmd->byte_length & 1 ? ID_ODD_SIZE : 0);
144 buffer_start [1] = (wpmd->byte_length + 1) >> 1;
145
146 if (wpmd->byte_length > 510) {
147 buffer_start [0] |= ID_LARGE;
148 buffer_start [2] = (wpmd->byte_length + 1) >> 9;
149 buffer_start [3] = (wpmd->byte_length + 1) >> 17;
150 }
151
152 if (wpmd->data && wpmd->byte_length) {
153 if (wpmd->byte_length > 510) {
154 buffer_start [0] |= ID_LARGE;
155 buffer_start [2] = (wpmd->byte_length + 1) >> 9;
156 buffer_start [3] = (wpmd->byte_length + 1) >> 17;
157 memcpy (buffer_start + 4, wpmd->data, mdsize - 4);
158 }
159 else
160 memcpy (buffer_start + 2, wpmd->data, mdsize - 2);
161 }
162
163 wphdr->ckSize += mdsize;
164 return TRUE;
165}
166
167void free_metadata (WavpackMetadata *wpmd)
168{
169 wpmd->data = NULL;
170}
171