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:
Martijn van Beurden 2022-04-01 21:25:51 +02:00
parent 9b3826006a
commit 9df24ac202
12 changed files with 377 additions and 108 deletions

View File

@ -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;

View File

@ -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];

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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! */

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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);

View File

@ -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;