summaryrefslogtreecommitdiff
path: root/plugins/fast_float/src/fast_float_internal.h
blob: 8499483f651ec2d34e90d4807a2f3690df3b08f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
//---------------------------------------------------------------------------------
//
//  Little Color Management System, fast floating point extensions
//  Copyright (c) 1998-2020 Marti Maria Saguer, all rights reserved
//
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------------

#ifndef _FAST_INTERNAL_H
#define _FAST_INTERNAL_H

#include "lcms2_fast_float.h"
#include <stdint.h>

#define REQUIRED_LCMS_VERSION 2100

// Unused parameter warning supression
#define UNUSED_PARAMETER(x) ((void)x) 

// The specification for "inline" is section 6.7.4 of the C99 standard (ISO/IEC 9899:1999).
// unfortunately VisualC++ does not conform that
#if defined(_MSC_VER) || defined(__BORLANDC__)
#   define cmsINLINE __inline
#else
#   define cmsINLINE static inline
#endif

// A fast way to convert from/to 16 <-> 8 bits
#define FROM_8_TO_16(rgb) (cmsUInt16Number) ((((cmsUInt16Number) (rgb)) << 8)|(rgb)) 
#define FROM_16_TO_8(rgb) (cmsUInt8Number) ((((rgb) * 65281 + 8388608) >> 24) & 0xFF)


// This macro return words stored as big endian
#define CHANGE_ENDIAN(w)    (cmsUInt16Number) ((cmsUInt16Number) ((w)<<8)|((w)>>8))

// This macro changes the polarity of a word
#define REVERSE_FLAVOR_16(x)    ((cmsUInt16Number)(0xffff-(x)))

// Fixed point
#define FIXED_TO_INT(x)         ((x)>>16)
#define FIXED_REST_TO_INT(x)    ((x)&0xFFFFU)

#define cmsFLAGS_CAN_CHANGE_FORMATTER     0x02000000   // Allow change buffer format

// Utility macros to convert from to 0...1.0 in 15.16 fixed domain to 0..0xffff as integer 
cmsINLINE cmsS15Fixed16Number _cmsToFixedDomain(int a)                   { return a + ((a + 0x7fff) / 0xffff); }
cmsINLINE int                 _cmsFromFixedDomain(cmsS15Fixed16Number a) { return a - ((a + 0x7fff) >> 16); }   

// This is the upper part of internal transform structure. Only format specifiers are used
typedef struct {

       cmsUInt32Number InputFormat, OutputFormat; // Keep formats for further reference

} _xform_head;


#define MAX_NODES_IN_CURVE 0x8001  


// To prevent out of bounds indexing
cmsINLINE cmsFloat32Number fclamp(cmsFloat32Number v)
{
       return v < 0.0f ? 0.0f : (v > 1.0f ? 1.0f : v);
}

// Fast floor conversion logic. 
cmsINLINE int _cmsQuickFloor(cmsFloat64Number val)
{
#ifdef CMS_DONT_USE_FAST_FLOOR
       return (int)floor(val);
#else
#define _lcms_double2fixmagic  (68719476736.0 * 1.5)  

       union {
              cmsFloat64Number val;
              int halves[2];
       } temp;

       temp.val = val + _lcms_double2fixmagic;

#ifdef CMS_USE_BIG_ENDIAN
       return temp.halves[1] >> 16;
#else
       return temp.halves[0] >> 16;
#endif
#endif
}

// Floor to word, taking care of saturation. This is not critical in terms of performance
cmsINLINE cmsUInt16Number _cmsSaturateWord(cmsFloat64Number d)
{
       d += 0.5;

       if (d <= 0) return 0;
       if (d >= 65535.0) return 0xffff;

       return (cmsUInt16Number)floor(d);
}


cmsINLINE cmsFloat32Number flerp(const cmsFloat32Number LutTable[], cmsFloat32Number v)
{
       cmsFloat32Number y1, y0;
       cmsFloat32Number rest;
       int cell0, cell1;
      
       if (v <= 0.0) {
              return LutTable[0];
       }
       else
              if (v >= 1.0) {
              return LutTable[MAX_NODES_IN_CURVE - 1];
              }

       v *= (MAX_NODES_IN_CURVE - 1);

       cell0 = _cmsQuickFloor(v);
       cell1 = (int)ceilf(v);

       // Rest is 16 LSB bits
       rest = v - cell0;

       y0 = LutTable[cell0];
       y1 = LutTable[cell1];

       return y0 + (y1 - y0) * rest;
}




// Some secret sauce from lcms
int  _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags);



// Compute the increments to be used by the transform functions
void  _cmsComputeComponentIncrements(cmsUInt32Number Format,                                                
                                     cmsUInt32Number BytesPerPlane,
                                     cmsUInt32Number* nChannels,
                                     cmsUInt32Number* nAlpha,
                                     cmsUInt32Number ComponentStartingOrder[], 
                                     cmsUInt32Number ComponentPointerIncrements[]);

// 15 bits formatters
cmsFormatter Formatter_15Bit_Factory(cmsUInt32Number Type,
                                     cmsFormatterDirection Dir,
                                     cmsUInt32Number dwFlags);

// Optimizers

//  8 bits on input allows matrix-shaper boost up a little bit
cmsBool Optimize8MatrixShaper(_cmsTransformFn* TransformFn,
                              void** UserData,
                              _cmsFreeUserDataFn* FreeUserData,
                              cmsPipeline** Lut,
                              cmsUInt32Number* InputFormat,
                              cmsUInt32Number* OutputFormat,
                              cmsUInt32Number* dwFlags);

cmsBool OptimizeMatrixShaper15(_cmsTransformFn* TransformFn,
                               void** UserData,
                               _cmsFreeUserDataFn* FreeUserData,
                               cmsPipeline** Lut,
                               cmsUInt32Number* InputFormat,
                               cmsUInt32Number* OutputFormat,
                               cmsUInt32Number* dwFlags);


cmsBool Optimize8ByJoiningCurves(_cmsTransformFn* TransformFn,
                                 void** UserData,
                                 _cmsFreeUserDataFn* FreeUserData,
                                 cmsPipeline** Lut,
                                 cmsUInt32Number* InputFormat,
                                 cmsUInt32Number* OutputFormat,
                                 cmsUInt32Number* dwFlags);

cmsBool OptimizeFloatByJoiningCurves(_cmsTransformFn* TransformFn,                                  
                                void** UserData,
                                _cmsFreeUserDataFn* FreeUserData,
                                cmsPipeline** Lut, 
                                cmsUInt32Number* InputFormat, 
                                cmsUInt32Number* OutputFormat, 
                                cmsUInt32Number* dwFlags);    

cmsBool OptimizeFloatMatrixShaper(_cmsTransformFn* TransformFn,                                  
                             void** UserData,
                             _cmsFreeUserDataFn* FreeUserData,
                             cmsPipeline** Lut, 
                             cmsUInt32Number* InputFormat, 
                             cmsUInt32Number* OutputFormat, 
                             cmsUInt32Number* dwFlags);

cmsBool Optimize8BitRGBTransform(_cmsTransformFn* TransformFn,
                                   void** UserData,
                                   _cmsFreeUserDataFn* FreeDataFn,
                                   cmsPipeline** Lut,
                                   cmsUInt32Number* InputFormat,
                                   cmsUInt32Number* OutputFormat,
                                   cmsUInt32Number* dwFlags);

cmsBool Optimize16BitRGBTransform(_cmsTransformFn* TransformFn,
                                   void** UserData,
                                   _cmsFreeUserDataFn* FreeDataFn,
                                   cmsPipeline** Lut,
                                   cmsUInt32Number* InputFormat,
                                   cmsUInt32Number* OutputFormat,
                                   cmsUInt32Number* dwFlags);

cmsBool OptimizeCLUTRGBTransform(_cmsTransformFn* TransformFn,
                                  void** UserData,
                                  _cmsFreeUserDataFn* FreeDataFn,
                                  cmsPipeline** Lut, 
                                  cmsUInt32Number* InputFormat, 
                                  cmsUInt32Number* OutputFormat, 
                                  cmsUInt32Number* dwFlags);      

cmsBool OptimizeCLUTCMYKTransform(_cmsTransformFn* TransformFn,
					void** UserData,
					_cmsFreeUserDataFn* FreeDataFn,
					cmsPipeline** Lut,
					cmsUInt32Number* InputFormat,
					cmsUInt32Number* OutputFormat,
					cmsUInt32Number* dwFlags);

#endif