Commit | Line | Data |
---|---|---|
9b1ec2b8 TC |
1 | #include "imager.h" |
2 | #include "imrender.h" | |
3 | #include "imageri.h" | |
4 | ||
5 | int | |
6 | i_compose_mask(i_img *out, i_img *src, i_img *mask, | |
7 | int out_left, int out_top, | |
8 | int src_left, int src_top, | |
9 | int mask_left, int mask_top, | |
10 | int width, int height, | |
11 | int combine, | |
12 | double opacity) { | |
13 | i_render r; | |
14 | int dy; | |
15 | i_fill_combine_f combinef_8; | |
16 | i_fill_combinef_f combinef_double; | |
17 | int channel_zero = 0; | |
18 | ||
19 | i_clear_error(); | |
20 | if (out_left >= out->xsize | |
21 | || out_top >= out->ysize | |
22 | || src_left >= src->xsize | |
23 | || src_top >= src->ysize | |
24 | || width <= 0 | |
25 | || height <= 0 | |
26 | || out_left + width <= 0 | |
27 | || out_top + height <= 0 | |
28 | || src_left + width <= 0 | |
29 | || src_top + height <= 0 | |
30 | || mask_left >= mask->xsize | |
31 | || mask_top >= mask->ysize | |
32 | || mask_left + width <= 0 | |
33 | || mask_top + height <= 0) | |
34 | return 0; | |
35 | ||
36 | if (out_left < 0) { | |
37 | width = out_left + width; | |
38 | out_left = 0; | |
39 | } | |
40 | if (out_left + width > out->xsize) | |
41 | width = out->xsize - out_left; | |
42 | ||
43 | if (out_top < 0) { | |
44 | height = out_top + height; | |
45 | out_top = 0; | |
46 | } | |
47 | if (out_top + height > out->ysize) | |
48 | height = out->ysize - out_top; | |
49 | ||
50 | if (src_left < 0) { | |
51 | width = src_left + width; | |
52 | src_left = 0; | |
53 | } | |
54 | if (src_left + width > src->xsize) | |
55 | width = src->xsize - src_left; | |
56 | ||
57 | if (src_top < 0) { | |
58 | height = src_top + height; | |
59 | src_top = 0; | |
60 | } | |
61 | if (src_top + height > src->ysize) | |
62 | height = src->ysize - src_left; | |
63 | ||
64 | if (mask_left < 0) { | |
65 | width = mask_left + width; | |
66 | mask_left = 0; | |
67 | } | |
68 | if (mask_left + width > mask->xsize) | |
69 | width = mask->xsize - mask_left; | |
70 | ||
71 | if (mask_top < 0) { | |
72 | height = mask->ysize + height; | |
73 | mask_top = 0; | |
74 | } | |
75 | if (mask_top + height > mask->ysize) | |
76 | height = mask->xsize - mask_top; | |
77 | ||
78 | if (opacity > 1.0) | |
79 | opacity = 1.0; | |
80 | else if (opacity <= 0) | |
81 | return 0; | |
82 | ||
83 | i_get_combine(combine, &combinef_8, &combinef_double); | |
84 | ||
85 | i_render_init(&r, out, width); | |
86 | #code out->bits <= 8 && src->bits<= 8 && mask->bits <= 8 | |
87 | IM_COLOR *src_line = mymalloc(sizeof(IM_COLOR) * width); | |
88 | IM_SAMPLE_T *mask_line = mymalloc(sizeof(IM_SAMPLE_T) * width); | |
89 | int adapt_channels = out->channels; | |
90 | ||
91 | if (adapt_channels == 1 || adapt_channels == 3) | |
92 | ++adapt_channels; | |
93 | ||
94 | for (dy = 0; dy < height; ++dy) { | |
95 | IM_GLIN(src, src_left, src_left + width, src_top + dy, src_line); | |
96 | IM_ADAPT_COLORS(adapt_channels, src->channels, src_line, width); | |
97 | IM_GSAMP(mask, mask_left, mask_left + width, mask_top + dy, | |
98 | mask_line, &channel_zero, 1); | |
99 | if (opacity < 1.0) { | |
100 | int i; | |
101 | IM_SAMPLE_T *maskp = mask_line; | |
102 | for (i = 0; i < width; ++i) { | |
103 | *maskp = IM_ROUND(*maskp * opacity); | |
104 | ++maskp; | |
105 | } | |
106 | } | |
107 | IM_RENDER_LINE(&r, out_left, out_top+dy, width, mask_line, src_line, | |
108 | IM_SUFFIX(combinef)); | |
109 | } | |
110 | myfree(src_line); | |
111 | myfree(mask_line); | |
112 | ||
113 | #/code | |
114 | i_render_done(&r); | |
115 | ||
116 | return 1; | |
117 | } | |
118 | ||
119 | int | |
120 | i_compose(i_img *out, i_img *src, | |
121 | int out_left, int out_top, | |
122 | int src_left, int src_top, | |
123 | int width, int height, | |
124 | int combine, | |
125 | double opacity) { | |
126 | i_render r; | |
127 | int dy; | |
128 | i_fill_combine_f combinef_8; | |
129 | i_fill_combinef_f combinef_double; | |
130 | ||
131 | i_clear_error(); | |
132 | if (out_left >= out->xsize | |
133 | || out_top >= out->ysize | |
134 | || src_left >= src->xsize | |
135 | || src_top >= src->ysize | |
136 | || width <= 0 | |
137 | || height <= 0 | |
138 | || out_left + width <= 0 | |
139 | || out_top + height <= 0 | |
140 | || src_left + width <= 0 | |
141 | || src_top + height <= 0) | |
142 | return 0; | |
143 | ||
144 | if (out_left < 0) { | |
145 | width = out_left + width; | |
146 | out_left = 0; | |
147 | } | |
148 | if (out_left + width > out->xsize) | |
149 | width = out->xsize - out_left; | |
150 | ||
151 | if (out_top < 0) { | |
152 | height = out_top + height; | |
153 | out_top = 0; | |
154 | } | |
155 | if (out_top + height > out->ysize) | |
156 | height = out->ysize - out_top; | |
157 | ||
158 | if (src_left < 0) { | |
159 | width = src_left + width; | |
160 | src_left = 0; | |
161 | } | |
162 | if (src_left + width > src->xsize) | |
163 | width = src->xsize - src_left; | |
164 | ||
165 | if (src_top < 0) { | |
166 | height = src_top + height; | |
167 | src_top = 0; | |
168 | } | |
169 | if (src_top + height > src->ysize) | |
170 | height = src->ysize - src_left; | |
171 | ||
172 | if (opacity > 1.0) | |
173 | opacity = 1.0; | |
174 | else if (opacity <= 0) | |
175 | return 0; | |
176 | ||
177 | i_get_combine(combine, &combinef_8, &combinef_double); | |
178 | ||
179 | i_render_init(&r, out, width); | |
180 | #code out->bits <= 8 && src->bits <= 8 | |
181 | IM_COLOR *src_line = mymalloc(sizeof(IM_COLOR) * width); | |
182 | IM_SAMPLE_T *mask_line = NULL; | |
183 | int adapt_channels = out->channels; | |
184 | ||
185 | if (opacity != 1.0) { | |
186 | int i; | |
187 | IM_SAMPLE_T mask_value = IM_ROUND(opacity * IM_SAMPLE_MAX); | |
188 | mask_line = mymalloc(sizeof(IM_SAMPLE_T) * width); | |
189 | ||
190 | for (i = 0; i < width; ++i) | |
191 | mask_line[i] = mask_value; | |
192 | } | |
193 | ||
194 | if (adapt_channels == 1 || adapt_channels == 3) | |
195 | ++adapt_channels; | |
196 | ||
197 | for (dy = 0; dy < height; ++dy) { | |
198 | IM_GLIN(src, src_left, src_left + width, src_top + dy, src_line); | |
199 | IM_ADAPT_COLORS(adapt_channels, src->channels, src_line, width); | |
200 | IM_RENDER_LINE(&r, out_left, out_top+dy, width, mask_line, src_line, | |
201 | IM_SUFFIX(combinef)); | |
202 | } | |
203 | myfree(src_line); | |
204 | if (mask_line) | |
205 | myfree(mask_line); | |
206 | ||
207 | #/code | |
208 | i_render_done(&r); | |
209 | ||
210 | return 1; | |
211 | } |