Skip to content

Commit 1961dca

Browse files
jkbonfielddaviesrob
authored andcommitted
Protection from attempting to do SIMD rans encoding on small data
We can't just change do_simd as we may then have a combination of SIMD (pack or rle-meta) and non-SIMD (rle-meta or rle-data). So instead we remove the ability to do SIMD. This only happens when we have large blocks of data that enable SIMD mode which then turn out to be heavily compressible after PACK or RLE to yield a small sub-stream which isn't SIMD compressible.
1 parent ce66e5f commit 1961dca

File tree

1 file changed

+33
-0
lines changed

1 file changed

+33
-0
lines changed

htscodecs/rANS_static4x16pr.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,6 +1169,12 @@ unsigned char *rans_compress_to_4x16(unsigned char *in, unsigned int in_size,
11691169
return NULL;
11701170
}
11711171

1172+
#ifdef VALIDATE_RANS
1173+
int orig_order = order;
1174+
int orig_in_size = in_size;
1175+
unsigned char *orig_in = in;
1176+
#endif
1177+
11721178
unsigned int c_meta_len;
11731179
uint8_t *meta = NULL, *rle = NULL, *packed = NULL;
11741180
uint8_t *out_free = NULL;
@@ -1385,6 +1391,11 @@ unsigned char *rans_compress_to_4x16(unsigned char *in, unsigned int in_size,
13851391
int sz = var_put_u32(out+c_meta_len, out_end, in_size);
13861392
c_meta_len += sz;
13871393
*out_size -= sz;
1394+
1395+
if (do_simd && in_size < 32) {
1396+
do_simd = 0;
1397+
out[0] &= ~RANS_ORDER_X32;
1398+
}
13881399
}
13891400
} else if (do_pack) {
13901401
out[0] &= ~RANS_ORDER_PACK;
@@ -1430,6 +1441,10 @@ unsigned char *rans_compress_to_4x16(unsigned char *in, unsigned int in_size,
14301441
return NULL;
14311442
}
14321443
c_rmeta_len = *out_size - (c_meta_len+sz+5);
1444+
if (do_simd && (rmeta_len < 32 || rle_len < 32)) {
1445+
do_simd = 0;
1446+
out[0] &= ~RANS_ORDER_X32;
1447+
}
14331448
if (!rans_enc_func(do_simd, 0)(meta, rmeta_len, out+c_meta_len+sz+5, &c_rmeta_len)) {
14341449
free(out_free);
14351450
free(rle);
@@ -1503,6 +1518,24 @@ unsigned char *rans_compress_to_4x16(unsigned char *in, unsigned int in_size,
15031518

15041519
*out_size += c_meta_len;
15051520

1521+
// Validation mode
1522+
#ifdef VALIDATE_RANS
1523+
unsigned int decoded_size = orig_in_size;
1524+
unsigned char *decoded = malloc(decoded_size);
1525+
decoded = rans_uncompress_to_4x16(out, *out_size,
1526+
decoded, &decoded_size);
1527+
if (!decoded ||
1528+
decoded_size != orig_in_size ||
1529+
memcmp(orig_in, decoded, orig_in_size) != 0) {
1530+
fprintf(stderr, "rans round trip failed for order %d. Written to fd 5\n", orig_order);
1531+
if (write(5, orig_in, orig_in_size) < 0)
1532+
abort();
1533+
abort();
1534+
}
1535+
free(decoded);
1536+
#endif
1537+
1538+
15061539
return out;
15071540
}
15081541

0 commit comments

Comments
 (0)