Warning, file /office/calligra/libs/pigment/KoIntegerMaths.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002  *  Copyright (c) 2005 Adrian Page <adrian@pagenet.plus.com>
0003  *
0004  * This library is free software; you can redistribute it and/or
0005  * modify it under the terms of the GNU Library General Public
0006  * License as published by the Free Software Foundation; either
0007  * version 2 of the License, or (at your option) any later version.
0008  *
0009  * This library is distributed in the hope that it will be useful,
0010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012  * Library General Public License for more details.
0013  *
0014  * You should have received a copy of the GNU Library General Public License
0015  * along with this library; see the file COPYING.LIB.  If not, write to
0016  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017  * Boston, MA 02110-1301, USA.
0018 */
0019 
0020 #ifndef KO_INTEGER_MATHS_H
0021 #define KO_INTEGER_MATHS_H
0022 
0023 #ifndef UINT8_MAX
0024 #define UINT8_MAX 255u
0025 #endif
0026 
0027 #ifndef UINT8_MIN
0028 #define UINT8_MIN 0u
0029 #endif
0030 
0031 #ifndef UINT16_MAX
0032 #define UINT16_MAX 65535u
0033 #endif
0034 
0035 #ifndef UINT16_MIN
0036 #define UINT16_MIN 0u
0037 #endif
0038 
0039 #ifndef UINT32_MAX
0040 #define UINT32_MAX (4294967295u)
0041 #endif
0042 
0043 #ifndef UINT32_MIN
0044 #define UINT32_MIN 0u
0045 #endif
0046 
0047 #ifndef INT16_MAX
0048 #define INT16_MAX 32767
0049 #endif
0050 
0051 #ifndef INT16_MIN
0052 #define INT16_MIN -32768
0053 #endif
0054 
0055 typedef unsigned int uint;
0056 
0057 template<typename _T_, typename _T2_, typename _T3_>
0058 inline _T_ CLAMP(_T_ x, _T2_ l, _T3_ u)
0059 {
0060     if (x < l)
0061         return _T_(l);
0062     else if (x > u)
0063         return _T_(u);
0064     return x;
0065 }
0066 
0067 /// take a and scale it up by 256*b/255
0068 inline uint UINT8_SCALEBY(uint a, uint b)
0069 {
0070     uint c = a * b + 0x80u;
0071     return (c >> 8) + c;
0072 }
0073 
0074 /// multiplication of two scale values
0075 /// A scale value is interpreted as 255 equaling 1.0 (such as seen in rgb8 triplets)
0076 /// thus "255*255=255" because 1.0*1.0=1.0
0077 inline uint UINT8_MULT(uint a, uint b)
0078 {
0079     uint c = a * b + 0x80u;
0080     return ((c >> 8) + c) >> 8;
0081 }
0082 
0083 inline uint UINT8_DIVIDE(uint a, uint b)
0084 {
0085     uint c = (a * UINT8_MAX + (b / 2u)) / b;
0086     return c;
0087 }
0088 
0089 /// Approximation of (a * b * c + 32512) / 65025.0
0090 inline uint UINT8_MULT3(uint a, uint b, uint c)
0091 {
0092   uint t = a * b * c + 0x7F5B;
0093   return ((t >> 7) + t) >> 16;
0094 }
0095 
0096 /// Blending of two scale values as described by the alpha scale value
0097 /// A scale value is interpreted as 255 equaling 1.0 (such as seen in rgb8 triplets)
0098 /// Basically we do: a*alpha + b*(1-alpha)
0099 inline uint UINT8_BLEND(uint a, uint b, uint alpha)
0100 {
0101     // However the formula is refactored to (a-b)*alpha + b  since that saves a multiplication
0102     // Signed arithmetic is needed since a-b might be negative
0103     int c = (int(a) - int(b)) * alpha + 0x80u;
0104     c = ((c >> 8) + c) >> 8;
0105     return c + b;
0106 }
0107 
0108 inline uint UINT16_MULT(uint a, uint b)
0109 {
0110     uint c = a * b + 0x8000u;
0111     return ((c >> 16) + c) >> 16;
0112 }
0113 
0114 inline int INT16_MULT(int a, int b)
0115 {
0116     return (a*b) / INT16_MAX;
0117 }
0118 
0119 inline uint UINT16_DIVIDE(uint a, uint b)
0120 {
0121     uint c = (a * UINT16_MAX + (b / 2u)) / b;
0122     return c;
0123 }
0124 
0125 inline uint UINT16_BLEND(uint a, uint b, uint alpha)
0126 {
0127     // Basically we do a*alpha + b*(1-alpha)
0128     // However refactored to (a-b)*alpha + b  since that saves a multiplication
0129     // Signed arithmetic is needed since a-b might be negative
0130     int c = ((int(a) - int(b)) * int(alpha)) >> 16;
0131     return uint(c + b);
0132 }
0133 
0134 inline uint UINT8_TO_UINT16(uint c)
0135 {
0136     return c | (c << 8);
0137 }
0138 
0139 inline uint UINT16_TO_UINT8(uint c)
0140 {
0141     //return round(c / 257.0);
0142     //For all UINT16 this calculation is the same and a lot faster (off by c/65656 which for every c is 0)
0143     c = c - (c >> 8) + 128;
0144     return c >> 8;
0145 }
0146 
0147 inline int INT16_BLEND(int a, int b, uint alpha)
0148 {
0149     // Basically we do a*alpha + b*(1-alpha)
0150     // However refactored to (a-b)*alpha + b  since that saves a multiplication
0151     int c = ((int(a) - int(b)) * int(alpha)) >> 16;
0152     return c + b;
0153 }
0154 
0155 #endif
0156