File Coverage

img8.c
Criterion Covered Total %
statement 226 268 84.3
branch 217 270 80.3
condition n/a
subroutine n/a
pod n/a
total 443 538 82.3


line stmt bran cond sub pod time code
1             #define IMAGER_NO_CONTEXT
2              
3             #include "imager.h"
4             #include "imageri.h"
5              
6             static int i_ppix_d(i_img *im, i_img_dim x, i_img_dim y, const i_color *val);
7             static int i_gpix_d(i_img *im, i_img_dim x, i_img_dim y, i_color *val);
8             static i_img_dim i_glin_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_color *vals);
9             static i_img_dim i_plin_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_color *vals);
10             static int i_ppixf_d(i_img *im, i_img_dim x, i_img_dim y, const i_fcolor *val);
11             static int i_gpixf_d(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *val);
12             static i_img_dim i_glinf_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fcolor *vals);
13             static i_img_dim i_plinf_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_fcolor *vals);
14             static i_img_dim i_gsamp_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_sample_t *samps, const int *chans, int chan_count);
15             static i_img_dim i_gsampf_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fsample_t *samps, const int *chans, int chan_count);
16             static i_img_dim i_psamp_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_sample_t *samps, const int *chans, int chan_count);
17             static i_img_dim i_psampf_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_fsample_t *samps, const int *chans, int chan_count);
18              
19             /*
20             =item IIM_base_8bit_direct (static)
21              
22             A static i_img object used to initialize direct 8-bit per sample images.
23              
24             =cut
25             */
26             static i_img IIM_base_8bit_direct =
27             {
28             0, /* channels set */
29             0, 0, 0, /* xsize, ysize, bytes */
30             ~0U, /* ch_mask */
31             i_8_bits, /* bits */
32             i_direct_type, /* type */
33             0, /* virtual */
34             NULL, /* idata */
35             { 0, 0, NULL }, /* tags */
36             NULL, /* ext_data */
37              
38             i_ppix_d, /* i_f_ppix */
39             i_ppixf_d, /* i_f_ppixf */
40             i_plin_d, /* i_f_plin */
41             i_plinf_d, /* i_f_plinf */
42             i_gpix_d, /* i_f_gpix */
43             i_gpixf_d, /* i_f_gpixf */
44             i_glin_d, /* i_f_glin */
45             i_glinf_d, /* i_f_glinf */
46             i_gsamp_d, /* i_f_gsamp */
47             i_gsampf_d, /* i_f_gsampf */
48              
49             NULL, /* i_f_gpal */
50             NULL, /* i_f_ppal */
51             NULL, /* i_f_addcolors */
52             NULL, /* i_f_getcolors */
53             NULL, /* i_f_colorcount */
54             NULL, /* i_f_maxcolors */
55             NULL, /* i_f_findcolor */
56             NULL, /* i_f_setcolors */
57              
58             NULL, /* i_f_destroy */
59              
60             i_gsamp_bits_fb,
61             NULL, /* i_f_psamp_bits */
62              
63             i_psamp_d,
64             i_psampf_d
65             };
66              
67             /*static void set_8bit_direct(i_img *im) {
68             im->i_f_ppix = i_ppix_d;
69             im->i_f_ppixf = i_ppixf_d;
70             im->i_f_plin = i_plin_d;
71             im->i_f_plinf = i_plinf_d;
72             im->i_f_gpix = i_gpix_d;
73             im->i_f_gpixf = i_gpixf_d;
74             im->i_f_glin = i_glin_d;
75             im->i_f_glinf = i_glinf_d;
76             im->i_f_gpal = NULL;
77             im->i_f_ppal = NULL;
78             im->i_f_addcolor = NULL;
79             im->i_f_getcolor = NULL;
80             im->i_f_colorcount = NULL;
81             im->i_f_findcolor = NULL;
82             }*/
83              
84             /*
85             =item im_img_8_new(ctx, x, y, ch)
86             XX
87             =category Image creation/destruction
88             =synopsis i_img *img = im_img_8_new(aIMCTX, width, height, channels);
89             =synopsis i_img *img = i_img_8_new(width, height, channels);
90              
91             Creates a new image object I pixels wide, and I pixels high with
92             I channels.
93              
94             =cut
95             */
96              
97             i_img *
98 662           im_img_8_new(pIMCTX, i_img_dim x,i_img_dim y,int ch) {
99             i_img *im;
100              
101 662           im_log((aIMCTX, 1,"im_img_8_new(x %" i_DF ", y %" i_DF ", ch %d)\n",
102             i_DFc(x), i_DFc(y), ch));
103              
104 662           im = im_img_empty_ch(aIMCTX, NULL,x,y,ch);
105            
106 662           im_log((aIMCTX, 1,"(%p) <- IIM_new\n",im));
107 662           return im;
108             }
109              
110             /*
111             =item i_img_empty(im, x, y)
112              
113             Re-new image reference (assumes 3 channels)
114              
115             im - Image pointer
116             x - xsize of destination image
117             y - ysize of destination image
118              
119             **FIXME** what happens if a live image is passed in here?
120              
121             Should this just call i_img_empty_ch()?
122              
123             =cut
124             */
125              
126             i_img *
127 0           im_img_empty(pIMCTX, i_img *im,i_img_dim x,i_img_dim y) {
128 0           im_log((aIMCTX, 1,"i_img_empty(*im %p, x %" i_DF ", y %" i_DF ")\n",
129             im, i_DFc(x), i_DFc(y)));
130 0           return im_img_empty_ch(aIMCTX, im, x, y, 3);
131             }
132              
133             /*
134             =item i_img_empty_ch(im, x, y, ch)
135              
136             Re-new image reference
137              
138             im - Image pointer
139             x - xsize of destination image
140             y - ysize of destination image
141             ch - number of channels
142              
143             =cut
144             */
145              
146             i_img *
147 1105           im_img_empty_ch(pIMCTX, i_img *im,i_img_dim x,i_img_dim y,int ch) {
148             size_t bytes;
149              
150 1105           im_log((aIMCTX, 1,"i_img_empty_ch(*im %p, x %" i_DF ", y %" i_DF ", ch %d)\n",
151             im, i_DFc(x), i_DFc(y), ch));
152              
153 1105 100         if (x < 1 || y < 1) {
    100          
154 5           im_push_error(aIMCTX, 0, "Image sizes must be positive");
155 5           return NULL;
156             }
157 1100 100         if (ch < 1 || ch > MAXCHANNELS) {
    100          
158 2           im_push_errorf(aIMCTX, 0, "channels must be between 1 and %d", MAXCHANNELS);
159 2           return NULL;
160             }
161             /* check this multiplication doesn't overflow */
162 1098           bytes = x*y*ch;
163 1098 50         if (bytes / y / ch != x) {
164 0           im_push_errorf(aIMCTX, 0, "integer overflow calculating image allocation");
165 0           return NULL;
166             }
167              
168 1098 100         if (im == NULL)
169 1089           im = im_img_alloc(aIMCTX);
170              
171 1098           memcpy(im, &IIM_base_8bit_direct, sizeof(i_img));
172 1098           i_tags_new(&im->tags);
173 1098           im->xsize = x;
174 1098           im->ysize = y;
175 1098           im->channels = ch;
176 1098           im->ch_mask = ~0U;
177 1098           im->bytes=bytes;
178 1098 50         if ( (im->idata=mymalloc(im->bytes)) == NULL)
179 0           im_fatal(aIMCTX, 2,"malloc() error\n");
180 1098           memset(im->idata,0,(size_t)im->bytes);
181            
182 1098           im->ext_data = NULL;
183              
184 1098           im_img_init(aIMCTX, im);
185            
186 1098           im_log((aIMCTX, 1,"(%p) <- i_img_empty_ch\n",im));
187 1098           return im;
188             }
189              
190             /*
191             =head2 8-bit per sample image internal functions
192              
193             These are the functions installed in an 8-bit per sample image.
194              
195             =over
196              
197             =item i_ppix_d(im, x, y, col)
198              
199             Internal function.
200              
201             This is the function kept in the i_f_ppix member of an i_img object.
202             It does a normal store of a pixel into the image with range checking.
203              
204             Returns 0 if the pixel could be set, -1 otherwise.
205              
206             =cut
207             */
208             static
209             int
210 5534316           i_ppix_d(i_img *im, i_img_dim x, i_img_dim y, const i_color *val) {
211             int ch;
212            
213 5534316 100         if ( x>-1 && xxsize && y>-1 && yysize ) {
    100          
    100          
    100          
214 21738475 100         for(ch=0;chchannels;ch++)
215 16231919 100         if (im->ch_mask&(1<
216 16231918           im->idata[(x+y*im->xsize)*im->channels+ch]=val->channel[ch];
217 5506556           return 0;
218             }
219 27760           return -1; /* error was clipped */
220             }
221              
222             /*
223             =item i_gpix_d(im, x, y, &col)
224              
225             Internal function.
226              
227             This is the function kept in the i_f_gpix member of an i_img object.
228             It does normal retrieval of a pixel from the image with range checking.
229              
230             Returns 0 if the pixel could be retrieved, -1 otherwise.
231              
232             =cut
233             */
234             static
235             int
236 24129364           i_gpix_d(i_img *im, i_img_dim x, i_img_dim y, i_color *val) {
237             int ch;
238 24129364 100         if (x>-1 && xxsize && y>-1 && yysize) {
    100          
    100          
    100          
239 94325970 100         for(ch=0;chchannels;ch++)
240 70336360           val->channel[ch]=im->idata[(x+y*im->xsize)*im->channels+ch];
241 23989610           return 0;
242             }
243 559748 100         for(ch=0;chchannels;ch++) val->channel[ch] = 0;
244 139754           return -1; /* error was cliped */
245             }
246              
247             /*
248             =item i_glin_d(im, l, r, y, vals)
249              
250             Reads a line of data from the image, storing the pixels at vals.
251              
252             The line runs from (l,y) inclusive to (r,y) non-inclusive
253              
254             vals should point at space for (r-l) pixels.
255              
256             l should never be less than zero (to avoid confusion about where to
257             put the pixels in vals).
258              
259             Returns the number of pixels copied (eg. if r, l or y is out of range)
260              
261             =cut
262             */
263             static
264             i_img_dim
265 156771           i_glin_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_color *vals) {
266             int ch;
267             i_img_dim count, i;
268             unsigned char *data;
269 156771 50         if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
    50          
    50          
    50          
270 156771 50         if (r > im->xsize)
271 0           r = im->xsize;
272 156771           data = im->idata + (l+y*im->xsize) * im->channels;
273 156771           count = r - l;
274 4655845 100         for (i = 0; i < count; ++i) {
275 17744954 100         for (ch = 0; ch < im->channels; ++ch)
276 13245880           vals[i].channel[ch] = *data++;
277             }
278 156771           return count;
279             }
280             else {
281 0           return 0;
282             }
283             }
284              
285             /*
286             =item i_plin_d(im, l, r, y, vals)
287              
288             Writes a line of data into the image, using the pixels at vals.
289              
290             The line runs from (l,y) inclusive to (r,y) non-inclusive
291              
292             vals should point at (r-l) pixels.
293              
294             l should never be less than zero (to avoid confusion about where to
295             get the pixels in vals).
296              
297             Returns the number of pixels copied (eg. if r, l or y is out of range)
298              
299             =cut
300             */
301             static
302             i_img_dim
303 507020           i_plin_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_color *vals) {
304             int ch;
305             i_img_dim count, i;
306             unsigned char *data;
307 507020 50         if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
    100          
    50          
    50          
308 506960 100         if (r > im->xsize)
309 300           r = im->xsize;
310 506960           data = im->idata + (l+y*im->xsize) * im->channels;
311 506960           count = r - l;
312 7867903 100         for (i = 0; i < count; ++i) {
313 28707925 100         for (ch = 0; ch < im->channels; ++ch) {
314 21346982 100         if (im->ch_mask & (1 << ch))
315 20420761           *data = vals[i].channel[ch];
316 21346982           ++data;
317             }
318             }
319 506960           return count;
320             }
321             else {
322 60           return 0;
323             }
324             }
325              
326             /*
327             =item i_ppixf_d(im, x, y, val)
328              
329             =cut
330             */
331             static
332             int
333 17           i_ppixf_d(i_img *im, i_img_dim x, i_img_dim y, const i_fcolor *val) {
334             int ch;
335            
336 17 100         if ( x>-1 && xxsize && y>-1 && yysize ) {
    100          
    100          
    100          
337 40 100         for(ch=0;chchannels;ch++)
338 30 100         if (im->ch_mask&(1<
339 29           im->idata[(x+y*im->xsize)*im->channels+ch] =
340 29           SampleFTo8(val->channel[ch]);
341             }
342 10           return 0;
343             }
344 7           return -1; /* error was clipped */
345             }
346              
347             /*
348             =item i_gpixf_d(im, x, y, val)
349              
350             =cut
351             */
352             static
353             int
354 18           i_gpixf_d(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *val) {
355             int ch;
356 18 100         if (x>-1 && xxsize && y>-1 && yysize) {
    100          
    50          
    50          
357 64 100         for(ch=0;chchannels;ch++) {
358 48           val->channel[ch] =
359 48           Sample8ToF(im->idata[(x+y*im->xsize)*im->channels+ch]);
360             }
361 16           return 0;
362             }
363 2           return -1; /* error was cliped */
364             }
365              
366             /*
367             =item i_glinf_d(im, l, r, y, vals)
368              
369             Reads a line of data from the image, storing the pixels at vals.
370              
371             The line runs from (l,y) inclusive to (r,y) non-inclusive
372              
373             vals should point at space for (r-l) pixels.
374              
375             l should never be less than zero (to avoid confusion about where to
376             put the pixels in vals).
377              
378             Returns the number of pixels copied (eg. if r, l or y is out of range)
379              
380             =cut
381             */
382             static
383             i_img_dim
384 2393           i_glinf_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fcolor *vals) {
385             int ch;
386             i_img_dim count, i;
387             unsigned char *data;
388 2393 50         if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
    50          
    50          
    50          
389 2393 50         if (r > im->xsize)
390 0           r = im->xsize;
391 2393           data = im->idata + (l+y*im->xsize) * im->channels;
392 2393           count = r - l;
393 313112 100         for (i = 0; i < count; ++i) {
394 1251169 100         for (ch = 0; ch < im->channels; ++ch)
395 940450           vals[i].channel[ch] = Sample8ToF(*data++);
396             }
397 2393           return count;
398             }
399             else {
400 0           return 0;
401             }
402             }
403              
404             /*
405             =item i_plinf_d(im, l, r, y, vals)
406              
407             Writes a line of data into the image, using the pixels at vals.
408              
409             The line runs from (l,y) inclusive to (r,y) non-inclusive
410              
411             vals should point at (r-l) pixels.
412              
413             l should never be less than zero (to avoid confusion about where to
414             get the pixels in vals).
415              
416             Returns the number of pixels copied (eg. if r, l or y is out of range)
417              
418             =cut
419             */
420             static
421             i_img_dim
422 1438           i_plinf_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_fcolor *vals) {
423             int ch;
424             i_img_dim count, i;
425             unsigned char *data;
426 1438 50         if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
    50          
    50          
    50          
427 1438 50         if (r > im->xsize)
428 0           r = im->xsize;
429 1438           data = im->idata + (l+y*im->xsize) * im->channels;
430 1438           count = r - l;
431 165981 100         for (i = 0; i < count; ++i) {
432 658196 100         for (ch = 0; ch < im->channels; ++ch) {
433 493653 100         if (im->ch_mask & (1 << ch))
434 493652           *data = SampleFTo8(vals[i].channel[ch]);
435 493653           ++data;
436             }
437             }
438 1438           return count;
439             }
440             else {
441 0           return 0;
442             }
443             }
444              
445             /*
446             =item i_gsamp_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_sample_t *samps, int *chans, int chan_count)
447              
448             Reads sample values from im for the horizontal line (l, y) to (r-1,y)
449             for the channels specified by chans, an array of int with chan_count
450             elements.
451              
452             Returns the number of samples read (which should be (r-l) * bits_set(chan_mask)
453              
454             =cut
455             */
456             static
457             i_img_dim
458 205364           i_gsamp_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_sample_t *samps,
459             const int *chans, int chan_count) {
460             int ch;
461             i_img_dim count, i, w;
462             unsigned char *data;
463              
464 205364 50         if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
    50          
    50          
    50          
465 205364 50         if (r > im->xsize)
466 0           r = im->xsize;
467 205364           data = im->idata + (l+y*im->xsize) * im->channels;
468 205364           w = r - l;
469 205364           count = 0;
470              
471 205364 100         if (chans) {
472             /* make sure we have good channel numbers */
473 410277 100         for (ch = 0; ch < chan_count; ++ch) {
474 208148 50         if (chans[ch] < 0 || chans[ch] >= im->channels) {
    50          
475 0           dIMCTXim(im);
476 0           im_push_errorf(aIMCTX, 0, "No channel %d in this image", chans[ch]);
477 0           return 0;
478             }
479             }
480 1348591 100         for (i = 0; i < w; ++i) {
481 3073898 100         for (ch = 0; ch < chan_count; ++ch) {
482 1927436           *samps++ = data[chans[ch]];
483 1927436           ++count;
484             }
485 1146462           data += im->channels;
486             }
487             }
488             else {
489 3235 50         if (chan_count <= 0 || chan_count > im->channels) {
    50          
490 0           dIMCTXim(im);
491 0           im_push_errorf(aIMCTX, 0, "chan_count %d out of range, must be >0, <= channels",
492             chan_count);
493 0           return 0;
494             }
495 383756 100         for (i = 0; i < w; ++i) {
496 1495696 100         for (ch = 0; ch < chan_count; ++ch) {
497 1115175           *samps++ = data[ch];
498 1115175           ++count;
499             }
500 380521           data += im->channels;
501             }
502             }
503              
504 205364           return count;
505             }
506             else {
507 0           return 0;
508             }
509             }
510              
511             /*
512             =item i_gsampf_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fsample_t *samps, int *chans, int chan_count)
513              
514             Reads sample values from im for the horizontal line (l, y) to (r-1,y)
515             for the channels specified by chan_mask, where bit 0 is the first
516             channel.
517              
518             Returns the number of samples read (which should be (r-l) * bits_set(chan_mask)
519              
520             =cut
521             */
522             static
523             i_img_dim
524 154           i_gsampf_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fsample_t *samps,
525             const int *chans, int chan_count) {
526             int ch;
527             i_img_dim count, i, w;
528             unsigned char *data;
529 316 100         for (ch = 0; ch < chan_count; ++ch) {
530 162 50         if (chans[ch] < 0 || chans[ch] >= im->channels) {
    50          
531 0           dIMCTXim(im);
532 0           im_push_errorf(aIMCTX, 0, "No channel %d in this image", chans[ch]);
533             }
534             }
535 154 50         if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
    50          
    50          
    50          
536 154 50         if (r > im->xsize)
537 0           r = im->xsize;
538 154           data = im->idata + (l+y*im->xsize) * im->channels;
539 154           w = r - l;
540 154           count = 0;
541              
542 154 50         if (chans) {
543             /* make sure we have good channel numbers */
544 316 100         for (ch = 0; ch < chan_count; ++ch) {
545 162 50         if (chans[ch] < 0 || chans[ch] >= im->channels) {
    50          
546 0           dIMCTXim(im);
547 0           im_push_errorf(aIMCTX, 0, "No channel %d in this image", chans[ch]);
548 0           return 0;
549             }
550             }
551 22676 100         for (i = 0; i < w; ++i) {
552 45088 100         for (ch = 0; ch < chan_count; ++ch) {
553 22566           *samps++ = Sample8ToF(data[chans[ch]]);
554 22566           ++count;
555             }
556 22522           data += im->channels;
557             }
558             }
559             else {
560 0 0         if (chan_count <= 0 || chan_count > im->channels) {
    0          
561 0           dIMCTXim(im);
562 0           im_push_errorf(aIMCTX, 0, "chan_count %d out of range, must be >0, <= channels",
563             chan_count);
564 0           return 0;
565             }
566 0 0         for (i = 0; i < w; ++i) {
567 0 0         for (ch = 0; ch < chan_count; ++ch) {
568 0           *samps++ = Sample8ToF(data[ch]);
569 0           ++count;
570             }
571 0           data += im->channels;
572             }
573             }
574 154           return count;
575             }
576             else {
577 0           return 0;
578             }
579             }
580              
581             /*
582             =item i_psamp_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_sample_t *samps, int *chans, int chan_count)
583              
584             Writes sample values to im for the horizontal line (l, y) to (r-1,y)
585             for the channels specified by chans, an array of int with chan_count
586             elements.
587              
588             Returns the number of samples written (which should be (r-l) *
589             bits_set(chan_mask)
590              
591             =cut
592             */
593              
594             static
595             i_img_dim
596 197           i_psamp_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y,
597             const i_sample_t *samps, const int *chans, int chan_count) {
598             int ch;
599             i_img_dim count, i, w;
600             unsigned char *data;
601              
602 197 100         if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
    100          
    100          
    100          
603 192 100         if (r > im->xsize)
604 1           r = im->xsize;
605 192           data = im->idata + (l+y*im->xsize) * im->channels;
606 192           w = r - l;
607 192           count = 0;
608              
609 192 100         if (chans) {
610             /* make sure we have good channel numbers */
611             /* and test if all channels specified are in the mask */
612 19           int all_in_mask = 1;
613 66 100         for (ch = 0; ch < chan_count; ++ch) {
614 54 100         if (chans[ch] < 0 || chans[ch] >= im->channels) {
    100          
615 7           dIMCTXim(im);
616 7           im_push_errorf(aIMCTX, 0, "No channel %d in this image", chans[ch]);
617 7           return -1;
618             }
619 47 100         if (!((1 << chans[ch]) & im->ch_mask))
620 3           all_in_mask = 0;
621             }
622 12 100         if (all_in_mask) {
623 51 100         for (i = 0; i < w; ++i) {
624 162 100         for (ch = 0; ch < chan_count; ++ch) {
625 120           data[chans[ch]] = *samps++;
626 120           ++count;
627             }
628 42           data += im->channels;
629             }
630             }
631             else {
632 15 100         for (i = 0; i < w; ++i) {
633 12 100         for (ch = 0; ch < chan_count; ++ch) {
634 9 100         if (im->ch_mask & (1 << (chans[ch])))
635 6           data[chans[ch]] = *samps;
636 9           ++samps;
637 9           ++count;
638             }
639 3           data += im->channels;
640             }
641             }
642             }
643             else {
644 173 50         if (chan_count <= 0 || chan_count > im->channels) {
    50          
645 0           dIMCTXim(im);
646 0           im_push_errorf(aIMCTX, 0, "chan_count %d out of range, must be >0, <= channels",
647             chan_count);
648 0           return -1;
649             }
650 22806 100         for (i = 0; i < w; ++i) {
651 22633           unsigned mask = 1;
652 90532 100         for (ch = 0; ch < chan_count; ++ch) {
653 67899 100         if (im->ch_mask & mask)
654 67896           data[ch] = *samps;
655 67899           ++samps;
656 67899           ++count;
657 67899           mask <<= 1;
658             }
659 22633           data += im->channels;
660             }
661             }
662              
663 185           return count;
664             }
665             else {
666 5           dIMCTXim(im);
667 5           i_push_error(0, "Image position outside of image");
668 5           return -1;
669             }
670             }
671              
672             /*
673             =item i_psampf_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_fsample_t *samps, int *chans, int chan_count)
674              
675             Writes sample values to im for the horizontal line (l, y) to (r-1,y)
676             for the channels specified by chans, an array of int with chan_count
677             elements.
678              
679             Returns the number of samples written (which should be (r-l) *
680             bits_set(chan_mask)
681              
682             =cut
683             */
684              
685             static
686             i_img_dim
687 37           i_psampf_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y,
688             const i_fsample_t *samps, const int *chans, int chan_count) {
689             int ch;
690             i_img_dim count, i, w;
691             unsigned char *data;
692              
693 37 100         if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
    100          
    100          
    100          
694 32 100         if (r > im->xsize)
695 1           r = im->xsize;
696 32           data = im->idata + (l+y*im->xsize) * im->channels;
697 32           w = r - l;
698 32           count = 0;
699              
700 32 100         if (chans) {
701             /* make sure we have good channel numbers */
702             /* and test if all channels specified are in the mask */
703 19           int all_in_mask = 1;
704 66 100         for (ch = 0; ch < chan_count; ++ch) {
705 54 100         if (chans[ch] < 0 || chans[ch] >= im->channels) {
    100          
706 7           dIMCTXim(im);
707 7           im_push_errorf(aIMCTX, 0, "No channel %d in this image", chans[ch]);
708 7           return -1;
709             }
710 47 100         if (!((1 << chans[ch]) & im->ch_mask))
711 3           all_in_mask = 0;
712             }
713 12 100         if (all_in_mask) {
714 51 100         for (i = 0; i < w; ++i) {
715 162 100         for (ch = 0; ch < chan_count; ++ch) {
716 120           data[chans[ch]] = SampleFTo8(*samps);
717 120           ++samps;
718 120           ++count;
719             }
720 42           data += im->channels;
721             }
722             }
723             else {
724 15 100         for (i = 0; i < w; ++i) {
725 12 100         for (ch = 0; ch < chan_count; ++ch) {
726 9 100         if (im->ch_mask & (1 << (chans[ch])))
727 6           data[chans[ch]] = SampleFTo8(*samps);
728 9           ++samps;
729 9           ++count;
730             }
731 3           data += im->channels;
732             }
733             }
734             }
735             else {
736 13 50         if (chan_count <= 0 || chan_count > im->channels) {
    50          
737 0           dIMCTXim(im);
738 0           im_push_errorf(aIMCTX, 0, "chan_count %d out of range, must be >0, <= channels",
739             chan_count);
740 0           return -1;
741             }
742 45 100         for (i = 0; i < w; ++i) {
743 32           unsigned mask = 1;
744 128 100         for (ch = 0; ch < chan_count; ++ch) {
745 96 100         if (im->ch_mask & mask)
746 93           data[ch] = SampleFTo8(*samps);
747 96           ++samps;
748 96           ++count;
749 96           mask <<= 1;
750             }
751 32           data += im->channels;
752             }
753             }
754              
755 25           return count;
756             }
757             else {
758 5           dIMCTXim(im);
759 5           i_push_error(0, "Image position outside of image");
760 5           return -1;
761             }
762             }
763              
764             /*
765             =back
766              
767             =head1 AUTHOR
768              
769             Arnar M. Hrafnkelsson
770              
771             Tony Cook
772              
773             =head1 SEE ALSO
774              
775             L
776              
777             =cut
778             */