chalk

kis_integer_maths.h
1/*
2 * Copyright (c) 2005 Adrian Page <adrian@pagenet.plus.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19#ifndef KIS_INTEGER_MATHS_H
20#define KIS_INTEGER_MATHS_H
21
22#include <config.h>
23#if defined(HAVE_STDINT_H)
24#include <stdint.h>
25#endif
26
27#if !defined(UINT8_MAX)
28#define UINT8_MAX 255u
29#endif
30#if !defined(UINT8_MIN)
31#define UINT8_MIN 0u
32#endif
33
34#if !defined(UINT16_MAX)
35#define UINT16_MAX 65535u
36#endif
37#if !defined(UINT16_MIN)
38#define UINT16_MIN 0u
39#endif
40
41#if !defined(UINT32_MAX)
42#define UINT32_MAX (4294967295u)
43#endif
44#if !defined(UINT32_MIN)
45#define UINT32_MIN 0u
46#endif
47
48#if !defined(INT16_MAX)
49#define INT16_MAX 32767
50#endif
51#if !defined(INT16_MIN)
52#define INT16_MIN -32768
53#endif
54
56inline uint UINT8_SCALEBY(uint a, uint b)
57{
58 uint c = a * b + 0x80u;
59 return (c >> 8) + c;
60}
61
62inline uint UINT8_MULT(uint a, uint b)
63{
64 uint c = a * b + 0x80u;
65 return ((c >> 8) + c) >> 8;
66}
67
68inline uint UINT8_DIVIDE(uint a, uint b)
69{
70 uint c = (a * UINT8_MAX + (b / 2u)) / b;
71 return c;
72}
73
74inline uint UINT8_BLEND(uint a, uint b, uint alpha)
75{
76 // Basically we do a*alpha + b*(1-alpha)
77 // However refactored to (a-b)*alpha + b since that saves a multiplication
78 // Signed arithmetic is needed since a-b might be negative
79 int c = ((int(a) - int(b)) * int(alpha)) >> 8;
80
81 return uint(c + b);
82}
83
84inline uint UINT16_MULT(uint a, uint b)
85{
86 uint c = a * b + 0x8000u;
87 return ((c >> 16) + c) >> 16;
88}
89
90inline int INT16_MULT(int a, int b)
91{
92 return (a*b) / INT16_MAX;
93}
94
95inline uint UINT16_DIVIDE(uint a, uint b)
96{
97 uint c = (a * UINT16_MAX + (b / 2u)) / b;
98 return c;
99}
100
101inline uint UINT16_BLEND(uint a, uint b, uint alpha)
102{
103 // Basically we do a*alpha + b*(1-alpha)
104 // However refactored to (a-b)*alpha + b since that saves a multiplication
105 // Signed arithmetic is needed since a-b might be negative
106 int c = ((int(a) - int(b)) * int(alpha)) >> 16;
107 return uint(c + b);
108}
109
110inline uint UINT8_TO_UINT16(uint c)
111{
112 return c | (c<<8);
113}
114
115inline uint UINT16_TO_UINT8(uint c)
116{
117 //return round(c / 257.0);
118 //For all UINT16 this calculation is the same and a lot faster (off by c/65656 which for every c is 0)
119 c = c - (c >> 8) + 128;
120 return c >>8;
121}
122
123inline int INT16_BLEND(int a, int b, uint alpha)
124{
125 // Basically we do a*alpha + b*(1-alpha)
126 // However refactored to (a-b)*alpha + b since that saves a multiplication
127 int c = ((int(a) - int(b)) * int(alpha)) >> 16;
128 return c + b;
129}
130
131#endif
132