-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathluce.h
288 lines (250 loc) · 8.78 KB
/
luce.h
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
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
// ****************************************************************************
// By Antonino Perricone
// http://amicoperry.altervista.org/luce/
//
// This work is licensed under the Creative Commons
// Attribution-NonCommercial-ShareAlike 3.0 Unported License.
// To view a copy of this license, visit
// http://creativecommons.org/licenses/by-nc-sa/3.0/.
// ****************************************************************************
#pragma once
#include <cstddef>
//#define SHOWPERFORMANCE
struct LucePointDouble
{
double x;
double y;
};
struct LucePointFloat
{
float x;
float y;
};
class CLuce;
class LuceOptions
{
friend class CLuce;
public:
void InitDefault()
{
pointLight = true;
quadraticAttenuation = false;
zeroMode = true;
addSource = true;
sourceZero = true;
sourcePositiveNormalize = true;
sourceNegativeNormalize = true;
positiveNormalize = true;
negativeNormalize = true;
numThreadsToUse = 1;
positiveIntensity = 1.0f;
negativeIntensity = 1.0f;
center.x = 0.5;
center.y = 0.5;
direction.x = -0.707f;
direction.y = -0.707f;
zeros[0] = 0.0f;
zeros[1] = 0.0f;
zeros[2] = 0.0f;
zeros[3] = 0.0f;
zeros[4] = 0.0f;
}
const LuceOptions& operator=(const LuceOptions& b)
{
pointLight = b.pointLight ;
quadraticAttenuation = b.quadraticAttenuation ;
zeroMode = b.zeroMode ;
addSource = b.addSource ;
sourceZero = b.sourceZero ;
sourcePositiveNormalize = b.sourcePositiveNormalize ;
sourceNegativeNormalize = b.sourceNegativeNormalize ;
positiveNormalize = b.positiveNormalize ;
negativeNormalize = b.negativeNormalize ;
positiveIntensity = b.positiveIntensity ;
negativeIntensity = b.negativeIntensity ;
numThreadsToUse = b.numThreadsToUse ;
center.x = b.center.x ;
center.y = b.center.y ;
direction.x = b.direction.x ;
direction.y = b.direction.y ;
zeros[0] = b.zeros[0] ;
zeros[1] = b.zeros[1] ;
zeros[2] = b.zeros[2] ;
zeros[3] = b.zeros[3] ;
zeros[4] = b.zeros[4] ;
return *this;
}
bool IsPointLight() const { return pointLight; }
bool IsDirectionaLight() const { return !pointLight; }
bool IsQuadraticAttenuation() const { return quadraticAttenuation; }
bool IsLinearAttenuation() const { return !quadraticAttenuation; }
bool IsZeroMode() const { return zeroMode; }
bool IsLightformMode() const { return !zeroMode; }
bool IsNormalizePositive() const { return positiveNormalize; }
bool IsMantainPositiveScale() const { return !positiveNormalize; }
bool IsNormalizeNegative() const { return negativeNormalize; }
bool IsMantainNegativeScale() const { return !negativeNormalize; }
float GetPositiveIntensity() const { return positiveIntensity; }
float GetNegativeIntensity() const { return negativeIntensity; }
bool IsAddSource() const { return addSource; }
bool IsNotAddSource() const { return !addSource; }
bool IsSrcApplyZero() const { return sourceZero; }
bool IsSrcIgnoreZero() const { return !sourceZero; }
bool IsSrcNormalizePositive() const { return sourcePositiveNormalize; }
bool IsSrcMantainPositiveScale()const { return !sourcePositiveNormalize; }
bool IsSrcNormalizeNegative() const { return sourceNegativeNormalize; }
bool IsSrcMantainNegativeScale()const { return !sourceNegativeNormalize; }
unsigned short GetNumThreadsToUse() const { return numThreadsToUse; }
const LucePointDouble& GetCenter() const { return center; }
const LucePointFloat& GetDirection() const { return direction; }
float GetZero(int id) const { return zeros[id]; }
void SetPointLight() { pointLight = true; }
void SetDirectionaLight() { pointLight = false; }
void SetQuadraticAttenuation() { quadraticAttenuation = true; }
void SetLinearAttenuation() { quadraticAttenuation = false; }
void SetZeroMode() { zeroMode = true; }
void SetLightformMode() { zeroMode = false; }
void SetNormalizePositive() { positiveNormalize = true; }
void SetMantainPositiveScale() { positiveNormalize = false; }
void SetNormalizeNegative() { negativeNormalize = true; }
void SetMantainNegativeScale() { negativeNormalize = false; }
void SetPositiveIntensity(float v) { positiveIntensity = v; }
void SetNegativeIntensity(float v) { negativeIntensity = v; }
void SetAddSource() { addSource = true; }
void SetNotAddSource() { addSource = false; }
void SetSrcApplyZero() { sourceZero = true; }
void SetSrcIgnoreZero() { sourceZero = false; }
void SetSrcNormalizePositive() { sourcePositiveNormalize = true; }
void SetSrcMantainPositiveScale(){ sourcePositiveNormalize = false; }
void SetSrcNormalizeNegative() { sourceNegativeNormalize = true; }
void SetSrcMantainNegativeScale(){ sourceNegativeNormalize = false; }
void SetNumThreadsToUse(unsigned short n);
void SetCenter(double x,double y) { center.x=x; center.y=y; }
void SetDirection(float x,float y);
void SetZero(int id,float v) { zeros[id] = v; }
private:
//! If true it is a point light
bool pointLight:1;
//! If true the attenuation with distance is quadratic
bool quadraticAttenuation:1;
//! If true the algorithm is zeromode
bool zeroMode:1;
//! If true, on the values between zero and whire are normalize like black
//! to white
bool positiveNormalize:1;
//! If true, on the values between zero and whire are normalize like black
//! to white
bool negativeNormalize:1;
//! If true the source will be added to luce result
bool addSource:1;
//! If true, when add the source the zero color (and negatives) is converted
//! to black
bool sourceZero:1;
//! If true, when add the source the color between zero color and white is
//! scaled to be black to white
bool sourcePositiveNormalize:1;
//! If true, when add the source the color between black and zero color is
//! scaled to be black to white negative
bool sourceNegativeNormalize:1;
//! Multiplication factor for positive value (further normalize)
float positiveIntensity;
//! Multiplication factor for negative value (further normalize)
float negativeIntensity;
//! position in case of point light, it is percent of image
//! it is double to support large images
LucePointDouble center;
//! direction in case of directional light
LucePointFloat direction;
float zeros[5];
//! If true the plugin will use the tinythread library
unsigned short numThreadsToUse;
};
struct BitmapData
{
//! difference for x+1
ptrdiff_t iPixelSize;
//! difference for y+1
ptrdiff_t iStride;
//! data
unsigned char* pBits;
};
class CLuce
{
public:
typedef void ProgressFn(float v);
void SetProgressFn(ProgressFn *fn,float minDelta = 0.1f);
CLuce();
long width;
long height;
long numchannels;
long alphaInInputChannel; //outside 0<=x<numchannels if the alpha is not in input.
BitmapData input;
BitmapData output;
BitmapData alpha;
const LuceOptions *pOpt;
int currentZero;
// Change data applying luce
void Do8Bit();
void Do16Bit();
void Do32Bit();
private:
// useful templates
template<typename T> float GetValue(void* ptr,int idx);
template<typename T> void SetValue(void* ptr,int idx,float v);
template<typename T> void Line(long px,long py);
template<typename T> void DoPoint();
template<typename T> void DoDirectional();
template<typename T> void CallThreads();
template<typename T> void AddSource();
template<typename T> void Do();
// starting points
unsigned char* lightInput;
unsigned char* lightOutput;
unsigned char* lightAlpha;
long lx;
long ly;
void SetupLightPointers(long _lx,long _ly,
unsigned char*& _lightInput,
unsigned char*& _lightOutput,
unsigned char*& _lightAlpha );
// progress indicator support
float fProgressMinDeltaTime;
ProgressFn *pProgress;
void CheckProgress(float v);
// calculated scale
float positiveFactor;
float negativeFactor;
// an extra scale factor for directional light
float dirScale;
// extra optimizations
bool doLeft:1;
bool doTop:1;
bool doRight:1;
bool doBottom:1;
struct ThreadLightData
{
CLuce *pLuce;
long startPixel;
long endPixel; //actually minus+1
ThreadLightData(CLuce *pLuce,long startPixel,long endPixel);
};
template<typename T> static unsigned long __stdcall ThreadLightFunc(void*);
struct ThreadAddSourceData
{
CLuce *pLuce;
long left,top,right,bottom;
float srcDelta[5];
float srcPositiveFactor[5];
float srcNegativeFactor[5];
ThreadAddSourceData(CLuce *pLuce,
long left,long top,long right,long bottom,
float* srcDelta,float* srcPositiveFactor,
float* srcNegativeFactor);
};
template<typename T> static unsigned long __stdcall ThreadAddFunc(void*);
struct Rect
{
long left,top;
long right,bottom;
};
};