mirror of
https://github.com/claunia/flac.git
synced 2026-05-20 23:26:26 +00:00
Update CRC16 for larger data blocks when decoding.
This commit is contained in:
committed by
Erik de Castro Lopo
parent
5579f2922f
commit
8874ecc082
@@ -1,6 +1,6 @@
|
||||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
* Copyright (C) 2011-2018 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -109,6 +109,7 @@ struct FLAC__BitReader {
|
||||
uint32_t consumed_words; /* #words ... */
|
||||
uint32_t consumed_bits; /* ... + (#bits of head word) already consumed from the front of buffer */
|
||||
uint32_t read_crc16; /* the running frame CRC */
|
||||
uint32_t crc16_offset; /* the number of words in the current buffer that should not be CRC'd */
|
||||
uint32_t crc16_align; /* the number of bits in the current consumed word that should not be CRC'd */
|
||||
FLAC__BitReaderReadCallback read_callback;
|
||||
void *client_data;
|
||||
@@ -117,32 +118,33 @@ struct FLAC__BitReader {
|
||||
static inline void crc16_update_word_(FLAC__BitReader *br, brword word)
|
||||
{
|
||||
register uint32_t crc = br->read_crc16;
|
||||
#if FLAC__BYTES_PER_WORD == 4
|
||||
switch(br->crc16_align) {
|
||||
case 0: crc = FLAC__CRC16_UPDATE((uint32_t)(word >> 24), crc); /* Falls through. */
|
||||
case 8: crc = FLAC__CRC16_UPDATE((uint32_t)((word >> 16) & 0xff), crc); /* Falls through. */
|
||||
case 16: crc = FLAC__CRC16_UPDATE((uint32_t)((word >> 8) & 0xff), crc); /* Falls through. */
|
||||
case 24: br->read_crc16 = FLAC__CRC16_UPDATE((uint32_t)(word & 0xff), crc); /* Falls through. */
|
||||
}
|
||||
#elif FLAC__BYTES_PER_WORD == 8
|
||||
switch(br->crc16_align) {
|
||||
case 0: crc = FLAC__CRC16_UPDATE((uint32_t)(word >> 56), crc); /* Falls through. */
|
||||
case 8: crc = FLAC__CRC16_UPDATE((uint32_t)((word >> 48) & 0xff), crc); /* Falls through. */
|
||||
case 16: crc = FLAC__CRC16_UPDATE((uint32_t)((word >> 40) & 0xff), crc); /* Falls through. */
|
||||
case 24: crc = FLAC__CRC16_UPDATE((uint32_t)((word >> 32) & 0xff), crc); /* Falls through. */
|
||||
case 32: crc = FLAC__CRC16_UPDATE((uint32_t)((word >> 24) & 0xff), crc); /* Falls through. */
|
||||
case 40: crc = FLAC__CRC16_UPDATE((uint32_t)((word >> 16) & 0xff), crc); /* Falls through. */
|
||||
case 48: crc = FLAC__CRC16_UPDATE((uint32_t)((word >> 8) & 0xff), crc); /* Falls through. */
|
||||
case 56: br->read_crc16 = FLAC__CRC16_UPDATE((uint32_t)(word & 0xff), crc);
|
||||
}
|
||||
#else
|
||||
|
||||
for( ; br->crc16_align < FLAC__BITS_PER_WORD; br->crc16_align += 8)
|
||||
crc = FLAC__CRC16_UPDATE((uint32_t)((word >> (FLAC__BITS_PER_WORD-8-br->crc16_align)) & 0xff), crc);
|
||||
|
||||
br->read_crc16 = crc;
|
||||
#endif
|
||||
br->crc16_align = 0;
|
||||
}
|
||||
|
||||
static inline void crc16_update_block_(FLAC__BitReader *br)
|
||||
{
|
||||
if(br->crc16_align)
|
||||
crc16_update_word_(br, br->buffer[br->crc16_offset++]);
|
||||
|
||||
#if FLAC__BYTES_PER_WORD == 4
|
||||
br->read_crc16 = FLAC__crc16_update_words32(br->buffer + br->crc16_offset, br->consumed_words - br->crc16_offset, br->read_crc16);
|
||||
#elif FLAC__BYTES_PER_WORD == 8
|
||||
br->read_crc16 = FLAC__crc16_update_words64(br->buffer + br->crc16_offset, br->consumed_words - br->crc16_offset, br->read_crc16);
|
||||
#else
|
||||
unsigned i;
|
||||
|
||||
for(i = br->crc16_offset; i < br->consumed_words; i++)
|
||||
crc16_update_word_(br, br->buffer[i]);
|
||||
#endif
|
||||
|
||||
br->crc16_offset = 0;
|
||||
}
|
||||
|
||||
static FLAC__bool bitreader_read_from_client_(FLAC__BitReader *br)
|
||||
{
|
||||
uint32_t start, end;
|
||||
@@ -151,6 +153,8 @@ static FLAC__bool bitreader_read_from_client_(FLAC__BitReader *br)
|
||||
|
||||
/* first shift the unconsumed buffer data toward the front as much as possible */
|
||||
if(br->consumed_words > 0) {
|
||||
crc16_update_block_(br); /* CRC consumed words */
|
||||
|
||||
start = br->consumed_words;
|
||||
end = br->words + (br->bytes? 1:0);
|
||||
memmove(br->buffer, br->buffer+start, FLAC__BYTES_PER_WORD * (end - start));
|
||||
@@ -328,6 +332,7 @@ void FLAC__bitreader_reset_read_crc16(FLAC__BitReader *br, FLAC__uint16 seed)
|
||||
FLAC__ASSERT((br->consumed_bits & 7) == 0);
|
||||
|
||||
br->read_crc16 = (uint32_t)seed;
|
||||
br->crc16_offset = br->consumed_words;
|
||||
br->crc16_align = br->consumed_bits;
|
||||
}
|
||||
|
||||
@@ -335,6 +340,10 @@ FLAC__uint16 FLAC__bitreader_get_read_crc16(FLAC__BitReader *br)
|
||||
{
|
||||
FLAC__ASSERT(0 != br);
|
||||
FLAC__ASSERT(0 != br->buffer);
|
||||
|
||||
/* CRC consumed words up to here */
|
||||
crc16_update_block_(br);
|
||||
|
||||
FLAC__ASSERT((br->consumed_bits & 7) == 0);
|
||||
FLAC__ASSERT(br->crc16_align <= br->consumed_bits);
|
||||
|
||||
@@ -397,7 +406,6 @@ FLAC__bool FLAC__bitreader_read_raw_uint32(FLAC__BitReader *br, FLAC__uint32 *va
|
||||
/* (FLAC__BITS_PER_WORD - br->consumed_bits <= bits) ==> (FLAC__WORD_ALL_ONES >> br->consumed_bits) has no more than 'bits' non-zero bits */
|
||||
*val = (FLAC__uint32)(word & (FLAC__WORD_ALL_ONES >> br->consumed_bits));
|
||||
bits -= n;
|
||||
crc16_update_word_(br, word);
|
||||
br->consumed_words++;
|
||||
br->consumed_bits = 0;
|
||||
if(bits) { /* if there are still bits left to read, there have to be less than 32 so they will all be in the next word */
|
||||
@@ -416,7 +424,6 @@ FLAC__bool FLAC__bitreader_read_raw_uint32(FLAC__BitReader *br, FLAC__uint32 *va
|
||||
}
|
||||
/* at this point bits == FLAC__BITS_PER_WORD == 32; because of previous assertions, it can't be larger */
|
||||
*val = (FLAC__uint32)word;
|
||||
crc16_update_word_(br, word);
|
||||
br->consumed_words++;
|
||||
return true;
|
||||
}
|
||||
@@ -663,7 +670,6 @@ FLAC__bool FLAC__bitreader_read_unary_unsigned(FLAC__BitReader *br, uint32_t *va
|
||||
i++;
|
||||
br->consumed_bits += i;
|
||||
if(br->consumed_bits >= FLAC__BITS_PER_WORD) { /* faster way of testing if(br->consumed_bits == FLAC__BITS_PER_WORD) */
|
||||
crc16_update_word_(br, br->buffer[br->consumed_words]);
|
||||
br->consumed_words++;
|
||||
br->consumed_bits = 0;
|
||||
}
|
||||
@@ -671,7 +677,6 @@ FLAC__bool FLAC__bitreader_read_unary_unsigned(FLAC__BitReader *br, uint32_t *va
|
||||
}
|
||||
else {
|
||||
*val += FLAC__BITS_PER_WORD - br->consumed_bits;
|
||||
crc16_update_word_(br, br->buffer[br->consumed_words]);
|
||||
br->consumed_words++;
|
||||
br->consumed_bits = 0;
|
||||
/* didn't find stop bit yet, have to keep going... */
|
||||
@@ -789,7 +794,7 @@ FLAC__bool FLAC__bitreader_read_rice_signed_block(FLAC__BitReader *br, int vals[
|
||||
x = ucbits;
|
||||
do {
|
||||
/* didn't find stop bit yet, have to keep going... */
|
||||
crc16_update_word_(br, br->buffer[cwords++]);
|
||||
cwords++;
|
||||
if (cwords >= words)
|
||||
goto incomplete_msbs;
|
||||
b = br->buffer[cwords];
|
||||
@@ -809,7 +814,7 @@ FLAC__bool FLAC__bitreader_read_rice_signed_block(FLAC__BitReader *br, int vals[
|
||||
b <<= parameter;
|
||||
} else {
|
||||
/* there are still bits left to read, they will all be in the next word */
|
||||
crc16_update_word_(br, br->buffer[cwords++]);
|
||||
cwords++;
|
||||
if (cwords >= words)
|
||||
goto incomplete_lsbs;
|
||||
b = br->buffer[cwords];
|
||||
@@ -865,7 +870,7 @@ incomplete_lsbs:
|
||||
|
||||
if(ucbits == 0 && cwords < words) {
|
||||
/* don't leave the head word with no unconsumed bits */
|
||||
crc16_update_word_(br, br->buffer[cwords++]);
|
||||
cwords++;
|
||||
ucbits = FLAC__BITS_PER_WORD;
|
||||
}
|
||||
|
||||
|
||||
@@ -394,3 +394,43 @@ FLAC__uint16 FLAC__crc16(const FLAC__byte *data, uint32_t len)
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
FLAC__uint16 FLAC__crc16_update_words32(const FLAC__uint32 *words, uint32_t len, FLAC__uint16 crc)
|
||||
{
|
||||
while (len >= 2) {
|
||||
crc ^= words[0] >> 16;
|
||||
|
||||
crc = FLAC__crc16_table[7][crc >> 8 ] ^ FLAC__crc16_table[6][crc & 0xFF ] ^
|
||||
FLAC__crc16_table[5][(words[0] >> 8) & 0xFF] ^ FLAC__crc16_table[4][ words[0] & 0xFF] ^
|
||||
FLAC__crc16_table[3][ words[1] >> 24 ] ^ FLAC__crc16_table[2][(words[1] >> 16) & 0xFF] ^
|
||||
FLAC__crc16_table[1][(words[1] >> 8) & 0xFF] ^ FLAC__crc16_table[0][ words[1] & 0xFF];
|
||||
|
||||
words += 2;
|
||||
len -= 2;
|
||||
}
|
||||
|
||||
if (len) {
|
||||
crc ^= words[0] >> 16;
|
||||
|
||||
crc = FLAC__crc16_table[3][crc >> 8 ] ^ FLAC__crc16_table[2][crc & 0xFF ] ^
|
||||
FLAC__crc16_table[1][(words[0] >> 8) & 0xFF] ^ FLAC__crc16_table[0][words[0] & 0xFF];
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
FLAC__uint16 FLAC__crc16_update_words64(const FLAC__uint64 *words, uint32_t len, FLAC__uint16 crc)
|
||||
{
|
||||
while (len--) {
|
||||
crc ^= words[0] >> 48;
|
||||
|
||||
crc = FLAC__crc16_table[7][crc >> 8 ] ^ FLAC__crc16_table[6][crc & 0xFF ] ^
|
||||
FLAC__crc16_table[5][(words[0] >> 40) & 0xFF] ^ FLAC__crc16_table[4][(words[0] >> 32) & 0xFF] ^
|
||||
FLAC__crc16_table[3][(words[0] >> 24) & 0xFF] ^ FLAC__crc16_table[2][(words[0] >> 16) & 0xFF] ^
|
||||
FLAC__crc16_table[1][(words[0] >> 8) & 0xFF] ^ FLAC__crc16_table[0][ words[0] & 0xFF];
|
||||
|
||||
words++;
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
@@ -54,5 +54,7 @@ extern FLAC__uint16 const FLAC__crc16_table[8][256];
|
||||
#endif
|
||||
|
||||
FLAC__uint16 FLAC__crc16(const FLAC__byte *data, uint32_t len);
|
||||
FLAC__uint16 FLAC__crc16_update_words32(const FLAC__uint32 *words, uint32_t len, FLAC__uint16 crc);
|
||||
FLAC__uint16 FLAC__crc16_update_words64(const FLAC__uint64 *words, uint32_t len, FLAC__uint16 crc);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user