From f40bfc9267b13b54e6379dfe7539447662879d24 Mon Sep 17 00:00:00 2001 From: Sean Bartell Date: Sat, 25 Jun 2011 21:32:25 -0400 Subject: Add codecs to librbcodec. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Id7f4717d51ed02d67cb9f9cb3c0ada4a81843f97 Reviewed-on: http://gerrit.rockbox.org/137 Reviewed-by: Nils Wallménius Tested-by: Nils Wallménius --- lib/rbcodec/codecs/libwavpack/metadata.c | 171 +++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 lib/rbcodec/codecs/libwavpack/metadata.c (limited to 'lib/rbcodec/codecs/libwavpack/metadata.c') 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 @@ +//////////////////////////////////////////////////////////////////////////// +// **** 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) +{ + uint32_t bytes_to_read; + uchar tchar; + + if (wpc->stream.block_bytes_left < 2 || !wpc->infile (&wpmd->id, 1) || !wpc->infile (&tchar, 1)) + return FALSE; + + wpmd->byte_length = tchar << 1; + wpc->stream.block_bytes_left -= 2; + + if (wpmd->id & ID_LARGE) { + wpmd->id &= ~ID_LARGE; + + if (wpc->stream.block_bytes_left < 2 || !wpc->infile (&tchar, 1)) + return FALSE; + + wpmd->byte_length += (int32_t) tchar << 9; + + if (!wpc->infile (&tchar, 1)) + return FALSE; + + wpmd->byte_length += (int32_t) tchar << 17; + wpc->stream.block_bytes_left -= 2; + } + + if ((wpc->stream.block_bytes_left -= wpmd->byte_length) < 0) + return FALSE; + + if (wpmd->id & ID_ODD_SIZE) { + wpmd->id &= ~ID_ODD_SIZE; + wpmd->byte_length--; + } + + if (!wpmd->byte_length || wpmd->id == ID_WV_BITSTREAM) { + wpmd->data = NULL; + return TRUE; + } + + bytes_to_read = wpmd->byte_length + (wpmd->byte_length & 1); + + if (bytes_to_read > sizeof (wpc->read_buffer)) { + wpmd->data = NULL; + + while (bytes_to_read > sizeof (wpc->read_buffer)) + if (wpc->infile (wpc->read_buffer, sizeof (wpc->read_buffer)) == sizeof (wpc->read_buffer)) + bytes_to_read -= sizeof (wpc->read_buffer); + else + return FALSE; + } + else + wpmd->data = wpc->read_buffer; + + if (bytes_to_read && wpc->infile (wpc->read_buffer, bytes_to_read) != (int32_t) bytes_to_read) { + wpmd->data = NULL; + return FALSE; + } + + 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_SAMPLE_RATE: + return read_sample_rate (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) +{ + uint32_t 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; +} + -- cgit v1.2.3