mirror of
https://github.com/claunia/flac.git
synced 2025-12-16 18:54:26 +00:00
src/flac/decode.c : Fix a cast-align warning from GCC.
The old code was creating an array of FLAC__int8, and then casting that to a set of signed and unsigned 16 and 32 bit integers. This was replaced with a single union containing all the requred array. This solution means that there are fewer pointer casts and actually gives the compiler more information with which to generate fast code.
This commit is contained in:
@@ -966,12 +966,16 @@ FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder
|
||||
));
|
||||
unsigned wide_samples = frame->header.blocksize, wide_sample, sample, channel;
|
||||
unsigned frame_bytes = 0;
|
||||
static FLAC__int8 s8buffer[FLAC__MAX_BLOCK_SIZE * FLAC__MAX_CHANNELS * sizeof(FLAC__int32)]; /* WATCHOUT: can be up to 2 megs */
|
||||
FLAC__uint8 *u8buffer = (FLAC__uint8 *)s8buffer;
|
||||
FLAC__int16 *s16buffer = (FLAC__int16 *)s8buffer;
|
||||
FLAC__uint16 *u16buffer = (FLAC__uint16 *)s8buffer;
|
||||
FLAC__int32 *s32buffer = (FLAC__int32 *)s8buffer;
|
||||
FLAC__uint32 *u32buffer = (FLAC__uint32 *)s8buffer;
|
||||
|
||||
static union
|
||||
{ FLAC__int8 s8buffer [FLAC__MAX_BLOCK_SIZE * FLAC__MAX_CHANNELS * sizeof(FLAC__int32)]; /* WATCHOUT: can be up to 2 megs */
|
||||
FLAC__uint8 u8buffer [FLAC__MAX_BLOCK_SIZE * FLAC__MAX_CHANNELS * sizeof(FLAC__int32)];
|
||||
FLAC__int16 s16buffer [FLAC__MAX_BLOCK_SIZE * FLAC__MAX_CHANNELS * sizeof(FLAC__int16)];
|
||||
FLAC__uint16 u16buffer [FLAC__MAX_BLOCK_SIZE * FLAC__MAX_CHANNELS * sizeof(FLAC__int16)];
|
||||
FLAC__int32 s32buffer [FLAC__MAX_BLOCK_SIZE * FLAC__MAX_CHANNELS];
|
||||
FLAC__uint32 u32buffer [FLAC__MAX_BLOCK_SIZE * FLAC__MAX_CHANNELS];
|
||||
} ubuf;
|
||||
|
||||
size_t bytes_to_write = 0;
|
||||
|
||||
(void)decoder;
|
||||
@@ -1092,7 +1096,7 @@ FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder
|
||||
}
|
||||
if(decoder_session->replaygain.apply) {
|
||||
bytes_to_write = FLAC__replaygain_synthesis__apply_gain(
|
||||
u8buffer,
|
||||
ubuf.u8buffer,
|
||||
!is_big_endian,
|
||||
is_unsigned_samples,
|
||||
buffer,
|
||||
@@ -1108,17 +1112,17 @@ FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder
|
||||
}
|
||||
/* first some special code for common cases */
|
||||
else if(is_big_endian == is_big_endian_host_ && !is_unsigned_samples && channels == 2 && bps+shift == 16) {
|
||||
FLAC__int16 *buf1_ = s16buffer + 1;
|
||||
FLAC__int16 *buf1_ = ubuf.s16buffer + 1;
|
||||
if(is_big_endian)
|
||||
memcpy(s16buffer, ((FLAC__byte*)(buffer[0]))+2, sizeof(FLAC__int32) * wide_samples - 2);
|
||||
memcpy(ubuf.s16buffer, ((FLAC__byte*)(buffer[0]))+2, sizeof(FLAC__int32) * wide_samples - 2);
|
||||
else
|
||||
memcpy(s16buffer, buffer[0], sizeof(FLAC__int32) * wide_samples);
|
||||
memcpy(ubuf.s16buffer, buffer[0], sizeof(FLAC__int32) * wide_samples);
|
||||
for(sample = 0; sample < wide_samples; sample++, buf1_+=2)
|
||||
*buf1_ = (FLAC__int16)buffer[1][sample];
|
||||
bytes_to_write = 4 * sample;
|
||||
}
|
||||
else if(is_big_endian == is_big_endian_host_ && !is_unsigned_samples && channels == 1 && bps+shift == 16) {
|
||||
FLAC__int16 *buf1_ = s16buffer;
|
||||
FLAC__int16 *buf1_ = ubuf.s16buffer;
|
||||
for(sample = 0; sample < wide_samples; sample++)
|
||||
*buf1_++ = (FLAC__int16)buffer[0][sample];
|
||||
bytes_to_write = 2 * sample;
|
||||
@@ -1128,35 +1132,35 @@ FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder
|
||||
if(is_unsigned_samples) {
|
||||
if(channels == 2) {
|
||||
for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++) {
|
||||
u16buffer[sample++] = (FLAC__uint16)(buffer[0][wide_sample] + 0x8000);
|
||||
u16buffer[sample++] = (FLAC__uint16)(buffer[1][wide_sample] + 0x8000);
|
||||
ubuf.u16buffer[sample++] = (FLAC__uint16)(buffer[0][wide_sample] + 0x8000);
|
||||
ubuf.u16buffer[sample++] = (FLAC__uint16)(buffer[1][wide_sample] + 0x8000);
|
||||
}
|
||||
}
|
||||
else if(channels == 1) {
|
||||
for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
|
||||
u16buffer[sample++] = (FLAC__uint16)(buffer[0][wide_sample] + 0x8000);
|
||||
ubuf.u16buffer[sample++] = (FLAC__uint16)(buffer[0][wide_sample] + 0x8000);
|
||||
}
|
||||
else { /* works for any 'channels' but above flavors are faster for 1 and 2 */
|
||||
for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
|
||||
for(channel = 0; channel < channels; channel++, sample++)
|
||||
u16buffer[sample] = (FLAC__uint16)(buffer[channel][wide_sample] + 0x8000);
|
||||
ubuf.u16buffer[sample] = (FLAC__uint16)(buffer[channel][wide_sample] + 0x8000);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(channels == 2) {
|
||||
for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++) {
|
||||
s16buffer[sample++] = (FLAC__int16)(buffer[0][wide_sample]);
|
||||
s16buffer[sample++] = (FLAC__int16)(buffer[1][wide_sample]);
|
||||
ubuf.s16buffer[sample++] = (FLAC__int16)(buffer[0][wide_sample]);
|
||||
ubuf.s16buffer[sample++] = (FLAC__int16)(buffer[1][wide_sample]);
|
||||
}
|
||||
}
|
||||
else if(channels == 1) {
|
||||
for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
|
||||
s16buffer[sample++] = (FLAC__int16)(buffer[0][wide_sample]);
|
||||
ubuf.s16buffer[sample++] = (FLAC__int16)(buffer[0][wide_sample]);
|
||||
}
|
||||
else { /* works for any 'channels' but above flavors are faster for 1 and 2 */
|
||||
for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
|
||||
for(channel = 0; channel < channels; channel++, sample++)
|
||||
s16buffer[sample] = (FLAC__int16)(buffer[channel][wide_sample]);
|
||||
ubuf.s16buffer[sample] = (FLAC__int16)(buffer[channel][wide_sample]);
|
||||
}
|
||||
}
|
||||
if(is_big_endian != is_big_endian_host_) {
|
||||
@@ -1164,9 +1168,9 @@ FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder
|
||||
const unsigned bytes = sample * 2;
|
||||
unsigned b;
|
||||
for(b = 0; b < bytes; b += 2) {
|
||||
tmp = u8buffer[b];
|
||||
u8buffer[b] = u8buffer[b+1];
|
||||
u8buffer[b+1] = tmp;
|
||||
tmp = ubuf.u8buffer[b];
|
||||
ubuf.u8buffer[b] = ubuf.u8buffer[b+1];
|
||||
ubuf.u8buffer[b+1] = tmp;
|
||||
}
|
||||
}
|
||||
bytes_to_write = 2 * sample;
|
||||
@@ -1175,24 +1179,24 @@ FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder
|
||||
if(is_unsigned_samples) {
|
||||
for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
|
||||
for(channel = 0; channel < channels; channel++, sample++)
|
||||
u32buffer[sample] = buffer[channel][wide_sample] + 0x800000;
|
||||
ubuf.u32buffer[sample] = buffer[channel][wide_sample] + 0x800000;
|
||||
}
|
||||
else {
|
||||
for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
|
||||
for(channel = 0; channel < channels; channel++, sample++)
|
||||
s32buffer[sample] = buffer[channel][wide_sample];
|
||||
ubuf.s32buffer[sample] = buffer[channel][wide_sample];
|
||||
}
|
||||
if(is_big_endian != is_big_endian_host_) {
|
||||
unsigned char tmp;
|
||||
const unsigned bytes = sample * 4;
|
||||
unsigned b;
|
||||
for(b = 0; b < bytes; b += 4) {
|
||||
tmp = u8buffer[b];
|
||||
u8buffer[b] = u8buffer[b+3];
|
||||
u8buffer[b+3] = tmp;
|
||||
tmp = u8buffer[b+1];
|
||||
u8buffer[b+1] = u8buffer[b+2];
|
||||
u8buffer[b+2] = tmp;
|
||||
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;
|
||||
}
|
||||
}
|
||||
if(is_big_endian) {
|
||||
@@ -1200,18 +1204,18 @@ FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder
|
||||
const unsigned bytes = sample * 4;
|
||||
for(lbyte = b = 0; b < bytes; ) {
|
||||
b++;
|
||||
u8buffer[lbyte++] = u8buffer[b++];
|
||||
u8buffer[lbyte++] = u8buffer[b++];
|
||||
u8buffer[lbyte++] = u8buffer[b++];
|
||||
ubuf.u8buffer[lbyte++] = ubuf.u8buffer[b++];
|
||||
ubuf.u8buffer[lbyte++] = ubuf.u8buffer[b++];
|
||||
ubuf.u8buffer[lbyte++] = ubuf.u8buffer[b++];
|
||||
}
|
||||
}
|
||||
else {
|
||||
unsigned b, lbyte;
|
||||
const unsigned bytes = sample * 4;
|
||||
for(lbyte = b = 0; b < bytes; ) {
|
||||
u8buffer[lbyte++] = u8buffer[b++];
|
||||
u8buffer[lbyte++] = u8buffer[b++];
|
||||
u8buffer[lbyte++] = u8buffer[b++];
|
||||
ubuf.u8buffer[lbyte++] = ubuf.u8buffer[b++];
|
||||
ubuf.u8buffer[lbyte++] = ubuf.u8buffer[b++];
|
||||
ubuf.u8buffer[lbyte++] = ubuf.u8buffer[b++];
|
||||
b++;
|
||||
}
|
||||
}
|
||||
@@ -1221,12 +1225,12 @@ FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder
|
||||
if(is_unsigned_samples) {
|
||||
for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
|
||||
for(channel = 0; channel < channels; channel++, sample++)
|
||||
u8buffer[sample] = (FLAC__uint8)(buffer[channel][wide_sample] + 0x80);
|
||||
ubuf.u8buffer[sample] = (FLAC__uint8)(buffer[channel][wide_sample] + 0x80);
|
||||
}
|
||||
else {
|
||||
for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
|
||||
for(channel = 0; channel < channels; channel++, sample++)
|
||||
s8buffer[sample] = (FLAC__int8)(buffer[channel][wide_sample]);
|
||||
ubuf.s8buffer[sample] = (FLAC__int8)(buffer[channel][wide_sample]);
|
||||
}
|
||||
bytes_to_write = sample;
|
||||
}
|
||||
@@ -1239,7 +1243,7 @@ FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder
|
||||
}
|
||||
}
|
||||
if(bytes_to_write > 0) {
|
||||
if(flac__utils_fwrite(u8buffer, 1, bytes_to_write, fout) != bytes_to_write) {
|
||||
if(flac__utils_fwrite(ubuf.u8buffer, 1, bytes_to_write, fout) != bytes_to_write) {
|
||||
/* if a pipe closed when writing to stdout, we let it go without an error message */
|
||||
if(errno == EPIPE && decoder_session->fout == stdout)
|
||||
decoder_session->aborting_due_to_until = true;
|
||||
|
||||
Reference in New Issue
Block a user