JasPer: jas_math.h Source File

JasPer 3.0.3 |

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
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
131JAS_ATTRIBUTE_CONST
132JAS_ATTRIBUTE_DISABLE_UBSAN
133inline 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
144JAS_ATTRIBUTE_CONST
145JAS_ATTRIBUTE_DISABLE_UBSAN
146inline 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
157JAS_ATTRIBUTE_CONST
158JAS_ATTRIBUTE_DISABLE_UBSAN
159inline 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
170JAS_ATTRIBUTE_CONST
171JAS_ATTRIBUTE_DISABLE_UBSAN
172inline 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
183JAS_ATTRIBUTE_CONST
184JAS_ATTRIBUTE_DISABLE_UBSAN
185inline 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
196JAS_ATTRIBUTE_CONST
197JAS_ATTRIBUTE_DISABLE_UBSAN
198inline 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. */
218inline 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. */
241inline 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. */
256inline 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. */
277inline 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. */
298inline 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. */
344inline 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. */
359inline 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/*
383This function is potentially useful but not currently used.
384So, it is commented out.
385*/
386inline 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
404typedef struct {
405 bool valid;
406 uint_least64_t value;
407} jas_safeui64_t;
408
409static inline
410jas_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
423static inline
424jas_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
437static inline
438jas_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
451static inline
452jas_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
466static inline
467jas_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
480static inline
481jas_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
494static inline
495int 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_compiler.h
Compiler-related macros.
jas_types.h
Primitive Types.