JasPer: jas_math.h Source File

JasPer 4.0.0 |

Loading...
Searching...
No Matches
jas_math.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 1999-2000 Image Power, Inc. and the University of
3 * British Columbia.
4 * Copyright (c) 2001-2002 Michael David Adams.
5 * All rights reserved.
6 */
7
8/* __START_OF_JASPER_LICENSE__
9 *
10 * JasPer License Version 2.0
11 *
12 * Copyright (c) 2001-2006 Michael David Adams
13 * Copyright (c) 1999-2000 Image Power, Inc.
14 * Copyright (c) 1999-2000 The University of British Columbia
15 *
16 * All rights reserved.
17 *
18 * Permission is hereby granted, free of charge, to any person (the
19 * "User") obtaining a copy of this software and associated documentation
20 * files (the "Software"), to deal in the Software without restriction,
21 * including without limitation the rights to use, copy, modify, merge,
22 * publish, distribute, and/or sell copies of the Software, and to permit
23 * persons to whom the Software is furnished to do so, subject to the
24 * following conditions:
25 *
26 * 1. The above copyright notices and this permission notice (which
27 * includes the disclaimer below) shall be included in all copies or
28 * substantial portions of the Software.
29 *
30 * 2. The name of a copyright holder shall not be used to endorse or
31 * promote products derived from the Software without specific prior
32 * written permission.
33 *
34 * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
35 * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
36 * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
37 * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
38 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
39 * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO
40 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
41 * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
42 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
43 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
44 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE
45 * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
46 * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
47 * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
48 * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
49 * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS
50 * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
51 * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE
52 * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
53 * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
54 * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
55 * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
56 * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
57 * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
58 * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
59 * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
60 *
61 * __END_OF_JASPER_LICENSE__
62 */
63
69#ifndef JAS_MATH_H
70#define JAS_MATH_H
71
72/******************************************************************************\
73* Includes
74\******************************************************************************/
75
76/* The configuration header file should be included first. */
77#include <jasper/jas_config.h>
78
79#include <jasper/jas_compiler.h>
80#include <jasper/jas_types.h>
81
82#include <assert.h>
83#include <string.h>
84#include <stdint.h>
85#include <limits.h>
86
87#ifdef __cplusplus
88extern "C" {
89#endif
90
91/******************************************************************************\
92* Macros
93\******************************************************************************/
94
95#define JAS_KIBI JAS_CAST(size_t, 1024)
96#define JAS_MEBI (JAS_KIBI * JAS_KIBI)
97
98/* Compute the absolute value. */
99#define JAS_ABS(x) \
100 (((x) >= 0) ? (x) : (-(x)))
101
102/* Compute the minimum of two values. */
103#define JAS_MIN(x, y) \
104 (((x) < (y)) ? (x) : (y))
105
106/* Compute the maximum of two values. */
107#define JAS_MAX(x, y) \
108 (((x) > (y)) ? (x) : (y))
109
110/* Compute the remainder from division (where division is defined such
111 that the remainder is always nonnegative). */
112#define JAS_MOD(x, y) \
113 (((x) < 0) ? (((-x) % (y)) ? ((y) - ((-(x)) % (y))) : (0)) : ((x) % (y)))
114
115/* Compute the integer with the specified number of least significant bits
116 set to one. */
117#define JAS_ONES(n) \
118 ((1 << (n)) - 1)
119#if 0
120#define JAS_ONES_X(type, n) \
121 ((JAS_CAST(type, 1) << (n)) - 1)
122#endif
123#define JAS_POW2_X(type, n) \
124 (JAS_CAST(type, 1) << (n))
125
126/******************************************************************************\
127*
128\******************************************************************************/
129
130#if defined(__clang__) || (defined(__GNUC__) && __GNUC__ > 6)
131/* suppress clang warning "shifting a negative signed value is
132 undefined" in the assertions below */
133#pragma GCC diagnostic push
134#pragma GCC diagnostic ignored "-Wshift-negative-value"
135#endif
136
137JAS_ATTRIBUTE_CONST
138JAS_ATTRIBUTE_DISABLE_UBSAN
139inline static int jas_int_asr(int x, unsigned n)
140{
141 // Ensure that the shift of a negative value appears to behave as a
142 // signed arithmetic shift.
143 assert(((-1) >> 1) == -1);
144 // The behavior is undefined when x is negative.
145 // We tacitly assume the behavior is equivalent to a signed
146 // arithmetic right shift.
147 return x >> n;
148}
149
150JAS_ATTRIBUTE_CONST
151JAS_ATTRIBUTE_DISABLE_UBSAN
152inline static int jas_int_asl(int x, unsigned n)
153{
154 // Ensure that the shift of a negative value appears to behave as a
155 // signed arithmetic shift.
156 assert(((-1) << 1) == -2);
157 // The behavior is undefined when x is negative.
158 // We tacitly assume the behavior is equivalent to a signed
159 // arithmetic left shift.
160 return x << n;
161}
162
163JAS_ATTRIBUTE_CONST
164JAS_ATTRIBUTE_DISABLE_UBSAN
165inline static int_least32_t jas_least32_asr(int_least32_t x, unsigned n)
166{
167 // Ensure that the shift of a negative value appears to behave as a
168 // signed arithmetic shift.
169 assert(((JAS_CAST(int_least32_t, -1)) >> 1) == JAS_CAST(int_least32_t, -1));
170 // The behavior is undefined when x is negative.
171 // We tacitly assume the behavior is equivalent to a signed
172 // arithmetic right shift.
173 return x >> n;
174}
175
176JAS_ATTRIBUTE_CONST
177JAS_ATTRIBUTE_DISABLE_UBSAN
178inline static int_least32_t jas_least32_asl(int_least32_t x, unsigned n)
179{
180 // Ensure that the shift of a negative value appears to behave as a
181 // signed arithmetic shift.
182 assert(((JAS_CAST(int_least32_t, -1)) << 1) == JAS_CAST(int_least32_t, -2));
183 // The behavior is undefined when x is negative.
184 // We tacitly assume the behavior is equivalent to a signed
185 // arithmetic left shift.
186 return x << n;
187}
188
189JAS_ATTRIBUTE_CONST
190JAS_ATTRIBUTE_DISABLE_UBSAN
191inline static int_fast32_t jas_fast32_asr(int_fast32_t x, unsigned n)
192{
193 // Ensure that the shift of a negative value appears to behave as a
194 // signed arithmetic shift.
195 assert(((JAS_CAST(int_fast32_t, -1)) >> 1) == JAS_CAST(int_fast32_t, -1));
196 // The behavior is undefined when x is negative.
197 // We tacitly assume the behavior is equivalent to a signed
198 // arithmetic right shift.
199 return x >> n;
200}
201
202JAS_ATTRIBUTE_CONST
203JAS_ATTRIBUTE_DISABLE_UBSAN
204inline static int_fast32_t jas_fast32_asl(int_fast32_t x, unsigned n)
205{
206 // Ensure that the shift of a negative value appears to behave as a
207 // signed arithmetic shift.
208 assert(((JAS_CAST(int_fast32_t, -1)) << 1) == JAS_CAST(int_fast32_t, -2));
209 // The behavior is undefined when x is negative.
210 // We tacitly assume the behavior is equivalent to a signed
211 // arithmetic left shift.
212 return x << n;
213}
214
215#if defined(__clang__) || (defined(__GNUC__) && __GNUC__ > 6)
216#pragma GCC diagnostic pop
217#endif
218
219/******************************************************************************\
220* Safe integer arithmetic (i.e., with overflow checking).
221\******************************************************************************/
222
223/* Compute the product of two size_t integers with overflow checking. */
224inline static bool jas_safe_size_mul(size_t x, size_t y, size_t *result)
225{
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;
231 }
232 return valid;
233#else
234 /* Check if overflow would occur */
235 if (x && y > SIZE_MAX / x) {
236 /* Overflow would occur. */
237 return false;
238 }
239 if (result) {
240 *result = x * y;
241 }
242 return true;
243#endif
244}
245
246/* Compute the product of three size_t integers with overflow checking. */
247inline static bool jas_safe_size_mul3(size_t a, size_t b, size_t c,
248 size_t *result)
249{
250 size_t tmp;
251 if (!jas_safe_size_mul(a, b, &tmp) ||
252 !jas_safe_size_mul(tmp, c, &tmp)) {
253 return false;
254 }
255 if (result) {
256 *result = tmp;
257 }
258 return true;
259}
260
261/* Compute the sum of two size_t integers with overflow checking. */
262inline static bool jas_safe_size_add(size_t x, size_t y, size_t *result)
263{
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;
269 }
270 return valid;
271#else
272 if (y > SIZE_MAX - x) {
273 return false;
274 }
275 if (result) {
276 *result = x + y;
277 }
278 return true;
279#endif
280}
281
282/* Compute the difference of two size_t integers with overflow checking. */
283inline static bool jas_safe_size_sub(size_t x, size_t y, size_t *result)
284{
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;
290 }
291 return valid;
292#else
293 if (y > x) {
294 return false;
295 }
296 if (result) {
297 *result = x - y;
298 }
299 return true;
300#endif
301}
302
303/* Compute the product of two int_fast32_t integers with overflow checking. */
304inline static bool jas_safe_intfast32_mul(int_fast32_t x, int_fast32_t y,
305 int_fast32_t *result)
306{
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;
312 }
313 return valid;
314#else
315 if (x > 0) {
316 /* x is positive */
317 if (y > 0) {
318 /* x and y are positive */
319 if (x > INT_FAST32_MAX / y) {
320 return false;
321 }
322 } else {
323 /* x positive, y nonpositive */
324 if (y < INT_FAST32_MIN / x) {
325 return false;
326 }
327 }
328 } else {
329 /* x is nonpositive */
330 if (y > 0) {
331 /* x is nonpositive, y is positive */
332 if (x < INT_FAST32_MIN / y) {
333 return false;
334 }
335 } else { /* x and y are nonpositive */
336 if (x != 0 && y < INT_FAST32_MAX / x) {
337 return false;
338 }
339 }
340 }
341
342 if (result) {
343 *result = x * y;
344 }
345 return true;
346#endif
347}
348
349/* Compute the product of three int_fast32_t integers with overflow checking. */
350inline static bool jas_safe_intfast32_mul3(int_fast32_t a, int_fast32_t b,
351 int_fast32_t c, int_fast32_t *result)
352{
353 int_fast32_t tmp;
354 if (!jas_safe_intfast32_mul(a, b, &tmp) ||
355 !jas_safe_intfast32_mul(tmp, c, &tmp)) {
356 return false;
357 }
358 if (result) {
359 *result = tmp;
360 }
361 return true;
362}
363
364/* Compute the sum of two int_fast32_t integers with overflow checking. */
365inline static bool jas_safe_intfast32_add(int_fast32_t x, int_fast32_t y,
366 int_fast32_t *result)
367{
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;
373 }
374 return valid;
375#else
376 if ((y > 0 && x > INT_FAST32_MAX - y) ||
377 (y < 0 && x < INT_FAST32_MIN - y)) {
378 return false;
379 }
380 if (result) {
381 *result = x + y;
382 }
383 return true;
384#endif
385}
386
387#if 0
388/*
389This function is potentially useful but not currently used.
390So, it is commented out.
391*/
392inline static bool jas_safe_uint_mul(unsigned x, unsigned y, unsigned *result)
393{
394 /* Check if overflow would occur */
395 if (x && y > UINT_MAX / x) {
396 /* Overflow would occur. */
397 return false;
398 }
399 if (result) {
400 *result = x * y;
401 }
402 return true;
403}
404#endif
405
406/******************************************************************************\
407* Safe 32-bit unsigned integer arithmetic (i.e., with overflow checking).
408\******************************************************************************/
409
410#define JAS_SAFEUI32_MAX (0xffffffffU)
411
412typedef struct {
413 bool valid;
414 uint_least32_t value;
415} jas_safeui32_t;
416
417JAS_ATTRIBUTE_CONST
418static inline jas_safeui32_t jas_safeui32_from_ulong(unsigned long x)
419{
420 jas_safeui32_t result;
421 if (x <= JAS_SAFEUI32_MAX) {
422 result.valid = 1;
423 result.value = JAS_CAST(uint_least32_t, x);
424 } else {
425 result.valid = 0;
426 result.value = 0;
427 }
428 return result;
429}
430
431JAS_ATTRIBUTE_PURE
432static inline bool jas_safeui32_to_intfast32(jas_safeui32_t x,
433 int_fast32_t* y)
434{
435 if (x.value <= INT_FAST32_MAX) {
436 *y = x.value;
437 return true;
438 } else {
439 return false;
440 }
441}
442
443JAS_ATTRIBUTE_CONST
444static inline jas_safeui32_t jas_safeui32_add(jas_safeui32_t x,
445 jas_safeui32_t y)
446{
447 jas_safeui32_t result;
448 if (x.valid && y.valid && y.value <= UINT_LEAST32_MAX - x.value) {
449 result.valid = true;
450 result.value = x.value + y.value;
451 } else {
452 result.valid = false;
453 result.value = 0;
454 }
455 return result;
456}
457
458JAS_ATTRIBUTE_CONST
459static inline
460jas_safeui32_t jas_safeui32_sub(jas_safeui32_t x, jas_safeui32_t y)
461{
462 jas_safeui32_t result;
463 if (x.valid && y.valid && y.value <= x.value) {
464 result.valid = true;
465 result.value = x.value - y.value;
466 } else {
467 result.valid = false;
468 result.value = 0;
469 }
470 return result;
471}
472
473JAS_ATTRIBUTE_CONST
474static inline jas_safeui32_t jas_safeui32_mul(jas_safeui32_t x,
475 jas_safeui32_t y)
476{
477 jas_safeui32_t result;
478 if (!x.valid || !y.valid || (x.value && y.value > UINT_LEAST32_MAX /
479 x.value)) {
480 result.valid = false;
481 result.value = 0;
482 } else {
483 result.valid = true;
484 result.value = x.value * y.value;
485 }
486 return result;
487}
488
489/******************************************************************************\
490* Safe 64-bit unsigned integer arithmetic (i.e., with overflow checking).
491\******************************************************************************/
492
493typedef struct {
494 bool valid;
495 uint_least64_t value;
496} jas_safeui64_t;
497
498JAS_ATTRIBUTE_CONST
499static inline
500jas_safeui64_t jas_safeui64_from_intmax(intmax_t x)
501{
502 jas_safeui64_t result;
503 if (x >= 0 && x <= UINT_LEAST64_MAX) {
504 result.valid = true;
505 result.value = JAS_CAST(uint_least64_t, x);
506 } else {
507 result.valid = false;
508 result.value = 0;
509 }
510 return result;
511}
512
513JAS_ATTRIBUTE_CONST
514static inline
515jas_safeui64_t jas_safeui64_add(jas_safeui64_t x, jas_safeui64_t y)
516{
517 jas_safeui64_t result;
518 if (x.valid && y.valid && y.value <= UINT_LEAST64_MAX - x.value) {
519 result.valid = true;
520 result.value = x.value + y.value;
521 } else {
522 result.valid = false;
523 result.value = 0;
524 }
525 return result;
526}
527
528JAS_ATTRIBUTE_CONST
529static inline
530jas_safeui64_t jas_safeui64_sub(jas_safeui64_t x, jas_safeui64_t y)
531{
532 jas_safeui64_t result;
533 if (x.valid && y.valid && y.value <= x.value) {
534 result.valid = true;
535 result.value = x.value - y.value;
536 } else {
537 result.valid = false;
538 result.value = 0;
539 }
540 return result;
541}
542
543JAS_ATTRIBUTE_CONST
544static inline
545jas_safeui64_t jas_safeui64_mul(jas_safeui64_t x, jas_safeui64_t y)
546{
547 jas_safeui64_t result;
548 if (!x.valid || !y.valid || (x.value && y.value > UINT_LEAST64_MAX /
549 x.value)) {
550 result.valid = false;
551 result.value = 0;
552 } else {
553 result.valid = true;
554 result.value = x.value * y.value;
555 }
556 return result;
557}
558
559JAS_ATTRIBUTE_CONST
560static inline
561jas_safeui64_t jas_safeui64_div(jas_safeui64_t x, jas_safeui64_t y)
562{
563 jas_safeui64_t result;
564 if (x.valid && y.valid && y.value) {
565 result.valid = true;
566 result.value = x.value / y.value;
567 } else {
568 result.valid = false;
569 result.value = 0;
570 }
571 return result;
572}
573
574JAS_ATTRIBUTE_CONST
575static inline
576jas_safeui64_t jas_safeui64_pow2_intmax(intmax_t x)
577{
578 jas_safeui64_t result;
579 if (x >= 0 && x < 64) {
580 result.valid = true;
581 result.value = JAS_CAST(uint_least64_t, 1) << x;
582 } else {
583 result.valid = false;
584 result.value = 0;
585 }
586 return result;
587}
588
589JAS_ATTRIBUTE_CONST
590static inline
591int jas_safeui64_to_int(jas_safeui64_t x, int invalid_value)
592{
593 int result;
594 if (x.valid && x.value <= INT_MAX) {
595 result = JAS_CAST(int, x.value);
596 } else {
597 result = invalid_value;
598 }
599 return result;
600}
601
602/******************************************************************************\
603\******************************************************************************/
604
605#ifdef __cplusplus
606}
607#endif
608
609#endif
jas_compiler.h
Compiler-related macros.
jas_types.h
Primitive Types.