summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/FLAC/format.h18
-rw-r--r--src/flac/analyze.c6
-rw-r--r--src/flac/decode.c34
-rw-r--r--src/libFLAC/bitreader.c15
-rw-r--r--src/libFLAC/fixed.c68
-rw-r--r--src/libFLAC/include/private/bitreader.h1
-rw-r--r--src/libFLAC/include/private/fixed.h2
-rw-r--r--src/libFLAC/include/private/lpc.h7
-rw-r--r--src/libFLAC/lpc.c137
-rw-r--r--src/libFLAC/stream_decoder.c192
-rw-r--r--src/libFLAC/stream_encoder.c3
-rw-r--r--src/libFLAC/stream_encoder_framing.c2
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;