77 #include <jasper/jas_config.h>
95 #define JAS_KIBI JAS_CAST(size_t, 1024)
96 #define JAS_MEBI (JAS_KIBI * JAS_KIBI)
100 (((x) >= 0) ? (x) : (-(x)))
103 #define JAS_MIN(x, y) \
104 (((x) < (y)) ? (x) : (y))
107 #define JAS_MAX(x, y) \
108 (((x) > (y)) ? (x) : (y))
112 #define JAS_MOD(x, y) \
113 (((x) < 0) ? (((-x) % (y)) ? ((y) - ((-(x)) % (y))) : (0)) : ((x) % (y)))
117 #define JAS_ONES(n) \
120 #define JAS_ONES_X(type, n) \
121 ((JAS_CAST(type, 1) << (n)) - 1)
123 #define JAS_POW2_X(type, n) \
124 (JAS_CAST(type, 1) << (n))
130 #if defined(__clang__) || (defined(__GNUC__) && __GNUC__ > 6)
133 #pragma GCC diagnostic push
134 #pragma GCC diagnostic ignored "-Wshift-negative-value"
138 JAS_ATTRIBUTE_DISABLE_UBSAN
139 inline static int jas_int_asr(
int x,
unsigned n)
143 assert(((-1) >> 1) == -1);
151 JAS_ATTRIBUTE_DISABLE_UBSAN
152 inline static int jas_int_asl(
int x,
unsigned n)
156 assert(((-1) << 1) == -2);
164 JAS_ATTRIBUTE_DISABLE_UBSAN
165 inline static int_least32_t jas_least32_asr(int_least32_t x,
unsigned n)
169 assert(((JAS_CAST(int_least32_t, -1)) >> 1) == JAS_CAST(int_least32_t, -1));
177 JAS_ATTRIBUTE_DISABLE_UBSAN
178 inline static int_least32_t jas_least32_asl(int_least32_t x,
unsigned n)
182 assert(((JAS_CAST(int_least32_t, -1)) << 1) == JAS_CAST(int_least32_t, -2));
190 JAS_ATTRIBUTE_DISABLE_UBSAN
191 inline static int_fast32_t jas_fast32_asr(int_fast32_t x,
unsigned n)
195 assert(((JAS_CAST(int_fast32_t, -1)) >> 1) == JAS_CAST(int_fast32_t, -1));
203 JAS_ATTRIBUTE_DISABLE_UBSAN
204 inline static int_fast32_t jas_fast32_asl(int_fast32_t x,
unsigned n)
208 assert(((JAS_CAST(int_fast32_t, -1)) << 1) == JAS_CAST(int_fast32_t, -2));
215 #if defined(__clang__) || (defined(__GNUC__) && __GNUC__ > 6)
216 #pragma GCC diagnostic pop
224 inline static bool jas_safe_size_mul(
size_t x,
size_t y,
size_t *result)
226 #if jas_has_builtin(__builtin_mul_overflow) || (defined(__GNUC__) && __GNUC__ > 5)
227 size_t result_buffer;
228 bool valid = !__builtin_mul_overflow(x, y, &result_buffer);
229 if (valid && result) {
230 *result = result_buffer;
235 if (x && y > SIZE_MAX / x) {
247 inline static bool jas_safe_size_mul3(
size_t a,
size_t b,
size_t c,
251 if (!jas_safe_size_mul(a, b, &tmp) ||
252 !jas_safe_size_mul(tmp, c, &tmp)) {
262 inline static bool jas_safe_size_add(
size_t x,
size_t y,
size_t *result)
264 #if jas_has_builtin(__builtin_add_overflow) || (defined(__GNUC__) && __GNUC__ > 5)
265 size_t result_buffer;
266 bool valid = !__builtin_add_overflow(x, y, &result_buffer);
267 if (valid && result) {
268 *result = result_buffer;
272 if (y > SIZE_MAX - x) {
283 inline static bool jas_safe_size_sub(
size_t x,
size_t y,
size_t *result)
285 #if jas_has_builtin(__builtin_sub_overflow) || (defined(__GNUC__) && __GNUC__ > 5)
286 size_t result_buffer;
287 bool valid = !__builtin_sub_overflow(x, y, &result_buffer);
288 if (valid && result) {
289 *result = result_buffer;
304 inline static bool jas_safe_intfast32_mul(int_fast32_t x, int_fast32_t y,
305 int_fast32_t *result)
307 #if jas_has_builtin(__builtin_mul_overflow) || (defined(__GNUC__) && __GNUC__ > 5)
308 int_fast32_t result_buffer;
309 bool valid = !__builtin_mul_overflow(x, y, &result_buffer);
310 if (valid && result) {
311 *result = result_buffer;
319 if (x > INT_FAST32_MAX / y) {
324 if (y < INT_FAST32_MIN / x) {
332 if (x < INT_FAST32_MIN / y) {
336 if (x != 0 && y < INT_FAST32_MAX / x) {
350 inline static bool jas_safe_intfast32_mul3(int_fast32_t a, int_fast32_t b,
351 int_fast32_t c, int_fast32_t *result)
354 if (!jas_safe_intfast32_mul(a, b, &tmp) ||
355 !jas_safe_intfast32_mul(tmp, c, &tmp)) {
365 inline static bool jas_safe_intfast32_add(int_fast32_t x, int_fast32_t y,
366 int_fast32_t *result)
368 #if jas_has_builtin(__builtin_add_overflow) || (defined(__GNUC__) && __GNUC__ > 5)
369 int_fast32_t result_buffer;
370 bool valid = !__builtin_add_overflow(x, y, &result_buffer);
371 if (valid && result) {
372 *result = result_buffer;
376 if ((y > 0 && x > INT_FAST32_MAX - y) ||
377 (y < 0 && x < INT_FAST32_MIN - y)) {
392 inline static bool jas_safe_uint_mul(
unsigned x,
unsigned y,
unsigned *result)
395 if (x && y > UINT_MAX / x) {
410 #define JAS_SAFEUI32_MAX (0xffffffffUL)
414 uint_least32_t value;
418 static inline jas_safeui32_t jas_safeui32_from_ulong(
unsigned long x)
420 jas_safeui32_t result;
421 if (x <= JAS_SAFEUI32_MAX) {
423 result.value = JAS_CAST(uint_least32_t, x);
432 static inline bool jas_safeui32_to_intfast32(jas_safeui32_t x,
435 const long I32_MAX = 0x7fffffffL;
436 if (x.value <= I32_MAX) {
445 static inline jas_safeui32_t jas_safeui32_add(jas_safeui32_t x,
448 jas_safeui32_t result;
449 if (x.valid && y.valid && y.value <= UINT_LEAST32_MAX - x.value) {
451 result.value = x.value + y.value;
453 result.valid =
false;
461 jas_safeui32_t jas_safeui32_sub(jas_safeui32_t x, jas_safeui32_t y)
463 jas_safeui32_t result;
464 if (x.valid && y.valid && y.value <= x.value) {
466 result.value = x.value - y.value;
468 result.valid =
false;
475 static inline jas_safeui32_t jas_safeui32_mul(jas_safeui32_t x,
478 jas_safeui32_t result;
479 if (!x.valid || !y.valid || (x.value && y.value > UINT_LEAST32_MAX /
481 result.valid =
false;
485 result.value = x.value * y.value;
501 jas_safei64_t jas_safei64_from_intmax(intmax_t x)
503 jas_safei64_t result;
504 if (x >= INT_LEAST64_MIN && x <= INT_LEAST64_MAX) {
506 result.value = JAS_CAST(int_least64_t, x);
508 result.valid =
false;
516 jas_safei64_t jas_safei64_add(jas_safei64_t x, jas_safei64_t y)
518 jas_safei64_t result;
519 if (((y.value > 0) && (x.value > (INT_LEAST64_MAX - y.value))) ||
520 ((y.value < 0) && (x.value < (INT_LEAST64_MIN - y.value)))) {
521 result.value =
false;
525 result.value = x.value + y.value;
532 jas_safei64_t jas_safei64_sub(jas_safei64_t x, jas_safei64_t y)
534 jas_safei64_t result;
535 if ((y.value > 0 && x.value < INT_LEAST64_MIN + y.value) ||
536 (y.value < 0 && x.value > INT_LEAST64_MAX + y.value)) {
537 result.valid =
false;
541 result.value = x.value - y.value;
548 jas_safei64_t jas_safei64_mul(jas_safei64_t x, jas_safei64_t y)
550 jas_safei64_t result;
553 if (x.value > (INT_LEAST64_MAX / y.value)) {
557 if (y.value < (INT_LEAST64_MIN / x.value)) {
563 if (x.value < (INT_LEAST64_MIN / y.value)) {
567 if ( (x.value != 0) && (y.value < (INT_LEAST64_MAX / x.value))) {
573 result.value = x.value * y.value;
576 result.valid =
false;
584 jas_safei64_t jas_safei64_div(jas_safei64_t x, jas_safei64_t y)
587 jas_safei64_t result;
588 result.valid =
false;
596 jas_i32_t jas_safei64_to_i32(jas_safei64_t x, jas_i32_t invalid_value)
599 if (x.valid && x.value >= JAS_I32_MIN && x.value <= JAS_I32_MAX) {
600 result = JAS_CAST(jas_i32_t, x.value);
602 result = invalid_value;
613 uint_least64_t value;
618 jas_safeui64_t jas_safeui64_from_intmax(intmax_t x)
620 jas_safeui64_t result;
621 if (x >= 0 && x <= UINT_LEAST64_MAX) {
623 result.value = JAS_CAST(uint_least64_t, x);
625 result.valid =
false;
633 jas_safeui64_t jas_safeui64_add(jas_safeui64_t x, jas_safeui64_t y)
635 jas_safeui64_t result;
636 if (x.valid && y.valid && y.value <= UINT_LEAST64_MAX - x.value) {
638 result.value = x.value + y.value;
640 result.valid =
false;
648 jas_safeui64_t jas_safeui64_sub(jas_safeui64_t x, jas_safeui64_t y)
650 jas_safeui64_t result;
651 if (x.valid && y.valid && y.value <= x.value) {
653 result.value = x.value - y.value;
655 result.valid =
false;
663 jas_safeui64_t jas_safeui64_mul(jas_safeui64_t x, jas_safeui64_t y)
665 jas_safeui64_t result;
666 if (!x.valid || !y.valid || (x.value && y.value > UINT_LEAST64_MAX /
668 result.valid =
false;
672 result.value = x.value * y.value;
679 jas_safeui64_t jas_safeui64_div(jas_safeui64_t x, jas_safeui64_t y)
681 jas_safeui64_t result;
682 if (x.valid && y.valid && y.value) {
684 result.value = x.value / y.value;
686 result.valid =
false;
694 jas_safeui64_t jas_safeui64_pow2_intmax(intmax_t x)
696 jas_safeui64_t result;
697 if (x >= 0 && x < 64) {
699 result.value = JAS_CAST(uint_least64_t, 1) << x;
701 result.valid =
false;
709 int jas_safeui64_to_int(jas_safeui64_t x,
int invalid_value)
712 if (x.valid && x.value <= INT_MAX) {
713 result = JAS_CAST(
int, x.value);
715 result = invalid_value;
722 jas_ui32_t jas_safeui64_to_ui32(jas_safeui64_t x, jas_ui32_t invalid_value)
725 if (x.valid && x.value <= JAS_UI32_MAX) {
726 result = JAS_CAST(jas_ui32_t, x.value);
728 result = invalid_value;
735 jas_i32_t jas_safeui64_to_i32(jas_safeui64_t x, jas_i32_t invalid_value)
738 if (x.valid && x.value >= JAS_I32_MIN && x.value <= JAS_I32_MAX) {
739 result = JAS_CAST(jas_i32_t, x.value);
741 result = invalid_value;