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 ////////////////////////////////////////////////////////////////////////////
11 // This module handles the metadata structure introduced in WavPack 4.0
17 int read_metadata_buff (WavpackContext
*wpc
, WavpackMetadata
*wpmd
)
19 uint32_t bytes_to_read
;
22 if (wpc
->stream
.block_bytes_left
< 2 || !wpc
->infile (&wpmd
->id
, 1) || !wpc
->infile (&tchar
, 1))
25 wpmd
->byte_length
= tchar
<< 1;
26 wpc
->stream
.block_bytes_left
-= 2;
28 if (wpmd
->id
& ID_LARGE
) {
29 wpmd
->id
&= ~ID_LARGE
;
31 if (wpc
->stream
.block_bytes_left
< 2 || !wpc
->infile (&tchar
, 1))
34 wpmd
->byte_length
+= (int32_t) tchar
<< 9;
36 if (!wpc
->infile (&tchar
, 1))
39 wpmd
->byte_length
+= (int32_t) tchar
<< 17;
40 wpc
->stream
.block_bytes_left
-= 2;
43 if ((wpc
->stream
.block_bytes_left
-= wpmd
->byte_length
) < 0)
46 if (wpmd
->id
& ID_ODD_SIZE
) {
47 wpmd
->id
&= ~ID_ODD_SIZE
;
51 if (!wpmd
->byte_length
|| wpmd
->id
== ID_WV_BITSTREAM
) {
56 bytes_to_read
= wpmd
->byte_length
+ (wpmd
->byte_length
& 1);
58 if (bytes_to_read
> sizeof (wpc
->read_buffer
)) {
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
);
68 wpmd
->data
= wpc
->read_buffer
;
70 if (bytes_to_read
&& wpc
->infile (wpc
->read_buffer
, bytes_to_read
) != (int32_t) bytes_to_read
) {
78 int process_metadata (WavpackContext
*wpc
, WavpackMetadata
*wpmd
)
80 WavpackStream
*wps
= &wpc
->stream
;
87 return read_decorr_terms (wps
, wpmd
);
89 case ID_DECORR_WEIGHTS
:
90 return read_decorr_weights (wps
, wpmd
);
92 case ID_DECORR_SAMPLES
:
93 return read_decorr_samples (wps
, wpmd
);
96 return read_entropy_vars (wps
, wpmd
);
98 case ID_HYBRID_PROFILE
:
99 return read_hybrid_profile (wps
, wpmd
);
102 return read_float_info (wps
, wpmd
);
105 return read_int32_info (wps
, wpmd
);
107 case ID_CHANNEL_INFO
:
108 return read_channel_info (wpc
, wpmd
);
111 return read_sample_rate (wpc
, wpmd
);
113 case ID_CONFIG_BLOCK
:
114 return read_config_info (wpc
, wpmd
);
116 case ID_WV_BITSTREAM
:
117 return init_wv_bitstream (wpc
, wpmd
);
119 case ID_SHAPING_WEIGHTS
:
120 case ID_WVC_BITSTREAM
:
121 case ID_WVX_BITSTREAM
:
125 return (wpmd
->id
& ID_OPTIONAL_DATA
) ? TRUE
: FALSE
;
129 int copy_metadata (WavpackMetadata
*wpmd
, uchar
*buffer_start
, uchar
*buffer_end
)
131 uint32_t mdsize
= wpmd
->byte_length
+ (wpmd
->byte_length
& 1);
132 WavpackHeader
*wphdr
= (WavpackHeader
*) buffer_start
;
134 if (wpmd
->byte_length
& 1)
135 ((char *) wpmd
->data
) [wpmd
->byte_length
] = 0;
137 mdsize
+= (wpmd
->byte_length
> 510) ? 4 : 2;
138 buffer_start
+= wphdr
->ckSize
+ 8;
140 if (buffer_start
+ mdsize
>= buffer_end
)
143 buffer_start
[0] = wpmd
->id
| (wpmd
->byte_length
& 1 ? ID_ODD_SIZE
: 0);
144 buffer_start
[1] = (wpmd
->byte_length
+ 1) >> 1;
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;
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);
160 memcpy (buffer_start
+ 2, wpmd
->data
, mdsize
- 2);
163 wphdr
->ckSize
+= mdsize
;
167 void free_metadata (WavpackMetadata
*wpmd
)