diff --git a/src/libFLAC/format.c b/src/libFLAC/format.c index 0e8d5f48..2998970e 100644 --- a/src/libFLAC/format.c +++ b/src/libFLAC/format.c @@ -21,6 +21,12 @@ #include /* for qsort() */ #include "FLAC/assert.h" #include "FLAC/format.h" +#include "private/format.h" + +#ifdef min +#undef min +#endif +#define min(a,b) ((a)<(b)?(a):(b)) const FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' }; const unsigned FLAC__STREAM_SYNC = 0x664C6143; @@ -195,3 +201,73 @@ unsigned FLAC__format_seektable_sort(FLAC__StreamMetadata_SeekTable *seek_table) return j; } + +unsigned FLAC__format_get_max_rice_partition_order(unsigned blocksize, unsigned predictor_order) +{ + return + FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order( + FLAC__format_get_max_rice_partition_order_from_blocksize(blocksize), + blocksize, + predictor_order + ); +} + +unsigned FLAC__format_get_max_rice_partition_order_from_blocksize(unsigned blocksize) +{ + unsigned max_rice_partition_order = 0; + while(!(blocksize & 1)) { + max_rice_partition_order++; + blocksize >>= 1; + } + return min(FLAC__MAX_RICE_PARTITION_ORDER, max_rice_partition_order); +} + +unsigned FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(unsigned limit, unsigned blocksize, unsigned predictor_order) +{ + unsigned max_rice_partition_order = limit; + + while(max_rice_partition_order > 0 && (blocksize >> max_rice_partition_order) <= predictor_order) + max_rice_partition_order--; + + FLAC__ASSERT(blocksize >> max_rice_partition_order > predictor_order); + + return max_rice_partition_order; +} + +void FLAC__format_entropy_coding_method_partitioned_rice_init(FLAC__EntropyCodingMethod_PartitionedRice *object) +{ + FLAC__ASSERT(0 != object); + + object->order = 0; + object->parameters = 0; + object->raw_bits = 0; + object->capacity_by_order = 0; +} + +void FLAC__format_entropy_coding_method_partitioned_rice_clear(FLAC__EntropyCodingMethod_PartitionedRice *object) +{ + FLAC__ASSERT(0 != object); + + if(0 != object->parameters) + free(object->parameters); + if(0 != object->raw_bits) + free(object->raw_bits); + FLAC__format_entropy_coding_method_partitioned_rice_init(object); +} + +FLAC__bool FLAC__format_entropy_coding_method_partitioned_rice_ensure_size(FLAC__EntropyCodingMethod_PartitionedRice *object, unsigned max_partition_order) +{ + FLAC__ASSERT(0 != object); + + FLAC__ASSERT(object->capacity_by_order > 0 || (0 == object->parameters && 0 == object->raw_bits)); + + if(object->capacity_by_order < max_partition_order) { + if(0 == (object->parameters = realloc(object->parameters, sizeof(unsigned)*(1 << max_partition_order)))) + return false; + if(0 == (object->raw_bits = realloc(object->raw_bits, sizeof(unsigned)*(1 << max_partition_order)))) + return false; + object->capacity_by_order = max_partition_order; + } + + return true; +} diff --git a/src/libFLAC/include/private/format.h b/src/libFLAC/include/private/format.h new file mode 100644 index 00000000..ca4adc60 --- /dev/null +++ b/src/libFLAC/include/private/format.h @@ -0,0 +1,32 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000,2001,2002 Josh Coalson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef FLAC__PRIVATE__FORMAT_H +#define FLAC__PRIVATE__FORMAT_H + +#include "FLAC/format.h" + +unsigned FLAC__format_get_max_rice_partition_order(unsigned blocksize, unsigned predictor_order); +unsigned FLAC__format_get_max_rice_partition_order_from_blocksize(unsigned blocksize); +unsigned FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(unsigned limit, unsigned blocksize, unsigned predictor_order); +void FLAC__format_entropy_coding_method_partitioned_rice_init(FLAC__EntropyCodingMethod_PartitionedRice *object); +void FLAC__format_entropy_coding_method_partitioned_rice_clear(FLAC__EntropyCodingMethod_PartitionedRice *object); +FLAC__bool FLAC__format_entropy_coding_method_partitioned_rice_ensure_size(FLAC__EntropyCodingMethod_PartitionedRice *object, unsigned max_partition_order); + +#endif