]> mj.ucw.cz Git - libucw.git/blob - images/alpha.c
Merge with git+ssh://cvs.ucw.cz/projects/sherlock/GIT/sherlock.git
[libucw.git] / images / alpha.c
1 /*
2  *      Image Library -- Alpha channels
3  *
4  *      (c) 2006 Pavel Charvat <pchar@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU Lesser General Public License.
8  */
9
10 #undef LOCAL_DEBUG
11
12 #include "lib/lib.h"
13 #include "images/images.h"
14 #include "images/color.h"
15
16 static inline uns
17 merge_func(uns value, uns alpha, uns acoef, uns bcoef)
18 {
19   return ((uns)(acoef + (int)alpha * (int)(value - bcoef)) * (0xffffffffU / 255 / 255)) >> 24;
20 }
21
22 int
23 image_apply_background(struct image_thread *thread UNUSED, struct image *dest, struct image *src, struct color *background)
24 {
25   DBG("image_apply_background()");
26
27   /* Grayscale */
28   if (src->pixel_size == 2)
29     {
30       ASSERT(dest->pixel_size == 1);
31       byte bg;
32       if (background->color_space)
33         color_put_grayscale(&bg, background);
34       else
35         bg = 0;
36       uns a = 255 * bg, b = bg;
37 #     define IMAGE_WALK_PREFIX(x) walk_##x
38 #     define IMAGE_WALK_INLINE
39 #     define IMAGE_WALK_DOUBLE
40 #     define IMAGE_WALK_UNROLL 4
41 #     define IMAGE_WALK_IMAGE dest
42 #     define IMAGE_WALK_SEC_IMAGE src
43 #     define IMAGE_WALK_COL_STEP 1
44 #     define IMAGE_WALK_SEC_COL_STEP 2
45 #     define IMAGE_WALK_DO_STEP do{ walk_pos[0] = merge_func(walk_sec_pos[0], walk_sec_pos[1], a, b); }while(0)
46 #     include "images/image-walk.h"
47     }
48
49   /* RGBA to RGB or aligned RGB */
50   else if (src->pixel_size == 4)
51     {
52       ASSERT((src->flags & IMAGE_ALPHA) && dest->pixel_size >= 3 && !(dest->flags & IMAGE_ALPHA));
53       byte bg[3];
54       if (background->color_space)
55         color_put_rgb(bg, background);
56       else
57         bg[0] = bg[1] = bg[2] = 0;
58       uns a0 = 255 * bg[0], b0 = bg[0];
59       uns a1 = 255 * bg[1], b1 = bg[1];
60       uns a2 = 255 * bg[2], b2 = bg[2];
61 #     define IMAGE_WALK_PREFIX(x) walk_##x
62 #     define IMAGE_WALK_INLINE
63 #     define IMAGE_WALK_DOUBLE
64 #     define IMAGE_WALK_UNROLL 2
65 #     define IMAGE_WALK_IMAGE dest
66 #     define IMAGE_WALK_SEC_IMAGE src
67 #     define IMAGE_WALK_SEC_COL_STEP 4
68 #     define IMAGE_WALK_DO_STEP do{ \
69           walk_pos[0] = merge_func(walk_sec_pos[0], walk_sec_pos[3], a0, b0); \
70           walk_pos[1] = merge_func(walk_sec_pos[1], walk_sec_pos[3], a1, b1); \
71           walk_pos[2] = merge_func(walk_sec_pos[2], walk_sec_pos[3], a2, b2); \
72         }while(0)
73 #     include "images/image-walk.h"
74     }
75   else
76     ASSERT(0);
77   return 1;
78 }