1 #define IMAGER_NO_CONTEXT
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);
20 =item IIM_base_8bit_direct (static)
22 A static i_img object used to initialize direct 8-bit per sample images.
26 static i_img IIM_base_8bit_direct =
29 0, 0, 0, /* xsize, ysize, bytes */
32 i_direct_type, /* type */
35 { 0, 0, NULL }, /* tags */
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 */
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 */
58 NULL, /* i_f_destroy */
61 NULL, /* i_f_psamp_bits */
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;
78 im->i_f_addcolor = NULL;
79 im->i_f_getcolor = NULL;
80 im->i_f_colorcount = NULL;
81 im->i_f_findcolor = NULL;
85 =item im_img_8_new(ctx, x, y, ch)
86 X<im_img_8_new API>X<i_img_8_new API>
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);
91 Creates a new image object I<x> pixels wide, and I<y> pixels high with
98 im_img_8_new(pIMCTX, i_img_dim x,i_img_dim y,int ch) {
101 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));
104 im = im_img_empty_ch(aIMCTX, NULL,x,y,ch);
106 im_log((aIMCTX, 1,"(%p) <- IIM_new\n",im));
111 =item i_img_empty(im, x, y)
113 Re-new image reference (assumes 3 channels)
116 x - xsize of destination image
117 y - ysize of destination image
119 **FIXME** what happens if a live image is passed in here?
121 Should this just call i_img_empty_ch()?
127 im_img_empty(pIMCTX, i_img *im,i_img_dim x,i_img_dim y) {
128 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 return im_img_empty_ch(aIMCTX, im, x, y, 3);
134 =item i_img_empty_ch(im, x, y, ch)
136 Re-new image reference
139 x - xsize of destination image
140 y - ysize of destination image
141 ch - number of channels
147 im_img_empty_ch(pIMCTX, i_img *im,i_img_dim x,i_img_dim y,int ch) {
150 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));
153 if (x < 1 || y < 1) {
154 im_push_error(aIMCTX, 0, "Image sizes must be positive");
157 if (ch < 1 || ch > MAXCHANNELS) {
158 im_push_errorf(aIMCTX, 0, "channels must be between 1 and %d", MAXCHANNELS);
161 /* check this multiplication doesn't overflow */
163 if (bytes / y / ch != x) {
164 im_push_errorf(aIMCTX, 0, "integer overflow calculating image allocation");
169 im = im_img_alloc(aIMCTX);
171 memcpy(im, &IIM_base_8bit_direct, sizeof(i_img));
172 i_tags_new(&im->tags);
176 im->ch_mask = MAXINT;
178 if ( (im->idata=mymalloc(im->bytes)) == NULL)
179 im_fatal(aIMCTX, 2,"malloc() error\n");
180 memset(im->idata,0,(size_t)im->bytes);
184 im_img_init(aIMCTX, im);
186 im_log((aIMCTX, 1,"(%p) <- i_img_empty_ch\n",im));
191 =head2 8-bit per sample image internal functions
193 These are the functions installed in an 8-bit per sample image.
197 =item i_ppix_d(im, x, y, col)
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.
204 Returns 0 if the pixel could be set, -1 otherwise.
210 i_ppix_d(i_img *im, i_img_dim x, i_img_dim y, const i_color *val) {
213 if ( x>-1 && x<im->xsize && y>-1 && y<im->ysize ) {
214 for(ch=0;ch<im->channels;ch++)
215 if (im->ch_mask&(1<<ch))
216 im->idata[(x+y*im->xsize)*im->channels+ch]=val->channel[ch];
219 return -1; /* error was clipped */
223 =item i_gpix_d(im, x, y, &col)
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.
230 Returns 0 if the pixel could be set, -1 otherwise.
236 i_gpix_d(i_img *im, i_img_dim x, i_img_dim y, i_color *val) {
238 if (x>-1 && x<im->xsize && y>-1 && y<im->ysize) {
239 for(ch=0;ch<im->channels;ch++)
240 val->channel[ch]=im->idata[(x+y*im->xsize)*im->channels+ch];
243 for(ch=0;ch<im->channels;ch++) val->channel[ch] = 0;
244 return -1; /* error was cliped */
248 =item i_glin_d(im, l, r, y, vals)
250 Reads a line of data from the image, storing the pixels at vals.
252 The line runs from (l,y) inclusive to (r,y) non-inclusive
254 vals should point at space for (r-l) pixels.
256 l should never be less than zero (to avoid confusion about where to
257 put the pixels in vals).
259 Returns the number of pixels copied (eg. if r, l or y is out of range)
265 i_glin_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_color *vals) {
269 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
272 data = im->idata + (l+y*im->xsize) * im->channels;
274 for (i = 0; i < count; ++i) {
275 for (ch = 0; ch < im->channels; ++ch)
276 vals[i].channel[ch] = *data++;
286 =item i_plin_d(im, l, r, y, vals)
288 Writes a line of data into the image, using the pixels at vals.
290 The line runs from (l,y) inclusive to (r,y) non-inclusive
292 vals should point at (r-l) pixels.
294 l should never be less than zero (to avoid confusion about where to
295 get the pixels in vals).
297 Returns the number of pixels copied (eg. if r, l or y is out of range)
303 i_plin_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_color *vals) {
307 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
310 data = im->idata + (l+y*im->xsize) * im->channels;
312 for (i = 0; i < count; ++i) {
313 for (ch = 0; ch < im->channels; ++ch) {
314 if (im->ch_mask & (1 << ch))
315 *data = vals[i].channel[ch];
327 =item i_ppixf_d(im, x, y, val)
333 i_ppixf_d(i_img *im, i_img_dim x, i_img_dim y, const i_fcolor *val) {
336 if ( x>-1 && x<im->xsize && y>-1 && y<im->ysize ) {
337 for(ch=0;ch<im->channels;ch++)
338 if (im->ch_mask&(1<<ch)) {
339 im->idata[(x+y*im->xsize)*im->channels+ch] =
340 SampleFTo8(val->channel[ch]);
344 return -1; /* error was clipped */
348 =item i_gpixf_d(im, x, y, val)
354 i_gpixf_d(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *val) {
356 if (x>-1 && x<im->xsize && y>-1 && y<im->ysize) {
357 for(ch=0;ch<im->channels;ch++) {
359 Sample8ToF(im->idata[(x+y*im->xsize)*im->channels+ch]);
363 return -1; /* error was cliped */
367 =item i_glinf_d(im, l, r, y, vals)
369 Reads a line of data from the image, storing the pixels at vals.
371 The line runs from (l,y) inclusive to (r,y) non-inclusive
373 vals should point at space for (r-l) pixels.
375 l should never be less than zero (to avoid confusion about where to
376 put the pixels in vals).
378 Returns the number of pixels copied (eg. if r, l or y is out of range)
384 i_glinf_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fcolor *vals) {
388 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
391 data = im->idata + (l+y*im->xsize) * im->channels;
393 for (i = 0; i < count; ++i) {
394 for (ch = 0; ch < im->channels; ++ch)
395 vals[i].channel[ch] = Sample8ToF(*data++);
405 =item i_plinf_d(im, l, r, y, vals)
407 Writes a line of data into the image, using the pixels at vals.
409 The line runs from (l,y) inclusive to (r,y) non-inclusive
411 vals should point at (r-l) pixels.
413 l should never be less than zero (to avoid confusion about where to
414 get the pixels in vals).
416 Returns the number of pixels copied (eg. if r, l or y is out of range)
422 i_plinf_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_fcolor *vals) {
426 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
429 data = im->idata + (l+y*im->xsize) * im->channels;
431 for (i = 0; i < count; ++i) {
432 for (ch = 0; ch < im->channels; ++ch) {
433 if (im->ch_mask & (1 << ch))
434 *data = SampleFTo8(vals[i].channel[ch]);
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)
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
452 Returns the number of samples read (which should be (r-l) * bits_set(chan_mask)
458 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) {
461 i_img_dim count, i, w;
464 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
467 data = im->idata + (l+y*im->xsize) * im->channels;
472 /* make sure we have good channel numbers */
473 for (ch = 0; ch < chan_count; ++ch) {
474 if (chans[ch] < 0 || chans[ch] >= im->channels) {
476 im_push_errorf(aIMCTX, 0, "No channel %d in this image", chans[ch]);
480 for (i = 0; i < w; ++i) {
481 for (ch = 0; ch < chan_count; ++ch) {
482 *samps++ = data[chans[ch]];
485 data += im->channels;
489 if (chan_count <= 0 || chan_count > im->channels) {
491 im_push_errorf(aIMCTX, 0, "chan_count %d out of range, must be >0, <= channels",
495 for (i = 0; i < w; ++i) {
496 for (ch = 0; ch < chan_count; ++ch) {
500 data += im->channels;
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)
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
518 Returns the number of samples read (which should be (r-l) * bits_set(chan_mask)
524 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) {
527 i_img_dim count, i, w;
529 for (ch = 0; ch < chan_count; ++ch) {
530 if (chans[ch] < 0 || chans[ch] >= im->channels) {
532 im_push_errorf(aIMCTX, 0, "No channel %d in this image", chans[ch]);
535 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
538 data = im->idata + (l+y*im->xsize) * im->channels;
543 /* make sure we have good channel numbers */
544 for (ch = 0; ch < chan_count; ++ch) {
545 if (chans[ch] < 0 || chans[ch] >= im->channels) {
547 im_push_errorf(aIMCTX, 0, "No channel %d in this image", chans[ch]);
551 for (i = 0; i < w; ++i) {
552 for (ch = 0; ch < chan_count; ++ch) {
553 *samps++ = Sample8ToF(data[chans[ch]]);
556 data += im->channels;
560 if (chan_count <= 0 || chan_count > im->channels) {
562 im_push_errorf(aIMCTX, 0, "chan_count %d out of range, must be >0, <= channels",
566 for (i = 0; i < w; ++i) {
567 for (ch = 0; ch < chan_count; ++ch) {
568 *samps++ = Sample8ToF(data[ch]);
571 data += im->channels;
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)
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
588 Returns the number of samples written (which should be (r-l) *
596 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) {
599 i_img_dim count, i, w;
602 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
605 data = im->idata + (l+y*im->xsize) * im->channels;
610 /* make sure we have good channel numbers */
611 /* and test if all channels specified are in the mask */
613 for (ch = 0; ch < chan_count; ++ch) {
614 if (chans[ch] < 0 || chans[ch] >= im->channels) {
616 im_push_errorf(aIMCTX, 0, "No channel %d in this image", chans[ch]);
619 if (!((1 << chans[ch]) & im->ch_mask))
623 for (i = 0; i < w; ++i) {
624 for (ch = 0; ch < chan_count; ++ch) {
625 data[chans[ch]] = *samps++;
628 data += im->channels;
632 for (i = 0; i < w; ++i) {
633 for (ch = 0; ch < chan_count; ++ch) {
634 if (im->ch_mask & (1 << (chans[ch])))
635 data[chans[ch]] = *samps;
639 data += im->channels;
644 if (chan_count <= 0 || chan_count > im->channels) {
646 im_push_errorf(aIMCTX, 0, "chan_count %d out of range, must be >0, <= channels",
650 for (i = 0; i < w; ++i) {
652 for (ch = 0; ch < chan_count; ++ch) {
653 if (im->ch_mask & mask)
659 data += im->channels;
667 i_push_error(0, "Image position outside of image");
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)
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
679 Returns the number of samples written (which should be (r-l) *
687 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) {
690 i_img_dim count, i, w;
693 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
696 data = im->idata + (l+y*im->xsize) * im->channels;
701 /* make sure we have good channel numbers */
702 /* and test if all channels specified are in the mask */
704 for (ch = 0; ch < chan_count; ++ch) {
705 if (chans[ch] < 0 || chans[ch] >= im->channels) {
707 im_push_errorf(aIMCTX, 0, "No channel %d in this image", chans[ch]);
710 if (!((1 << chans[ch]) & im->ch_mask))
714 for (i = 0; i < w; ++i) {
715 for (ch = 0; ch < chan_count; ++ch) {
716 data[chans[ch]] = SampleFTo8(*samps);
720 data += im->channels;
724 for (i = 0; i < w; ++i) {
725 for (ch = 0; ch < chan_count; ++ch) {
726 if (im->ch_mask & (1 << (chans[ch])))
727 data[chans[ch]] = SampleFTo8(*samps);
731 data += im->channels;
736 if (chan_count <= 0 || chan_count > im->channels) {
738 im_push_errorf(aIMCTX, 0, "chan_count %d out of range, must be >0, <= channels",
742 for (i = 0; i < w; ++i) {
744 for (ch = 0; ch < chan_count; ++ch) {
745 if (im->ch_mask & mask)
746 data[ch] = SampleFTo8(*samps);
751 data += im->channels;
759 i_push_error(0, "Image position outside of image");
769 Arnar M. Hrafnkelsson <addi@umich.edu>
771 Tony Cook <tony@develop-help.com>