LMMS
Loading...
Searching...
No Matches
lice_combine.h
Go to the documentation of this file.
1#ifndef _LICE_COMBINE_H_
2#define _LICE_COMBINE_H_
3
4
5#if defined(_MSC_VER)
6#pragma warning(disable:4244) // float-to-int
7#endif
8
9#define __LICE_BOUND(x,lo,hi) ((x)<(lo)?(lo):((x)>(hi)?(hi):(x)))
10
11
12#define LICE_PIXEL_HALF(x) (((x)>>1)&0x7F7F7F7F)
13#define LICE_PIXEL_QUARTER(x) (((x)>>2)&0x3F3F3F3F)
14#define LICE_PIXEL_EIGHTH(x) (((x)>>3)&0x1F1F1F1F)
15
16
17static inline void __LICE_BilinearFilterI(int *r, int *g, int *b, int *a, const LICE_pixel_chan *pin, const LICE_pixel_chan *pinnext, unsigned int xfrac, unsigned int yfrac)
18{
19 const unsigned int f4=(xfrac*yfrac)>>16;
20 const unsigned int f3=yfrac-f4; // (1.0-xfrac)*yfrac;
21 const unsigned int f2=xfrac-f4; // xfrac*(1.0-yfrac);
22 const unsigned int f1=65536-yfrac-xfrac+f4; // (1.0-xfrac)*(1.0-yfrac);
23 #define DOCHAN(output, inchan) \
24 (output)=(pin[(inchan)]*f1 + pin[4+(inchan)]*f2 + pinnext[(inchan)]*f3 + pinnext[4+(inchan)]*f4)>>16;
29 #undef DOCHAN
30}
31
32static inline void __LICE_BilinearFilterIPixOut(LICE_pixel_chan *out, const LICE_pixel_chan *pin, const LICE_pixel_chan *pinnext, unsigned int xfrac, unsigned int yfrac)
33{
34 const unsigned int f4=(xfrac*yfrac)>>16;
35 const unsigned int f3=yfrac-f4; // (1.0-xfrac)*yfrac;
36 const unsigned int f2=xfrac-f4; // xfrac*(1.0-yfrac);
37 const unsigned int f1=65536-yfrac-xfrac+f4; // (1.0-xfrac)*(1.0-yfrac);
38 #define DOCHAN(inchan) \
39 (out[inchan])=(pin[(inchan)]*f1 + pin[4+(inchan)]*f2 + pinnext[(inchan)]*f3 + pinnext[4+(inchan)]*f4)>>16;
44 #undef DOCHAN
45}
46
47
48static inline void __LICE_BilinearFilterI_2(int *r, int *g, int *b, int *a, const LICE_pixel_chan *pin, const LICE_pixel_chan *pinnext, int npoffs, unsigned int xfrac, unsigned int yfrac)
49{
50 const unsigned int f4=(xfrac*yfrac)>>16;
51 const unsigned int f3=yfrac-f4; // (1.0-xfrac)*yfrac;
52 const unsigned int f2=xfrac-f4; // xfrac*(1.0-yfrac);
53 const unsigned int f1=65536-yfrac-xfrac+f4; // (1.0-xfrac)*(1.0-yfrac);
54 *r=(pin[LICE_PIXEL_R]*f1 + pin[npoffs+LICE_PIXEL_R]*f2 + pinnext[LICE_PIXEL_R]*f3 + pinnext[npoffs+LICE_PIXEL_R]*f4)>>16;
55 *g=(pin[LICE_PIXEL_G]*f1 + pin[npoffs+LICE_PIXEL_G]*f2 + pinnext[LICE_PIXEL_G]*f3 + pinnext[npoffs+LICE_PIXEL_G]*f4)>>16;
56 *b=(pin[LICE_PIXEL_B]*f1 + pin[npoffs+LICE_PIXEL_B]*f2 + pinnext[LICE_PIXEL_B]*f3 + pinnext[npoffs+LICE_PIXEL_B]*f4)>>16;
57 *a=(pin[LICE_PIXEL_A]*f1 + pin[npoffs+LICE_PIXEL_A]*f2 + pinnext[LICE_PIXEL_A]*f3 + pinnext[npoffs+LICE_PIXEL_A]*f4)>>16;
58}
59
60
61static inline void __LICE_LinearFilterI(int *r, int *g, int *b, int *a, const LICE_pixel_chan *pin, const LICE_pixel_chan *pinnext, unsigned int frac)
62{
63 const unsigned int f=65536-frac;
64 *r=(pin[LICE_PIXEL_R]*f + pinnext[LICE_PIXEL_R]*frac)>>16;
65 *g=(pin[LICE_PIXEL_G]*f + pinnext[LICE_PIXEL_G]*frac)>>16;
66 *b=(pin[LICE_PIXEL_B]*f + pinnext[LICE_PIXEL_B]*frac)>>16;
67 *a=(pin[LICE_PIXEL_A]*f + pinnext[LICE_PIXEL_A]*frac)>>16;
68}
69static inline void __LICE_LinearFilterIPixOut(LICE_pixel_chan *out, const LICE_pixel_chan *pin, const LICE_pixel_chan *pinnext, unsigned int frac)
70{
71 const unsigned int f=65536-frac;
72 out[LICE_PIXEL_R]=(pin[LICE_PIXEL_R]*f + pinnext[LICE_PIXEL_R]*frac)>>16;
73 out[LICE_PIXEL_G]=(pin[LICE_PIXEL_G]*f + pinnext[LICE_PIXEL_G]*frac)>>16;
74 out[LICE_PIXEL_B]=(pin[LICE_PIXEL_B]*f + pinnext[LICE_PIXEL_B]*frac)>>16;
75 out[LICE_PIXEL_A]=(pin[LICE_PIXEL_A]*f + pinnext[LICE_PIXEL_A]*frac)>>16;
76}
77
78static void inline _LICE_MakePixelClamp(LICE_pixel_chan *out, int r, int g, int b, int a)
79{
80#define LICE_PIX_MAKECHAN(a,b) out[a] = (b&~0xff) ? (b<0?0:255) : b;
85#undef LICE_PIX_MAKECHAN
86}
87
97
98
99
100#define HSV_P v*(256-s)/256
101#define HSV_Q(hval) v*(16384-(hval)*s)/16384
102#define HSV_T(hval) v*(16384-(64-(hval))*s)/16384
103#define HSV_X v
104extern unsigned short _LICE_RGB2HSV_invtab[256]; // 65536/idx - 1
105
106#ifdef LICE_COMBINE_IMPLEMENT_HSV
107 LICE_pixel LICE_HSV2Pix(int h, int s, int v, int alpha)
108 #define __LICE_HSV2Pix LICE_HSV2Pix
109#else
110 static inline LICE_pixel __LICE_HSV2Pix(int h, int s, int v, int alpha)
111#endif
112{
113 if (h<192)
114 {
115 if (h<64) return LICE_RGBA(HSV_X,HSV_T(h),HSV_P,alpha);
116 if (h<128) return LICE_RGBA(HSV_Q(h-64),HSV_X,HSV_P,alpha);
117 return LICE_RGBA(HSV_P,HSV_X,HSV_T(h-128),alpha);
118 }
119 if (h < 256) return LICE_RGBA(HSV_P,HSV_Q(h-192),HSV_X,alpha);
120 if (h < 320) return LICE_RGBA(HSV_T(h-256),HSV_P,HSV_X,alpha);
121 return LICE_RGBA(HSV_X,HSV_P,HSV_Q(h-320),alpha);
122}
123
124#ifdef LICE_COMBINE_IMPLEMENT_HSV
125void LICE_HSV2RGB(int h, int s, int v, int* r, int* g, int* b)
126#define __LICE_HSV2RGB LICE_HSV2RGB
127#else
128static inline void __LICE_HSV2RGB(int h, int s, int v, int* r, int* g, int* b)
129#endif
130{
131 if (h<192)
132 {
133 if (h<64)
134 {
135 *r = HSV_X; *g = HSV_T(h); *b = HSV_P;
136 }
137 else if (h<128)
138 {
139 *r = HSV_Q(h-64); *g = HSV_X; *b = HSV_P;
140 }
141 else
142 {
143 *r = HSV_P; *g = HSV_X; *b = HSV_T(h-128);
144 }
145 }
146 else
147 {
148 if (h < 256)
149 {
150 *r = HSV_P; *g = HSV_Q(h-192); *b = HSV_X;
151 }
152 else if (h < 320)
153 {
154 *r = HSV_T(h-256); *g = HSV_P; *b = HSV_X;
155 }
156 else
157 {
158 *r = HSV_X; *g = HSV_P; *b = HSV_Q(h-320);
159 }
160 }
161}
162
163
164#define LICE_RGB2HSV_USE_TABLE
165// h = [0,384), s and v = [0,256)
166
167#ifdef LICE_COMBINE_IMPLEMENT_HSV
168 void LICE_RGB2HSV(int r, int g, int b, int* h, int* s, int* v)
169 #define __LICE_RGB2HSV LICE_RGB2HSV
170#else
171 static inline void __LICE_RGB2HSV(int r, int g, int b, int* h, int* s, int* v)
172#endif
173{
174
175 // this makes it just 3 conditional branches per call
176 int df,d,maxrgb;
177 int degoffs;
178 if (g > r)
179 {
180 if (g>b) // green max
181 {
182 maxrgb=g;
183 degoffs=128;
184 df = maxrgb - lice_min(b,r);
185 d=b-r;
186 }
187 else // blue max
188 {
189 maxrgb=b;
190 degoffs=256;
191 df = maxrgb - lice_min(g,r);
192 d=r-g;
193 }
194 }
195 else // r >= g
196 {
197 if (r > b) // red max
198 {
199 maxrgb=r;
200
201 if (g<b)
202 {
203 degoffs=383; // not technically correct, but close enough (and simplifies the rounding case -- if you want more accuracy, set to 384,
204 // then add a if (*h == 384) *h=0; after the *h assignment below
205 df = maxrgb - g;
206 }
207 else
208 {
209 degoffs=0;
210 df = maxrgb - b;
211 }
212 d=g-b;
213 }
214 else // blue max
215 {
216 maxrgb=b;
217 degoffs=256;
218 df = maxrgb - lice_min(g,r);
219 d=r-g;
220 }
221 }
222
223
224 *v = maxrgb;
225#ifndef LICE_RGB2HSV_USE_TABLE // table mode doesnt need this check
226 if (!df) {
227 *h = *s = 0;
228 }
229 else
230#endif
231 {
232
233#ifdef LICE_RGB2HSV_USE_TABLE
234
235
236 *h = (d*((int)(_LICE_RGB2HSV_invtab[df]+1)))/1024 + degoffs;
237 *s = (df*((int)_LICE_RGB2HSV_invtab[maxrgb]))/256;
238#else
239 *h = ((d*64)/df) + degoffs;
240 *s = (df*256)/(maxrgb+1);
241#endif
242 }
243}
244
245//void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) // alpha is ignored.
246// generally speaking, the "a" is 0-255, and alpha is 0-256/1-256.
247
248// Optimization when a=255 and alpha=1.0f, useful for doing a big vector drawn fill or something.
249// This could be called _LICE_PutPixel but that would probably be confusing.
251{
252public:
253 static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) // alpha is ignored.
254 {
255 _LICE_MakePixelNoClamp(dest, r, g, b, a);
256 }
257};
258
260{
261public:
262 static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) // alpha is ignored.
263 {
264 _LICE_MakePixelClamp(dest, r, g, b, a);
265 }
266};
267
269{
270public:
271 static inline void doPixFAST(LICE_pixel *dest, LICE_pixel src) // alpha is ignored.
272 {
273 *dest = src;
274 }
275};
276
278{
279public:
280 static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
281 {
283 (dest[LICE_PIXEL_R]+r)>>1,
284 (dest[LICE_PIXEL_G]+g)>>1,
285 (dest[LICE_PIXEL_B]+b)>>1,
286 (dest[LICE_PIXEL_A]+a)>>1);
287 }
288};
289
291{
292public:
293 static inline void doPixFAST(LICE_pixel *dest, LICE_pixel src) // src is full range
294 {
295 *dest = ((*dest>>1) &0x7f7f7f7f) + ((src>>1)&0x7f7f7f7f);
296 }
297};
298
300{
301public:
302 static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
303 {
305 (dest[LICE_PIXEL_R]+r)>>1,
306 (dest[LICE_PIXEL_G]+g)>>1,
307 (dest[LICE_PIXEL_B]+b)>>1,
308 (dest[LICE_PIXEL_A]+a)>>1);
309 }
310
311};
312
313
315{
316public:
317 static inline void doPixFAST(LICE_pixel *dest, LICE_pixel src) // src is pre-halfed and masked
318 {
319 *dest = ((*dest>>1) &0x7f7f7f7f) + src;
320 }
321};
322
324{
325public:
326 static inline void doPixFAST(LICE_pixel *dest, LICE_pixel src) // src is pre-quartered and masked
327 {
328 LICE_pixel tmp = *dest;
329 *dest = ((tmp>>1) &0x7f7f7f7f) + ((tmp>>2) &0x3f3f3f3f) + src;
330 }
331};
332
334{
335public:
336 static inline void doPixFAST(LICE_pixel *dest, LICE_pixel src) // src is pre-three-eighthed and masked
337 {
338 LICE_pixel tmp = *dest;
339 *dest = ((tmp>>1) &0x7f7f7f7f) + ((tmp>>3) &0x1f1f1f1f) + src;
340 }
341};
342
344{
345public:
346 static inline void doPixFAST(LICE_pixel *dest, LICE_pixel src) // src is pre-three-quartered and masked
347 {
348 *dest = ((*dest>>2) &0x3f3f3f3f) + src;
349 }
350};
351
353{
354public:
355 static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
356 {
357 const int sc=(256-alpha);
358
359 // don't check alpha=0 here, since the caller should (since alpha is usually used for static alphas)
361 r + ((dest[LICE_PIXEL_R]-r)*sc)/256,
362 g + ((dest[LICE_PIXEL_G]-g)*sc)/256,
363 b + ((dest[LICE_PIXEL_B]-b)*sc)/256,
364 a + ((dest[LICE_PIXEL_A]-a)*sc)/256);
365 }
366};
367
369{
370public:
371 static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
372 {
373 const int sc=(256-alpha);
374
375 // don't check alpha=0 here, since the caller should (since alpha is usually used for static alphas)
377 r + ((dest[LICE_PIXEL_R]-r)*sc)/256,
378 g + ((dest[LICE_PIXEL_G]-g)*sc)/256,
379 b + ((dest[LICE_PIXEL_B]-b)*sc)/256,
380 a + ((dest[LICE_PIXEL_A]-a)*sc)/256);
381 }
382};
383
385{
386public:
387 static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
388 {
389 if (a)
390 {
391 const int sc2=(alpha*(a+1))/256;
392 const int sc = 256 - sc2;
393
395 r + ((dest[LICE_PIXEL_R]-r)*sc)/256,
396 g + ((dest[LICE_PIXEL_G]-g)*sc)/256,
397 b + ((dest[LICE_PIXEL_B]-b)*sc)/256,
398 lice_min(255,sc2 + dest[LICE_PIXEL_A]));
399 }
400 }
401};
402
404{
405public:
406 static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
407 {
408 if (a)
409 {
410 const int sc2=(alpha*(a+1))/256;
411 const int sc = 256 - sc2;
412
414 r + ((dest[LICE_PIXEL_R]-r)*sc)/256,
415 g + ((dest[LICE_PIXEL_G]-g)*sc)/256,
416 b + ((dest[LICE_PIXEL_B]-b)*sc)/256,
417 sc2 + dest[LICE_PIXEL_A]);
418 }
419 }
420};
422{
423public:
424 static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
425 {
426 if (a)
427 {
428 if (a==255)
429 {
431 }
432 else
433 {
434 const int sc=(255-a);
435
437 r + ((dest[LICE_PIXEL_R]-r)*sc)/256,
438 g + ((dest[LICE_PIXEL_G]-g)*sc)/256,
439 b + ((dest[LICE_PIXEL_B]-b)*sc)/256,
440 lice_min(255,a + dest[LICE_PIXEL_A]));
441 }
442 }
443 }
444};
446{
447public:
448 static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
449 {
450 if (a)
451 {
452 if (a==255)
453 {
454 _LICE_MakePixelClamp(dest,r,g,b,a);
455 }
456 else
457 {
458 const int sc=(255-a);
459
461 r + ((dest[LICE_PIXEL_R]-r)*sc)/256,
462 g + ((dest[LICE_PIXEL_G]-g)*sc)/256,
463 b + ((dest[LICE_PIXEL_B]-b)*sc)/256,
464 a + dest[LICE_PIXEL_A]);
465 }
466 }
467 }
468};
469
470#ifndef LICE_DISABLE_BLEND_ADD
471
473{
474public:
475 static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
476 {
477 // don't check alpha=0 here, since the caller should (since alpha is usually used for static alphas)
478
480 dest[LICE_PIXEL_R]+(r*alpha)/256,
481 dest[LICE_PIXEL_G]+(g*alpha)/256,
482 dest[LICE_PIXEL_B]+(b*alpha)/256,
483 dest[LICE_PIXEL_A]+(a*alpha)/256);
484
485 }
486};
488{
489public:
490 static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
491 {
492 if (a)
493 {
494 alpha=(alpha*(a+1))/256;
496 dest[LICE_PIXEL_R]+(r*alpha)/256,
497 dest[LICE_PIXEL_G]+(g*alpha)/256,
498 dest[LICE_PIXEL_B]+(b*alpha)/256,
499 dest[LICE_PIXEL_A]+(a*alpha)/256);
500 }
501 }
502};
503
504#else // !LICE_DISABLE_BLEND_ADD
505#define _LICE_CombinePixelsAddSourceAlpha _LICE_CombinePixelsCopySourceAlphaClamp
506#define _LICE_CombinePixelsAdd _LICE_CombinePixelsCopyClamp
507#endif
508
509#ifndef LICE_DISABLE_BLEND_DODGE
510
512{
513public:
514 static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
515 {
516 const int src_r = 256-r*alpha/256;
517 const int src_g = 256-g*alpha/256;
518 const int src_b = 256-b*alpha/256;
519 const int src_a = 256-a*alpha/256;
520
522 src_r > 1 ? 256*dest[LICE_PIXEL_R] / src_r : 256*dest[LICE_PIXEL_R],
523 src_g > 1 ? 256*dest[LICE_PIXEL_G] / src_g : 256*dest[LICE_PIXEL_G],
524 src_b > 1 ? 256*dest[LICE_PIXEL_B] / src_b : 256*dest[LICE_PIXEL_B],
525 src_a > 1 ? 256*dest[LICE_PIXEL_A] / src_a : 256*dest[LICE_PIXEL_A]);
526 }
527};
528
530{
531public:
532 static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
533 {
534 const int ualpha=(alpha*(a+1))/256;
535
536 const int src_r = 256-r*ualpha/256;
537 const int src_g = 256-g*ualpha/256;
538 const int src_b = 256-b*ualpha/256;
539 const int src_a = 256-a*ualpha/256;
540
542 src_r > 1 ? 256*dest[LICE_PIXEL_R] / src_r : 256*dest[LICE_PIXEL_R],
543 src_g > 1 ? 256*dest[LICE_PIXEL_G] / src_g : 256*dest[LICE_PIXEL_G],
544 src_b > 1 ? 256*dest[LICE_PIXEL_B] / src_b : 256*dest[LICE_PIXEL_B],
545 src_a > 1 ? 256*dest[LICE_PIXEL_A] / src_a : 256*dest[LICE_PIXEL_A]);
546 }
547};
548
549#else // !LICE_DISABLE_BLEND_DODGE
550#define _LICE_CombinePixelsColorDodgeSourceAlpha _LICE_CombinePixelsCopySourceAlphaClamp
551#define _LICE_CombinePixelsColorDodge _LICE_CombinePixelsCopyClamp
552#endif
553
554
555#ifndef LICE_DISABLE_BLEND_MUL
556
558{
559public:
560 static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
561 {
562 // we could check alpha=0 here, but the caller should (since alpha is usually used for static alphas)
563
564 const int da=(256-alpha)*256;
566 (dest[LICE_PIXEL_R]*(da + (r*alpha)))>>16,
567 (dest[LICE_PIXEL_G]*(da + (g*alpha)))>>16,
568 (dest[LICE_PIXEL_B]*(da + (b*alpha)))>>16,
569 (dest[LICE_PIXEL_A]*(da + (a*alpha)))>>16);
570
571 }
572};
574{
575public:
576 static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
577 {
578 // we could check alpha=0 here, but the caller should (since alpha is usually used for static alphas)
579
580 const int da=(256-alpha)*256;
582 (dest[LICE_PIXEL_R]*(da + (r*alpha)))>>16,
583 (dest[LICE_PIXEL_G]*(da + (g*alpha)))>>16,
584 (dest[LICE_PIXEL_B]*(da + (b*alpha)))>>16,
585 (dest[LICE_PIXEL_A]*(da + (a*alpha)))>>16);
586
587 }
588};
590{
591public:
592 static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
593 {
594 if (a)
595 {
596 const int ualpha=(alpha*(a+1))/256;
597 const int da=(256-ualpha)*256;
599 (dest[LICE_PIXEL_R]*(da + (r*ualpha)))>>16,
600 (dest[LICE_PIXEL_G]*(da + (g*ualpha)))>>16,
601 (dest[LICE_PIXEL_B]*(da + (b*ualpha)))>>16,
602 (dest[LICE_PIXEL_A]*(da + (a*ualpha)))>>16);
603
604 }
605 }
606};
608{
609public:
610 static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
611 {
612 if (a)
613 {
614 const int ualpha=(alpha*(a+1))/256;
615 const int da=(256-ualpha)*256;
617 (dest[LICE_PIXEL_R]*(da + (r*ualpha)))>>16,
618 (dest[LICE_PIXEL_G]*(da + (g*ualpha)))>>16,
619 (dest[LICE_PIXEL_B]*(da + (b*ualpha)))>>16,
620 (dest[LICE_PIXEL_A]*(da + (a*ualpha)))>>16);
621
622 }
623 }
624};
625
626#else // !LICE_DISABLE_BLEND_MUL
627#define _LICE_CombinePixelsMulSourceAlphaNoClamp _LICE_CombinePixelsCopySourceAlphaNoClamp
628#define _LICE_CombinePixelsMulSourceAlphaClamp _LICE_CombinePixelsCopySourceAlphaClamp
629#define _LICE_CombinePixelsMulNoClamp _LICE_CombinePixelsCopyNoClamp
630#define _LICE_CombinePixelsMulClamp _LICE_CombinePixelsCopyClamp
631#endif
632
633//#define LICE_DISABLE_BLEND_OVERLAY
634#ifndef LICE_DISABLE_BLEND_OVERLAY
635
637{
638public:
639 static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
640 {
641 // we could check alpha=0 here, but the caller should (since alpha is usually used for static alphas)
642
643 int destr = dest[LICE_PIXEL_R], destg = dest[LICE_PIXEL_G], destb = dest[LICE_PIXEL_B], desta = dest[LICE_PIXEL_A];
644
645#if 0
646 int srcr = r*alpha, srcg = g*alpha, srcb = b*alpha, srca = a*alpha;
647 int da=(256-alpha)*256;
648 int mr = (destr*(da+srcr))/65536;
649 int mg = (destg*(da+srcg))/65536;
650 int mb = (destb*(da+srcb))/65536;
651 int ma = (desta*(da+srca))/65536;
652 int sr = 256-(65536-srcr)*(256-destr)/65536;
653 int sg = 256-(65536-srcg)*(256-destg)/65536;
654 int sb = 256-(65536-srcb)*(256-destb)/65536;
655 int sa = 256-(65536-srca)*(256-desta)/65536;
656
657 destr = (destr*sr+(256-destr)*mr)/256;
658 destg = (destg*sg+(256-destg)*mg)/256;
659 destb = (destb*sb+(256-destb)*mb)/256;
660 desta = (desta*sa+(256-desta)*ma)/256;
661#else
662 // can produce slightly diff (+-1) results from above due to rounding
663 const int da=(256-alpha)*128;
664 const int srcr = r*alpha+da, srcg = g*alpha+da, srcb = b*alpha+da, srca = a*alpha + da;
665 destr = ( destr*( (destr*(32768-srcr))/256 + srcr ) ) >> 15;
666 destg = ( destg*( (destg*(32768-srcg))/256 + srcg ) ) >> 15;
667 destb = ( destb*( (destb*(32768-srcb))/256 + srcb ) ) >> 15;
668 desta = ( desta*( (desta*(32768-srca))/256 + srca ) ) >> 15;
669
670#endif
671
672 _LICE_MakePixelClamp(dest, destr, destg, destb, desta);
673 }
674};
675
677{
678public:
679 static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
680 {
681 _LICE_CombinePixelsOverlay::doPix(dest, r, g, b, a, (alpha*(a+1))/256);
682 }
683};
684
685#else // !LICE_DISABLE_BLEND_OVERLAY
686#define _LICE_CombinePixelsOverlaySourceAlpha _LICE_CombinePixelsCopySourceAlphaClamp
687#define _LICE_CombinePixelsOverlay _LICE_CombinePixelsCopyClamp
688#endif
689
690
691//#define LICE_DISABLE_BLEND_HSVADJ
692#ifndef LICE_DISABLE_BLEND_HSVADJ
693
695{
696public:
697 static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
698 {
699 int h,s,v;
701 h+=(((r+r/2) - 192) * alpha)/256;
702 if (h<0)h+=384;
703 else if (h>=384) h-=384;
704 s+=((g-128)*alpha)/128;
705 if (s&~0xff)
706 {
707 if (s<0)s=0;
708 else s=255;
709 }
710 v+=((b-128)*alpha)/128;
711 if (v&~0xff)
712 {
713 if (v<0)v=0;
714 else v=255;
715 }
716
717 *(LICE_pixel *)dest = __LICE_HSV2Pix(h,s,v,a);
718 }
719};
720
722{
723public:
724 static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
725 {
726 _LICE_CombinePixelsHSVAdjust::doPix(dest, r, g, b, a, (alpha*(a+1))/256);
727 }
728};
729
730#else // !LICE_DISABLE_BLEND_HSVADJ
731#define _LICE_CombinePixelsHSVAdjustSourceAlpha _LICE_CombinePixelsCopySourceAlphaClamp
732#define _LICE_CombinePixelsHSVAdjust _LICE_CombinePixelsCopyClamp
733#endif
734
735// note: the "clamp" parameter would generally be false, unless you're working with
736// input colors that need to be clamped (i.e. if you have a r value of >255 or <0, etc.
737// if your input is LICE_pixel only then use false, and it will clamp as needed depending
738// on the blend mode..
739
740//#define __LICE__ACTION(comb) templateclass<comb>::function(parameters)
741//__LICE_ACTION_SRCALPHA(mode,alpha,clamp);
742//#undef __LICE__ACTION
743
744
745// use this for paths that support LICE_BLIT_USE_ALPHA (source-alpha combining), but
746// otherwise have constant alpha
747#define __LICE_ACTION_SRCALPHA(mode,ia,clamp) \
748 if ((ia)!=0) switch ((mode)&(LICE_BLIT_MODE_MASK|LICE_BLIT_USE_ALPHA)) { \
749 case LICE_BLIT_MODE_COPY: if ((ia)>0) { \
750 if (clamp) { \
751 if ((ia)==256) { __LICE__ACTION(_LICE_CombinePixelsClobberClamp); } \
752 else { __LICE__ACTION(_LICE_CombinePixelsCopyClamp); } \
753 } else { \
754 if ((ia)==256) { __LICE__ACTION(_LICE_CombinePixelsClobberNoClamp); } \
755 else { __LICE__ACTION(_LICE_CombinePixelsCopyNoClamp); } \
756 } \
757 } \
758 break; \
759 case LICE_BLIT_MODE_ADD: __LICE__ACTION(_LICE_CombinePixelsAdd); break; \
760 case LICE_BLIT_MODE_DODGE: __LICE__ACTION(_LICE_CombinePixelsColorDodge); break; \
761 case LICE_BLIT_MODE_MUL: \
762 if (clamp) { __LICE__ACTION(_LICE_CombinePixelsMulClamp); } \
763 else { __LICE__ACTION(_LICE_CombinePixelsMulNoClamp); } \
764 break; \
765 case LICE_BLIT_MODE_OVERLAY: __LICE__ACTION(_LICE_CombinePixelsOverlay); break; \
766 case LICE_BLIT_MODE_HSVADJ: __LICE__ACTION(_LICE_CombinePixelsHSVAdjust); break; \
767 case LICE_BLIT_MODE_COPY|LICE_BLIT_USE_ALPHA: \
768 if (clamp) { \
769 if ((ia)==256) { __LICE__ACTION(_LICE_CombinePixelsCopySourceAlphaIgnoreAlphaParmClamp);} \
770 else { __LICE__ACTION(_LICE_CombinePixelsCopySourceAlphaClamp); } \
771 } else { \
772 if ((ia)==256) { __LICE__ACTION(_LICE_CombinePixelsCopySourceAlphaIgnoreAlphaParmNoClamp); } \
773 else { __LICE__ACTION(_LICE_CombinePixelsCopySourceAlphaNoClamp); } \
774 } \
775 break; \
776 case LICE_BLIT_MODE_ADD|LICE_BLIT_USE_ALPHA: \
777 __LICE__ACTION(_LICE_CombinePixelsAddSourceAlpha); \
778 break; \
779 case LICE_BLIT_MODE_DODGE|LICE_BLIT_USE_ALPHA: \
780 __LICE__ACTION(_LICE_CombinePixelsColorDodgeSourceAlpha); \
781 break; \
782 case LICE_BLIT_MODE_MUL|LICE_BLIT_USE_ALPHA: \
783 if (clamp) { __LICE__ACTION(_LICE_CombinePixelsMulSourceAlphaClamp); } \
784 else { __LICE__ACTION(_LICE_CombinePixelsMulSourceAlphaNoClamp); } \
785 break; \
786 case LICE_BLIT_MODE_OVERLAY|LICE_BLIT_USE_ALPHA: \
787 __LICE__ACTION(_LICE_CombinePixelsOverlaySourceAlpha); \
788 break; \
789 case LICE_BLIT_MODE_HSVADJ|LICE_BLIT_USE_ALPHA: \
790 __LICE__ACTION(_LICE_CombinePixelsHSVAdjustSourceAlpha); \
791 break; \
792 }
793
794
795// use this for paths that can have per pixel alpha, but calculate it themselves
796#define __LICE_ACTION_NOSRCALPHA(mode, ia,clamp) \
797 if ((ia)!=0) switch ((mode)&LICE_BLIT_MODE_MASK) { \
798 case LICE_BLIT_MODE_COPY: if ((ia)>0) { if (clamp) { __LICE__ACTION(_LICE_CombinePixelsCopyClamp); } else { __LICE__ACTION(_LICE_CombinePixelsCopyNoClamp); } } break; \
799 case LICE_BLIT_MODE_ADD: __LICE__ACTION(_LICE_CombinePixelsAdd); break; \
800 case LICE_BLIT_MODE_DODGE: __LICE__ACTION(_LICE_CombinePixelsColorDodge); break; \
801 case LICE_BLIT_MODE_MUL: if (clamp) { __LICE__ACTION(_LICE_CombinePixelsMulClamp); } else { __LICE__ACTION(_LICE_CombinePixelsMulNoClamp); } break; \
802 case LICE_BLIT_MODE_OVERLAY: __LICE__ACTION(_LICE_CombinePixelsOverlay); break; \
803 case LICE_BLIT_MODE_HSVADJ: __LICE__ACTION(_LICE_CombinePixelsHSVAdjust); break; \
804 }
805
806// For drawing where there is constant alpha and no per-pixel alpha.
807#define __LICE_ACTION_CONSTANTALPHA(mode,ia,clamp) \
808 if ((ia)!=0) switch ((mode)&LICE_BLIT_MODE_MASK) { \
809 case LICE_BLIT_MODE_COPY: \
810 if ((ia)==256) { if (clamp) { __LICE__ACTION(_LICE_CombinePixelsClobberClamp); } else { __LICE__ACTION(_LICE_CombinePixelsClobberNoClamp); } } \
811 else if ((ia)==128) { if (clamp) { __LICE__ACTION(_LICE_CombinePixelsHalfMixClamp); } else { __LICE__ACTION(_LICE_CombinePixelsHalfMixNoClamp); } } \
812 else if ((ia)>0) { if (clamp) { __LICE__ACTION(_LICE_CombinePixelsCopyClamp); } else { __LICE__ACTION(_LICE_CombinePixelsCopyNoClamp); } } \
813 break; \
814 case LICE_BLIT_MODE_ADD: __LICE__ACTION(_LICE_CombinePixelsAdd); break; \
815 case LICE_BLIT_MODE_DODGE: __LICE__ACTION(_LICE_CombinePixelsColorDodge); break; \
816 case LICE_BLIT_MODE_MUL: if (clamp) { __LICE__ACTION(_LICE_CombinePixelsMulClamp); } else { __LICE__ACTION(_LICE_CombinePixelsMulNoClamp); } break; \
817 case LICE_BLIT_MODE_OVERLAY: __LICE__ACTION(_LICE_CombinePixelsOverlay); break; \
818 case LICE_BLIT_MODE_HSVADJ: __LICE__ACTION(_LICE_CombinePixelsHSVAdjust); break; \
819 }
820
821typedef void (*LICE_COMBINEFUNC)(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha);
822
823#define __LICE_SC(x) do { (x) = ((x)*(__sc))/256; } while (0)
824#define __LICE_SCU(x) do { (x) = ((x)*(__sc))>>8; } while (0)
825
826#endif // _LICE_COMBINE_H_
uint8_t a
Definition Spc_Cpu.h:141
Definition lice_combine.h:473
static void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
Definition lice_combine.h:475
Definition lice_combine.h:488
static void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
Definition lice_combine.h:490
Definition lice_combine.h:260
static void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
Definition lice_combine.h:262
Definition lice_combine.h:269
static void doPixFAST(LICE_pixel *dest, LICE_pixel src)
Definition lice_combine.h:271
Definition lice_combine.h:251
static void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
Definition lice_combine.h:253
Definition lice_combine.h:512
static void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
Definition lice_combine.h:514
Definition lice_combine.h:530
static void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
Definition lice_combine.h:532
Definition lice_combine.h:369
static void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
Definition lice_combine.h:371
Definition lice_combine.h:353
static void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
Definition lice_combine.h:355
Definition lice_combine.h:404
static void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
Definition lice_combine.h:406
static void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
Definition lice_combine.h:448
static void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
Definition lice_combine.h:424
Definition lice_combine.h:385
static void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
Definition lice_combine.h:387
Definition lice_combine.h:695
static void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
Definition lice_combine.h:697
Definition lice_combine.h:722
static void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
Definition lice_combine.h:724
Definition lice_combine.h:315
static void doPixFAST(LICE_pixel *dest, LICE_pixel src)
Definition lice_combine.h:317
Definition lice_combine.h:300
static void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
Definition lice_combine.h:302
Definition lice_combine.h:291
static void doPixFAST(LICE_pixel *dest, LICE_pixel src)
Definition lice_combine.h:293
Definition lice_combine.h:278
static void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
Definition lice_combine.h:280
Definition lice_combine.h:574
static void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
Definition lice_combine.h:576
Definition lice_combine.h:558
static void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
Definition lice_combine.h:560
Definition lice_combine.h:608
static void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
Definition lice_combine.h:610
Definition lice_combine.h:590
static void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
Definition lice_combine.h:592
Definition lice_combine.h:637
static void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
Definition lice_combine.h:639
Definition lice_combine.h:677
static void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
Definition lice_combine.h:679
Definition lice_combine.h:324
static void doPixFAST(LICE_pixel *dest, LICE_pixel src)
Definition lice_combine.h:326
Definition lice_combine.h:334
static void doPixFAST(LICE_pixel *dest, LICE_pixel src)
Definition lice_combine.h:336
Definition lice_combine.h:344
static void doPixFAST(LICE_pixel *dest, LICE_pixel src)
Definition lice_combine.h:346
unsigned v[N_MAX]
Definition inflate.c:1584
unsigned d
Definition inflate.c:940
int g
Definition inflate.c:1573
unsigned s
Definition inflate.c:1555
unsigned f
Definition inflate.c:1572
unsigned short _LICE_RGB2HSV_invtab[256]
Definition lice.cpp:3022
#define LICE_PIXEL_B
Definition lice.h:69
void LICE_HSV2RGB(int h, int s, int v, int *r, int *g, int *b)
#define LICE_RGBA(r, g, b, a)
Definition lice.h:57
LICE_pixel LICE_HSV2Pix(int h, int s, int v, int alpha)
#define LICE_PIXEL_A
Definition lice.h:72
#define LICE_PIXEL_R
Definition lice.h:71
unsigned char LICE_pixel_chan
Definition lice.h:55
unsigned int LICE_pixel
Definition lice.h:54
void LICE_RGB2HSV(int r, int g, int b, int *h, int *s, int *v)
#define lice_min(x, y)
Definition lice.h:335
#define LICE_PIXEL_G
Definition lice.h:70
static void __LICE_LinearFilterI(int *r, int *g, int *b, int *a, const LICE_pixel_chan *pin, const LICE_pixel_chan *pinnext, unsigned int frac)
Definition lice_combine.h:61
#define LICE_PIX_MAKECHAN(a, b)
#define DOCHAN(output, inchan)
static void __LICE_LinearFilterIPixOut(LICE_pixel_chan *out, const LICE_pixel_chan *pin, const LICE_pixel_chan *pinnext, unsigned int frac)
Definition lice_combine.h:69
#define HSV_Q(hval)
Definition lice_combine.h:101
static void _LICE_MakePixelClamp(LICE_pixel_chan *out, int r, int g, int b, int a)
Definition lice_combine.h:78
static void _LICE_MakePixelNoClamp(LICE_pixel_chan *out, LICE_pixel_chan r, LICE_pixel_chan g, LICE_pixel_chan b, LICE_pixel_chan a)
Definition lice_combine.h:88
#define HSV_X
Definition lice_combine.h:103
#define HSV_P
Definition lice_combine.h:100
static void __LICE_BilinearFilterIPixOut(LICE_pixel_chan *out, const LICE_pixel_chan *pin, const LICE_pixel_chan *pinnext, unsigned int xfrac, unsigned int yfrac)
Definition lice_combine.h:32
void(* LICE_COMBINEFUNC)(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha)
Definition lice_combine.h:821
static void __LICE_RGB2HSV(int r, int g, int b, int *h, int *s, int *v)
Definition lice_combine.h:171
#define HSV_T(hval)
Definition lice_combine.h:102
static LICE_pixel __LICE_HSV2Pix(int h, int s, int v, int alpha)
Definition lice_combine.h:110
static void __LICE_HSV2RGB(int h, int s, int v, int *r, int *g, int *b)
Definition lice_combine.h:128
static void __LICE_BilinearFilterI(int *r, int *g, int *b, int *a, const LICE_pixel_chan *pin, const LICE_pixel_chan *pinnext, unsigned int xfrac, unsigned int yfrac)
Definition lice_combine.h:17
static void __LICE_BilinearFilterI_2(int *r, int *g, int *b, int *a, const LICE_pixel_chan *pin, const LICE_pixel_chan *pinnext, int npoffs, unsigned int xfrac, unsigned int yfrac)
Definition lice_combine.h:48
float out
Definition lilv_test.c:1461
int r
Definition crypt.c:458
uch h[RAND_HEAD_LEN]
Definition crypt.c:459
b
Definition crypt.c:628
typedef int(UZ_EXP MsgFn)()
#define void
Definition unzip.h:396