1 /*         ______   ___    ___
2  *        /\  _  \ /\_ \  /\_ \
3  *        \ \ \L\ \\//\ \ \//\ \      __     __   _ __   ___
4  *         \ \  __ \ \ \ \  \ \ \   /'__`\ /'_ `\/\`'__\/ __`\
5  *          \ \ \/\ \ \_\ \_ \_\ \_/\  __//\ \L\ \ \ \//\ \L\ \
6  *           \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7  *            \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
8  *                                           /\____/
9  *                                           \_/__/
10  *
11  *      Interpolation routines for hicolor and truecolor pixels.
12  *
13  *      By Cloud Wu and Burton Radons.
14  *
15  *      Alpha blending optimised by Peter Cech.
16  *
17  *      See readme.txt for copyright information.
18  */
19 
20 
21 #include "allegro.h"
22 #include "allegro/internal/aintern.h"
23 
24 
25 
26 #define BLEND(bpp, r, g, b)   _blender_trans##bpp(makecol##bpp(r, g, b), y, n)
27 
28 #define T(x, y, n)            (((y) - (x)) * (n) / 255 + (x))
29 
30 
31 
32 /* _blender_black:
33  *  Fallback routine for when we don't have anything better to do.
34  */
_blender_black(unsigned long x,unsigned long y,unsigned long n)35 unsigned long _blender_black(unsigned long x, unsigned long y, unsigned long n)
36 {
37    return 0;
38 }
39 
40 
41 
42 #if (defined ALLEGRO_COLOR24) || (defined ALLEGRO_COLOR32)
43 
44 
45 
46 #if (defined ALLEGRO_NO_ASM) || (!defined ALLEGRO_I386)
47 				    /* i386 asm version is in imisc.s */
48 
49 
50 /* _blender_trans24:
51  *  24 bit trans blender function.
52  */
_blender_trans24(unsigned long x,unsigned long y,unsigned long n)53 unsigned long _blender_trans24(unsigned long x, unsigned long y, unsigned long n)
54 {
55    unsigned long res, g;
56 
57    if (n)
58       n++;
59 
60    res = ((x & 0xFF00FF) - (y & 0xFF00FF)) * n / 256 + y;
61    y &= 0xFF00;
62    x &= 0xFF00;
63    g = (x - y) * n / 256 + y;
64 
65    res &= 0xFF00FF;
66    g &= 0xFF00;
67 
68    return res | g;
69 }
70 
71 
72 #endif      /* C version */
73 
74 
75 
76 /* _blender_alpha24:
77  *  Combines a 32 bit RGBA sprite with a 24 bit RGB destination.
78  */
_blender_alpha24(unsigned long x,unsigned long y,unsigned long n)79 unsigned long _blender_alpha24(unsigned long x, unsigned long y, unsigned long n)
80 {
81    unsigned long xx = makecol24(getr32(x), getg32(x), getb32(x));
82    unsigned long res, g;
83 
84    n = geta32(x);
85 
86    if (n)
87       n++;
88 
89    res = ((xx & 0xFF00FF) - (y & 0xFF00FF)) * n / 256 + y;
90    y &= 0xFF00;
91    xx &= 0xFF00;
92    g = (xx - y) * n / 256 + y;
93 
94    res &= 0xFF00FF;
95    g &= 0xFF00;
96 
97    return res | g;
98 }
99 
100 
101 
102 /* _blender_alpha32:
103  *  Combines a 32 bit RGBA sprite with a 32 bit RGB destination.
104  */
_blender_alpha32(unsigned long x,unsigned long y,unsigned long n)105 unsigned long _blender_alpha32(unsigned long x, unsigned long y, unsigned long n)
106 {
107    unsigned long res, g;
108 
109    n = geta32(x);
110 
111    if (n)
112       n++;
113 
114    res = ((x & 0xFF00FF) - (y & 0xFF00FF)) * n / 256 + y;
115    y &= 0xFF00;
116    x &= 0xFF00;
117    g = (x - y) * n / 256 + y;
118 
119    res &= 0xFF00FF;
120    g &= 0xFF00;
121 
122    return res | g;
123 }
124 
125 
126 
127 /* _blender_alpha24_bgr:
128  *  Combines a 32 bit RGBA sprite with a 24 bit RGB destination, optimised
129  *  for when one is in a BGR format and the other is RGB.
130  */
_blender_alpha24_bgr(unsigned long x,unsigned long y,unsigned long n)131 unsigned long _blender_alpha24_bgr(unsigned long x, unsigned long y, unsigned long n)
132 {
133    unsigned long res, g;
134 
135    n = x >> 24;
136 
137    if (n)
138       n++;
139 
140    x = ((x>>16)&0xFF) | (x&0xFF00) | ((x<<16)&0xFF0000);
141 
142    res = ((x & 0xFF00FF) - (y & 0xFF00FF)) * n / 256 + y;
143    y &= 0xFF00;
144    x &= 0xFF00;
145    g = (x - y) * n / 256 + y;
146 
147    res &= 0xFF00FF;
148    g &= 0xFF00;
149 
150    return res | g;
151 }
152 
153 
154 
155 /* _blender_add24:
156  *  24 bit additive blender function.
157  */
_blender_add24(unsigned long x,unsigned long y,unsigned long n)158 unsigned long _blender_add24(unsigned long x, unsigned long y, unsigned long n)
159 {
160    int r = getr24(y) + getr24(x) * n / 256;
161    int g = getg24(y) + getg24(x) * n / 256;
162    int b = getb24(y) + getb24(x) * n / 256;
163 
164    r = MIN(r, 255);
165    g = MIN(g, 255);
166    b = MIN(b, 255);
167 
168    return makecol24(r, g, b);
169 }
170 
171 
172 
173 /* _blender_burn24:
174  *  24 bit burn blender function.
175  */
_blender_burn24(unsigned long x,unsigned long y,unsigned long n)176 unsigned long _blender_burn24(unsigned long x, unsigned long y, unsigned long n)
177 {
178    return BLEND(24, MAX(getr24(x) - getr24(y), 0),
179 		    MAX(getg24(x) - getg24(y), 0),
180 		    MAX(getb24(x) - getb24(y), 0));
181 }
182 
183 
184 
185 /* _blender_color24:
186  *  24 bit color blender function.
187  */
_blender_color24(unsigned long x,unsigned long y,unsigned long n)188 unsigned long _blender_color24(unsigned long x, unsigned long y, unsigned long n)
189 {
190    float xh, xs, xv;
191    float yh, ys, yv;
192    int r, g, b;
193 
194    rgb_to_hsv(getr24(x), getg24(x), getb24(x), &xh, &xs, &xv);
195    rgb_to_hsv(getr24(y), getg24(y), getb24(y), &yh, &ys, &yv);
196 
197    xs = T(xs, ys, n);
198    xh = T(xh, yh, n);
199 
200    hsv_to_rgb(xh, xs, xv, &r, &g, &b);
201 
202    return makecol24(r, g, b);
203 }
204 
205 
206 
207 /* _blender_difference24:
208  *  24 bit difference blender function.
209  */
_blender_difference24(unsigned long x,unsigned long y,unsigned long n)210 unsigned long _blender_difference24(unsigned long x, unsigned long y, unsigned long n)
211 {
212    return BLEND(24, ABS(getr24(y) - getr24(x)),
213 		    ABS(getg24(y) - getg24(x)),
214 		    ABS(getb24(y) - getb24(x)));
215 }
216 
217 
218 
219 /* _blender_dissolve24:
220  *  24 bit dissolve blender function.
221  */
_blender_dissolve24(unsigned long x,unsigned long y,unsigned long n)222 unsigned long _blender_dissolve24(unsigned long x, unsigned long y, unsigned long n)
223 {
224    if (n == 255)
225       return x;
226 
227    return ((_al_rand() & 255) < (int)n) ? x : y;
228 }
229 
230 
231 
232 /* _blender_dodge24:
233  *  24 bit dodge blender function.
234  */
_blender_dodge24(unsigned long x,unsigned long y,unsigned long n)235 unsigned long _blender_dodge24(unsigned long x, unsigned long y, unsigned long n)
236 {
237    return BLEND(24, getr24(x) + (getr24(y) * n / 256),
238 		    getg24(x) + (getg24(y) * n / 256),
239 		    getb24(x) + (getb24(y) * n / 256));
240 }
241 
242 
243 
244 /* _blender_hue24:
245  *  24 bit hue blender function.
246  */
_blender_hue24(unsigned long x,unsigned long y,unsigned long n)247 unsigned long _blender_hue24(unsigned long x, unsigned long y, unsigned long n)
248 {
249    float xh, xs, xv;
250    float yh, ys, yv;
251    int r, g, b;
252 
253    rgb_to_hsv(getr24(x), getg24(x), getb24(x), &xh, &xs, &xv);
254    rgb_to_hsv(getr24(y), getg24(y), getb24(y), &yh, &ys, &yv);
255 
256    xh = T(xh, yh, n);
257 
258    hsv_to_rgb(xh, xs, xv, &r, &g, &b);
259 
260    return makecol24(r, g, b);
261 }
262 
263 
264 
265 /* _blender_invert24:
266  *  24 bit invert blender function.
267  */
_blender_invert24(unsigned long x,unsigned long y,unsigned long n)268 unsigned long _blender_invert24(unsigned long x, unsigned long y, unsigned long n)
269 {
270    return BLEND(24, 255-getr24(x), 255-getg24(x), 255-getb24(x));
271 }
272 
273 
274 
275 /* _blender_luminance24:
276  *  24 bit luminance blender function.
277  */
_blender_luminance24(unsigned long x,unsigned long y,unsigned long n)278 unsigned long _blender_luminance24(unsigned long x, unsigned long y, unsigned long n)
279 {
280    float xh, xs, xv;
281    float yh, ys, yv;
282    int r, g, b;
283 
284    rgb_to_hsv(getr24(x), getg24(x), getb24(x), &xh, &xs, &xv);
285    rgb_to_hsv(getr24(y), getg24(y), getb24(y), &yh, &ys, &yv);
286 
287    xv = T(xv, yv, n);
288 
289    hsv_to_rgb(xh, xs, xv, &r, &g, &b);
290 
291    return makecol24(r, g, b);
292 }
293 
294 
295 
296 /* _blender_multiply24:
297  *  24 bit multiply blender function.
298  */
_blender_multiply24(unsigned long x,unsigned long y,unsigned long n)299 unsigned long _blender_multiply24(unsigned long x, unsigned long y, unsigned long n)
300 {
301    return BLEND(24, getr24(x) * getr24(y) / 256,
302 		    getg24(x) * getg24(y) / 256,
303 		    getb24(x) * getb24(y) / 256);
304 }
305 
306 
307 
308 /* _blender_saturation24:
309  *  24 bit saturation blender function.
310  */
_blender_saturation24(unsigned long x,unsigned long y,unsigned long n)311 unsigned long _blender_saturation24(unsigned long x, unsigned long y, unsigned long n)
312 {
313    float xh, xs, xv;
314    float yh, ys, yv;
315    int r, g, b;
316 
317    rgb_to_hsv(getr24(x), getg24(x), getb24(x), &xh, &xs, &xv);
318    rgb_to_hsv(getr24(y), getg24(y), getb24(y), &yh, &ys, &yv);
319 
320    xs = T(xs, ys, n);
321 
322    hsv_to_rgb(xh, xs, xv, &r, &g, &b);
323 
324    return makecol24(r, g, b);
325 }
326 
327 
328 
329 /* _blender_screen24:
330  *  24 bit screen blender function.
331  */
_blender_screen24(unsigned long x,unsigned long y,unsigned long n)332 unsigned long _blender_screen24(unsigned long x, unsigned long y, unsigned long n)
333 {
334    return BLEND(24, 255 - ((255 - getr24(x)) * (255 - getr24(y))) / 256,
335 		    255 - ((255 - getg24(x)) * (255 - getg24(y))) / 256,
336 		    255 - ((255 - getb24(x)) * (255 - getb24(y))) / 256);
337 }
338 
339 
340 
341 #endif      /* end of 24/32 bit routines */
342 
343 
344 #if (defined ALLEGRO_COLOR15) || (defined ALLEGRO_COLOR16)
345 
346 
347 
348 /* _blender_trans16:
349  *  16 bit trans blender function.
350  */
_blender_trans16(unsigned long x,unsigned long y,unsigned long n)351 unsigned long _blender_trans16(unsigned long x, unsigned long y, unsigned long n)
352 {
353    unsigned long result;
354 
355    if (n)
356       n = (n + 1) / 8;
357 
358    x = ((x & 0xFFFF) | (x << 16)) & 0x7E0F81F;
359    y = ((y & 0xFFFF) | (y << 16)) & 0x7E0F81F;
360 
361    result = ((x - y) * n / 32 + y) & 0x7E0F81F;
362 
363    return ((result & 0xFFFF) | (result >> 16));
364 }
365 
366 
367 
368 /* _blender_alpha16:
369  *  Combines a 32 bit RGBA sprite with a 16 bit RGB destination.
370  */
_blender_alpha16(unsigned long x,unsigned long y,unsigned long n)371 unsigned long _blender_alpha16(unsigned long x, unsigned long y, unsigned long n)
372 {
373    unsigned long result;
374 
375    n = geta32(x);
376 
377    if (n)
378       n = (n + 1) / 8;
379 
380    x = makecol16(getr32(x), getg32(x), getb32(x));
381 
382    x = (x | (x << 16)) & 0x7E0F81F;
383    y = ((y & 0xFFFF) | (y << 16)) & 0x7E0F81F;
384 
385    result = ((x - y) * n / 32 + y) & 0x7E0F81F;
386 
387    return ((result & 0xFFFF) | (result >> 16));
388 }
389 
390 
391 
392 /* _blender_alpha16_rgb
393  *  Combines a 32 bit RGBA sprite with a 16 bit RGB destination, optimised
394  *  for when both pixels are in an RGB layout.
395  */
_blender_alpha16_rgb(unsigned long x,unsigned long y,unsigned long n)396 unsigned long _blender_alpha16_rgb(unsigned long x, unsigned long y, unsigned long n)
397 {
398    unsigned long result;
399 
400    n = x >> 24;
401 
402    if (n)
403       n = (n + 1) / 8;
404 
405    x = ((x>>3)&0x001F) | ((x>>5)&0x07E0) | ((x>>8)&0xF800);
406 
407    x = (x | (x << 16)) & 0x7E0F81F;
408    y = ((y & 0xFFFF) | (y << 16)) & 0x7E0F81F;
409 
410    result = ((x - y) * n / 32 + y) & 0x7E0F81F;
411 
412    return ((result & 0xFFFF) | (result >> 16));
413 }
414 
415 
416 
417 /* _blender_alpha16_bgr
418  *  Combines a 32 bit RGBA sprite with a 16 bit RGB destination, optimised
419  *  for when one pixel is in an RGB layout and the other is BGR.
420  */
_blender_alpha16_bgr(unsigned long x,unsigned long y,unsigned long n)421 unsigned long _blender_alpha16_bgr(unsigned long x, unsigned long y, unsigned long n)
422 {
423    unsigned long result;
424 
425    n = x >> 24;
426 
427    if (n)
428       n = (n + 1) / 8;
429 
430    x = ((x>>19)&0x001F) | ((x>>5)&0x07E0) | ((x<<8)&0xF800);
431 
432    x = (x | (x << 16)) & 0x7E0F81F;
433    y = ((y & 0xFFFF) | (y << 16)) & 0x7E0F81F;
434 
435    result = ((x - y) * n / 32 + y) & 0x7E0F81F;
436 
437    return ((result & 0xFFFF) | (result >> 16));
438 }
439 
440 
441 
442 /* _blender_add16:
443  *  16 bit additive blender function.
444  */
_blender_add16(unsigned long x,unsigned long y,unsigned long n)445 unsigned long _blender_add16(unsigned long x, unsigned long y, unsigned long n)
446 {
447    int r = getr16(y) + getr16(x) * n / 256;
448    int g = getg16(y) + getg16(x) * n / 256;
449    int b = getb16(y) + getb16(x) * n / 256;
450 
451    r = MIN(r, 255);
452    g = MIN(g, 255);
453    b = MIN(b, 255);
454 
455    return makecol16(r, g, b);
456 }
457 
458 
459 
460 /* _blender_burn16:
461  *  16 bit burn blender function.
462  */
_blender_burn16(unsigned long x,unsigned long y,unsigned long n)463 unsigned long _blender_burn16(unsigned long x, unsigned long y, unsigned long n)
464 {
465    return BLEND(16, MAX(getr16(x) - getr16(y), 0),
466 		    MAX(getg16(x) - getg16(y), 0),
467 		    MAX(getb16(x) - getb16(y), 0));
468 }
469 
470 
471 
472 /* _blender_color16:
473  *  16 bit color blender function.
474  */
_blender_color16(unsigned long x,unsigned long y,unsigned long n)475 unsigned long _blender_color16(unsigned long x, unsigned long y, unsigned long n)
476 {
477    float xh, xs, xv;
478    float yh, ys, yv;
479    int r, g, b;
480 
481    rgb_to_hsv(getr16(x), getg16(x), getb16(x), &xh, &xs, &xv);
482    rgb_to_hsv(getr16(y), getg16(y), getb16(y), &yh, &ys, &yv);
483 
484    xs = T(xs, ys, n);
485    xh = T(xh, yh, n);
486 
487    hsv_to_rgb(xh, xs, xv, &r, &g, &b);
488 
489    return makecol16(r, g, b);
490 }
491 
492 
493 
494 /* _blender_difference16:
495  *  16 bit difference blender function.
496  */
_blender_difference16(unsigned long x,unsigned long y,unsigned long n)497 unsigned long _blender_difference16(unsigned long x, unsigned long y, unsigned long n)
498 {
499    return BLEND(16, ABS(getr16(y) - getr16(x)),
500 		    ABS(getg16(y) - getg16(x)),
501 		    ABS(getb16(y) - getb16(x)));
502 }
503 
504 
505 
506 /* _blender_dissolve16:
507  *  16 bit dissolve blender function.
508  */
_blender_dissolve16(unsigned long x,unsigned long y,unsigned long n)509 unsigned long _blender_dissolve16(unsigned long x, unsigned long y, unsigned long n)
510 {
511    if (n == 255)
512       return x;
513 
514    return ((_al_rand() & 255) < (int)n) ? x : y;
515 }
516 
517 
518 
519 /* _blender_dodge16:
520  *  16 bit dodge blender function.
521  */
_blender_dodge16(unsigned long x,unsigned long y,unsigned long n)522 unsigned long _blender_dodge16(unsigned long x, unsigned long y, unsigned long n)
523 {
524    return BLEND(16, getr16(x) + (getr16(y) * n / 256),
525 		    getg16(x) + (getg16(y) * n / 256),
526 		    getb16(x) + (getb16(y) * n / 256));
527 }
528 
529 
530 
531 /* _blender_hue16:
532  *  16 bit hue blender function.
533  */
_blender_hue16(unsigned long x,unsigned long y,unsigned long n)534 unsigned long _blender_hue16(unsigned long x, unsigned long y, unsigned long n)
535 {
536    float xh, xs, xv;
537    float yh, ys, yv;
538    int r, g, b;
539 
540    rgb_to_hsv(getr16(x), getg16(x), getb16(x), &xh, &xs, &xv);
541    rgb_to_hsv(getr16(y), getg16(y), getb16(y), &yh, &ys, &yv);
542 
543    xh = T(xh, yh, n);
544 
545    hsv_to_rgb(xh, xs, xv, &r, &g, &b);
546 
547    return makecol16(r, g, b);
548 }
549 
550 
551 
552 /* _blender_invert16:
553  *  16 bit invert blender function.
554  */
_blender_invert16(unsigned long x,unsigned long y,unsigned long n)555 unsigned long _blender_invert16(unsigned long x, unsigned long y, unsigned long n)
556 {
557    return BLEND(16, 255-getr16(x), 255-getg16(x), 255-getb16(x));
558 }
559 
560 
561 
562 /* _blender_luminance16:
563  *  16 bit luminance blender function.
564  */
_blender_luminance16(unsigned long x,unsigned long y,unsigned long n)565 unsigned long _blender_luminance16(unsigned long x, unsigned long y, unsigned long n)
566 {
567    float xh, xs, xv;
568    float yh, ys, yv;
569    int r, g, b;
570 
571    rgb_to_hsv(getr16(x), getg16(x), getb16(x), &xh, &xs, &xv);
572    rgb_to_hsv(getr16(y), getg16(y), getb16(y), &yh, &ys, &yv);
573 
574    xv = T(xv, yv, n);
575 
576    hsv_to_rgb(xh, xs, xv, &r, &g, &b);
577 
578    return makecol16(r, g, b);
579 }
580 
581 
582 
583 /* _blender_multiply16:
584  *  16 bit multiply blender function.
585  */
_blender_multiply16(unsigned long x,unsigned long y,unsigned long n)586 unsigned long _blender_multiply16(unsigned long x, unsigned long y, unsigned long n)
587 {
588    return BLEND(16, getr16(x) * getr16(y) / 256,
589 		    getg16(x) * getg16(y) / 256,
590 		    getb16(x) * getb16(y) / 256);
591 }
592 
593 
594 
595 /* _blender_saturation16:
596  *  16 bit saturation blender function.
597  */
_blender_saturation16(unsigned long x,unsigned long y,unsigned long n)598 unsigned long _blender_saturation16(unsigned long x, unsigned long y, unsigned long n)
599 {
600    float xh, xs, xv;
601    float yh, ys, yv;
602    int r, g, b;
603 
604    rgb_to_hsv(getr16(x), getg16(x), getb16(x), &xh, &xs, &xv);
605    rgb_to_hsv(getr16(y), getg16(y), getb16(y), &yh, &ys, &yv);
606 
607    xs = T(xs, ys, n);
608 
609    hsv_to_rgb(xh, xs, xv, &r, &g, &b);
610 
611    return makecol16(r, g, b);
612 }
613 
614 
615 
616 /* _blender_screen16:
617  *  16 bit screen blender function.
618  */
_blender_screen16(unsigned long x,unsigned long y,unsigned long n)619 unsigned long _blender_screen16(unsigned long x, unsigned long y, unsigned long n)
620 {
621    return BLEND(16, 255 - ((255 - getr16(x)) * (255 - getr16(y))) / 256,
622 		    255 - ((255 - getg16(x)) * (255 - getg16(y))) / 256,
623 		    255 - ((255 - getb16(x)) * (255 - getb16(y))) / 256);
624 }
625 
626 
627 
628 /* _blender_trans15:
629  *  15 bit trans blender function.
630  */
_blender_trans15(unsigned long x,unsigned long y,unsigned long n)631 unsigned long _blender_trans15(unsigned long x, unsigned long y, unsigned long n)
632 {
633    unsigned long result;
634 
635    if (n)
636       n = (n + 1) / 8;
637 
638    x = ((x & 0xFFFF) | (x << 16)) & 0x3E07C1F;
639    y = ((y & 0xFFFF) | (y << 16)) & 0x3E07C1F;
640 
641    result = ((x - y) * n / 32 + y) & 0x3E07C1F;
642 
643    return ((result & 0xFFFF) | (result >> 16));
644 }
645 
646 
647 
648 /* _blender_alpha15:
649  *  Combines a 32 bit RGBA sprite with a 15 bit RGB destination.
650  */
_blender_alpha15(unsigned long x,unsigned long y,unsigned long n)651 unsigned long _blender_alpha15(unsigned long x, unsigned long y, unsigned long n)
652 {
653    unsigned long result;
654 
655    n = geta32(x);
656 
657    if (n)
658       n = (n + 1) / 8;
659 
660    x = makecol15(getr32(x), getg32(x), getb32(x));
661 
662    x = (x | (x << 16)) & 0x3E07C1F;
663    y = ((y & 0xFFFF) | (y << 16)) & 0x3E07C1F;
664 
665    result = ((x - y) * n / 32 + y) & 0x3E07C1F;
666 
667    return ((result & 0xFFFF) | (result >> 16));
668 }
669 
670 
671 
672 /* _blender_alpha15_rgb
673  *  Combines a 32 bit RGBA sprite with a 15 bit RGB destination, optimised
674  *  for when both pixels are in an RGB layout.
675  */
_blender_alpha15_rgb(unsigned long x,unsigned long y,unsigned long n)676 unsigned long _blender_alpha15_rgb(unsigned long x, unsigned long y, unsigned long n)
677 {
678    unsigned long result;
679 
680    n = x >> 24;
681 
682    if (n)
683       n = (n + 1) / 8;
684 
685    x = ((x>>3)&0x001F) | ((x>>6)&0x03E0) | ((x>>9)&0xEC00);
686 
687    x = (x | (x << 16)) & 0x3E07C1F;
688    y = ((y & 0xFFFF) | (y << 16)) & 0x3E07C1F;
689 
690    result = ((x - y) * n / 32 + y) & 0x3E07C1F;
691 
692    return ((result & 0xFFFF) | (result >> 16));
693 }
694 
695 
696 
697 /* _blender_alpha15_bgr
698  *  Combines a 32 bit RGBA sprite with a 15 bit RGB destination, optimised
699  *  for when one pixel is in an RGB layout and the other is BGR.
700  */
_blender_alpha15_bgr(unsigned long x,unsigned long y,unsigned long n)701 unsigned long _blender_alpha15_bgr(unsigned long x, unsigned long y, unsigned long n)
702 {
703    unsigned long result;
704 
705    n = x >> 24;
706 
707    if (n)
708       n = (n + 1) / 8;
709 
710    x = ((x>>19)&0x001F) | ((x>>6)&0x03E0) | ((x<<7)&0xEC00);
711 
712    x = (x | (x << 16)) & 0x3E07C1F;
713    y = ((y & 0xFFFF) | (y << 16)) & 0x3E07C1F;
714 
715    result = ((x - y) * n / 32 + y) & 0x3E07C1F;
716 
717    return ((result & 0xFFFF) | (result >> 16));
718 }
719 
720 
721 
722 /* _blender_add15:
723  *  15 bit additive blender function.
724  */
_blender_add15(unsigned long x,unsigned long y,unsigned long n)725 unsigned long _blender_add15(unsigned long x, unsigned long y, unsigned long n)
726 {
727    int r = getr15(y) + getr15(x) * n / 256;
728    int g = getg15(y) + getg15(x) * n / 256;
729    int b = getb15(y) + getb15(x) * n / 256;
730 
731    r = MIN(r, 255);
732    g = MIN(g, 255);
733    b = MIN(b, 255);
734 
735    return makecol15(r, g, b);
736 }
737 
738 
739 
740 /* _blender_burn15:
741  *  15 bit burn blender function.
742  */
_blender_burn15(unsigned long x,unsigned long y,unsigned long n)743 unsigned long _blender_burn15(unsigned long x, unsigned long y, unsigned long n)
744 {
745    return BLEND(15, MAX(getr15(x) - getr15(y), 0),
746 		    MAX(getg15(x) - getg15(y), 0),
747 		    MAX(getb15(x) - getb15(y), 0));
748 }
749 
750 
751 
752 /* _blender_color15:
753  *  15 bit color blender function.
754  */
_blender_color15(unsigned long x,unsigned long y,unsigned long n)755 unsigned long _blender_color15(unsigned long x, unsigned long y, unsigned long n)
756 {
757    float xh, xs, xv;
758    float yh, ys, yv;
759    int r, g, b;
760 
761    rgb_to_hsv(getr15(x), getg15(x), getb15(x), &xh, &xs, &xv);
762    rgb_to_hsv(getr15(y), getg15(y), getb15(y), &yh, &ys, &yv);
763 
764    xs = T(xs, ys, n);
765    xh = T(xh, yh, n);
766 
767    hsv_to_rgb(xh, xs, xv, &r, &g, &b);
768 
769    return makecol15(r, g, b);
770 }
771 
772 
773 
774 /* _blender_difference15:
775  *  15 bit difference blender function.
776  */
_blender_difference15(unsigned long x,unsigned long y,unsigned long n)777 unsigned long _blender_difference15(unsigned long x, unsigned long y, unsigned long n)
778 {
779    return BLEND(15, ABS(getr15(y) - getr15(x)),
780 		    ABS(getg15(y) - getg15(x)),
781 		    ABS(getb15(y) - getb15(x)));
782 }
783 
784 
785 
786 /* _blender_dissolve15:
787  *  15 bit dissolve blender function.
788  */
_blender_dissolve15(unsigned long x,unsigned long y,unsigned long n)789 unsigned long _blender_dissolve15(unsigned long x, unsigned long y, unsigned long n)
790 {
791    if (n == 255)
792       return x;
793 
794    return ((_al_rand() & 255) < (int)n) ? x : y;
795 }
796 
797 
798 
799 /* _blender_dodge15:
800  *  15 bit dodge blender function.
801  */
_blender_dodge15(unsigned long x,unsigned long y,unsigned long n)802 unsigned long _blender_dodge15(unsigned long x, unsigned long y, unsigned long n)
803 {
804    return BLEND(15, getr15(x) + (getr15(y) * n / 256),
805 		    getg15(x) + (getg15(y) * n / 256),
806 		    getb15(x) + (getb15(y) * n / 256));
807 }
808 
809 
810 
811 /* _blender_hue15:
812  *  15 bit hue blender function.
813  */
_blender_hue15(unsigned long x,unsigned long y,unsigned long n)814 unsigned long _blender_hue15(unsigned long x, unsigned long y, unsigned long n)
815 {
816    float xh, xs, xv;
817    float yh, ys, yv;
818    int r, g, b;
819 
820    rgb_to_hsv(getr15(x), getg15(x), getb15(x), &xh, &xs, &xv);
821    rgb_to_hsv(getr15(y), getg15(y), getb15(y), &yh, &ys, &yv);
822 
823    xh = T(xh, yh, n);
824 
825    hsv_to_rgb(xh, xs, xv, &r, &g, &b);
826 
827    return makecol15(r, g, b);
828 }
829 
830 
831 
832 /* _blender_invert15:
833  *  15 bit invert blender function.
834  */
_blender_invert15(unsigned long x,unsigned long y,unsigned long n)835 unsigned long _blender_invert15(unsigned long x, unsigned long y, unsigned long n)
836 {
837    return BLEND(15, 255-getr15(x), 255-getg15(x), 255-getb15(x));
838 }
839 
840 
841 
842 /* _blender_luminance15:
843  *  15 bit luminance blender function.
844  */
_blender_luminance15(unsigned long x,unsigned long y,unsigned long n)845 unsigned long _blender_luminance15(unsigned long x, unsigned long y, unsigned long n)
846 {
847    float xh, xs, xv;
848    float yh, ys, yv;
849    int r, g, b;
850 
851    rgb_to_hsv(getr15(x), getg15(x), getb15(x), &xh, &xs, &xv);
852    rgb_to_hsv(getr15(y), getg15(y), getb15(y), &yh, &ys, &yv);
853 
854    xv = T(xv, yv, n);
855 
856    hsv_to_rgb(xh, xs, xv, &r, &g, &b);
857 
858    return makecol15(r, g, b);
859 }
860 
861 
862 
863 /* _blender_multiply15:
864  *  15 bit multiply blender function.
865  */
_blender_multiply15(unsigned long x,unsigned long y,unsigned long n)866 unsigned long _blender_multiply15(unsigned long x, unsigned long y, unsigned long n)
867 {
868    return BLEND(15, getr15(x) * getr15(y) / 256,
869 		    getg15(x) * getg15(y) / 256,
870 		    getb15(x) * getb15(y) / 256);
871 }
872 
873 
874 
875 /* _blender_saturation15:
876  *  15 bit saturation blender function.
877  */
_blender_saturation15(unsigned long x,unsigned long y,unsigned long n)878 unsigned long _blender_saturation15(unsigned long x, unsigned long y, unsigned long n)
879 {
880    float xh, xs, xv;
881    float yh, ys, yv;
882    int r, g, b;
883 
884    rgb_to_hsv(getr15(x), getg15(x), getb15(x), &xh, &xs, &xv);
885    rgb_to_hsv(getr15(y), getg15(y), getb15(y), &yh, &ys, &yv);
886 
887    xs = T(xs, ys, n);
888 
889    hsv_to_rgb(xh, xs, xv, &r, &g, &b);
890 
891    return makecol15(r, g, b);
892 }
893 
894 
895 
896 /* _blender_screen15:
897  *  15 bit screen blender function.
898  */
_blender_screen15(unsigned long x,unsigned long y,unsigned long n)899 unsigned long _blender_screen15(unsigned long x, unsigned long y, unsigned long n)
900 {
901    return BLEND(15, 255 - ((255 - getr15(x)) * (255 - getr15(y))) / 256,
902 		    255 - ((255 - getg15(x)) * (255 - getg15(y))) / 256,
903 		    255 - ((255 - getb15(x)) * (255 - getb15(y))) / 256);
904 }
905 
906 
907 
908 #endif      /* end of 15/16 bit routines */
909 
910 
911 
912 #ifdef ALLEGRO_COLOR16
913    #define BF16(name)   name
914 #else
915    #define BF16(name)   _blender_black
916 #endif
917 
918 
919 #if (defined ALLEGRO_COLOR24) || (defined ALLEGRO_COLOR32)
920    #define BF24(name)   name
921 #else
922    #define BF24(name)   _blender_black
923 #endif
924 
925 
926 
927 /* these functions are all the same, so we can generate them with a macro */
928 #define SET_BLENDER_FUNC(name)                                 \
929    void set_##name##_blender(int r, int g, int b, int a)       \
930    {                                                           \
931       if (gfx_driver && gfx_driver->set_blender_mode)          \
932          gfx_driver->set_blender_mode(blender_mode_##name, r, g, b, a);\
933       set_blender_mode(BF16(_blender_##name##15),              \
934 		       BF16(_blender_##name##16),              \
935 		       BF24(_blender_##name##24),              \
936 		       r, g, b, a);                            \
937    }
938 
939 
940 SET_BLENDER_FUNC(trans);
941 SET_BLENDER_FUNC(add);
942 SET_BLENDER_FUNC(burn);
943 SET_BLENDER_FUNC(color);
944 SET_BLENDER_FUNC(difference);
945 SET_BLENDER_FUNC(dissolve);
946 SET_BLENDER_FUNC(dodge);
947 SET_BLENDER_FUNC(hue);
948 SET_BLENDER_FUNC(invert);
949 SET_BLENDER_FUNC(luminance);
950 SET_BLENDER_FUNC(multiply);
951 SET_BLENDER_FUNC(saturation);
952 SET_BLENDER_FUNC(screen);
953 
954 
955 
956 /* set_alpha_blender:
957  *  Sets the special RGBA blending mode.
958  */
set_alpha_blender(void)959 void set_alpha_blender(void)
960 {
961    BLENDER_FUNC f15, f16, f24, f32;
962    int r, b;
963 
964    /* Call gfx_driver->set_blender_mode() for hardware acceleration */
965    if (gfx_driver && gfx_driver->set_blender_mode)
966       gfx_driver->set_blender_mode(blender_mode_alpha, 0, 0, 0, 0);
967 
968    /* check which way around the 32 bit pixels are */
969    if ((_rgb_g_shift_32 == 8) && (_rgb_a_shift_32 == 24)) {
970       r = (_rgb_r_shift_32) ? 1 : 0;
971       b = (_rgb_b_shift_32) ? 1 : 0;
972    }
973    else
974       r = b = 0;
975 
976    #ifdef ALLEGRO_COLOR16
977 
978       /* decide which 15 bit blender to use */
979       if ((_rgb_r_shift_15 == r*10) && (_rgb_g_shift_15 == 5) && (_rgb_b_shift_15 == b*10))
980 	 f15 = _blender_alpha15_rgb;
981       else if ((_rgb_r_shift_15 == b*10) && (_rgb_g_shift_15 == 5) && (_rgb_b_shift_15 == r*10))
982 	 f15 = _blender_alpha15_bgr;
983       else
984 	 f15 = _blender_alpha15;
985 
986       /* decide which 16 bit blender to use */
987       if ((_rgb_r_shift_16 == r*11) && (_rgb_g_shift_16 == 5) && (_rgb_b_shift_16 == b*11))
988 	 f16 = _blender_alpha16_rgb;
989       else if ((_rgb_r_shift_16 == b*11) && (_rgb_g_shift_16 == 5) && (_rgb_b_shift_16 == r*11))
990 	 f16 = _blender_alpha16_bgr;
991       else
992 	 f16 = _blender_alpha16;
993 
994    #else
995 
996       /* hicolor not included in this build */
997       f15 = _blender_black;
998       f16 = _blender_black;
999 
1000    #endif
1001 
1002    #ifdef ALLEGRO_COLOR24
1003 
1004       /* decide which 24 bit blender to use */
1005       if ((_rgb_r_shift_24 == r*16) && (_rgb_g_shift_24 == 8) && (_rgb_b_shift_24 == b*16))
1006 	 f24 = _blender_alpha32;
1007       else if ((_rgb_r_shift_24 == b*16) && (_rgb_g_shift_24 == 8) && (_rgb_b_shift_24 == r*16))
1008 	 f24 = _blender_alpha24_bgr;
1009       else
1010 	 f24 = _blender_alpha24;
1011 
1012    #else
1013 
1014       /* 24 bit color not included in this build */
1015       f24 = _blender_black;
1016 
1017    #endif
1018 
1019    #ifdef ALLEGRO_COLOR32
1020       f32 = _blender_alpha32;
1021    #else
1022       f32 = _blender_black;
1023    #endif
1024 
1025    set_blender_mode_ex(_blender_black, _blender_black, _blender_black,
1026 		       f32, f15, f16, f24, 0, 0, 0, 0);
1027 }
1028 
1029 
1030 
1031 #ifdef ALLEGRO_COLOR32
1032 
1033 /* _blender_write_alpha:
1034  *  Overlays an alpha channel onto an existing 32 bit RGBA bitmap.
1035  */
_blender_write_alpha(unsigned long x,unsigned long y,unsigned long n)1036 unsigned long _blender_write_alpha(unsigned long x, unsigned long y, unsigned long n)
1037 {
1038    return (y & 0xFFFFFF) | (x << 24);
1039 }
1040 
1041 #endif
1042 
1043 
1044 
1045 /* set_write_alpha_blender:
1046  *  Sets the special RGBA editing mode.
1047  */
set_write_alpha_blender(void)1048 void set_write_alpha_blender(void)
1049 {
1050    BLENDER_FUNC f32;
1051 
1052    #ifdef ALLEGRO_COLOR32
1053       f32 = _blender_write_alpha;
1054    #else
1055       f32 = _blender_black;
1056    #endif
1057 
1058    set_blender_mode_ex(_blender_black, _blender_black, _blender_black,
1059 		       f32,
1060 		       _blender_black, _blender_black, _blender_black,
1061 		       0, 0, 0, 0);
1062 }
1063 
1064