- unsigned rice_parameter, partition_bits;
-#ifndef NO_RICE_SEARCH
- unsigned best_partition_bits;
- unsigned min_rice_parameter, max_rice_parameter, best_rice_parameter = 0;
-#endif
- unsigned bits_ = FLAC__ENTROPY_CODING_METHOD_TYPE_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN;
- unsigned *parameters;
-
- FLAC__ASSERT(suggested_rice_parameter < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER);
-
- FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(partitioned_rice_contents, max(6, partition_order));
- parameters = partitioned_rice_contents->parameters;
-
- if(partition_order == 0) {
- unsigned i;
-
-#ifndef NO_RICE_SEARCH
- if(rice_parameter_search_dist) {
- if(suggested_rice_parameter < rice_parameter_search_dist)
- min_rice_parameter = 0;
- else
- min_rice_parameter = suggested_rice_parameter - rice_parameter_search_dist;
- max_rice_parameter = suggested_rice_parameter + rice_parameter_search_dist;
- if(max_rice_parameter >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) {
-#ifdef DEBUG_VERBOSE
- fprintf(stderr, "clipping rice_parameter (%u -> %u) @2\n", max_rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1);
-#endif
- max_rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1;
- }
- }
- else
- min_rice_parameter = max_rice_parameter = suggested_rice_parameter;
-
- best_partition_bits = 0xffffffff;
- for(rice_parameter = min_rice_parameter; rice_parameter <= max_rice_parameter; rice_parameter++) {
-#endif
-#ifdef VARIABLE_RICE_BITS
- const unsigned rice_parameter_estimate = rice_parameter-1;
- partition_bits = (1+rice_parameter) * residual_samples;
-#else
- partition_bits = 0;
-#endif
- partition_bits += FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN;
- for(i = 0; i < residual_samples; i++) {
-#ifdef VARIABLE_RICE_BITS
- partition_bits += VARIABLE_RICE_BITS(abs_residual[i], rice_parameter_estimate);
-#else
- partition_bits += FLAC__bitbuffer_rice_bits(residual[i], rice_parameter); /* NOTE: we will need to pass in residual[] in addition to abs_residual[] */
-#endif
- }
-#ifndef NO_RICE_SEARCH
- if(partition_bits < best_partition_bits) {
- best_rice_parameter = rice_parameter;
- best_partition_bits = partition_bits;
- }
- }
-#endif
- parameters[0] = best_rice_parameter;
- bits_ += best_partition_bits;
- }
- else {
- unsigned partition, residual_sample, save_residual_sample, partition_sample;
- unsigned partition_samples;
- FLAC__uint64 mean, k;
- const unsigned partitions = 1u << partition_order;
- for(partition = residual_sample = 0; partition < partitions; partition++) {
- partition_samples = (residual_samples+predictor_order) >> partition_order;
- if(partition == 0) {
- if(partition_samples <= predictor_order)
- return false;
- else
- partition_samples -= predictor_order;
- }
- mean = 0;
- save_residual_sample = residual_sample;
- for(partition_sample = 0; partition_sample < partition_samples; residual_sample++, partition_sample++)
- mean += abs_residual[residual_sample];
- residual_sample = save_residual_sample;
- /* we are basically calculating the size in bits of the
- * average residual magnitude in the partition:
- * rice_parameter = floor(log2(mean/partition_samples))
- * 'mean' is not a good name for the variable, it is
- * actually the sum of magnitudes of all residual values
- * in the partition, so the actual mean is
- * mean/partition_samples
- */
- for(rice_parameter = 0, k = partition_samples; k < mean; rice_parameter++, k <<= 1)
- ;
- if(rice_parameter >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) {
-#ifdef DEBUG_VERBOSE
- fprintf(stderr, "clipping rice_parameter (%u -> %u) @3\n", rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1);
-#endif
- rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1;
- }
-
-#ifndef NO_RICE_SEARCH
- if(rice_parameter_search_dist) {
- if(rice_parameter < rice_parameter_search_dist)
- min_rice_parameter = 0;
- else
- min_rice_parameter = rice_parameter - rice_parameter_search_dist;
- max_rice_parameter = rice_parameter + rice_parameter_search_dist;
- if(max_rice_parameter >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) {
-#ifdef DEBUG_VERBOSE
- fprintf(stderr, "clipping rice_parameter (%u -> %u) @4\n", max_rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1);
-#endif
- max_rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1;
- }
- }
- else
- min_rice_parameter = max_rice_parameter = rice_parameter;
-
- best_partition_bits = 0xffffffff;
- for(rice_parameter = min_rice_parameter; rice_parameter <= max_rice_parameter; rice_parameter++) {
-#endif
-#ifdef VARIABLE_RICE_BITS
- const unsigned rice_parameter_estimate = rice_parameter-1;
- partition_bits = (1+rice_parameter) * partition_samples;
-#else
- partition_bits = 0;
-#endif
- partition_bits += FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN;
- save_residual_sample = residual_sample;
- for(partition_sample = 0; partition_sample < partition_samples; residual_sample++, partition_sample++) {
-#ifdef VARIABLE_RICE_BITS
- partition_bits += VARIABLE_RICE_BITS(abs_residual[residual_sample], rice_parameter_estimate);
-#else
- partition_bits += FLAC__bitbuffer_rice_bits(residual[residual_sample], rice_parameter); /* NOTE: we will need to pass in residual[] in addition to abs_residual[] */
-#endif
- }
-#ifndef NO_RICE_SEARCH
- if(rice_parameter != max_rice_parameter)
- residual_sample = save_residual_sample;
- if(partition_bits < best_partition_bits) {
- best_rice_parameter = rice_parameter;
- best_partition_bits = partition_bits;
- }
- }
-#endif
- parameters[partition] = best_rice_parameter;
- bits_ += best_partition_bits;
- }
- }
-
- *bits = bits_;
- return true;