My Project  2.0.17
jas_math.h
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 
64 /*
65  * Math-Related Code
66  *
67  * $Id$
68  */
69 
70 #ifndef JAS_MATH_H
71 #define JAS_MATH_H
72 
73 /******************************************************************************\
74 * Includes
75 \******************************************************************************/
76 
77 /* The configuration header file should be included first. */
78 #include <jasper/jas_config.h>
79 
80 #include <jasper/jas_types.h>
81 
82 #include <assert.h>
83 #include <stdio.h>
84 #include <string.h>
85 #include <stdint.h>
86 #include <limits.h>
87 
88 #ifdef __cplusplus
89 extern "C" {
90 #endif
91 
92 /******************************************************************************\
93 * Macros
94 \******************************************************************************/
95 
96 #define JAS_KIBI JAS_CAST(size_t, 1024)
97 #define JAS_MEBI (JAS_KIBI * JAS_KIBI)
98 
99 /* Compute the absolute value. */
100 #define JAS_ABS(x) \
101  (((x) >= 0) ? (x) : (-(x)))
102 
103 /* Compute the minimum of two values. */
104 #define JAS_MIN(x, y) \
105  (((x) < (y)) ? (x) : (y))
106 
107 /* Compute the maximum of two values. */
108 #define JAS_MAX(x, y) \
109  (((x) > (y)) ? (x) : (y))
110 
111 /* Compute the remainder from division (where division is defined such
112  that the remainder is always nonnegative). */
113 #define JAS_MOD(x, y) \
114  (((x) < 0) ? (((-x) % (y)) ? ((y) - ((-(x)) % (y))) : (0)) : ((x) % (y)))
115 
116 /* Compute the integer with the specified number of least significant bits
117  set to one. */
118 #define JAS_ONES(n) \
119  ((1 << (n)) - 1)
120 
121 /******************************************************************************\
122 *
123 \******************************************************************************/
124 
125 #ifdef __GNUC__
126 /* suppress clang warning "shifting a negative signed value is
127  undefined" in the assertions below */
128 #pragma GCC diagnostic push
129 #pragma GCC diagnostic ignored "-Wshift-negative-value"
130 #endif
131 
132 JAS_ATTRIBUTE_CONST
133 JAS_ATTRIBUTE_DISABLE_USAN
134 inline static int jas_int_asr(int x, int n)
135 {
136  // Ensure that the shift of a negative value appears to behave as a
137  // signed arithmetic shift.
138  assert(((-1) >> 1) == -1);
139  assert(n >= 0);
140  // The behavior is undefined when x is negative. */
141  // We tacitly assume the behavior is equivalent to a signed
142  // arithmetic right shift.
143  return x >> n;
144 }
145 
146 JAS_ATTRIBUTE_CONST
147 JAS_ATTRIBUTE_DISABLE_USAN
148 inline static int jas_int_asl(int x, int n)
149 {
150  // Ensure that the shift of a negative value appears to behave as a
151  // signed arithmetic shift.
152  assert(((-1) << 1) == -2);
153  assert(n >= 0);
154  // The behavior is undefined when x is negative. */
155  // We tacitly assume the behavior is equivalent to a signed
156  // arithmetic left shift.
157  return x << n;
158 }
159 
160 JAS_ATTRIBUTE_CONST
161 JAS_ATTRIBUTE_DISABLE_USAN
162 inline static int jas_fast32_asr(int_fast32_t x, int n)
163 {
164  // Ensure that the shift of a negative value appears to behave as a
165  // signed arithmetic shift.
166  assert(((JAS_CAST(int_fast32_t, -1)) >> 1) == JAS_CAST(int_fast32_t, -1));
167  assert(n >= 0);
168  // The behavior is undefined when x is negative. */
169  // We tacitly assume the behavior is equivalent to a signed
170  // arithmetic right shift.
171  return x >> n;
172 }
173 
174 JAS_ATTRIBUTE_CONST
175 JAS_ATTRIBUTE_DISABLE_USAN
176 inline static int jas_fast32_asl(int_fast32_t x, int n)
177 {
178  // Ensure that the shift of a negative value appears to behave as a
179  // signed arithmetic shift.
180  assert(((JAS_CAST(int_fast32_t, -1)) << 1) == JAS_CAST(int_fast32_t, -2));
181  assert(n >= 0);
182  // The behavior is undefined when x is negative. */
183  // We tacitly assume the behavior is equivalent to a signed
184  // arithmetic left shift.
185  return x << n;
186 }
187 
188 #ifdef __GNUC__
189 #pragma GCC diagnostic pop
190 #endif
191 
192 /******************************************************************************\
193 * Safe integer arithmetic (i.e., with overflow checking).
194 \******************************************************************************/
195 
196 /* Compute the product of two size_t integers with overflow checking. */
197 inline static bool jas_safe_size_mul(size_t x, size_t y, size_t *result)
198 {
199  /* Check if overflow would occur */
200  if (x && y > SIZE_MAX / x) {
201  /* Overflow would occur. */
202  return false;
203  }
204  if (result) {
205  *result = x * y;
206  }
207  return true;
208 }
209 
210 /* Compute the product of three size_t integers with overflow checking. */
211 inline static bool jas_safe_size_mul3(size_t a, size_t b, size_t c,
212  size_t *result)
213 {
214  size_t tmp;
215  if (!jas_safe_size_mul(a, b, &tmp) ||
216  !jas_safe_size_mul(tmp, c, &tmp)) {
217  return false;
218  }
219  if (result) {
220  *result = tmp;
221  }
222  return true;
223 }
224 
225 /* Compute the sum of two size_t integers with overflow checking. */
226 inline static bool jas_safe_size_add(size_t x, size_t y, size_t *result)
227 {
228  if (y > SIZE_MAX - x) {
229  return false;
230  }
231  if (result) {
232  *result = x + y;
233  }
234  return true;
235 }
236 
237 /* Compute the difference of two size_t integers with overflow checking. */
238 inline static bool jas_safe_size_sub(size_t x, size_t y, size_t *result)
239 {
240  if (y > x) {
241  return false;
242  }
243  if (result) {
244  *result = x - y;
245  }
246  return true;
247 }
248 
249 /* Compute the product of two int_fast32_t integers with overflow checking. */
250 inline static bool jas_safe_intfast32_mul(int_fast32_t x, int_fast32_t y,
251  int_fast32_t *result)
252 {
253  if (x > 0) {
254  /* x is positive */
255  if (y > 0) {
256  /* x and y are positive */
257  if (x > INT_FAST32_MAX / y) {
258  return false;
259  }
260  } else {
261  /* x positive, y nonpositive */
262  if (y < INT_FAST32_MIN / x) {
263  return false;
264  }
265  }
266  } else {
267  /* x is nonpositive */
268  if (y > 0) {
269  /* x is nonpositive, y is positive */
270  if (x < INT_FAST32_MIN / y) {
271  return false;
272  }
273  } else { /* x and y are nonpositive */
274  if (x != 0 && y < INT_FAST32_MAX / x) {
275  return false;
276  }
277  }
278  }
279 
280  if (result) {
281  *result = x * y;
282  }
283  return true;
284 }
285 
286 /* Compute the product of three int_fast32_t integers with overflow checking. */
287 inline static bool jas_safe_intfast32_mul3(int_fast32_t a, int_fast32_t b,
288  int_fast32_t c, int_fast32_t *result)
289 {
290  int_fast32_t tmp;
291  if (!jas_safe_intfast32_mul(a, b, &tmp) ||
292  !jas_safe_intfast32_mul(tmp, c, &tmp)) {
293  return false;
294  }
295  if (result) {
296  *result = tmp;
297  }
298  return true;
299 }
300 
301 /* Compute the sum of two int_fast32_t integers with overflow checking. */
302 inline static bool jas_safe_intfast32_add(int_fast32_t x, int_fast32_t y,
303  int_fast32_t *result)
304 {
305  if ((y > 0 && x > INT_FAST32_MAX - y) ||
306  (y < 0 && x < INT_FAST32_MIN - y)) {
307  return false;
308  }
309  if (result) {
310  *result = x + y;
311  }
312  return true;
313 }
314 
315 #ifdef __cplusplus
316 }
317 #endif
318 
319 #endif