File Coverage

maskimg.c
Criterion Covered Total %
statement 276 276 100.0
branch 227 254 89.3
condition n/a
subroutine n/a
pod n/a
total 503 530 94.9


line stmt bran cond sub pod time code
1             /*
2             =head1 NAME
3              
4             maskimg.c - implements masked images/image subsets
5              
6             =head1 SYNOPSIS
7              
8             =head1 DESCRIPTION
9              
10             =over
11             =cut
12             */
13              
14             #define IMAGER_NO_CONTEXT
15              
16             #include "imager.h"
17             #include "imageri.h"
18              
19             #include
20             /*
21             =item i_img_mask_ext
22              
23             A pointer to this type of object is kept in the ext_data of a masked
24             image.
25              
26             =cut
27             */
28              
29             typedef struct {
30             i_img *targ;
31             i_img *mask;
32             i_img_dim xbase, ybase;
33             i_sample_t *samps; /* temp space */
34             } i_img_mask_ext;
35              
36             #define MASKEXT(im) ((i_img_mask_ext *)((im)->ext_data))
37              
38             static void i_destroy_masked(i_img *im);
39             static int i_ppix_masked(i_img *im, i_img_dim x, i_img_dim y, const i_color *pix);
40             static int i_ppixf_masked(i_img *im, i_img_dim x, i_img_dim y, const i_fcolor *pix);
41             static i_img_dim i_plin_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_color *vals);
42             static i_img_dim i_plinf_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_fcolor *vals);
43             static int i_gpix_masked(i_img *im, i_img_dim x, i_img_dim y, i_color *pix);
44             static int i_gpixf_masked(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *pix);
45             static i_img_dim i_glin_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_color *vals);
46             static i_img_dim i_glinf_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fcolor *vals);
47             static i_img_dim i_gsamp_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_sample_t *samp,
48             int const *chans, int chan_count);
49             static i_img_dim i_gsampf_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fsample_t *samp,
50             int const *chans, int chan_count);
51             static i_img_dim i_gpal_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_palidx *vals);
52             static i_img_dim i_ppal_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_palidx *vals);
53             static i_img_dim
54             psamp_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y,
55             const i_sample_t *samples, const int *chans, int chan_count);
56             static i_img_dim
57             psampf_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y,
58             const i_fsample_t *samples, const int *chans, int chan_count);
59              
60             /*
61             =item IIM_base_masked
62              
63             The basic data we copy into a masked image.
64              
65             =cut
66             */
67             static i_img IIM_base_masked =
68             {
69             0, /* channels set */
70             0, 0, 0, /* xsize, ysize, bytes */
71             ~0U, /* ch_mask */
72             i_8_bits, /* bits */
73             i_palette_type, /* type */
74             1, /* virtual */
75             NULL, /* idata */
76             { 0, 0, NULL }, /* tags */
77             NULL, /* ext_data */
78              
79             i_ppix_masked, /* i_f_ppix */
80             i_ppixf_masked, /* i_f_ppixf */
81             i_plin_masked, /* i_f_plin */
82             i_plinf_masked, /* i_f_plinf */
83             i_gpix_masked, /* i_f_gpix */
84             i_gpixf_masked, /* i_f_gpixf */
85             i_glin_masked, /* i_f_glin */
86             i_glinf_masked, /* i_f_glinf */
87             i_gsamp_masked, /* i_f_gsamp */
88             i_gsampf_masked, /* i_f_gsampf */
89              
90             i_gpal_masked, /* i_f_gpal */
91             i_ppal_masked, /* i_f_ppal */
92             i_addcolors_forward, /* i_f_addcolors */
93             i_getcolors_forward, /* i_f_getcolors */
94             i_colorcount_forward, /* i_f_colorcount */
95             i_maxcolors_forward, /* i_f_maxcolors */
96             i_findcolor_forward, /* i_f_findcolor */
97             i_setcolors_forward, /* i_f_setcolors */
98              
99             i_destroy_masked, /* i_f_destroy */
100              
101             NULL, /* i_f_gsamp_bits */
102             NULL, /* i_f_psamp_bits */
103              
104             psamp_masked, /* i_f_psamp */
105             psampf_masked /* i_f_psampf */
106             };
107              
108             /*
109             =item i_img_masked_new(i_img *targ, i_img *mask, i_img_dim xbase, i_img_dim ybase, i_img_dim w, i_img_dim h)
110              
111             Create a new masked image.
112              
113             The image mask is optional, in which case the image is just a view of
114             a rectangular portion of the image.
115              
116             The mask only has an effect of writing to the image, the entire view
117             of the underlying image is readable.
118              
119             pixel access to mimg(x,y) is translated to targ(x+xbase, y+ybase), as long
120             as (0 <= x < w) and (0 <= y < h).
121              
122             For a pixel to be writable, the pixel mask(x,y) must have non-zero in
123             it's first channel. No scaling of the pixel is done, the channel
124             sample is treated as boolean.
125              
126             =cut
127             */
128              
129             i_img *
130 17           i_img_masked_new(i_img *targ, i_img *mask, i_img_dim x, i_img_dim y, i_img_dim w, i_img_dim h) {
131             i_img *im;
132             i_img_mask_ext *ext;
133 17           dIMCTXim(targ);
134              
135 17           im_clear_error(aIMCTX);
136 17 100         if (x >= targ->xsize || y >= targ->ysize) {
    50          
137 1           im_push_error(aIMCTX, 0, "subset outside of target image");
138 1           return NULL;
139             }
140 16 100         if (mask) {
141 7 100         if (w > mask->xsize)
142 3           w = mask->xsize;
143 7 100         if (h > mask->ysize)
144 3           h = mask->ysize;
145             }
146 16 100         if (x+w > targ->xsize)
147 1           w = targ->xsize - x;
148 16 100         if (y+h > targ->ysize)
149 1           h = targ->ysize - y;
150              
151 16           im = im_img_alloc(aIMCTX);
152              
153 16           memcpy(im, &IIM_base_masked, sizeof(i_img));
154 16           i_tags_new(&im->tags);
155 16           im->xsize = w;
156 16           im->ysize = h;
157 16           im->channels = targ->channels;
158 16           im->bits = targ->bits;
159 16           im->type = targ->type;
160 16           ext = mymalloc(sizeof(*ext));
161 16           ext->targ = targ;
162 16           ext->mask = mask;
163 16           ext->xbase = x;
164 16           ext->ybase = y;
165 16           ext->samps = mymalloc(sizeof(i_sample_t) * im->xsize);
166 16           im->ext_data = ext;
167              
168 16           im_img_init(aIMCTX, im);
169              
170 16           return im;
171             }
172              
173             /*
174             =item i_destroy_masked(i_img *im)
175              
176             The destruction handler for masked images.
177              
178             Releases the ext_data.
179              
180             Internal function.
181              
182             =cut
183             */
184              
185 16           static void i_destroy_masked(i_img *im) {
186 16           myfree(MASKEXT(im)->samps);
187 16           myfree(im->ext_data);
188 16           }
189              
190             /*
191             =item i_ppix_masked(i_img *im, i_img_dim x, i_img_dim y, const i_color *pix)
192              
193             Write a pixel to a masked image.
194              
195             Internal function.
196              
197             =cut
198             */
199 3           static int i_ppix_masked(i_img *im, i_img_dim x, i_img_dim y, const i_color *pix) {
200 3           i_img_mask_ext *ext = MASKEXT(im);
201             int result;
202              
203 3 50         if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize)
    100          
    50          
    50          
204 1           return -1;
205 2 50         if (ext->mask) {
206             i_sample_t samp;
207            
208 2 50         if (i_gsamp(ext->mask, x, x+1, y, &samp, NULL, 1) && !samp)
    100          
209 2           return 0; /* pretend it was good */
210             }
211 1           result = i_ppix(ext->targ, x + ext->xbase, y + ext->ybase, pix);
212 1           im->type = ext->targ->type;
213 1           return result;
214             }
215              
216             /*
217             =item i_ppixf_masked(i_img *im, i_img_dim x, i_img_dim y, const i_fcolor *pix)
218              
219             Write a pixel to a masked image.
220              
221             Internal function.
222              
223             =cut
224             */
225 3           static int i_ppixf_masked(i_img *im, i_img_dim x, i_img_dim y, const i_fcolor *pix) {
226 3           i_img_mask_ext *ext = MASKEXT(im);
227             int result;
228              
229 3 50         if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize)
    50          
    50          
    100          
230 1           return -1;
231 2 50         if (ext->mask) {
232             i_sample_t samp;
233            
234 2 50         if (i_gsamp(ext->mask, x, x+1, y, &samp, NULL, 1) && !samp)
    100          
235 2           return 0; /* pretend it was good */
236             }
237 1           result = i_ppixf(ext->targ, x + ext->xbase, y + ext->ybase, pix);
238 1           im->type = ext->targ->type;
239 1           return result;
240             }
241              
242             /*
243             =item i_plin_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_color *vals)
244              
245             Write a row of data to a masked image.
246              
247             Internal function.
248              
249             =cut
250             */
251 265           static i_img_dim i_plin_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_color *vals) {
252 265           i_img_mask_ext *ext = MASKEXT(im);
253              
254 265 50         if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
    50          
    100          
    50          
255 264 100         if (r > im->xsize)
256 1           r = im->xsize;
257 264 100         if (ext->mask) {
258             i_img_dim i;
259 213           int simple = 0;
260 213           i_sample_t *samps = ext->samps;
261 213           i_img_dim w = r - l;
262              
263 213           i_gsamp(ext->mask, l, r, y, samps, NULL, 1);
264 213 100         if (w < 10)
265 1           simple = 1;
266             else {
267             /* the idea is to make a fast scan to see how often the state
268             changes */
269 212           i_img_dim changes = 0;
270 15392 100         for (i = 0; i < w-1; ++i)
271 15180 100         if (!samps[i] != !samps[i+1])
272 404           ++changes;
273 212 100         if (changes > w/3) /* just rough */
274 1           simple = 1;
275             }
276 213 100         if (simple) {
277             /* we'd be calling a usually more complicated i_plin function
278             almost as often as the usually simple i_ppix(), so just
279             do a simple scan
280             */
281 26 100         for (i = 0; i < w; ++i) {
282 24 100         if (samps[i])
283 10           i_ppix(ext->targ, l + i + ext->xbase, y + ext->ybase, vals + i);
284             }
285 2           im->type = ext->targ->type;
286 2           return r-l;
287             }
288             else {
289             /* the scan above indicates there should be some contiguous
290             regions, look for them and render
291             */
292             i_img_dim start;
293 211           i = 0;
294 615 100         while (i < w) {
295 4714 100         while (i < w && !samps[i])
    100          
296 4310           ++i;
297 404           start = i;
298 11466 100         while (i < w && samps[i])
    100          
299 11062           ++i;
300 404 100         if (i != start)
301 193           i_plin(ext->targ, l + start + ext->xbase, l + i + ext->xbase,
302             y + ext->ybase, vals + start);
303             }
304 211           im->type = ext->targ->type;
305 211           return w;
306             }
307             }
308             else {
309 51           i_img_dim result = i_plin(ext->targ, l + ext->xbase, r + ext->xbase,
310             y + ext->ybase, vals);
311 51           im->type = ext->targ->type;
312 51           return result;
313             }
314             }
315             else {
316 1           return 0;
317             }
318             }
319              
320             /*
321             =item i_plinf_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_fcolor *vals)
322              
323             Write a row of data to a masked image.
324              
325             Internal function.
326              
327             =cut
328             */
329 5           static i_img_dim i_plinf_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_fcolor *vals) {
330 5           i_img_mask_ext *ext = MASKEXT(im);
331 5 50         if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
    50          
    100          
    50          
332 4 100         if (r > im->xsize)
333 1           r = im->xsize;
334 4 100         if (ext->mask) {
335             i_img_dim i;
336 3           int simple = 0;
337 3           i_sample_t *samps = ext->samps;
338 3           i_img_dim w = r - l;
339              
340 3           i_gsamp(ext->mask, l, r, y, samps, NULL, 1);
341 3 100         if (w < 10)
342 1           simple = 1;
343             else {
344             /* the idea is to make a fast scan to see how often the state
345             changes */
346 2           i_img_dim changes = 0;
347 92 100         for (i = 0; i < w-1; ++i)
348 90 100         if (!samps[i] != !samps[i+1])
349 20           ++changes;
350 2 100         if (changes > w/3) /* just rough */
351 1           simple = 1;
352             }
353 3 100         if (simple) {
354             /* we'd be calling a usually more complicated i_plin function
355             almost as often as the usually simple i_ppix(), so just
356             do a simple scan
357             */
358 26 100         for (i = 0; i < w; ++i) {
359 24 100         if (samps[i])
360 10           i_ppixf(ext->targ, l + i + ext->xbase, y + ext->ybase, vals+i);
361             }
362 2           im->type = ext->targ->type;
363 2           return r-l;
364             }
365             else {
366             /* the scan above indicates there should be some contiguous
367             regions, look for them and render
368             */
369             i_img_dim start;
370 1           i = 0;
371 3 100         while (i < w) {
372 38 100         while (i < w && !samps[i])
    100          
373 36           ++i;
374 2           start = i;
375 38 100         while (i < w && samps[i])
    100          
376 36           ++i;
377 2 100         if (i != start)
378 1           i_plinf(ext->targ, l + start + ext->xbase, l + i + ext->xbase,
379             y + ext->ybase, vals + start);
380             }
381 1           im->type = ext->targ->type;
382 1           return w;
383             }
384             }
385             else {
386 1           i_img_dim result = i_plinf(ext->targ, l + ext->xbase, r + ext->xbase,
387             y + ext->ybase, vals);
388 1           im->type = ext->targ->type;
389 1           return result;
390             }
391             }
392             else {
393 1           return 0;
394             }
395             }
396              
397             /*
398             =item i_gpix_masked(i_img *im, i_img_dim x, i_img_dim y, i_color *pix)
399              
400             Read a pixel from a masked image.
401              
402             Internal.
403              
404             =cut
405             */
406 22529           static int i_gpix_masked(i_img *im, i_img_dim x, i_img_dim y, i_color *pix) {
407 22529           i_img_mask_ext *ext = MASKEXT(im);
408              
409 22529 100         if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize)
    100          
    100          
    100          
410 4           return -1;
411              
412 22525           return i_gpix(ext->targ, x + ext->xbase, y + ext->ybase, pix);
413             }
414              
415             /*
416             =item i_gpixf_masked(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *pix)
417              
418             Read a pixel from a masked image.
419              
420             Internal.
421              
422             =cut
423             */
424 5           static int i_gpixf_masked(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *pix) {
425 5           i_img_mask_ext *ext = MASKEXT(im);
426              
427 5 100         if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize)
    100          
    100          
    100          
428 4           return -1;
429              
430 1           return i_gpixf(ext->targ, x + ext->xbase, y + ext->ybase, pix);
431             }
432              
433 6           static i_img_dim i_glin_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_color *vals) {
434 6           i_img_mask_ext *ext = MASKEXT(im);
435 6 100         if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
    100          
    100          
    100          
436 2 100         if (r > im->xsize)
437 1           r = im->xsize;
438 2           return i_glin(ext->targ, l + ext->xbase, r + ext->xbase,
439             y + ext->ybase, vals);
440             }
441             else {
442 4           return 0;
443             }
444             }
445              
446 6           static i_img_dim i_glinf_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fcolor *vals) {
447 6           i_img_mask_ext *ext = MASKEXT(im);
448 6 100         if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
    100          
    100          
    100          
449 2 100         if (r > im->xsize)
450 1           r = im->xsize;
451 2           return i_glinf(ext->targ, l + ext->xbase, r + ext->xbase,
452             y + ext->ybase, vals);
453             }
454             else {
455 4           return 0;
456             }
457             }
458              
459 310           static i_img_dim i_gsamp_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_sample_t *samp,
460             int const *chans, int chan_count) {
461 310           i_img_mask_ext *ext = MASKEXT(im);
462 310 100         if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
    100          
    100          
    100          
463 306 100         if (r > im->xsize)
464 1           r = im->xsize;
465 306           return i_gsamp(ext->targ, l + ext->xbase, r + ext->xbase,
466             y + ext->ybase, samp, chans, chan_count);
467             }
468             else {
469 4           return 0;
470             }
471             }
472              
473 6           static i_img_dim i_gsampf_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fsample_t *samp,
474             int const *chans, int chan_count) {
475 6           i_img_mask_ext *ext = MASKEXT(im);
476 6 100         if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
    100          
    100          
    100          
477 2 100         if (r > im->xsize)
478 1           r = im->xsize;
479 2           return i_gsampf(ext->targ, l + ext->xbase, r + ext->xbase,
480             y + ext->ybase, samp, chans, chan_count);
481             }
482             else {
483 4           return 0;
484             }
485             }
486              
487 2           static i_img_dim i_gpal_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_palidx *vals) {
488 2           i_img_mask_ext *ext = MASKEXT(im);
489 2 50         if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
    50          
    50          
    100          
490 1 50         if (r > im->xsize)
491 1           r = im->xsize;
492 1 50         return i_gpal(ext->targ, l + ext->xbase, r + ext->xbase,
493             y + ext->ybase, vals);
494             }
495             else {
496 1           return 0;
497             }
498             }
499              
500 4           static i_img_dim i_ppal_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_palidx *vals) {
501 4           i_img_mask_ext *ext = MASKEXT(im);
502 4 50         if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
    50          
    50          
    100          
503 3 100         if (r > im->xsize)
504 1           r = im->xsize;
505 3 100         if (ext->mask) {
506             i_img_dim i;
507 2           i_sample_t *samps = ext->samps;
508 2           i_img_dim w = r - l;
509             i_img_dim start;
510            
511 2           i_gsamp(ext->mask, l, r, y, samps, NULL, 1);
512 2           i = 0;
513 5 100         while (i < w) {
514 14 100         while (i < w && !samps[i])
    100          
515 11           ++i;
516 3           start = i;
517 42 100         while (i < w && samps[i])
    100          
518 39           ++i;
519 3 100         if (i != start)
520 1 50         i_ppal(ext->targ, l+start+ext->xbase, l+i+ext->xbase,
521             y+ext->ybase, vals+start);
522             }
523 2           return w;
524             }
525             else {
526 1 50         return i_ppal(ext->targ, l + ext->xbase, r + ext->xbase,
527             y + ext->ybase, vals);
528             }
529             }
530             else {
531 1           return 0;
532             }
533             }
534              
535             /*
536             =item psamp_masked()
537              
538             i_psamp() implementation for masked images.
539              
540             =cut
541             */
542              
543             static i_img_dim
544 25           psamp_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y,
545             const i_sample_t *samples, const int *chans, int chan_count) {
546 25           i_img_mask_ext *ext = MASKEXT(im);
547              
548 25 100         if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
    100          
    100          
    100          
549 17           unsigned old_ch_mask = ext->targ->ch_mask;
550 17           i_img_dim result = 0;
551 17           ext->targ->ch_mask = im->ch_mask;
552 17 100         if (r > im->xsize)
553 2           r = im->xsize;
554 17 100         if (ext->mask) {
555 9           i_img_dim w = r - l;
556 9           i_img_dim i = 0;
557 9           i_img_dim x = ext->xbase + l;
558 9           i_img_dim work_y = y + ext->ybase;
559 9           i_sample_t *mask_samps = ext->samps;
560            
561 9           i_gsamp(ext->mask, l, r, y, mask_samps, NULL, 1);
562             /* not optimizing this yet */
563 22 100         while (i < w) {
564 13 100         if (mask_samps[i]) {
565             /* found a set mask value, try to do a run */
566 10           i_img_dim run_left = x;
567 10           const i_sample_t *run_samps = samples;
568 10           ++i;
569 10           ++x;
570 10           samples += chan_count;
571            
572 26 100         while (i < w && mask_samps[i]) {
    100          
573 16           ++i;
574 16           ++x;
575 16           samples += chan_count;
576             }
577 10           result += i_psamp(ext->targ, run_left, x, work_y, run_samps, chans, chan_count);
578             }
579             else {
580 3           ++i;
581 3           ++x;
582 3           samples += chan_count;
583 3           result += chan_count; /* pretend we wrote masked off pixels */
584             }
585             }
586             }
587             else {
588 8           result = i_psamp(ext->targ, l + ext->xbase, r + ext->xbase,
589             y + ext->ybase, samples, chans, chan_count);
590 8           im->type = ext->targ->type;
591             }
592 17           ext->targ->ch_mask = old_ch_mask;
593 17           return result;
594             }
595             else {
596 8           dIMCTXim(im);
597 8           i_push_error(0, "Image position outside of image");
598 8           return -1;
599             }
600             }
601              
602             /*
603             =item psampf_masked()
604              
605             i_psampf() implementation for masked images.
606              
607             =cut
608             */
609              
610             static i_img_dim
611 25           psampf_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y,
612             const i_fsample_t *samples, const int *chans, int chan_count) {
613 25           i_img_mask_ext *ext = MASKEXT(im);
614              
615 25 100         if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
    100          
    100          
    100          
616 17           i_img_dim result = 0;
617 17           unsigned old_ch_mask = ext->targ->ch_mask;
618 17           ext->targ->ch_mask = im->ch_mask;
619 17 100         if (r > im->xsize)
620 2           r = im->xsize;
621 17 100         if (ext->mask) {
622 9           i_img_dim w = r - l;
623 9           i_img_dim i = 0;
624 9           i_img_dim x = ext->xbase + l;
625 9           i_img_dim work_y = y + ext->ybase;
626 9           i_sample_t *mask_samps = ext->samps;
627            
628 9           i_gsamp(ext->mask, l, r, y, mask_samps, NULL, 1);
629             /* not optimizing this yet */
630 22 100         while (i < w) {
631 13 100         if (mask_samps[i]) {
632             /* found a set mask value, try to do a run */
633 10           i_img_dim run_left = x;
634 10           const i_fsample_t *run_samps = samples;
635 10           ++i;
636 10           ++x;
637 10           samples += chan_count;
638            
639 26 100         while (i < w && mask_samps[i]) {
    100          
640 16           ++i;
641 16           ++x;
642 16           samples += chan_count;
643             }
644 10           result += i_psampf(ext->targ, run_left, x, work_y, run_samps, chans, chan_count);
645             }
646             else {
647 3           ++i;
648 3           ++x;
649 3           samples += chan_count;
650 3           result += chan_count; /* pretend we wrote masked off pixels */
651             }
652             }
653             }
654             else {
655 8           result = i_psampf(ext->targ, l + ext->xbase, r + ext->xbase,
656             y + ext->ybase, samples,
657             chans, chan_count);
658 8           im->type = ext->targ->type;
659             }
660 17           ext->targ->ch_mask = old_ch_mask;
661 17           return result;
662             }
663             else {
664 8           dIMCTXim(im);
665 8           i_push_error(0, "Image position outside of image");
666 8           return -1;
667             }
668             }
669              
670              
671             /*
672             =back
673              
674             =head1 AUTHOR
675              
676             Tony Cook
677              
678             =head1 SEE ALSO
679              
680             Imager(3)
681              
682             =cut
683             */