Skip to content

HTTPS clone URL

Subversion checkout URL

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