//////////////////////////////////////////////////////////////////////////// // **** WAVPACK **** // // Hybrid Lossless Wavefile Compressor // // Copyright (c) 1998 - 2003 Conifer Software. // // All Rights Reserved. // // Distributed under the BSD Software License (see license.txt) // //////////////////////////////////////////////////////////////////////////// // metadata.c // This module handles the metadata structure introduced in WavPack 4.0 #include "wavpack.h" #include int read_metadata_buff (WavpackContext *wpc, WavpackMetadata *wpmd) { uchar tchar; if (!wpc->infile (&wpmd->id, 1) || !wpc->infile (&tchar, 1)) return FALSE; wpmd->byte_length = tchar << 1; if (wpmd->id & ID_LARGE) { wpmd->id &= ~ID_LARGE; if (!wpc->infile (&tchar, 1)) return FALSE; wpmd->byte_length += (long) tchar << 9; if (!wpc->infile (&tchar, 1)) return FALSE; wpmd->byte_length += (long) tchar << 17; } if (wpmd->id & ID_ODD_SIZE) { wpmd->id &= ~ID_ODD_SIZE; wpmd->byte_length--; } if (wpmd->byte_length && wpmd->byte_length <= (long)sizeof (wpc->read_buffer)) { ulong bytes_to_read = wpmd->byte_length + (wpmd->byte_length & 1); if (wpc->infile (wpc->read_buffer, bytes_to_read) != (long) bytes_to_read) { wpmd->data = NULL; return FALSE; } wpmd->data = wpc->read_buffer; } else wpmd->data = NULL; return TRUE; } int process_metadata (WavpackContext *wpc, WavpackMetadata *wpmd) { WavpackStream *wps = &wpc->stream; switch (wpmd->id) { case ID_DUMMY: return TRUE; case ID_DECORR_TERMS: return read_decorr_terms (wps, wpmd); case ID_DECORR_WEIGHTS: return read_decorr_weights (wps, wpmd); case ID_DECORR_SAMPLES: return read_decorr_samples (wps, wpmd); case ID_ENTROPY_VARS: return read_entropy_vars (wps, wpmd); case ID_HYBRID_PROFILE: return read_hybrid_profile (wps, wpmd); case ID_FLOAT_INFO: return read_float_info (wps, wpmd); case ID_INT32_INFO: return read_int32_info (wps, wpmd); case ID_CHANNEL_INFO: return read_channel_info (wpc, wpmd); case ID_CONFIG_BLOCK: return read_config_info (wpc, wpmd); case ID_WV_BITSTREAM: return init_wv_bitstream (wpc, wpmd); case ID_SHAPING_WEIGHTS: case ID_WVC_BITSTREAM: case ID_WVX_BITSTREAM: return TRUE; default: return (wpmd->id & ID_OPTIONAL_DATA) ? TRUE : FALSE; } } int copy_metadata (WavpackMetadata *wpmd, uchar *buffer_start, uchar *buffer_end) { ulong mdsize = wpmd->byte_length + (wpmd->byte_length & 1); WavpackHeader *wphdr = (WavpackHeader *) buffer_start; if (wpmd->byte_length & 1) ((char *) wpmd->data) [wpmd->byte_length] = 0; mdsize += (wpmd->byte_length > 510) ? 4 : 2; buffer_start += wphdr->ckSize + 8; if (buffer_start + mdsize >= buffer_end) return FALSE; buffer_start [0] = wpmd->id | (wpmd->byte_length & 1 ? ID_ODD_SIZE : 0); buffer_start [1] = (wpmd->byte_length + 1) >> 1; if (wpmd->byte_length > 510) { buffer_start [0] |= ID_LARGE; buffer_start [2] = (wpmd->byte_length + 1) >> 9; buffer_start [3] = (wpmd->byte_length + 1) >> 17; } if (wpmd->data && wpmd->byte_length) { if (wpmd->byte_length > 510) { buffer_start [0] |= ID_LARGE; buffer_start [2] = (wpmd->byte_length + 1) >> 9; buffer_start [3] = (wpmd->byte_length + 1) >> 17; memcpy (buffer_start + 4, wpmd->data, mdsize - 4); } else memcpy (buffer_start + 2, wpmd->data, mdsize - 2); } wphdr->ckSize += mdsize; return TRUE; } void free_metadata (WavpackMetadata *wpmd) { wpmd->data = NULL; }