JasPer  4.0.0
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
88 extern "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 
137 JAS_ATTRIBUTE_CONST
138 JAS_ATTRIBUTE_DISABLE_UBSAN
139 inline 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 
150 JAS_ATTRIBUTE_CONST
151 JAS_ATTRIBUTE_DISABLE_UBSAN
152 inline 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 
163 JAS_ATTRIBUTE_CONST
164 JAS_ATTRIBUTE_DISABLE_UBSAN
165 inline 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 
176 JAS_ATTRIBUTE_CONST
177 JAS_ATTRIBUTE_DISABLE_UBSAN
178 inline 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 
189 JAS_ATTRIBUTE_CONST
190 JAS_ATTRIBUTE_DISABLE_UBSAN
191 inline 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 
202 JAS_ATTRIBUTE_CONST
203 JAS_ATTRIBUTE_DISABLE_UBSAN
204 inline 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. */
224 inline 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. */
247 inline 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. */
262 inline 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. */
283 inline 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. */
304 inline 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. */
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)
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. */
365 inline 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 /*
389 This function is potentially useful but not currently used.
390 So, it is commented out.
391 */
392 inline 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 
412 typedef struct {
413  bool valid;
414  uint_least32_t value;
415 } jas_safeui32_t;
416 
417 JAS_ATTRIBUTE_CONST
418 static 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 
431 JAS_ATTRIBUTE_PURE
432 static 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 
443 JAS_ATTRIBUTE_CONST
444 static 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 
458 JAS_ATTRIBUTE_CONST
459 static inline
460 jas_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 
473 JAS_ATTRIBUTE_CONST
474 static 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 
493 typedef struct {
494  bool valid;
495  uint_least64_t value;
496 } jas_safeui64_t;
497 
498 JAS_ATTRIBUTE_CONST
499 static inline
500 jas_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 
513 JAS_ATTRIBUTE_CONST
514 static inline
515 jas_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 
528 JAS_ATTRIBUTE_CONST
529 static inline
530 jas_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 
543 JAS_ATTRIBUTE_CONST
544 static inline
545 jas_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 
559 JAS_ATTRIBUTE_CONST
560 static inline
561 jas_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 
574 JAS_ATTRIBUTE_CONST
575 static inline
576 jas_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 
589 JAS_ATTRIBUTE_CONST
590 static inline
591 int 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_types.h
Primitive Types.
jas_compiler.h
Compiler-related macros.