summaryrefslogtreecommitdiff
path: root/libavcodec/siren.c
diff options
context:
space:
mode:
authorPeter Ross <pross@xvid.org>2021-09-04 21:14:37 +1000
committerPeter Ross <pross@xvid.org>2021-09-28 21:23:26 +1000
commit855014ff83dae786e914b4c7df88d263ec4122a7 (patch)
tree37e31cc86e8129d18ba3ea8ec77a2c6df28ac944 /libavcodec/siren.c
parente40593c0505a3ee143b8ac949af1bb70becafb21 (diff)
avcodec/siren: add checksum calculation
Reviewed-by: Lynne <dev@lynne.ee> Signed-off-by: Peter Ross <pross@xvid.org>
Diffstat (limited to 'libavcodec/siren.c')
-rw-r--r--libavcodec/siren.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/libavcodec/siren.c b/libavcodec/siren.c
index 0ecf0fcafc..6909ebbf2e 100644
--- a/libavcodec/siren.c
+++ b/libavcodec/siren.c
@@ -760,7 +760,37 @@ static int siren_decode(AVCodecContext *avctx, void *data,
frame_error = 1;
}
- skip_bits(gb, s->checksum_bits);
+ if ((avctx->err_recognition & AV_EF_CRCCHECK) && s->checksum_bits) {
+ static const uint16_t ChecksumTable[4] = {0x7F80, 0x7878, 0x6666, 0x5555};
+ int wpf, checksum, sum, calculated_checksum, temp1;
+
+ checksum = get_bits(gb, s->checksum_bits);
+
+ wpf = bits_per_frame / 16;
+ sum = 0;
+ for (int i = 0; i < wpf - 1; i++)
+ sum ^= AV_RB16(avpkt->data + i * 2) << (i % 15);
+ sum ^= (AV_RB16(avpkt->data + (wpf - 1) * 2) & ~checksum) << ((wpf - 1) % 15);
+ sum = (sum >> 15) ^ (sum & 0x7FFF);
+
+ calculated_checksum = 0;
+ for (int i = 0; i < 4; i++) {
+ temp1 = ChecksumTable[i] & sum;
+
+ for (int j = 8; j > 0; j >>= 1)
+ temp1 ^= temp1 >> j;
+
+ calculated_checksum <<= 1;
+ calculated_checksum |= temp1 & 1;
+ }
+
+ if (checksum != calculated_checksum) {
+ av_log(avctx, AV_LOG_WARNING, "Invalid checksum\n");
+ if (avctx->err_recognition & AV_EF_EXPLODE)
+ return AVERROR_INVALIDDATA;
+ frame_error = 1;
+ }
+ }
if (frame_error) {
memcpy(s->imdct_in, s->backup_frame, number_of_valid_coefs * sizeof(float));