JasPer  3.0.1
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 
120 /******************************************************************************\
121 *
122 \******************************************************************************/
123 
124 #if defined(__clang__) || (defined(__GNUC__) && __GNUC__ > 6)
125 /* suppress clang warning "shifting a negative signed value is
126  undefined" in the assertions below */
127 #pragma GCC diagnostic push
128 #pragma GCC diagnostic ignored "-Wshift-negative-value"
129 #endif
130 
131 JAS_ATTRIBUTE_CONST
132 JAS_ATTRIBUTE_DISABLE_UBSAN
133 inline static int jas_int_asr(int x, unsigned n)
134 {
135  // Ensure that the shift of a negative value appears to behave as a
136  // signed arithmetic shift.
137  assert(((-1) >> 1) == -1);
138  // The behavior is undefined when x is negative.
139  // We tacitly assume the behavior is equivalent to a signed
140  // arithmetic right shift.
141  return x >> n;
142 }
143 
144 JAS_ATTRIBUTE_CONST
145 JAS_ATTRIBUTE_DISABLE_UBSAN
146 inline static int jas_int_asl(int x, unsigned n)
147 {
148  // Ensure that the shift of a negative value appears to behave as a
149  // signed arithmetic shift.
150  assert(((-1) << 1) == -2);
151  // The behavior is undefined when x is negative.
152  // We tacitly assume the behavior is equivalent to a signed
153  // arithmetic left shift.
154  return x << n;
155 }
156 
157 JAS_ATTRIBUTE_CONST
158 JAS_ATTRIBUTE_DISABLE_UBSAN
159 inline static int_least32_t jas_least32_asr(int_least32_t x, unsigned n)
160 {
161  // Ensure that the shift of a negative value appears to behave as a
162  // signed arithmetic shift.
163  assert(((JAS_CAST(int_least32_t, -1)) >> 1) == JAS_CAST(int_least32_t, -1));
164  // The behavior is undefined when x is negative.
165  // We tacitly assume the behavior is equivalent to a signed
166  // arithmetic right shift.
167  return x >> n;
168 }
169 
170 JAS_ATTRIBUTE_CONST
171 JAS_ATTRIBUTE_DISABLE_UBSAN
172 inline static int_least32_t jas_least32_asl(int_least32_t x, unsigned n)
173 {
174  // Ensure that the shift of a negative value appears to behave as a
175  // signed arithmetic shift.
176  assert(((JAS_CAST(int_least32_t, -1)) << 1) == JAS_CAST(int_least32_t, -2));
177  // The behavior is undefined when x is negative.
178  // We tacitly assume the behavior is equivalent to a signed
179  // arithmetic left shift.
180  return x << n;
181 }
182 
183 JAS_ATTRIBUTE_CONST
184 JAS_ATTRIBUTE_DISABLE_UBSAN
185 inline static int_fast32_t jas_fast32_asr(int_fast32_t x, unsigned n)
186 {
187  // Ensure that the shift of a negative value appears to behave as a
188  // signed arithmetic shift.
189  assert(((JAS_CAST(int_fast32_t, -1)) >> 1) == JAS_CAST(int_fast32_t, -1));
190  // The behavior is undefined when x is negative.
191  // We tacitly assume the behavior is equivalent to a signed
192  // arithmetic right shift.
193  return x >> n;
194 }
195 
196 JAS_ATTRIBUTE_CONST
197 JAS_ATTRIBUTE_DISABLE_UBSAN
198 inline static int_fast32_t jas_fast32_asl(int_fast32_t x, unsigned n)
199 {
200  // Ensure that the shift of a negative value appears to behave as a
201  // signed arithmetic shift.
202  assert(((JAS_CAST(int_fast32_t, -1)) << 1) == JAS_CAST(int_fast32_t, -2));
203  // The behavior is undefined when x is negative.
204  // We tacitly assume the behavior is equivalent to a signed
205  // arithmetic left shift.
206  return x << n;
207 }
208 
209 #if defined(__clang__) || (defined(__GNUC__) && __GNUC__ > 6)
210 #pragma GCC diagnostic pop
211 #endif
212 
213 /******************************************************************************\
214 * Safe integer arithmetic (i.e., with overflow checking).
215 \******************************************************************************/
216 
217 /* Compute the product of two size_t integers with overflow checking. */
218 inline static bool jas_safe_size_mul(size_t x, size_t y, size_t *result)
219 {
220 #if jas_has_builtin(__builtin_mul_overflow) || (defined(__GNUC__) && __GNUC__ > 5)
221  size_t result_buffer;
222  bool valid = !__builtin_mul_overflow(x, y, &result_buffer);
223  if (valid && result) {
224  *result = result_buffer;
225  }
226  return valid;
227 #else
228  /* Check if overflow would occur */
229  if (x && y > SIZE_MAX / x) {
230  /* Overflow would occur. */
231  return false;
232  }
233  if (result) {
234  *result = x * y;
235  }
236  return true;
237 #endif
238 }
239 
240 /* Compute the product of three size_t integers with overflow checking. */
241 inline static bool jas_safe_size_mul3(size_t a, size_t b, size_t c,
242  size_t *result)
243 {
244  size_t tmp;
245  if (!jas_safe_size_mul(a, b, &tmp) ||
246  !jas_safe_size_mul(tmp, c, &tmp)) {
247  return false;
248  }
249  if (result) {
250  *result = tmp;
251  }
252  return true;
253 }
254 
255 /* Compute the sum of two size_t integers with overflow checking. */
256 inline static bool jas_safe_size_add(size_t x, size_t y, size_t *result)
257 {
258 #if jas_has_builtin(__builtin_add_overflow) || (defined(__GNUC__) && __GNUC__ > 5)
259  size_t result_buffer;
260  bool valid = !__builtin_add_overflow(x, y, &result_buffer);
261  if (valid && result) {
262  *result = result_buffer;
263  }
264  return valid;
265 #else
266  if (y > SIZE_MAX - x) {
267  return false;
268  }
269  if (result) {
270  *result = x + y;
271  }
272  return true;
273 #endif
274 }
275 
276 /* Compute the difference of two size_t integers with overflow checking. */
277 inline static bool jas_safe_size_sub(size_t x, size_t y, size_t *result)
278 {
279 #if jas_has_builtin(__builtin_sub_overflow) || (defined(__GNUC__) && __GNUC__ > 5)
280  size_t result_buffer;
281  bool valid = !__builtin_sub_overflow(x, y, &result_buffer);
282  if (valid && result) {
283  *result = result_buffer;
284  }
285  return valid;
286 #else
287  if (y > x) {
288  return false;
289  }
290  if (result) {
291  *result = x - y;
292  }
293  return true;
294 #endif
295 }
296 
297 /* Compute the product of two int_fast32_t integers with overflow checking. */
298 inline static bool jas_safe_intfast32_mul(int_fast32_t x, int_fast32_t y,
299  int_fast32_t *result)
300 {
301 #if jas_has_builtin(__builtin_mul_overflow) || (defined(__GNUC__) && __GNUC__ > 5)
302  int_fast32_t result_buffer;
303  bool valid = !__builtin_mul_overflow(x, y, &result_buffer);
304  if (valid && result) {
305  *result = result_buffer;
306  }
307  return valid;
308 #else
309  if (x > 0) {
310  /* x is positive */
311  if (y > 0) {
312  /* x and y are positive */
313  if (x > INT_FAST32_MAX / y) {
314  return false;
315  }
316  } else {
317  /* x positive, y nonpositive */
318  if (y < INT_FAST32_MIN / x) {
319  return false;
320  }
321  }
322  } else {
323  /* x is nonpositive */
324  if (y > 0) {
325  /* x is nonpositive, y is positive */
326  if (x < INT_FAST32_MIN / y) {
327  return false;
328  }
329  } else { /* x and y are nonpositive */
330  if (x != 0 && y < INT_FAST32_MAX / x) {
331  return false;
332  }
333  }
334  }
335 
336  if (result) {
337  *result = x * y;
338  }
339  return true;
340 #endif
341 }
342 
343 /* Compute the product of three int_fast32_t integers with overflow checking. */
344 inline static bool jas_safe_intfast32_mul3(int_fast32_t a, int_fast32_t b,
345  int_fast32_t c, int_fast32_t *result)
346 {
347  int_fast32_t tmp;
348  if (!jas_safe_intfast32_mul(a, b, &tmp) ||
349  !jas_safe_intfast32_mul(tmp, c, &tmp)) {
350  return false;
351  }
352  if (result) {
353  *result = tmp;
354  }
355  return true;
356 }
357 
358 /* Compute the sum of two int_fast32_t integers with overflow checking. */
359 inline static bool jas_safe_intfast32_add(int_fast32_t x, int_fast32_t y,
360  int_fast32_t *result)
361 {
362 #if jas_has_builtin(__builtin_add_overflow) || (defined(__GNUC__) && __GNUC__ > 5)
363  int_fast32_t result_buffer;
364  bool valid = !__builtin_add_overflow(x, y, &result_buffer);
365  if (valid && result) {
366  *result = result_buffer;
367  }
368  return valid;
369 #else
370  if ((y > 0 && x > INT_FAST32_MAX - y) ||
371  (y < 0 && x < INT_FAST32_MIN - y)) {
372  return false;
373  }
374  if (result) {
375  *result = x + y;
376  }
377  return true;
378 #endif
379 }
380 
381 #if 0
382 /*
383 This function is potentially useful but not currently used.
384 So, it is commented out.
385 */
386 inline static bool jas_safe_uint_mul(unsigned x, unsigned y, unsigned *result)
387 {
388  /* Check if overflow would occur */
389  if (x && y > UINT_MAX / x) {
390  /* Overflow would occur. */
391  return false;
392  }
393  if (result) {
394  *result = x * y;
395  }
396  return true;
397 }
398 #endif
399 
400 /******************************************************************************\
401 * Safe integer arithmetic (i.e., with overflow checking).
402 \******************************************************************************/
403 
404 typedef struct {
405  bool valid;
406  uint_least64_t value;
407 } jas_safeui64_t;
408 
409 static inline
410 jas_safeui64_t jas_safeui64_from_intmax(intmax_t x)
411 {
412  jas_safeui64_t result;
413  if (x >= 0 && x <= UINT_LEAST64_MAX) {
414  result.valid = true;
415  result.value = JAS_CAST(uint_least64_t, x);
416  } else {
417  result.valid = false;
418  result.value = 0;
419  }
420  return result;
421 }
422 
423 static inline
424 jas_safeui64_t jas_safeui64_add(jas_safeui64_t x, jas_safeui64_t y)
425 {
426  jas_safeui64_t result;
427  if (x.valid && y.valid && y.value <= UINT_LEAST64_MAX - x.value) {
428  result.valid = true;
429  result.value = x.value + y.value;
430  } else {
431  result.valid = false;
432  result.value = 0;
433  }
434  return result;
435 }
436 
437 static inline
438 jas_safeui64_t jas_safeui64_sub(jas_safeui64_t x, jas_safeui64_t y)
439 {
440  jas_safeui64_t result;
441  if (x.valid && y.valid && y.value <= x.value) {
442  result.valid = true;
443  result.value = x.value - y.value;
444  } else {
445  result.valid = false;
446  result.value = 0;
447  }
448  return result;
449 }
450 
451 static inline
452 jas_safeui64_t jas_safeui64_mul(jas_safeui64_t x, jas_safeui64_t y)
453 {
454  jas_safeui64_t result;
455  if (!x.valid || !y.valid || (x.value && y.value > UINT_LEAST64_MAX /
456  x.value)) {
457  result.valid = false;
458  result.value = 0;
459  } else {
460  result.valid = true;
461  result.value = x.value * y.value;
462  }
463  return result;
464 }
465 
466 static inline
467 jas_safeui64_t jas_safeui64_div(jas_safeui64_t x, jas_safeui64_t y)
468 {
469  jas_safeui64_t result;
470  if (x.valid && y.valid && y.value) {
471  result.valid = true;
472  result.value = x.value / y.valid;
473  } else {
474  result.valid = false;
475  result.value = 0;
476  }
477  return result;
478 }
479 
480 static inline
481 jas_safeui64_t jas_safeui64_pow2_intmax(intmax_t x)
482 {
483  jas_safeui64_t result;
484  if (x >= 0 && x < 64) {
485  result.valid = true;
486  result.value = JAS_CAST(uint_least64_t, 1) << x;
487  } else {
488  result.valid = false;
489  result.value = 0;
490  }
491  return result;
492 }
493 
494 static inline
495 int jas_safeui64_to_int(jas_safeui64_t x, int invalid_value)
496 {
497  int result;
498  if (x.valid && x.value <= INT_MAX) {
499  result = JAS_CAST(int, x.value);
500  } else {
501  result = invalid_value;
502  }
503  return result;
504 }
505 
506 /******************************************************************************\
507 \******************************************************************************/
508 
509 #ifdef __cplusplus
510 }
511 #endif
512 
513 #endif
jas_types.h
Primitive Types.
jas_compiler.h
Compiler-related macros.