1 #include "common.h"
2 
3 #include "blend.h"
4 #include "colormod.h"
5 #include "image.h"
6 #include "span.h"
7 
8 #define ADD_COPY(r, g, b, dest) \
9 do { \
10                 ADD_COLOR(R_VAL(dest), r, R_VAL(dest)); \
11                 ADD_COLOR(G_VAL(dest), g, G_VAL(dest)); \
12                 ADD_COLOR(B_VAL(dest), b, B_VAL(dest)); \
13 } while (0)
14 
15 #define SUB_COPY(r, g, b, dest) \
16 do { \
17                 SUB_COLOR(R_VAL(dest), r, R_VAL(dest)); \
18                 SUB_COLOR(G_VAL(dest), g, G_VAL(dest)); \
19                 SUB_COLOR(B_VAL(dest), b, B_VAL(dest)); \
20 } while (0)
21 
22 #define RE_COPY(r, g, b, dest) \
23 do { \
24                 RESHADE_COLOR(R_VAL(dest), r, R_VAL(dest)); \
25                 RESHADE_COLOR(G_VAL(dest), g, G_VAL(dest)); \
26                 RESHADE_COLOR(B_VAL(dest), b, B_VAL(dest)); \
27 } while (0)
28 
29 #define MULT(na, a0, a1, tmp) \
30 do { \
31    tmp = ((a0) * (a1)) + 0x80;   \
32    na = (tmp + (tmp >> 8)) >> 8; \
33 } while (0)
34 
35 extern DATA8        pow_lut[256][256];
36 
37 /*   point drawing functions  */
38 
39 /* COPY OPS */
40 
41 static void
__imlib_CopyToRGBA(DATA32 color,DATA32 * dst)42 __imlib_CopyToRGBA(DATA32 color, DATA32 * dst)
43 {
44    *dst = color;
45 }
46 
47 static void
__imlib_CopyToRGB(DATA32 color,DATA32 * dst)48 __imlib_CopyToRGB(DATA32 color, DATA32 * dst)
49 {
50    *dst = (*dst & 0xff000000) | (color & 0x00ffffff);
51 }
52 
53 static void
__imlib_BlendToRGB(DATA32 color,DATA32 * dst)54 __imlib_BlendToRGB(DATA32 color, DATA32 * dst)
55 {
56    DATA32              tmp;
57 
58    BLEND(R_VAL(&color), G_VAL(&color), B_VAL(&color), A_VAL(&color), dst);
59 }
60 
61 static void
__imlib_BlendToRGBA(DATA32 color,DATA32 * dst)62 __imlib_BlendToRGBA(DATA32 color, DATA32 * dst)
63 {
64    DATA32              tmp;
65    DATA8               a;
66 
67    a = pow_lut[A_VAL(&color)][A_VAL(dst)];
68    BLEND_COLOR(A_VAL(&color), A_VAL(dst), 255, A_VAL(dst));
69    BLEND(R_VAL(&color), G_VAL(&color), B_VAL(&color), a, dst);
70 }
71 
72 /* ADD OPS */
73 
74 static void
__imlib_AddCopyToRGBA(DATA32 color,DATA32 * dst)75 __imlib_AddCopyToRGBA(DATA32 color, DATA32 * dst)
76 {
77    DATA32              tmp;
78 
79    A_VAL(dst) = A_VAL(&color);
80    ADD_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
81 }
82 
83 static void
__imlib_AddCopyToRGB(DATA32 color,DATA32 * dst)84 __imlib_AddCopyToRGB(DATA32 color, DATA32 * dst)
85 {
86    DATA32              tmp;
87 
88    ADD_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
89 }
90 
91 static void
__imlib_AddBlendToRGB(DATA32 color,DATA32 * dst)92 __imlib_AddBlendToRGB(DATA32 color, DATA32 * dst)
93 {
94    DATA32              tmp;
95 
96    BLEND_ADD(R_VAL(&color), G_VAL(&color), B_VAL(&color), A_VAL(&color), dst);
97 }
98 
99 static void
__imlib_AddBlendToRGBA(DATA32 color,DATA32 * dst)100 __imlib_AddBlendToRGBA(DATA32 color, DATA32 * dst)
101 {
102    DATA32              tmp;
103    DATA8               a;
104 
105    a = pow_lut[A_VAL(&color)][A_VAL(dst)];
106    BLEND_COLOR(A_VAL(&color), A_VAL(dst), 255, A_VAL(dst));
107    BLEND_ADD(R_VAL(&color), G_VAL(&color), B_VAL(&color), a, dst);
108 }
109 
110 /* SUBTRACT OPS */
111 
112 static void
__imlib_SubCopyToRGBA(DATA32 color,DATA32 * dst)113 __imlib_SubCopyToRGBA(DATA32 color, DATA32 * dst)
114 {
115    DATA32              tmp;
116 
117    A_VAL(dst) = A_VAL(&color);
118    SUB_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
119 }
120 
121 static void
__imlib_SubCopyToRGB(DATA32 color,DATA32 * dst)122 __imlib_SubCopyToRGB(DATA32 color, DATA32 * dst)
123 {
124    DATA32              tmp;
125 
126    SUB_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
127 }
128 
129 static void
__imlib_SubBlendToRGB(DATA32 color,DATA32 * dst)130 __imlib_SubBlendToRGB(DATA32 color, DATA32 * dst)
131 {
132    DATA32              tmp;
133 
134    BLEND_SUB(R_VAL(&color), G_VAL(&color), B_VAL(&color), A_VAL(&color), dst);
135 }
136 
137 static void
__imlib_SubBlendToRGBA(DATA32 color,DATA32 * dst)138 __imlib_SubBlendToRGBA(DATA32 color, DATA32 * dst)
139 {
140    DATA32              tmp;
141    DATA8               a;
142 
143    a = pow_lut[A_VAL(&color)][A_VAL(dst)];
144    BLEND_COLOR(A_VAL(&color), A_VAL(dst), 255, A_VAL(dst));
145    BLEND_SUB(R_VAL(&color), G_VAL(&color), B_VAL(&color), a, dst);
146 }
147 
148 /* RESHADE OPS */
149 
150 static void
__imlib_ReCopyToRGBA(DATA32 color,DATA32 * dst)151 __imlib_ReCopyToRGBA(DATA32 color, DATA32 * dst)
152 {
153    DATA32              tmp;
154 
155    A_VAL(dst) = A_VAL(&color);
156    RE_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
157 }
158 
159 static void
__imlib_ReCopyToRGB(DATA32 color,DATA32 * dst)160 __imlib_ReCopyToRGB(DATA32 color, DATA32 * dst)
161 {
162    DATA32              tmp;
163 
164    RE_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
165 }
166 
167 static void
__imlib_ReBlendToRGB(DATA32 color,DATA32 * dst)168 __imlib_ReBlendToRGB(DATA32 color, DATA32 * dst)
169 {
170    DATA32              tmp;
171 
172    BLEND_RE(R_VAL(&color), G_VAL(&color), B_VAL(&color), A_VAL(&color), dst);
173 }
174 
175 static void
__imlib_ReBlendToRGBA(DATA32 color,DATA32 * dst)176 __imlib_ReBlendToRGBA(DATA32 color, DATA32 * dst)
177 {
178    DATA32              tmp;
179    DATA8               a;
180 
181    a = pow_lut[A_VAL(&color)][A_VAL(dst)];
182    BLEND_COLOR(A_VAL(&color), A_VAL(dst), 255, A_VAL(dst));
183    BLEND_RE(R_VAL(&color), G_VAL(&color), B_VAL(&color), a, dst);
184 }
185 
186 /*  span drawing functions*  */
187 
188 /* COPY OPS */
189 
190 static void
__imlib_CopySpanToRGBA(DATA32 color,DATA32 * dst,int len)191 __imlib_CopySpanToRGBA(DATA32 color, DATA32 * dst, int len)
192 {
193    while (len--)
194      {
195         *dst = color;
196         dst++;
197      }
198 }
199 
200 static void
__imlib_CopySpanToRGB(DATA32 color,DATA32 * dst,int len)201 __imlib_CopySpanToRGB(DATA32 color, DATA32 * dst, int len)
202 {
203    while (len--)
204      {
205         *dst = (*dst & 0xff000000) | (color & 0x00ffffff);
206         dst++;
207      }
208 }
209 
210 static void
__imlib_BlendSpanToRGB(DATA32 color,DATA32 * dst,int len)211 __imlib_BlendSpanToRGB(DATA32 color, DATA32 * dst, int len)
212 {
213    while (len--)
214      {
215         DATA32              tmp;
216 
217         BLEND(R_VAL(&color), G_VAL(&color), B_VAL(&color), A_VAL(&color), dst);
218         dst++;
219      }
220 }
221 
222 static void
__imlib_BlendSpanToRGBA(DATA32 color,DATA32 * dst,int len)223 __imlib_BlendSpanToRGBA(DATA32 color, DATA32 * dst, int len)
224 {
225    while (len--)
226      {
227         DATA32              tmp;
228         DATA8               a;
229 
230         a = pow_lut[A_VAL(&color)][A_VAL(dst)];
231         BLEND_COLOR(A_VAL(&color), A_VAL(dst), 255, A_VAL(dst));
232         BLEND(R_VAL(&color), G_VAL(&color), B_VAL(&color), a, dst);
233         dst++;
234      }
235 }
236 
237 /* ADD OPS */
238 
239 static void
__imlib_AddCopySpanToRGBA(DATA32 color,DATA32 * dst,int len)240 __imlib_AddCopySpanToRGBA(DATA32 color, DATA32 * dst, int len)
241 {
242    while (len--)
243      {
244         DATA32              tmp;
245 
246         A_VAL(dst) = A_VAL(&color);
247         ADD_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
248         dst++;
249      }
250 }
251 
252 static void
__imlib_AddCopySpanToRGB(DATA32 color,DATA32 * dst,int len)253 __imlib_AddCopySpanToRGB(DATA32 color, DATA32 * dst, int len)
254 {
255    while (len--)
256      {
257         DATA32              tmp;
258 
259         ADD_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
260         dst++;
261      }
262 }
263 
264 static void
__imlib_AddBlendSpanToRGB(DATA32 color,DATA32 * dst,int len)265 __imlib_AddBlendSpanToRGB(DATA32 color, DATA32 * dst, int len)
266 {
267    while (len--)
268      {
269         DATA32              tmp;
270 
271         BLEND_ADD(R_VAL(&color), G_VAL(&color), B_VAL(&color), A_VAL(&color),
272                   dst);
273         dst++;
274      }
275 }
276 
277 static void
__imlib_AddBlendSpanToRGBA(DATA32 color,DATA32 * dst,int len)278 __imlib_AddBlendSpanToRGBA(DATA32 color, DATA32 * dst, int len)
279 {
280    while (len--)
281      {
282         DATA32              tmp;
283         DATA8               a;
284 
285         a = pow_lut[A_VAL(&color)][A_VAL(dst)];
286         BLEND_COLOR(A_VAL(&color), A_VAL(dst), 255, A_VAL(dst));
287         BLEND_ADD(R_VAL(&color), G_VAL(&color), B_VAL(&color), a, dst);
288         dst++;
289      }
290 }
291 
292 /* SUBTRACT OPS */
293 
294 static void
__imlib_SubCopySpanToRGBA(DATA32 color,DATA32 * dst,int len)295 __imlib_SubCopySpanToRGBA(DATA32 color, DATA32 * dst, int len)
296 {
297    while (len--)
298      {
299         DATA32              tmp;
300 
301         A_VAL(dst) = A_VAL(&color);
302         SUB_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
303         dst++;
304      }
305 }
306 
307 static void
__imlib_SubCopySpanToRGB(DATA32 color,DATA32 * dst,int len)308 __imlib_SubCopySpanToRGB(DATA32 color, DATA32 * dst, int len)
309 {
310    while (len--)
311      {
312         DATA32              tmp;
313 
314         SUB_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
315         dst++;
316      }
317 }
318 
319 static void
__imlib_SubBlendSpanToRGB(DATA32 color,DATA32 * dst,int len)320 __imlib_SubBlendSpanToRGB(DATA32 color, DATA32 * dst, int len)
321 {
322    while (len--)
323      {
324         DATA32              tmp;
325 
326         BLEND_SUB(R_VAL(&color), G_VAL(&color), B_VAL(&color), A_VAL(&color),
327                   dst);
328         dst++;
329      }
330 }
331 
332 static void
__imlib_SubBlendSpanToRGBA(DATA32 color,DATA32 * dst,int len)333 __imlib_SubBlendSpanToRGBA(DATA32 color, DATA32 * dst, int len)
334 {
335    while (len--)
336      {
337         DATA32              tmp;
338         DATA8               a;
339 
340         a = pow_lut[A_VAL(&color)][A_VAL(dst)];
341         BLEND_COLOR(A_VAL(&color), A_VAL(dst), 255, A_VAL(dst));
342         BLEND_SUB(R_VAL(&color), G_VAL(&color), B_VAL(&color), a, dst);
343         dst++;
344      }
345 }
346 
347 /* RESHADE OPS */
348 
349 static void
__imlib_ReCopySpanToRGBA(DATA32 color,DATA32 * dst,int len)350 __imlib_ReCopySpanToRGBA(DATA32 color, DATA32 * dst, int len)
351 {
352    while (len--)
353      {
354         DATA32              tmp;
355 
356         A_VAL(dst) = A_VAL(&color);
357         RE_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
358         dst++;
359      }
360 }
361 
362 static void
__imlib_ReCopySpanToRGB(DATA32 color,DATA32 * dst,int len)363 __imlib_ReCopySpanToRGB(DATA32 color, DATA32 * dst, int len)
364 {
365    while (len--)
366      {
367         DATA32              tmp;
368 
369         RE_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
370         dst++;
371      }
372 }
373 
374 static void
__imlib_ReBlendSpanToRGB(DATA32 color,DATA32 * dst,int len)375 __imlib_ReBlendSpanToRGB(DATA32 color, DATA32 * dst, int len)
376 {
377    while (len--)
378      {
379         DATA32              tmp;
380 
381         BLEND_RE(R_VAL(&color), G_VAL(&color), B_VAL(&color), A_VAL(&color),
382                  dst);
383         dst++;
384      }
385 }
386 
387 static void
__imlib_ReBlendSpanToRGBA(DATA32 color,DATA32 * dst,int len)388 __imlib_ReBlendSpanToRGBA(DATA32 color, DATA32 * dst, int len)
389 {
390    while (len--)
391      {
392         DATA32              tmp;
393         DATA8               a;
394 
395         a = pow_lut[A_VAL(&color)][A_VAL(dst)];
396         BLEND_COLOR(A_VAL(&color), A_VAL(dst), 255, A_VAL(dst));
397         BLEND_RE(R_VAL(&color), G_VAL(&color), B_VAL(&color), a, dst);
398         dst++;
399      }
400 }
401 
402 /*  shaped span drawing functions*  */
403 
404 /* COPY OPS */
405 
406 static void
__imlib_CopyShapedSpanToRGBA(DATA8 * src,DATA32 color,DATA32 * dst,int len)407 __imlib_CopyShapedSpanToRGBA(DATA8 * src, DATA32 color, DATA32 * dst, int len)
408 {
409    DATA32              col = color;
410 
411    if (A_VAL(&color) < 255)
412      {
413         while (len--)
414           {
415              DATA32              tmp;
416 
417              switch (*src)
418                {
419                case 0:
420                   break;
421                case 255:
422                   {
423                      *dst = color;
424                      break;
425                   }
426                default:
427                   {
428                      MULT(A_VAL(&col), *src, A_VAL(&color), tmp);
429                      *dst = col;
430                      break;
431                   }
432                }
433              src++;
434              dst++;
435           }
436         return;
437      }
438 
439    while (len--)
440      {
441         switch (*src)
442           {
443           case 0:
444              break;
445           case 255:
446              {
447                 *dst = color;
448                 break;
449              }
450           default:
451              {
452                 A_VAL(&col) = *src;
453                 *dst = col;
454                 break;
455              }
456           }
457         src++;
458         dst++;
459      }
460 }
461 
462 static void
__imlib_CopyShapedSpanToRGB(DATA8 * src,DATA32 color,DATA32 * dst,int len)463 __imlib_CopyShapedSpanToRGB(DATA8 * src, DATA32 color, DATA32 * dst, int len)
464 {
465    while (len--)
466      {
467         if (*src)
468            *dst = (*dst & 0xff000000) | (color & 0x00ffffff);
469 
470         src++;
471         dst++;
472      }
473 }
474 
475 static void
__imlib_BlendShapedSpanToRGB(DATA8 * src,DATA32 color,DATA32 * dst,int len)476 __imlib_BlendShapedSpanToRGB(DATA8 * src, DATA32 color, DATA32 * dst, int len)
477 {
478    if (A_VAL(&color) < 255)
479      {
480         while (len--)
481           {
482              DATA32              tmp;
483              DATA8               a;
484 
485              switch (*src)
486                {
487                case 0:
488                   break;
489                case 255:
490                   {
491                      BLEND(R_VAL(&color), G_VAL(&color), B_VAL(&color),
492                            A_VAL(&color), dst);
493                      break;
494                   }
495                default:
496                   {
497                      MULT(a, *src, A_VAL(&color), tmp);
498                      BLEND(R_VAL(&color), G_VAL(&color), B_VAL(&color), a, dst);
499                      break;
500                   }
501                }
502              src++;
503              dst++;
504           }
505         return;
506      }
507 
508    while (len--)
509      {
510         DATA32              tmp;
511 
512         switch (*src)
513           {
514           case 0:
515              break;
516           case 255:
517              {
518                 *dst = (*dst & 0xff000000) | (color & 0x00ffffff);
519                 break;
520              }
521           default:
522              {
523                 BLEND(R_VAL(&color), G_VAL(&color), B_VAL(&color), *src, dst);
524                 break;
525              }
526           }
527         src++;
528         dst++;
529      }
530 }
531 
532 static void
__imlib_BlendShapedSpanToRGBA(DATA8 * src,DATA32 color,DATA32 * dst,int len)533 __imlib_BlendShapedSpanToRGBA(DATA8 * src, DATA32 color, DATA32 * dst, int len)
534 {
535    if (A_VAL(&color) < 255)
536      {
537         while (len--)
538           {
539              DATA32              tmp;
540              DATA8               a, aa;
541 
542              switch (*src)
543                {
544                case 0:
545                   break;
546                case 255:
547                   {
548                      a = pow_lut[A_VAL(&color)][A_VAL(dst)];
549                      BLEND_COLOR(A_VAL(&color), A_VAL(dst), 255, A_VAL(dst));
550                      BLEND(R_VAL(&color), G_VAL(&color), B_VAL(&color), a, dst);
551                      break;
552                   }
553                default:
554                   {
555                      MULT(aa, *src, A_VAL(&color), tmp);
556                      a = pow_lut[aa][A_VAL(dst)];
557                      BLEND_COLOR(aa, A_VAL(dst), 255, A_VAL(dst));
558                      BLEND(R_VAL(&color), G_VAL(&color), B_VAL(&color), a, dst);
559                      break;
560                   }
561                }
562              src++;
563              dst++;
564           }
565         return;
566      }
567 
568    while (len--)
569      {
570         DATA32              tmp;
571         DATA8               a;
572 
573         switch (*src)
574           {
575           case 0:
576              break;
577           case 255:
578              {
579                 *dst = color;
580                 break;
581              }
582           default:
583              {
584                 a = pow_lut[*src][A_VAL(dst)];
585                 BLEND_COLOR(*src, A_VAL(dst), 255, A_VAL(dst));
586                 BLEND(R_VAL(&color), G_VAL(&color), B_VAL(&color), a, dst);
587                 break;
588              }
589           }
590         src++;
591         dst++;
592      }
593 }
594 
595 /* ADD OPS */
596 
597 static void
__imlib_AddCopyShapedSpanToRGBA(DATA8 * src,DATA32 color,DATA32 * dst,int len)598 __imlib_AddCopyShapedSpanToRGBA(DATA8 * src, DATA32 color, DATA32 * dst,
599                                 int len)
600 {
601    if (A_VAL(&color) < 255)
602      {
603         while (len--)
604           {
605              DATA32              tmp;
606 
607              switch (*src)
608                {
609                case 0:
610                   break;
611                case 255:
612                   {
613                      A_VAL(dst) = A_VAL(&color);
614                      ADD_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
615                      break;
616                   }
617                default:
618                   {
619                      MULT(A_VAL(dst), *src, A_VAL(&color), tmp);
620                      ADD_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
621                      break;
622                   }
623                }
624              src++;
625              dst++;
626           }
627         return;
628      }
629 
630    while (len--)
631      {
632         DATA32              tmp;
633 
634         if (*src)
635           {
636              A_VAL(dst) = *src;
637              ADD_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
638           }
639         src++;
640         dst++;
641      }
642 }
643 
644 static void
__imlib_AddCopyShapedSpanToRGB(DATA8 * src,DATA32 color,DATA32 * dst,int len)645 __imlib_AddCopyShapedSpanToRGB(DATA8 * src, DATA32 color, DATA32 * dst, int len)
646 {
647    while (len--)
648      {
649         DATA32              tmp;
650 
651         if (*src)
652           {
653              ADD_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
654           }
655 
656         src++;
657         dst++;
658      }
659 }
660 
661 static void
__imlib_AddBlendShapedSpanToRGB(DATA8 * src,DATA32 color,DATA32 * dst,int len)662 __imlib_AddBlendShapedSpanToRGB(DATA8 * src, DATA32 color, DATA32 * dst,
663                                 int len)
664 {
665    if (A_VAL(&color) < 255)
666      {
667         while (len--)
668           {
669              DATA32              tmp;
670              DATA8               a;
671 
672              switch (*src)
673                {
674                case 0:
675                   break;
676                case 255:
677                   {
678                      BLEND_ADD(R_VAL(&color), G_VAL(&color), B_VAL(&color),
679                                A_VAL(&color), dst);
680                      break;
681                   }
682                default:
683                   {
684                      MULT(a, *src, A_VAL(&color), tmp);
685                      BLEND_ADD(R_VAL(&color), G_VAL(&color), B_VAL(&color), a,
686                                dst);
687                      break;
688                   }
689                }
690              src++;
691              dst++;
692           }
693         return;
694      }
695 
696    while (len--)
697      {
698         DATA32              tmp;
699 
700         switch (*src)
701           {
702           case 0:
703              break;
704           case 255:
705              {
706                 ADD_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
707                 break;
708              }
709           default:
710              {
711                 BLEND_ADD(R_VAL(&color), G_VAL(&color), B_VAL(&color), *src,
712                           dst);
713                 break;
714              }
715           }
716         src++;
717         dst++;
718      }
719 }
720 
721 static void
__imlib_AddBlendShapedSpanToRGBA(DATA8 * src,DATA32 color,DATA32 * dst,int len)722 __imlib_AddBlendShapedSpanToRGBA(DATA8 * src, DATA32 color, DATA32 * dst,
723                                  int len)
724 {
725    if (A_VAL(&color) < 255)
726      {
727         while (len--)
728           {
729              DATA32              tmp;
730              DATA8               a, aa;
731 
732              switch (*src)
733                {
734                case 0:
735                   break;
736                case 255:
737                   {
738                      a = pow_lut[A_VAL(&color)][A_VAL(dst)];
739                      BLEND_COLOR(A_VAL(&color), A_VAL(dst), 255, A_VAL(dst));
740                      BLEND_ADD(R_VAL(&color), G_VAL(&color), B_VAL(&color), a,
741                                dst);
742                      break;
743                   }
744                default:
745                   {
746                      MULT(aa, *src, A_VAL(&color), tmp);
747                      a = pow_lut[aa][A_VAL(dst)];
748                      BLEND_COLOR(aa, A_VAL(dst), 255, A_VAL(dst));
749                      BLEND_ADD(R_VAL(&color), G_VAL(&color), B_VAL(&color), a,
750                                dst);
751                      break;
752                   }
753                }
754              src++;
755              dst++;
756           }
757         return;
758      }
759 
760    while (len--)
761      {
762         DATA32              tmp;
763         DATA8               a;
764 
765         switch (*src)
766           {
767           case 0:
768              break;
769           case 255:
770              {
771                 A_VAL(dst) = 255;
772                 ADD_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
773                 break;
774              }
775           default:
776              {
777                 a = pow_lut[*src][A_VAL(dst)];
778                 BLEND_COLOR(*src, A_VAL(dst), 255, A_VAL(dst));
779                 BLEND_ADD(R_VAL(&color), G_VAL(&color), B_VAL(&color), a, dst);
780                 break;
781              }
782           }
783         src++;
784         dst++;
785      }
786 }
787 
788 /* SUBTRACT OPS */
789 
790 static void
__imlib_SubCopyShapedSpanToRGBA(DATA8 * src,DATA32 color,DATA32 * dst,int len)791 __imlib_SubCopyShapedSpanToRGBA(DATA8 * src, DATA32 color, DATA32 * dst,
792                                 int len)
793 {
794    if (A_VAL(&color) < 255)
795      {
796         while (len--)
797           {
798              DATA32              tmp;
799 
800              switch (*src)
801                {
802                case 0:
803                   break;
804                case 255:
805                   {
806                      A_VAL(dst) = A_VAL(&color);
807                      SUB_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
808                      break;
809                   }
810                default:
811                   {
812                      MULT(A_VAL(dst), *src, A_VAL(&color), tmp);
813                      SUB_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
814                      break;
815                   }
816                }
817              src++;
818              dst++;
819           }
820         return;
821      }
822 
823    while (len--)
824      {
825         DATA32              tmp;
826 
827         if (*src)
828           {
829              A_VAL(dst) = *src;
830              SUB_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
831           }
832         src++;
833         dst++;
834      }
835 }
836 
837 static void
__imlib_SubCopyShapedSpanToRGB(DATA8 * src,DATA32 color,DATA32 * dst,int len)838 __imlib_SubCopyShapedSpanToRGB(DATA8 * src, DATA32 color, DATA32 * dst, int len)
839 {
840    while (len--)
841      {
842         DATA32              tmp;
843 
844         if (*src)
845           {
846              SUB_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
847           }
848 
849         src++;
850         dst++;
851      }
852 }
853 
854 static void
__imlib_SubBlendShapedSpanToRGB(DATA8 * src,DATA32 color,DATA32 * dst,int len)855 __imlib_SubBlendShapedSpanToRGB(DATA8 * src, DATA32 color, DATA32 * dst,
856                                 int len)
857 {
858    if (A_VAL(&color) < 255)
859      {
860         while (len--)
861           {
862              DATA32              tmp;
863              DATA8               a;
864 
865              switch (*src)
866                {
867                case 0:
868                   break;
869                case 255:
870                   {
871                      BLEND_SUB(R_VAL(&color), G_VAL(&color), B_VAL(&color),
872                                A_VAL(&color), dst);
873                      break;
874                   }
875                default:
876                   {
877                      MULT(a, *src, A_VAL(&color), tmp);
878                      BLEND_SUB(R_VAL(&color), G_VAL(&color), B_VAL(&color), a,
879                                dst);
880                      break;
881                   }
882                }
883              src++;
884              dst++;
885           }
886         return;
887      }
888 
889    while (len--)
890      {
891         DATA32              tmp;
892 
893         switch (*src)
894           {
895           case 0:
896              break;
897           case 255:
898              {
899                 SUB_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
900                 break;
901              }
902           default:
903              {
904                 BLEND_SUB(R_VAL(&color), G_VAL(&color), B_VAL(&color), *src,
905                           dst);
906                 break;
907              }
908           }
909         src++;
910         dst++;
911      }
912 }
913 
914 static void
__imlib_SubBlendShapedSpanToRGBA(DATA8 * src,DATA32 color,DATA32 * dst,int len)915 __imlib_SubBlendShapedSpanToRGBA(DATA8 * src, DATA32 color, DATA32 * dst,
916                                  int len)
917 {
918    if (A_VAL(&color) < 255)
919      {
920         while (len--)
921           {
922              DATA32              tmp;
923              DATA8               a, aa;
924 
925              switch (*src)
926                {
927                case 0:
928                   break;
929                case 255:
930                   {
931                      a = pow_lut[A_VAL(&color)][A_VAL(dst)];
932                      BLEND_COLOR(A_VAL(&color), A_VAL(dst), 255, A_VAL(dst));
933                      BLEND_SUB(R_VAL(&color), G_VAL(&color), B_VAL(&color), a,
934                                dst);
935                      break;
936                   }
937                default:
938                   {
939                      MULT(aa, *src, A_VAL(&color), tmp);
940                      a = pow_lut[aa][A_VAL(dst)];
941                      BLEND_COLOR(aa, A_VAL(dst), 255, A_VAL(dst));
942                      BLEND_SUB(R_VAL(&color), G_VAL(&color), B_VAL(&color), a,
943                                dst);
944                      break;
945                   }
946                }
947              src++;
948              dst++;
949           }
950         return;
951      }
952 
953    while (len--)
954      {
955         DATA32              tmp;
956         DATA8               a;
957 
958         switch (*src)
959           {
960           case 0:
961              break;
962           case 255:
963              {
964                 A_VAL(dst) = 255;
965                 SUB_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
966                 break;
967              }
968           default:
969              {
970                 a = pow_lut[*src][A_VAL(dst)];
971                 BLEND_COLOR(*src, A_VAL(dst), 255, A_VAL(dst));
972                 BLEND_SUB(R_VAL(&color), G_VAL(&color), B_VAL(&color), a, dst);
973                 break;
974              }
975           }
976         src++;
977         dst++;
978      }
979 }
980 
981 /* RESHADE OPS */
982 
983 static void
__imlib_ReCopyShapedSpanToRGBA(DATA8 * src,DATA32 color,DATA32 * dst,int len)984 __imlib_ReCopyShapedSpanToRGBA(DATA8 * src, DATA32 color, DATA32 * dst, int len)
985 {
986    if (A_VAL(&color) < 255)
987      {
988         while (len--)
989           {
990              DATA32              tmp;
991 
992              switch (*src)
993                {
994                case 0:
995                   break;
996                case 255:
997                   {
998                      A_VAL(dst) = A_VAL(&color);
999                      RE_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
1000                      break;
1001                   }
1002                default:
1003                   {
1004                      MULT(A_VAL(dst), *src, A_VAL(&color), tmp);
1005                      RE_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
1006                      break;
1007                   }
1008                }
1009              src++;
1010              dst++;
1011           }
1012         return;
1013      }
1014 
1015    while (len--)
1016      {
1017         DATA32              tmp;
1018 
1019         if (*src)
1020           {
1021              A_VAL(dst) = *src;
1022              RE_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
1023           }
1024         src++;
1025         dst++;
1026      }
1027 }
1028 
1029 static void
__imlib_ReCopyShapedSpanToRGB(DATA8 * src,DATA32 color,DATA32 * dst,int len)1030 __imlib_ReCopyShapedSpanToRGB(DATA8 * src, DATA32 color, DATA32 * dst, int len)
1031 {
1032    while (len--)
1033      {
1034         DATA32              tmp;
1035 
1036         if (*src)
1037           {
1038              RE_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
1039           }
1040 
1041         src++;
1042         dst++;
1043      }
1044 }
1045 
1046 static void
__imlib_ReBlendShapedSpanToRGB(DATA8 * src,DATA32 color,DATA32 * dst,int len)1047 __imlib_ReBlendShapedSpanToRGB(DATA8 * src, DATA32 color, DATA32 * dst, int len)
1048 {
1049    if (A_VAL(&color) < 255)
1050      {
1051         while (len--)
1052           {
1053              DATA32              tmp;
1054              DATA8               a;
1055 
1056              switch (*src)
1057                {
1058                case 0:
1059                   break;
1060                case 255:
1061                   {
1062                      BLEND_RE(R_VAL(&color), G_VAL(&color), B_VAL(&color),
1063                               A_VAL(&color), dst);
1064                      break;
1065                   }
1066                default:
1067                   {
1068                      MULT(a, *src, A_VAL(&color), tmp);
1069                      BLEND_RE(R_VAL(&color), G_VAL(&color), B_VAL(&color), a,
1070                               dst);
1071                      break;
1072                   }
1073                }
1074              src++;
1075              dst++;
1076           }
1077         return;
1078      }
1079 
1080    while (len--)
1081      {
1082         DATA32              tmp;
1083 
1084         switch (*src)
1085           {
1086           case 0:
1087              break;
1088           case 255:
1089              {
1090                 RE_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
1091                 break;
1092              }
1093           default:
1094              {
1095                 BLEND_RE(R_VAL(&color), G_VAL(&color), B_VAL(&color), *src,
1096                          dst);
1097                 break;
1098              }
1099           }
1100         src++;
1101         dst++;
1102      }
1103 }
1104 
1105 static void
__imlib_ReBlendShapedSpanToRGBA(DATA8 * src,DATA32 color,DATA32 * dst,int len)1106 __imlib_ReBlendShapedSpanToRGBA(DATA8 * src, DATA32 color, DATA32 * dst,
1107                                 int len)
1108 {
1109    if (A_VAL(&color) < 255)
1110      {
1111         while (len--)
1112           {
1113              DATA32              tmp;
1114              DATA8               a, aa;
1115 
1116              switch (*src)
1117                {
1118                case 0:
1119                   break;
1120                case 255:
1121                   {
1122                      a = pow_lut[A_VAL(&color)][A_VAL(dst)];
1123                      BLEND_COLOR(A_VAL(&color), A_VAL(dst), 255, A_VAL(dst));
1124                      BLEND_RE(R_VAL(&color), G_VAL(&color), B_VAL(&color), a,
1125                               dst);
1126                      break;
1127                   }
1128                default:
1129                   {
1130                      MULT(aa, *src, A_VAL(&color), tmp);
1131                      a = pow_lut[aa][A_VAL(dst)];
1132                      BLEND_COLOR(aa, A_VAL(dst), 255, A_VAL(dst));
1133                      BLEND_RE(R_VAL(&color), G_VAL(&color), B_VAL(&color), a,
1134                               dst);
1135                      break;
1136                   }
1137                }
1138              src++;
1139              dst++;
1140           }
1141         return;
1142      }
1143 
1144    while (len--)
1145      {
1146         DATA32              tmp;
1147         DATA8               a;
1148 
1149         switch (*src)
1150           {
1151           case 0:
1152              break;
1153           case 255:
1154              {
1155                 A_VAL(dst) = 255;
1156                 RE_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
1157                 break;
1158              }
1159           default:
1160              {
1161                 a = pow_lut[*src][A_VAL(dst)];
1162                 BLEND_COLOR(*src, A_VAL(dst), 255, A_VAL(dst));
1163                 BLEND_RE(R_VAL(&color), G_VAL(&color), B_VAL(&color), a, dst);
1164                 break;
1165              }
1166           }
1167         src++;
1168         dst++;
1169      }
1170 }
1171 
1172 ImlibPointDrawFunction
__imlib_GetPointDrawFunction(ImlibOp op,char dst_alpha,char blend)1173 __imlib_GetPointDrawFunction(ImlibOp op, char dst_alpha, char blend)
1174 {
1175    /* [ operation ][ dst_alpha ][ blend ]  */
1176    static ImlibPointDrawFunction ptfuncs[4][2][2] =
1177       /* OP_COPY */
1178    { {{__imlib_CopyToRGB, __imlib_BlendToRGB},
1179       {__imlib_CopyToRGBA, __imlib_BlendToRGBA}},
1180    /* OP_ADD */
1181    {{__imlib_AddCopyToRGB, __imlib_AddBlendToRGB},
1182     {__imlib_AddCopyToRGBA, __imlib_AddBlendToRGBA}},
1183    /* OP_SUBTRACT */
1184    {{__imlib_SubCopyToRGB, __imlib_SubBlendToRGB},
1185     {__imlib_SubCopyToRGBA, __imlib_SubBlendToRGBA}},
1186    /* OP_RESHADE */
1187    {{__imlib_ReCopyToRGB, __imlib_ReBlendToRGB},
1188     {__imlib_ReCopyToRGBA, __imlib_ReBlendToRGBA}},
1189    };
1190 
1191    int                 opi = (op == OP_COPY) ? 0
1192       : (op == OP_ADD) ? 1
1193       : (op == OP_SUBTRACT) ? 2 : (op == OP_RESHADE) ? 3 : -1;
1194 
1195    if (opi == -1)
1196       return NULL;
1197 
1198    return ptfuncs[opi][!!dst_alpha][!!blend];
1199 }
1200 
1201 ImlibSpanDrawFunction
__imlib_GetSpanDrawFunction(ImlibOp op,char dst_alpha,char blend)1202 __imlib_GetSpanDrawFunction(ImlibOp op, char dst_alpha, char blend)
1203 {
1204    static ImlibSpanDrawFunction spanfuncs[4][2][2] =
1205       /* OP_COPY */
1206    { {{__imlib_CopySpanToRGB, __imlib_BlendSpanToRGB},
1207       {__imlib_CopySpanToRGBA, __imlib_BlendSpanToRGBA}},
1208    /* OP_ADD */
1209    {{__imlib_AddCopySpanToRGB, __imlib_AddBlendSpanToRGB},
1210     {__imlib_AddCopySpanToRGBA, __imlib_AddBlendSpanToRGBA}},
1211    /* OP_SUBTRACT */
1212    {{__imlib_SubCopySpanToRGB, __imlib_SubBlendSpanToRGB},
1213     {__imlib_SubCopySpanToRGBA, __imlib_SubBlendSpanToRGBA}},
1214    /* OP_RESHADE */
1215    {{__imlib_ReCopySpanToRGB, __imlib_ReBlendSpanToRGB},
1216     {__imlib_ReCopySpanToRGBA, __imlib_ReBlendSpanToRGBA}},
1217    };
1218 
1219    int                 opi = (op == OP_COPY) ? 0
1220       : (op == OP_ADD) ? 1
1221       : (op == OP_SUBTRACT) ? 2 : (op == OP_RESHADE) ? 3 : -1;
1222 
1223    if (opi == -1)
1224       return NULL;
1225 
1226    return spanfuncs[opi][!!dst_alpha][!!blend];
1227 }
1228 
1229 ImlibShapedSpanDrawFunction
__imlib_GetShapedSpanDrawFunction(ImlibOp op,char dst_alpha,char blend)1230 __imlib_GetShapedSpanDrawFunction(ImlibOp op, char dst_alpha, char blend)
1231 {
1232    static ImlibShapedSpanDrawFunction shapedspanfuncs[4][2][2] =
1233       /* OP_COPY */
1234    { {{__imlib_CopyShapedSpanToRGB, __imlib_BlendShapedSpanToRGB},
1235       {__imlib_CopyShapedSpanToRGBA, __imlib_BlendShapedSpanToRGBA}},
1236    /* OP_ADD */
1237    {{__imlib_AddCopyShapedSpanToRGB, __imlib_AddBlendShapedSpanToRGB},
1238     {__imlib_AddCopyShapedSpanToRGBA, __imlib_AddBlendShapedSpanToRGBA}},
1239    /* OP_SUBTRACT */
1240    {{__imlib_SubCopyShapedSpanToRGB, __imlib_SubBlendShapedSpanToRGB},
1241     {__imlib_SubCopyShapedSpanToRGBA, __imlib_SubBlendShapedSpanToRGBA}},
1242    /* OP_RESHADE */
1243    {{__imlib_ReCopyShapedSpanToRGB, __imlib_ReBlendShapedSpanToRGB},
1244     {__imlib_ReCopyShapedSpanToRGBA, __imlib_ReBlendShapedSpanToRGBA}},
1245    };
1246 
1247    int                 opi = (op == OP_COPY) ? 0
1248       : (op == OP_ADD) ? 1
1249       : (op == OP_SUBTRACT) ? 2 : (op == OP_RESHADE) ? 3 : -1;
1250 
1251    if (opi == -1)
1252       return NULL;
1253 
1254    return shapedspanfuncs[opi][!!dst_alpha][!!blend];
1255 }
1256