mirror of https://github.com/xiph/flac
Add 32-bit decoding capability
Decoding for 32-bit files is added, including the ability to decode a 33-bit side subframe. However, residuals are assumed to be limited to a 32-bit signed int, the encoder must make sure of this
This commit is contained in:
parent
9b3826006a
commit
9df24ac202
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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! */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue