File Coverage

compose.im
Criterion Covered Total %
statement 154 154 100.0
branch 110 134 82.0
condition n/a
subroutine n/a
pod n/a
total 264 288 91.6


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