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);
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);
18 =item IIM_base_8bit_direct (static)
20 A static i_img object used to initialize direct 8-bit per sample images.
24 static i_img IIM_base_8bit_direct =
27 0, 0, 0, /* xsize, ysize, bytes */
30 i_direct_type, /* type */
33 { 0, 0, NULL }, /* tags */
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 */
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 */
56 NULL, /* i_f_destroy */
59 NULL, /* i_f_psamp_bits */
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;
76 im->i_f_addcolor = NULL;
77 im->i_f_getcolor = NULL;
78 im->i_f_colorcount = NULL;
79 im->i_f_findcolor = NULL;
83 =item IIM_new(x, y, ch)
85 =item i_img_8_new(x, y, ch)
87 =category Image creation/destruction
89 =synopsis i_img *img = i_img_8_new(width, height, channels);
91 Creates a new image object I<x> pixels wide, and I<y> pixels high with
99 IIM_new(i_img_dim x,i_img_dim y,int ch) {
102 mm_log((1,"IIM_new(x %" i_DF ", y %" i_DF ", ch %d)\n",
103 i_DFc(x), i_DFc(y), ch));
105 im=i_img_empty_ch(NULL,x,y,ch);
107 mm_log((1,"(%p) <- IIM_new\n",im));
113 IIM_DESTROY(i_img *im) {
114 mm_log((1,"IIM_DESTROY(im* %p)\n",im));
122 Create new image reference - notice that this isn't an object yet and
123 this should be fixed asap.
133 mm_log((1,"i_img_struct()\n"));
137 *im = IIM_base_8bit_direct;
147 mm_log((1,"(%p) <- i_img_struct\n",im));
152 =item i_img_empty(im, x, y)
154 Re-new image reference (assumes 3 channels)
157 x - xsize of destination image
158 y - ysize of destination image
160 **FIXME** what happens if a live image is passed in here?
162 Should this just call i_img_empty_ch()?
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)));
171 return i_img_empty_ch(im, x, y, 3);
175 =item i_img_empty_ch(im, x, y, ch)
177 Re-new image reference
180 x - xsize of destination image
181 y - ysize of destination image
182 ch - number of channels
188 i_img_empty_ch(i_img *im,i_img_dim x,i_img_dim y,int ch) {
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));
194 if (x < 1 || y < 1) {
195 i_push_error(0, "Image sizes must be positive");
198 if (ch < 1 || ch > MAXCHANNELS) {
199 i_push_errorf(0, "channels must be between 1 and %d", MAXCHANNELS);
202 /* check this multiplication doesn't overflow */
204 if (bytes / y / ch != x) {
205 i_push_errorf(0, "integer overflow calculating image allocation");
212 memcpy(im, &IIM_base_8bit_direct, sizeof(i_img));
213 i_tags_new(&im->tags);
217 im->ch_mask = MAXINT;
219 if ( (im->idata=mymalloc(im->bytes)) == NULL)
220 i_fatal(2,"malloc() error\n");
221 memset(im->idata,0,(size_t)im->bytes);
227 mm_log((1,"(%p) <- i_img_empty_ch\n",im));
232 =head2 8-bit per sample image internal functions
234 These are the functions installed in an 8-bit per sample image.
238 =item i_ppix_d(im, x, y, col)
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.
245 Returns 0 if the pixel could be set, -1 otherwise.
251 i_ppix_d(i_img *im, i_img_dim x, i_img_dim y, const i_color *val) {
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];
260 return -1; /* error was clipped */
264 =item i_gpix_d(im, x, y, &col)
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.
271 Returns 0 if the pixel could be set, -1 otherwise.
277 i_gpix_d(i_img *im, i_img_dim x, i_img_dim y, i_color *val) {
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];
284 for(ch=0;ch<im->channels;ch++) val->channel[ch] = 0;
285 return -1; /* error was cliped */
289 =item i_glin_d(im, l, r, y, vals)
291 Reads a line of data from the image, storing the pixels at vals.
293 The line runs from (l,y) inclusive to (r,y) non-inclusive
295 vals should point at space for (r-l) pixels.
297 l should never be less than zero (to avoid confusion about where to
298 put the pixels in vals).
300 Returns the number of pixels copied (eg. if r, l or y is out of range)
306 i_glin_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_color *vals) {
310 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
313 data = im->idata + (l+y*im->xsize) * im->channels;
315 for (i = 0; i < count; ++i) {
316 for (ch = 0; ch < im->channels; ++ch)
317 vals[i].channel[ch] = *data++;
327 =item i_plin_d(im, l, r, y, vals)
329 Writes a line of data into the image, using the pixels at vals.
331 The line runs from (l,y) inclusive to (r,y) non-inclusive
333 vals should point at (r-l) pixels.
335 l should never be less than zero (to avoid confusion about where to
336 get the pixels in vals).
338 Returns the number of pixels copied (eg. if r, l or y is out of range)
344 i_plin_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_color *vals) {
348 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
351 data = im->idata + (l+y*im->xsize) * im->channels;
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];
368 =item i_ppixf_d(im, x, y, val)
374 i_ppixf_d(i_img *im, i_img_dim x, i_img_dim y, const i_fcolor *val) {
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]);
385 return -1; /* error was clipped */
389 =item i_gpixf_d(im, x, y, val)
395 i_gpixf_d(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *val) {
397 if (x>-1 && x<im->xsize && y>-1 && y<im->ysize) {
398 for(ch=0;ch<im->channels;ch++) {
400 Sample8ToF(im->idata[(x+y*im->xsize)*im->channels+ch]);
404 return -1; /* error was cliped */
408 =item i_glinf_d(im, l, r, y, vals)
410 Reads a line of data from the image, storing the pixels at vals.
412 The line runs from (l,y) inclusive to (r,y) non-inclusive
414 vals should point at space for (r-l) pixels.
416 l should never be less than zero (to avoid confusion about where to
417 put the pixels in vals).
419 Returns the number of pixels copied (eg. if r, l or y is out of range)
425 i_glinf_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fcolor *vals) {
429 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
432 data = im->idata + (l+y*im->xsize) * im->channels;
434 for (i = 0; i < count; ++i) {
435 for (ch = 0; ch < im->channels; ++ch)
436 vals[i].channel[ch] = Sample8ToF(*data++);
446 =item i_plinf_d(im, l, r, y, vals)
448 Writes a line of data into the image, using the pixels at vals.
450 The line runs from (l,y) inclusive to (r,y) non-inclusive
452 vals should point at (r-l) pixels.
454 l should never be less than zero (to avoid confusion about where to
455 get the pixels in vals).
457 Returns the number of pixels copied (eg. if r, l or y is out of range)
463 i_plinf_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_fcolor *vals) {
467 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
470 data = im->idata + (l+y*im->xsize) * im->channels;
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]);
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)
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
493 Returns the number of samples read (which should be (r-l) * bits_set(chan_mask)
499 i_gsamp_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_sample_t *samps,
500 const int *chans, int chan_count) {
502 i_img_dim count, i, w;
505 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
508 data = im->idata + (l+y*im->xsize) * im->channels;
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]);
520 for (i = 0; i < w; ++i) {
521 for (ch = 0; ch < chan_count; ++ch) {
522 *samps++ = data[chans[ch]];
525 data += im->channels;
529 if (chan_count <= 0 || chan_count > im->channels) {
530 i_push_errorf(0, "chan_count %d out of range, must be >0, <= channels",
534 for (i = 0; i < w; ++i) {
535 for (ch = 0; ch < chan_count; ++ch) {
539 data += im->channels;
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)
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
557 Returns the number of samples read (which should be (r-l) * bits_set(chan_mask)
563 i_gsampf_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fsample_t *samps,
564 const int *chans, int chan_count) {
566 i_img_dim count, i, w;
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]);
573 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
576 data = im->idata + (l+y*im->xsize) * im->channels;
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]);
588 for (i = 0; i < w; ++i) {
589 for (ch = 0; ch < chan_count; ++ch) {
590 *samps++ = Sample8ToF(data[chans[ch]]);
593 data += im->channels;
597 if (chan_count <= 0 || chan_count > im->channels) {
598 i_push_errorf(0, "chan_count %d out of range, must be >0, <= channels",
602 for (i = 0; i < w; ++i) {
603 for (ch = 0; ch < chan_count; ++ch) {
604 *samps++ = Sample8ToF(data[ch]);
607 data += im->channels;
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)
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
624 Returns the number of samples written (which should be (r-l) *
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) {
635 i_img_dim count, i, w;
638 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
642 data = im->idata + (l+y*im->xsize) * im->channels;
647 /* make sure we have good channel numbers */
648 /* and test if all channels specified are in the mask */
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]);
655 if (!((1 << chans[ch]) & im->ch_mask))
659 for (i = 0; i < w; ++i) {
660 for (ch = 0; ch < chan_count; ++ch) {
661 data[chans[ch]] = *samps++;
664 data += im->channels;
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;
675 data += im->channels;
680 if (chan_count <= 0 || chan_count > im->channels) {
681 i_push_errorf(0, "chan_count %d out of range, must be >0, <= channels",
685 for (i = 0; i < w; ++i) {
687 for (ch = 0; ch < chan_count; ++ch) {
688 if (im->ch_mask & mask)
694 data += im->channels;
701 i_push_error(0, "Image position outside of image");
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)
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
713 Returns the number of samples written (which should be (r-l) *
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) {
724 i_img_dim count, i, w;
727 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
731 data = im->idata + (l+y*im->xsize) * im->channels;
736 /* make sure we have good channel numbers */
737 /* and test if all channels specified are in the mask */
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]);
744 if (!((1 << chans[ch]) & im->ch_mask))
748 for (i = 0; i < w; ++i) {
749 for (ch = 0; ch < chan_count; ++ch) {
750 data[chans[ch]] = SampleFTo8(*samps);
754 data += im->channels;
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);
765 data += im->channels;
770 if (chan_count <= 0 || chan_count > im->channels) {
771 i_push_errorf(0, "chan_count %d out of range, must be >0, <= channels",
775 for (i = 0; i < w; ++i) {
777 for (ch = 0; ch < chan_count; ++ch) {
778 if (im->ch_mask & mask)
779 data[ch] = SampleFTo8(*samps);
784 data += im->channels;
791 i_push_error(0, "Image position outside of image");
801 Arnar M. Hrafnkelsson <addi@umich.edu>
803 Tony Cook <tony@develop-help.com>