diff options
-rw-r--r-- | include/FLAC/format.h | 18 | ||||
-rw-r--r-- | src/flac/analyze.c | 6 | ||||
-rw-r--r-- | src/flac/decode.c | 34 | ||||
-rw-r--r-- | src/libFLAC/bitreader.c | 15 | ||||
-rw-r--r-- | src/libFLAC/fixed.c | 68 | ||||
-rw-r--r-- | src/libFLAC/include/private/bitreader.h | 1 | ||||
-rw-r--r-- | src/libFLAC/include/private/fixed.h | 2 | ||||
-rw-r--r-- | src/libFLAC/include/private/lpc.h | 7 | ||||
-rw-r--r-- | src/libFLAC/lpc.c | 137 | ||||
-rw-r--r-- | src/libFLAC/stream_decoder.c | 192 | ||||
-rw-r--r-- | src/libFLAC/stream_encoder.c | 3 | ||||
-rw-r--r-- | src/libFLAC/stream_encoder_framing.c | 2 |
12 files changed, 377 insertions, 108 deletions
diff --git a/include/FLAC/format.h b/include/FLAC/format.h index cf5c25aa..28eda599 100644 --- a/include/FLAC/format.h +++ b/include/FLAC/format.h @@ -282,14 +282,24 @@ extern FLAC_API const char * const FLAC__SubframeTypeString[]; /** CONSTANT subframe. (c.f. <A HREF="../format.html#subframe_constant">format specification</A>) */ typedef struct { - FLAC__int32 value; /**< The constant signal value. */ + FLAC__int64 value; /**< The constant signal value. */ } FLAC__Subframe_Constant; +/** An enumeration of the possible verbatim subframe data types. */ +typedef enum { + FLAC__VERBATIM_SUBFRAME_DATA_TYPE_INT32, /**< verbatim subframe has 32-bit int */ + FLAC__VERBATIM_SUBFRAME_DATA_TYPE_INT64 /**< verbatim subframe has 64-bit int */ +} FLAC__VerbatimSubframeDataType; + /** VERBATIM subframe. (c.f. <A HREF="../format.html#subframe_verbatim">format specification</A>) */ typedef struct { - const FLAC__int32 *data; /**< A pointer to verbatim signal. */ + union { + const FLAC__int32 *int32; /**< A FLAC__int32 pointer to verbatim signal. */ + const FLAC__int64 *int64; /**< A FLAC__int64 pointer to verbatim signal. */ + } data; + FLAC__VerbatimSubframeDataType data_type; } FLAC__Subframe_Verbatim; @@ -302,7 +312,7 @@ typedef struct { uint32_t order; /**< The polynomial order. */ - FLAC__int32 warmup[FLAC__MAX_FIXED_ORDER]; + FLAC__int64 warmup[FLAC__MAX_FIXED_ORDER]; /**< Warmup samples to prime the predictor, length == order. */ const FLAC__int32 *residual; @@ -328,7 +338,7 @@ typedef struct { FLAC__int32 qlp_coeff[FLAC__MAX_LPC_ORDER]; /**< FIR filter coefficients. */ - FLAC__int32 warmup[FLAC__MAX_LPC_ORDER]; + FLAC__int64 warmup[FLAC__MAX_LPC_ORDER]; /**< Warmup samples to prime the predictor, length == order. */ const FLAC__int32 *residual; diff --git a/src/flac/analyze.c b/src/flac/analyze.c index 4c68094c..822c6c0b 100644 --- a/src/flac/analyze.c +++ b/src/flac/analyze.c @@ -78,13 +78,13 @@ void flac__analyze_frame(const FLAC__Frame *frame, uint32_t frame_number, FLAC__ fprintf(fout, "\tsubframe=%u\twasted_bits=%u\ttype=%s", channel, subframe->wasted_bits, FLAC__SubframeTypeString[subframe->type]); switch(subframe->type) { case FLAC__SUBFRAME_TYPE_CONSTANT: - fprintf(fout, "\tvalue=%d\n", subframe->data.constant.value); + fprintf(fout, "\tvalue=%" PRId64 "\n", subframe->data.constant.value); break; case FLAC__SUBFRAME_TYPE_FIXED: FLAC__ASSERT(subframe->data.fixed.entropy_coding_method.type <= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2); fprintf(fout, "\torder=%u\tresidual_type=%s\tpartition_order=%u\n", subframe->data.fixed.order, is_rice2? "RICE2":"RICE", subframe->data.fixed.entropy_coding_method.data.partitioned_rice.order); for(i = 0; i < subframe->data.fixed.order; i++) - fprintf(fout, "\t\twarmup[%u]=%d\n", i, subframe->data.fixed.warmup[i]); + fprintf(fout, "\t\twarmup[%u]=%" PRId64 "\n", i, subframe->data.fixed.warmup[i]); partitions = (1u << subframe->data.fixed.entropy_coding_method.data.partitioned_rice.order); for(i = 0; i < partitions; i++) { uint32_t parameter = subframe->data.fixed.entropy_coding_method.data.partitioned_rice.contents->parameters[i]; @@ -104,7 +104,7 @@ void flac__analyze_frame(const FLAC__Frame *frame, uint32_t frame_number, FLAC__ for(i = 0; i < subframe->data.lpc.order; i++) fprintf(fout, "\t\tqlp_coeff[%u]=%d\n", i, subframe->data.lpc.qlp_coeff[i]); for(i = 0; i < subframe->data.lpc.order; i++) - fprintf(fout, "\t\twarmup[%u]=%d\n", i, subframe->data.lpc.warmup[i]); + fprintf(fout, "\t\twarmup[%u]=%" PRId64 "\n", i, subframe->data.lpc.warmup[i]); partitions = (1u << subframe->data.lpc.entropy_coding_method.data.partitioned_rice.order); for(i = 0; i < partitions; i++) { uint32_t parameter = subframe->data.lpc.entropy_coding_method.data.partitioned_rice.contents->parameters[i]; diff --git a/src/flac/decode.c b/src/flac/decode.c index 4e93793e..a7d07210 100644 --- a/src/flac/decode.c +++ b/src/flac/decode.c @@ -1290,6 +1290,32 @@ FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder } bytes_to_write = sample; } + else if(bps+shift == 32) { + if(is_unsigned_samples) { + for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++) + for(channel = 0; channel < channels; channel++, sample++) + ubuf.u32buffer[sample] = buffer[channel][wide_sample]; + } + else { + for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++) + for(channel = 0; channel < channels; channel++, sample++) + ubuf.s32buffer[sample] = buffer[channel][wide_sample]; + } + if(is_big_endian != is_big_endian_host_) { + uint8_t tmp; + const uint32_t bytes = sample * 4; + uint32_t b; + for(b = 0; b < bytes; b += 4) { + tmp = ubuf.u8buffer[b]; + ubuf.u8buffer[b] = ubuf.u8buffer[b+3]; + ubuf.u8buffer[b+3] = tmp; + tmp = ubuf.u8buffer[b+1]; + ubuf.u8buffer[b+1] = ubuf.u8buffer[b+2]; + ubuf.u8buffer[b+2] = tmp; + } + } + bytes_to_write = 4 * sample; + } else { FLAC__ASSERT(0); /* double protection */ @@ -1365,14 +1391,14 @@ void metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMet decoder_session->total_samples -= (metadata->data.stream_info.total_samples - until); } - if(decoder_session->format == FORMAT_RAW && ((decoder_session->bps % 8) != 0 || decoder_session->bps < 4 || decoder_session->bps > 24)) { - flac__utils_printf(stderr, 1, "%s: ERROR: bits per sample is %u, must be 8/16/24 for raw format output\n", decoder_session->inbasefilename, decoder_session->bps); + if(decoder_session->format == FORMAT_RAW && ((decoder_session->bps % 8) != 0 || decoder_session->bps < 4)) { + flac__utils_printf(stderr, 1, "%s: ERROR: bits per sample is %u, must be 8/16/24/32 for raw format output\n", decoder_session->inbasefilename, decoder_session->bps); decoder_session->abort_flag = true; return; } - if(decoder_session->bps < 4 || decoder_session->bps > 24) { - flac__utils_printf(stderr, 1, "%s: ERROR: bits per sample is %u, must be 4-24\n", decoder_session->inbasefilename, decoder_session->bps); + if(decoder_session->bps < 4 || decoder_session->bps > 32) { + flac__utils_printf(stderr, 1, "%s: ERROR: bits per sample is %u, must be 4-32\n", decoder_session->inbasefilename, decoder_session->bps); decoder_session->abort_flag = true; return; } diff --git a/src/libFLAC/bitreader.c b/src/libFLAC/bitreader.c index 1b6e63f6..4796f337 100644 --- a/src/libFLAC/bitreader.c +++ b/src/libFLAC/bitreader.c @@ -529,7 +529,7 @@ FLAC__bool FLAC__bitreader_read_raw_int32(FLAC__BitReader *br, FLAC__int32 *val, return false; /* sign-extend *val assuming it is currently bits wide. */ /* From: https://graphics.stanford.edu/~seander/bithacks.html#FixedSignExtend */ - mask = bits >= 33 ? 0 : 1u << (bits - 1); + mask = bits >= 33 ? 0 : 1lu << (bits - 1); *val = (uval ^ mask) - mask; return true; } @@ -555,6 +555,19 @@ FLAC__bool FLAC__bitreader_read_raw_uint64(FLAC__BitReader *br, FLAC__uint64 *va return true; } +FLAC__bool FLAC__bitreader_read_raw_int64(FLAC__BitReader *br, FLAC__int64 *val, uint32_t bits) +{ + FLAC__uint64 uval, mask; + /* OPT: inline raw uint64 code here, or make into a macro if possible in the .h file */ + if (bits < 1 || ! FLAC__bitreader_read_raw_uint64(br, &uval, bits)) + return false; + /* sign-extend *val assuming it is currently bits wide. */ + /* From: https://graphics.stanford.edu/~seander/bithacks.html#FixedSignExtend */ + mask = bits >= 65 ? 0 : 1llu << (bits - 1); + *val = (uval ^ mask) - mask; + return true; +} + inline FLAC__bool FLAC__bitreader_read_uint32_little_endian(FLAC__BitReader *br, FLAC__uint32 *val) { FLAC__uint32 x8, x32 = 0; diff --git a/src/libFLAC/fixed.c b/src/libFLAC/fixed.c index dcb71c53..134fbff4 100644 --- a/src/libFLAC/fixed.c +++ b/src/libFLAC/fixed.c @@ -412,3 +412,71 @@ void FLAC__fixed_restore_signal(const FLAC__int32 residual[], uint32_t data_len, FLAC__ASSERT(0); } } + +void FLAC__fixed_restore_signal_wide(const FLAC__int32 residual[], uint32_t data_len, uint32_t order, FLAC__int32 data[]) +{ + int i, idata_len = (int)data_len; + + switch(order) { + case 0: + FLAC__ASSERT(sizeof(residual[0]) == sizeof(data[0])); + memcpy(data, residual, sizeof(residual[0])*data_len); + break; + case 1: + for(i = 0; i < idata_len; i++) + data[i] = (FLAC__int64)residual[i] + (FLAC__int64)data[i-1]; + break; + case 2: + for(i = 0; i < idata_len; i++) + data[i] = (FLAC__int64)residual[i] + 2*(FLAC__int64)data[i-1] - (FLAC__int64)data[i-2]; + break; + case 3: + for(i = 0; i < idata_len; i++) + data[i] = (FLAC__int64)residual[i] + 3*(FLAC__int64)data[i-1] - 3*(FLAC__int64)data[i-2] + (FLAC__int64)data[i-3]; + break; + case 4: + for(i = 0; i < idata_len; i++) + data[i] = (FLAC__int64)residual[i] + 4*(FLAC__int64)data[i-1] - 6*(FLAC__int64)data[i-2] + 4*(FLAC__int64)data[i-3] - (FLAC__int64)data[i-4]; + break; + default: + FLAC__ASSERT(0); + } +} + +#ifdef FUZZING_BUILD_MODE_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW +/* The attribute below is to silence the undefined sanitizer of oss-fuzz. + * Because fuzzing feeds bogus predictors and residual samples to the + * decoder, having overflows in this section is unavoidable. Also, + * because the calculated values are audio path only, there is no + * potential for security problems */ +__attribute__((no_sanitize("signed-integer-overflow"))) +#endif +void FLAC__fixed_restore_signal_wide_33bit(const FLAC__int32 residual[], uint32_t data_len, uint32_t order, FLAC__int64 data[]) +{ + int i, idata_len = (int)data_len; + + switch(order) { + case 0: + for(i = 0; i < idata_len; i++) + data[i] = residual[i]; + break; + case 1: + for(i = 0; i < idata_len; i++) + data[i] = (FLAC__int64)residual[i] + data[i-1]; + break; + case 2: + for(i = 0; i < idata_len; i++) + data[i] = (FLAC__int64)residual[i] + 2*data[i-1] - data[i-2]; + break; + case 3: + for(i = 0; i < idata_len; i++) + data[i] = (FLAC__int64)residual[i] + 3*data[i-1] - 3*data[i-2] + data[i-3]; + break; + case 4: + for(i = 0; i < idata_len; i++) + data[i] = (FLAC__int64)residual[i] + 4*data[i-1] - 6*data[i-2] + 4*data[i-3] - data[i-4]; + break; + default: + FLAC__ASSERT(0); + } +} diff --git a/src/libFLAC/include/private/bitreader.h b/src/libFLAC/include/private/bitreader.h index 3f7c1dd7..3c33f89d 100644 --- a/src/libFLAC/include/private/bitreader.h +++ b/src/libFLAC/include/private/bitreader.h @@ -81,6 +81,7 @@ void FLAC__bitreader_limit_invalidate(FLAC__BitReader *br); FLAC__bool FLAC__bitreader_read_raw_uint32(FLAC__BitReader *br, FLAC__uint32 *val, uint32_t bits); FLAC__bool FLAC__bitreader_read_raw_int32(FLAC__BitReader *br, FLAC__int32 *val, uint32_t bits); FLAC__bool FLAC__bitreader_read_raw_uint64(FLAC__BitReader *br, FLAC__uint64 *val, uint32_t bits); +FLAC__bool FLAC__bitreader_read_raw_int64(FLAC__BitReader *br, FLAC__int64 *val, uint32_t bits); FLAC__bool FLAC__bitreader_read_uint32_little_endian(FLAC__BitReader *br, FLAC__uint32 *val); /*only for bits=32*/ FLAC__bool FLAC__bitreader_skip_bits_no_crc(FLAC__BitReader *br, uint32_t bits); /* WATCHOUT: does not CRC the skipped data! */ /*@@@@ add to unit tests */ FLAC__bool FLAC__bitreader_skip_byte_block_aligned_no_crc(FLAC__BitReader *br, uint32_t nvals); /* WATCHOUT: does not CRC the read data! */ diff --git a/src/libFLAC/include/private/fixed.h b/src/libFLAC/include/private/fixed.h index 9edf0abd..7046e2b9 100644 --- a/src/libFLAC/include/private/fixed.h +++ b/src/libFLAC/include/private/fixed.h @@ -103,5 +103,7 @@ void FLAC__fixed_compute_residual(const FLAC__int32 data[], uint32_t data_len, u * OUT data[0,data_len-1] original signal */ void FLAC__fixed_restore_signal(const FLAC__int32 residual[], uint32_t data_len, uint32_t order, FLAC__int32 data[]); +void FLAC__fixed_restore_signal_wide(const FLAC__int32 residual[], uint32_t data_len, uint32_t order, FLAC__int32 data[]); +void FLAC__fixed_restore_signal_wide_33bit(const FLAC__int32 residual[], uint32_t data_len, uint32_t order, FLAC__int64 data[]); #endif diff --git a/src/libFLAC/include/private/lpc.h b/src/libFLAC/include/private/lpc.h index b1321bcf..318666aa 100644 --- a/src/libFLAC/include/private/lpc.h +++ b/src/libFLAC/include/private/lpc.h @@ -96,9 +96,6 @@ void FLAC__lpc_compute_autocorrelation_intrin_neon_lag_14(const FLAC__real data[ #endif #endif /* FLAC__NO_ASM */ -uint32_t FLAC__lpc_max_prediction_before_shift_bps(uint32_t subframe_bps, const FLAC__int32 qlp_coeff[], uint32_t order); -uint32_t FLAC__lpc_max_residual_bps(uint32_t subframe_bps, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization); - /* * FLAC__lpc_compute_lp_coefficients() * -------------------------------------------------------------------- @@ -192,6 +189,9 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_avx2(const FLA #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ +uint32_t FLAC__lpc_max_prediction_before_shift_bps(uint32_t subframe_bps, const FLAC__int32 qlp_coeff[], uint32_t order); +uint32_t FLAC__lpc_max_residual_bps(uint32_t subframe_bps, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization); + /* * FLAC__lpc_restore_signal() * -------------------------------------------------------------------- @@ -209,6 +209,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_avx2(const FLA */ void FLAC__lpc_restore_signal(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]); void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]); +void FLAC__lpc_restore_signal_wide_33bit(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int64 data[]); #ifndef FLAC__INTEGER_ONLY_LIBRARY diff --git a/src/libFLAC/lpc.c b/src/libFLAC/lpc.c index b2545ad5..c2d07654 100644 --- a/src/libFLAC/lpc.c +++ b/src/libFLAC/lpc.c @@ -260,31 +260,6 @@ int FLAC__lpc_quantize_coefficients(const FLAC__real lp_coeff[], uint32_t order, return 0; } - -uint32_t FLAC__lpc_max_prediction_before_shift_bps(uint32_t subframe_bps, const FLAC__int32 * flac_restrict qlp_coeff, uint32_t order) -{ - /* This used to be subframe_bps + qlp_coeff_precision + FLAC__bitmath_ilog2(order) - * but that treats both the samples as well as the predictor as unknown. The - * predictor is known however, so taking the log2 of the sum of the absolute values - * of all coefficients is a more accurate representation of the predictor */ - FLAC__int32 abs_sum_of_qlp_coeff = 0; - for(uint32_t i = 0; i < order; i++) - abs_sum_of_qlp_coeff += abs(qlp_coeff[i]); - if(abs_sum_of_qlp_coeff == 0) - abs_sum_of_qlp_coeff = 1; - return subframe_bps + FLAC__bitmath_silog2(abs_sum_of_qlp_coeff); -} - - -uint32_t FLAC__lpc_max_residual_bps(uint32_t subframe_bps, const FLAC__int32 * flac_restrict qlp_coeff, uint32_t order, int lp_quantization) -{ - FLAC__int32 predictor_sum_bps = FLAC__lpc_max_prediction_before_shift_bps(subframe_bps, qlp_coeff, order) - lp_quantization; - if((int)subframe_bps > predictor_sum_bps) - return subframe_bps + 1; - else - return predictor_sum_bps + 1; -} - #if defined(_MSC_VER) // silence MSVC warnings about __restrict modifier #pragma warning ( disable : 4028 ) @@ -807,6 +782,29 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * f #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ +uint32_t FLAC__lpc_max_prediction_before_shift_bps(uint32_t subframe_bps, const FLAC__int32 * flac_restrict qlp_coeff, uint32_t order) +{ + /* This used to be subframe_bps + qlp_coeff_precision + FLAC__bitmath_ilog2(order) + * but that treats both the samples as well as the predictor as unknown. The + * predictor is known however, so taking the log2 of the sum of the absolute values + * of all coefficients is a more accurate representation of the predictor */ + FLAC__int32 abs_sum_of_qlp_coeff = 0; + for(uint32_t i = 0; i < order; i++) + abs_sum_of_qlp_coeff += abs(qlp_coeff[i]); + if(abs_sum_of_qlp_coeff == 0) + abs_sum_of_qlp_coeff = 1; + return subframe_bps + FLAC__bitmath_silog2(abs_sum_of_qlp_coeff); +} + + +uint32_t FLAC__lpc_max_residual_bps(uint32_t subframe_bps, const FLAC__int32 * flac_restrict qlp_coeff, uint32_t order, int lp_quantization) +{ + FLAC__int32 predictor_sum_bps = FLAC__lpc_max_prediction_before_shift_bps(subframe_bps, qlp_coeff, order) - lp_quantization; + if((int)subframe_bps > predictor_sum_bps) + return subframe_bps + 1; + else + return predictor_sum_bps + 1; +} #ifdef FUZZING_BUILD_MODE_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW /* The attribute below is to silence the undefined sanitizer of oss-fuzz. @@ -839,8 +837,10 @@ void FLAC__lpc_restore_signal(const FLAC__int32 * flac_restrict residual, uint32 for(j = 0; j < order; j++) { sum += qlp_coeff[j] * (*(--history)); sumo += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*history); +#ifdef FLAC__OVERFLOW_DETECT if(sumo > 2147483647ll || sumo < -2147483648ll) fprintf(stderr,"FLAC__lpc_restore_signal: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%" PRId64 "\n",i,j,qlp_coeff[j],*history,sumo); +#endif } *(data++) = *(r++) + (sum >> lp_quantization); } @@ -1097,14 +1097,12 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 * flac_restrict residual, u history = data; for(j = 0; j < order; j++) sum += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*(--history)); - if(FLAC__bitmath_silog2(sum >> lp_quantization) > 32) { - fprintf(stderr,"FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, sum=%" PRId64 "\n", i, (sum >> lp_quantization)); - break; - } +#ifdef FLAC__OVERFLOW_DETECT if(FLAC__bitmath_silog2((FLAC__int64)(*r) + (sum >> lp_quantization)) > 32) { fprintf(stderr,"FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, residual=%d, sum=%" PRId64 ", data=%" PRId64 "\n", i, *r, (sum >> lp_quantization), ((FLAC__int64)(*r) + (sum >> lp_quantization))); break; } +#endif *(data++) = *(r++) + (FLAC__int32)(sum >> lp_quantization); } } @@ -1331,6 +1329,87 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 * flac_restrict residual, u } #endif +#ifdef FUZZING_BUILD_MODE_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW +/* The attribute below is to silence the undefined sanitizer of oss-fuzz. + * Because fuzzing feeds bogus predictors and residual samples to the + * decoder, having overflows in this section is unavoidable. Also, + * because the calculated values are audio path only, there is no + * potential for security problems */ +__attribute__((no_sanitize("signed-integer-overflow"))) +#endif +void FLAC__lpc_restore_signal_wide_33bit(const FLAC__int32 * flac_restrict residual, uint32_t data_len, const FLAC__int32 * flac_restrict qlp_coeff, uint32_t order, int lp_quantization, FLAC__int64 * flac_restrict data) +#if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS) +{ + uint32_t i, j; + FLAC__int64 sum; + const FLAC__int32 *r = residual; + const FLAC__int64 *history; + + FLAC__ASSERT(order > 0); + + for(i = 0; i < data_len; i++) { + sum = 0; + history = data; + for(j = 0; j < order; j++) + sum += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*(--history)); +#ifdef FLAC__OVERFLOW_DETECT + if(FLAC__bitmath_silog2((FLAC__int64)(*r) + (sum >> lp_quantization)) > 33) { + fprintf(stderr,"FLAC__lpc_restore_signal_33bit: OVERFLOW, i=%u, residual=%d, sum=%" PRId64 ", data=%" PRId64 "\n", i, *r, (sum >> lp_quantization), ((FLAC__int64)(*r) + (sum >> lp_quantization))); + break; + } +#endif + *(data++) = (FLAC__int64)(*(r++)) + (sum >> lp_quantization); + } +} +#else /* unrolled version for normal use */ +{ + int i; + FLAC__int64 sum; + + FLAC__ASSERT(order > 0); + FLAC__ASSERT(order <= 32); + + for(i = 0; i < (int)data_len; i++) { + sum = 0; + switch(order) { + case 32: sum += qlp_coeff[31] * data[i-32]; /* Falls through. */ + case 31: sum += qlp_coeff[30] * data[i-31]; /* Falls through. */ + case 30: sum += qlp_coeff[29] * data[i-30]; /* Falls through. */ + case 29: sum += qlp_coeff[28] * data[i-29]; /* Falls through. */ + case 28: sum += qlp_coeff[27] * data[i-28]; /* Falls through. */ + case 27: sum += qlp_coeff[26] * data[i-27]; /* Falls through. */ + case 26: sum += qlp_coeff[25] * data[i-26]; /* Falls through. */ + case 25: sum += qlp_coeff[24] * data[i-25]; /* Falls through. */ + case 24: sum += qlp_coeff[23] * data[i-24]; /* Falls through. */ + case 23: sum += qlp_coeff[22] * data[i-23]; /* Falls through. */ + case 22: sum += qlp_coeff[21] * data[i-22]; /* Falls through. */ + case 21: sum += qlp_coeff[20] * data[i-21]; /* Falls through. */ + case 20: sum += qlp_coeff[19] * data[i-20]; /* Falls through. */ + case 19: sum += qlp_coeff[18] * data[i-19]; /* Falls through. */ + case 18: sum += qlp_coeff[17] * data[i-18]; /* Falls through. */ + case 17: sum += qlp_coeff[16] * data[i-17]; /* Falls through. */ + case 16: sum += qlp_coeff[15] * data[i-16]; /* Falls through. */ + case 15: sum += qlp_coeff[14] * data[i-15]; /* Falls through. */ + case 14: sum += qlp_coeff[13] * data[i-14]; /* Falls through. */ + case 13: sum += qlp_coeff[12] * data[i-13]; /* Falls through. */ + case 12: sum += qlp_coeff[11] * data[i-12]; /* Falls through. */ + case 11: sum += qlp_coeff[10] * data[i-11]; /* Falls through. */ + case 10: sum += qlp_coeff[ 9] * data[i-10]; /* Falls through. */ + case 9: sum += qlp_coeff[ 8] * data[i- 9]; /* Falls through. */ + case 8: sum += qlp_coeff[ 7] * data[i- 8]; /* Falls through. */ + case 7: sum += qlp_coeff[ 6] * data[i- 7]; /* Falls through. */ + case 6: sum += qlp_coeff[ 5] * data[i- 6]; /* Falls through. */ + case 5: sum += qlp_coeff[ 4] * data[i- 5]; /* Falls through. */ + case 4: sum += qlp_coeff[ 3] * data[i- 4]; /* Falls through. */ + case 3: sum += qlp_coeff[ 2] * data[i- 3]; /* Falls through. */ + case 2: sum += qlp_coeff[ 1] * data[i- 2]; /* Falls through. */ + case 1: sum += qlp_coeff[ 0] * data[i- 1]; + } + data[i] = residual[i] + (sum >> lp_quantization); + } +} +#endif + #if defined(_MSC_VER) #pragma warning ( default : 4028 ) #endif diff --git a/src/libFLAC/stream_decoder.c b/src/libFLAC/stream_decoder.c index 2669870c..195aa678 100644 --- a/src/libFLAC/stream_decoder.c +++ b/src/libFLAC/stream_decoder.c @@ -74,7 +74,7 @@ static const FLAC__byte ID3V2_TAG_[3] = { 'I', 'D', '3' }; static void set_defaults_(FLAC__StreamDecoder *decoder); static FILE *get_binary_stdin_(void); -static FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, uint32_t size, uint32_t channels); +static FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, uint32_t size, uint32_t channels, uint32_t bps); static FLAC__bool has_id_filtered_(FLAC__StreamDecoder *decoder, FLAC__byte *id); static FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder); static FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder); @@ -133,6 +133,8 @@ typedef struct FLAC__StreamDecoderPrivate { FLAC__BitReader *input; FLAC__int32 *output[FLAC__MAX_CHANNELS]; FLAC__int32 *residual[FLAC__MAX_CHANNELS]; /* WATCHOUT: these are the aligned pointers; the real pointers that should be free()'d are residual_unaligned[] below */ + FLAC__int64 *side_subframe; + FLAC__bool side_subframe_in_use; FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents[FLAC__MAX_CHANNELS]; uint32_t output_capacity, output_channels; FLAC__uint32 fixed_block_size, next_fixed_block_size; @@ -281,6 +283,8 @@ FLAC_API FLAC__StreamDecoder *FLAC__stream_decoder_new(void) decoder->private_->residual_unaligned[i] = decoder->private_->residual[i] = 0; } + decoder->private_->side_subframe = 0; + decoder->private_->output_capacity = 0; decoder->private_->output_channels = 0; decoder->private_->has_seek_table = false; @@ -617,6 +621,10 @@ FLAC_API FLAC__bool FLAC__stream_decoder_finish(FLAC__StreamDecoder *decoder) decoder->private_->residual_unaligned[i] = decoder->private_->residual[i] = 0; } } + if(0 != decoder->private_->side_subframe) { + free(decoder->private_->side_subframe); + decoder->private_->side_subframe = 0; + } decoder->private_->output_capacity = 0; decoder->private_->output_channels = 0; @@ -1225,12 +1233,13 @@ FILE *get_binary_stdin_(void) return stdin; } -FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, uint32_t size, uint32_t channels) +FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, uint32_t size, uint32_t channels, uint32_t bps) { uint32_t i; FLAC__int32 *tmp; - if(size <= decoder->private_->output_capacity && channels <= decoder->private_->output_channels) + if(size <= decoder->private_->output_capacity && channels <= decoder->private_->output_channels && + (bps < 32 || decoder->private_->side_subframe != 0)) return true; /* simply using realloc() is not practical because the number of channels may change mid-stream */ @@ -1246,6 +1255,11 @@ FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, uint32_t size, uint32_ } } + if(0 != decoder->private_->side_subframe) { + free(decoder->private_->side_subframe); + decoder->private_->side_subframe = 0; + } + for(i = 0; i < channels; i++) { /* WATCHOUT: * FLAC__lpc_restore_signal_asm_ia32_mmx() and ..._intrin_sseN() @@ -1267,6 +1281,9 @@ FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, uint32_t size, uint32_ } } + if(bps == 32) + decoder->private_->side_subframe = safe_malloc_mul_2op_p(sizeof(FLAC__int64), /*times (*/size); + decoder->private_->output_capacity = size; decoder->private_->output_channels = channels; @@ -2010,6 +2027,7 @@ FLAC__bool read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool *got_a_frame, FL FLAC__uint32 x; *got_a_frame = false; + decoder->private_->side_subframe_in_use = false; /* init the CRC */ frame_crc = 0; @@ -2021,7 +2039,7 @@ FLAC__bool read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool *got_a_frame, FL return false; if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) /* means we didn't sync on a valid header */ return true; - if(!allocate_output_(decoder, decoder->private_->frame.header.blocksize, decoder->private_->frame.header.channels)) + if(!allocate_output_(decoder, decoder->private_->frame.header.blocksize, decoder->private_->frame.header.channels, decoder->private_->frame.header.bits_per_sample)) return false; for(channel = 0; channel < decoder->private_->frame.header.channels; channel++) { /* @@ -2143,7 +2161,7 @@ FLAC__bool read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool *got_a_frame, FL FLAC__ASSERT(empty_frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER); decoder->private_->samples_decoded = empty_frame.header.number.sample_number + empty_frame.header.blocksize; - if(!allocate_output_(decoder, empty_frame.header.blocksize, empty_frame.header.channels)) + if(!allocate_output_(decoder, empty_frame.header.blocksize, empty_frame.header.channels, empty_frame.header.bits_per_sample)) return false; for(channel = 0; channel < empty_frame.header.channels; channel++) { @@ -2399,6 +2417,9 @@ FLAC__bool read_frame_header_(FLAC__StreamDecoder *decoder) case 2: decoder->private_->frame.header.bits_per_sample = 12; break; + case 3: + is_unparseable = true; + break; case 4: decoder->private_->frame.header.bits_per_sample = 16; break; @@ -2408,20 +2429,13 @@ FLAC__bool read_frame_header_(FLAC__StreamDecoder *decoder) case 6: decoder->private_->frame.header.bits_per_sample = 24; break; - case 3: case 7: - is_unparseable = true; - break; + decoder->private_->frame.header.bits_per_sample = 32; default: FLAC__ASSERT(0); break; } - if(decoder->private_->frame.header.bits_per_sample == 32 && decoder->private_->frame.header.channel_assignment != FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT){ - /* Decoder isn't equipped for 33-bit side frame */ - is_unparseable = true; - } - #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION /* check to make sure that reserved bit is 0 */ if(raw_header[3] & 0x01) /* MAGIC NUMBER */ @@ -2587,12 +2601,6 @@ FLAC__bool read_subframe_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32 } else if(x <= 24) { uint32_t predictor_order = (x>>1)&7; - if(decoder->private_->frame.header.bits_per_sample > 24){ - /* Decoder isn't equipped for fixed subframes with more than 24 bps */ - send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM); - decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; - return true; - } if(decoder->private_->frame.header.blocksize <= predictor_order){ send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; @@ -2623,9 +2631,21 @@ FLAC__bool read_subframe_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32 if(wasted_bits && do_full_decode) { x = decoder->private_->frame.subframes[channel].wasted_bits; - for(i = 0; i < decoder->private_->frame.header.blocksize; i++) { - uint32_t val = decoder->private_->output[channel][i]; - decoder->private_->output[channel][i] = (val << x); + if((bps + x) < 33) { + for(i = 0; i < decoder->private_->frame.header.blocksize; i++) { + uint32_t val = decoder->private_->output[channel][i]; + decoder->private_->output[channel][i] = (val << x); + } + } + else { + /* When there are wasted bits, bps is never 33 and so + * side_subframe is never already in use */ + FLAC__ASSERT(!decoder->private_->side_subframe_in_use); + decoder->private_->side_subframe_in_use = true; + for(i = 0; i < decoder->private_->frame.header.blocksize; i++) { + uint64_t val = decoder->private_->output[channel][i]; + decoder->private_->side_subframe[i] = (val << x); + } } } @@ -2635,13 +2655,13 @@ FLAC__bool read_subframe_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32 FLAC__bool read_subframe_constant_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32_t bps, FLAC__bool do_full_decode) { FLAC__Subframe_Constant *subframe = &decoder->private_->frame.subframes[channel].data.constant; - FLAC__int32 x; + FLAC__int64 x; uint32_t i; FLAC__int32 *output = decoder->private_->output[channel]; decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_CONSTANT; - if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &x, bps)) + if(!FLAC__bitreader_read_raw_int64(decoder->private_->input, &x, bps)) return false; /* read_callback_ sets the state for us */ subframe->value = x; @@ -2658,7 +2678,7 @@ FLAC__bool read_subframe_constant_(FLAC__StreamDecoder *decoder, uint32_t channe FLAC__bool read_subframe_fixed_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32_t bps, const uint32_t order, FLAC__bool do_full_decode) { FLAC__Subframe_Fixed *subframe = &decoder->private_->frame.subframes[channel].data.fixed; - FLAC__int32 i32; + FLAC__int64 i64; FLAC__uint32 u32; uint32_t u; @@ -2669,9 +2689,9 @@ FLAC__bool read_subframe_fixed_(FLAC__StreamDecoder *decoder, uint32_t channel, /* read warm-up samples */ for(u = 0; u < order; u++) { - if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i32, bps)) + if(!FLAC__bitreader_read_raw_int64(decoder->private_->input, &i64, bps)) return false; /* read_callback_ sets the state for us */ - subframe->warmup[u] = i32; + subframe->warmup[u] = i64; } /* read entropy coding method info */ @@ -2711,8 +2731,19 @@ FLAC__bool read_subframe_fixed_(FLAC__StreamDecoder *decoder, uint32_t channel, /* decode the subframe */ if(do_full_decode) { - memcpy(decoder->private_->output[channel], subframe->warmup, sizeof(FLAC__int32) * order); - FLAC__fixed_restore_signal(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, order, decoder->private_->output[channel]+order); + if(bps < 33){ + for(uint32_t i = 0; i < order; i++) + decoder->private_->output[channel][i] = subframe->warmup[i]; + if(bps+order <= 32) + FLAC__fixed_restore_signal(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, order, decoder->private_->output[channel]+order); + else + FLAC__fixed_restore_signal_wide(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, order, decoder->private_->output[channel]+order); + } + else { + decoder->private_->side_subframe_in_use = true; + memcpy(decoder->private_->side_subframe, subframe->warmup, sizeof(FLAC__int64) * order); + FLAC__fixed_restore_signal_wide_33bit(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, order, decoder->private_->side_subframe+order); + } } return true; @@ -2722,6 +2753,7 @@ FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, uint32_t channel, ui { FLAC__Subframe_LPC *subframe = &decoder->private_->frame.subframes[channel].data.lpc; FLAC__int32 i32; + FLAC__int64 i64; FLAC__uint32 u32; uint32_t u; @@ -2732,9 +2764,9 @@ FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, uint32_t channel, ui /* read warm-up samples */ for(u = 0; u < order; u++) { - if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i32, bps)) + if(!FLAC__bitreader_read_raw_int64(decoder->private_->input, &i64, bps)) return false; /* read_callback_ sets the state for us */ - subframe->warmup[u] = i32; + subframe->warmup[u] = i64; } /* read qlp coeff precision */ @@ -2801,12 +2833,20 @@ FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, uint32_t channel, ui /* decode the subframe */ if(do_full_decode) { - memcpy(decoder->private_->output[channel], subframe->warmup, sizeof(FLAC__int32) * order); - if(FLAC__lpc_max_residual_bps(bps, subframe->qlp_coeff, order, subframe->quantization_level) <= 32 && - FLAC__lpc_max_prediction_before_shift_bps(bps, subframe->qlp_coeff, order) <= 32) - FLAC__lpc_restore_signal(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order); - else - FLAC__lpc_restore_signal_wide(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order); + if(bps <= 32) { + for(uint32_t i = 0; i < order; i++) + decoder->private_->output[channel][i] = subframe->warmup[i]; + if(FLAC__lpc_max_residual_bps(bps, subframe->qlp_coeff, order, subframe->quantization_level) <= 32 && + FLAC__lpc_max_prediction_before_shift_bps(bps, subframe->qlp_coeff, order) <= 32) + FLAC__lpc_restore_signal(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order); + else + FLAC__lpc_restore_signal_wide(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order); + } + else { + decoder->private_->side_subframe_in_use = true; + memcpy(decoder->private_->side_subframe, subframe->warmup, sizeof(FLAC__int64) * order); + FLAC__lpc_restore_signal_wide_33bit(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->side_subframe+order); + } } return true; @@ -2815,22 +2855,39 @@ FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, uint32_t channel, ui FLAC__bool read_subframe_verbatim_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32_t bps, FLAC__bool do_full_decode) { FLAC__Subframe_Verbatim *subframe = &decoder->private_->frame.subframes[channel].data.verbatim; - FLAC__int32 x, *residual = decoder->private_->residual[channel]; uint32_t i; decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_VERBATIM; - subframe->data = residual; + if(bps < 33) { + FLAC__int32 x, *residual = decoder->private_->residual[channel]; - for(i = 0; i < decoder->private_->frame.header.blocksize; i++) { - if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &x, bps)) - return false; /* read_callback_ sets the state for us */ - residual[i] = x; + subframe->data_type = FLAC__VERBATIM_SUBFRAME_DATA_TYPE_INT32; + subframe->data.int32 = residual; + + for(i = 0; i < decoder->private_->frame.header.blocksize; i++) { + if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &x, bps)) + return false; /* read_callback_ sets the state for us */ + residual[i] = x; + } + + /* decode the subframe */ + if(do_full_decode) + memcpy(decoder->private_->output[channel], subframe->data.int32, sizeof(FLAC__int32) * decoder->private_->frame.header.blocksize); } + else { + FLAC__int64 x, *side = decoder->private_->side_subframe; - /* decode the subframe */ - if(do_full_decode) - memcpy(decoder->private_->output[channel], subframe->data, sizeof(FLAC__int32) * decoder->private_->frame.header.blocksize); + subframe->data_type = FLAC__VERBATIM_SUBFRAME_DATA_TYPE_INT64; + subframe->data.int64 = side; + decoder->private_->side_subframe_in_use = true; + + for(i = 0; i < decoder->private_->frame.header.blocksize; i++) { + if(!FLAC__bitreader_read_raw_int64(decoder->private_->input, &x, bps)) + return false; /* read_callback_ sets the state for us */ + side[i] = x; + } + } return true; } @@ -3000,37 +3057,48 @@ FLAC__bool read_callback_(FLAC__byte buffer[], size_t *bytes, void *client_data) __attribute__((no_sanitize("signed-integer-overflow"))) #endif void undo_channel_coding(FLAC__StreamDecoder *decoder) { - FLAC__int32 mid, side; switch(decoder->private_->frame.header.channel_assignment) { case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT: /* do nothing */ break; case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE: FLAC__ASSERT(decoder->private_->frame.header.channels == 2); + FLAC__ASSERT(decoder->private_->side_subframe_in_use != /* logical XOR */ (decoder->private_->frame.header.bits_per_sample < 32)); for(uint32_t i = 0; i < decoder->private_->frame.header.blocksize; i++) - decoder->private_->output[1][i] = decoder->private_->output[0][i] - decoder->private_->output[1][i]; + if(decoder->private_->side_subframe_in_use) + decoder->private_->output[1][i] = decoder->private_->output[0][i] - decoder->private_->side_subframe[i]; + else + decoder->private_->output[1][i] = decoder->private_->output[0][i] - decoder->private_->output[1][i]; break; case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE: FLAC__ASSERT(decoder->private_->frame.header.channels == 2); + FLAC__ASSERT(decoder->private_->side_subframe_in_use != /* logical XOR */ (decoder->private_->frame.header.bits_per_sample < 32)); for(uint32_t i = 0; i < decoder->private_->frame.header.blocksize; i++) - decoder->private_->output[0][i] += decoder->private_->output[1][i]; + if(decoder->private_->side_subframe_in_use) + decoder->private_->output[0][i] = decoder->private_->output[1][i] + decoder->private_->side_subframe[i]; + else + decoder->private_->output[0][i] += decoder->private_->output[1][i]; break; case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE: FLAC__ASSERT(decoder->private_->frame.header.channels == 2); + FLAC__ASSERT(decoder->private_->side_subframe_in_use != /* logical XOR */ (decoder->private_->frame.header.bits_per_sample < 32)); for(uint32_t i = 0; i < decoder->private_->frame.header.blocksize; i++) { -#if 1 - mid = decoder->private_->output[0][i]; - side = decoder->private_->output[1][i]; - mid = ((uint32_t) mid) << 1; - mid |= (side & 1); /* i.e. if 'side' is odd... */ - decoder->private_->output[0][i] = (mid + side) >> 1; - decoder->private_->output[1][i] = (mid - side) >> 1; -#else - /* OPT: without 'side' temp variable */ - mid = (decoder->private_->output[0][i] << 1) | (decoder->private_->output[1][i] & 1); /* i.e. if 'side' is odd... */ - decoder->private_->output[0][i] = (mid + decoder->private_->output[1][i]) >> 1; - decoder->private_->output[1][i] = (mid - decoder->private_->output[1][i]) >> 1; -#endif + if(!decoder->private_->side_subframe_in_use){ + FLAC__int32 mid, side; + mid = decoder->private_->output[0][i]; + side = decoder->private_->output[1][i]; + mid = ((uint32_t) mid) << 1; + mid |= (side & 1); /* i.e. if 'side' is odd... */ + decoder->private_->output[0][i] = (mid + side) >> 1; + decoder->private_->output[1][i] = (mid - side) >> 1; + } + else { /* bps == 32 */ + FLAC__int64 mid; + mid = ((uint64_t)decoder->private_->output[0][i]) << 1; + mid |= (decoder->private_->side_subframe[i] & 1); /* i.e. if 'side' is odd... */ + decoder->private_->output[0][i] = (mid + decoder->private_->side_subframe[i]) >> 1; + decoder->private_->output[1][i] = (mid - decoder->private_->side_subframe[i]) >> 1; + } } break; default: diff --git a/src/libFLAC/stream_encoder.c b/src/libFLAC/stream_encoder.c index 75f5b867..4d8e5a84 100644 --- a/src/libFLAC/stream_encoder.c +++ b/src/libFLAC/stream_encoder.c @@ -3934,7 +3934,8 @@ uint32_t evaluate_verbatim_subframe_( subframe->type = FLAC__SUBFRAME_TYPE_VERBATIM; - subframe->data.verbatim.data = signal; + subframe->data.verbatim.data_type = FLAC__VERBATIM_SUBFRAME_DATA_TYPE_INT32; + subframe->data.verbatim.data.int32 = signal; estimate = FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + subframe->wasted_bits + (blocksize * subframe_bps); diff --git a/src/libFLAC/stream_encoder_framing.c b/src/libFLAC/stream_encoder_framing.c index 49b35d3b..af1822bd 100644 --- a/src/libFLAC/stream_encoder_framing.c +++ b/src/libFLAC/stream_encoder_framing.c @@ -468,7 +468,7 @@ FLAC__bool FLAC__subframe_add_lpc(const FLAC__Subframe_LPC *subframe, uint32_t r FLAC__bool FLAC__subframe_add_verbatim(const FLAC__Subframe_Verbatim *subframe, uint32_t samples, uint32_t subframe_bps, uint32_t wasted_bits, FLAC__BitWriter *bw) { uint32_t i; - const FLAC__int32 *signal = subframe->data; + const FLAC__int32 *signal = subframe->data.int32; if(!FLAC__bitwriter_write_raw_uint32(bw, FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK | (wasted_bits? 1:0), FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN)) return false; |