4 static int i_ppix_d(i_img *im, int x, int y, const i_color *val);
5 static int i_gpix_d(i_img *im, int x, int y, i_color *val);
6 static int i_glin_d(i_img *im, int l, int r, int y, i_color *vals);
7 static int i_plin_d(i_img *im, int l, int r, int y, const i_color *vals);
8 static int i_ppixf_d(i_img *im, int x, int y, const i_fcolor *val);
9 static int i_gpixf_d(i_img *im, int x, int y, i_fcolor *val);
10 static int i_glinf_d(i_img *im, int l, int r, int y, i_fcolor *vals);
11 static int i_plinf_d(i_img *im, int l, int r, int y, const i_fcolor *vals);
12 static int i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps, const int *chans, int chan_count);
13 static int i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps, const int *chans, int chan_count);
16 =item IIM_base_8bit_direct (static)
18 A static i_img object used to initialize direct 8-bit per sample images.
22 static i_img IIM_base_8bit_direct =
25 0, 0, 0, /* xsize, ysize, bytes */
28 i_direct_type, /* type */
31 { 0, 0, NULL }, /* tags */
34 i_ppix_d, /* i_f_ppix */
35 i_ppixf_d, /* i_f_ppixf */
36 i_plin_d, /* i_f_plin */
37 i_plinf_d, /* i_f_plinf */
38 i_gpix_d, /* i_f_gpix */
39 i_gpixf_d, /* i_f_gpixf */
40 i_glin_d, /* i_f_glin */
41 i_glinf_d, /* i_f_glinf */
42 i_gsamp_d, /* i_f_gsamp */
43 i_gsampf_d, /* i_f_gsampf */
47 NULL, /* i_f_addcolors */
48 NULL, /* i_f_getcolors */
49 NULL, /* i_f_colorcount */
50 NULL, /* i_f_maxcolors */
51 NULL, /* i_f_findcolor */
52 NULL, /* i_f_setcolors */
54 NULL, /* i_f_destroy */
57 NULL, /* i_f_psamp_bits */
60 /*static void set_8bit_direct(i_img *im) {
61 im->i_f_ppix = i_ppix_d;
62 im->i_f_ppixf = i_ppixf_d;
63 im->i_f_plin = i_plin_d;
64 im->i_f_plinf = i_plinf_d;
65 im->i_f_gpix = i_gpix_d;
66 im->i_f_gpixf = i_gpixf_d;
67 im->i_f_glin = i_glin_d;
68 im->i_f_glinf = i_glinf_d;
71 im->i_f_addcolor = NULL;
72 im->i_f_getcolor = NULL;
73 im->i_f_colorcount = NULL;
74 im->i_f_findcolor = NULL;
78 =item IIM_new(x, y, ch)
80 =item i_img_8_new(x, y, ch)
82 =category Image creation/destruction
84 =synopsis i_img *img = i_img_8_new(width, height, channels);
86 Creates a new image object I<x> pixels wide, and I<y> pixels high with
94 IIM_new(int x,int y,int ch) {
96 mm_log((1,"IIM_new(x %d,y %d,ch %d)\n",x,y,ch));
98 im=i_img_empty_ch(NULL,x,y,ch);
100 mm_log((1,"(%p) <- IIM_new\n",im));
106 IIM_DESTROY(i_img *im) {
107 mm_log((1,"IIM_DESTROY(im* %p)\n",im));
115 Create new image reference - notice that this isn't an object yet and
116 this should be fixed asap.
126 mm_log((1,"i_img_struct()\n"));
130 *im = IIM_base_8bit_direct;
140 mm_log((1,"(%p) <- i_img_struct\n",im));
145 =item i_img_empty(im, x, y)
147 Re-new image reference (assumes 3 channels)
150 x - xsize of destination image
151 y - ysize of destination image
153 **FIXME** what happens if a live image is passed in here?
155 Should this just call i_img_empty_ch()?
161 i_img_empty(i_img *im,int x,int y) {
162 mm_log((1,"i_img_empty(*im %p, x %d, y %d)\n",im, x, y));
163 return i_img_empty_ch(im, x, y, 3);
167 =item i_img_empty_ch(im, x, y, ch)
169 Re-new image reference
172 x - xsize of destination image
173 y - ysize of destination image
174 ch - number of channels
180 i_img_empty_ch(i_img *im,int x,int y,int ch) {
183 mm_log((1,"i_img_empty_ch(*im %p, x %d, y %d, ch %d)\n", im, x, y, ch));
185 if (x < 1 || y < 1) {
186 i_push_error(0, "Image sizes must be positive");
189 if (ch < 1 || ch > MAXCHANNELS) {
190 i_push_errorf(0, "channels must be between 1 and %d", MAXCHANNELS);
193 /* check this multiplication doesn't overflow */
195 if (bytes / y / ch != x) {
196 i_push_errorf(0, "integer overflow calculating image allocation");
203 memcpy(im, &IIM_base_8bit_direct, sizeof(i_img));
204 i_tags_new(&im->tags);
208 im->ch_mask = MAXINT;
210 if ( (im->idata=mymalloc(im->bytes)) == NULL)
211 i_fatal(2,"malloc() error\n");
212 memset(im->idata,0,(size_t)im->bytes);
218 mm_log((1,"(%p) <- i_img_empty_ch\n",im));
223 =head2 8-bit per sample image internal functions
225 These are the functions installed in an 8-bit per sample image.
229 =item i_ppix_d(im, x, y, col)
233 This is the function kept in the i_f_ppix member of an i_img object.
234 It does a normal store of a pixel into the image with range checking.
236 Returns 0 if the pixel could be set, -1 otherwise.
242 i_ppix_d(i_img *im, int x, int y, const i_color *val) {
245 if ( x>-1 && x<im->xsize && y>-1 && y<im->ysize ) {
246 for(ch=0;ch<im->channels;ch++)
247 if (im->ch_mask&(1<<ch))
248 im->idata[(x+y*im->xsize)*im->channels+ch]=val->channel[ch];
251 return -1; /* error was clipped */
255 =item i_gpix_d(im, x, y, &col)
259 This is the function kept in the i_f_gpix member of an i_img object.
260 It does normal retrieval of a pixel from the image with range checking.
262 Returns 0 if the pixel could be set, -1 otherwise.
268 i_gpix_d(i_img *im, int x, int y, i_color *val) {
270 if (x>-1 && x<im->xsize && y>-1 && y<im->ysize) {
271 for(ch=0;ch<im->channels;ch++)
272 val->channel[ch]=im->idata[(x+y*im->xsize)*im->channels+ch];
275 for(ch=0;ch<im->channels;ch++) val->channel[ch] = 0;
276 return -1; /* error was cliped */
280 =item i_glin_d(im, l, r, y, vals)
282 Reads a line of data from the image, storing the pixels at vals.
284 The line runs from (l,y) inclusive to (r,y) non-inclusive
286 vals should point at space for (r-l) pixels.
288 l should never be less than zero (to avoid confusion about where to
289 put the pixels in vals).
291 Returns the number of pixels copied (eg. if r, l or y is out of range)
297 i_glin_d(i_img *im, int l, int r, int y, i_color *vals) {
300 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
303 data = im->idata + (l+y*im->xsize) * im->channels;
305 for (i = 0; i < count; ++i) {
306 for (ch = 0; ch < im->channels; ++ch)
307 vals[i].channel[ch] = *data++;
317 =item i_plin_d(im, l, r, y, vals)
319 Writes a line of data into the image, using the pixels at vals.
321 The line runs from (l,y) inclusive to (r,y) non-inclusive
323 vals should point at (r-l) pixels.
325 l should never be less than zero (to avoid confusion about where to
326 get the pixels in vals).
328 Returns the number of pixels copied (eg. if r, l or y is out of range)
334 i_plin_d(i_img *im, int l, int r, int y, const i_color *vals) {
337 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
340 data = im->idata + (l+y*im->xsize) * im->channels;
342 for (i = 0; i < count; ++i) {
343 for (ch = 0; ch < im->channels; ++ch) {
344 if (im->ch_mask & (1 << ch))
345 *data = vals[i].channel[ch];
357 =item i_ppixf_d(im, x, y, val)
363 i_ppixf_d(i_img *im, int x, int y, const i_fcolor *val) {
366 if ( x>-1 && x<im->xsize && y>-1 && y<im->ysize ) {
367 for(ch=0;ch<im->channels;ch++)
368 if (im->ch_mask&(1<<ch)) {
369 im->idata[(x+y*im->xsize)*im->channels+ch] =
370 SampleFTo8(val->channel[ch]);
374 return -1; /* error was clipped */
378 =item i_gpixf_d(im, x, y, val)
384 i_gpixf_d(i_img *im, int x, int y, i_fcolor *val) {
386 if (x>-1 && x<im->xsize && y>-1 && y<im->ysize) {
387 for(ch=0;ch<im->channels;ch++) {
389 Sample8ToF(im->idata[(x+y*im->xsize)*im->channels+ch]);
393 return -1; /* error was cliped */
397 =item i_glinf_d(im, l, r, y, vals)
399 Reads a line of data from the image, storing the pixels at vals.
401 The line runs from (l,y) inclusive to (r,y) non-inclusive
403 vals should point at space for (r-l) pixels.
405 l should never be less than zero (to avoid confusion about where to
406 put the pixels in vals).
408 Returns the number of pixels copied (eg. if r, l or y is out of range)
414 i_glinf_d(i_img *im, int l, int r, int y, i_fcolor *vals) {
417 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
420 data = im->idata + (l+y*im->xsize) * im->channels;
422 for (i = 0; i < count; ++i) {
423 for (ch = 0; ch < im->channels; ++ch)
424 vals[i].channel[ch] = Sample8ToF(*data++);
434 =item i_plinf_d(im, l, r, y, vals)
436 Writes a line of data into the image, using the pixels at vals.
438 The line runs from (l,y) inclusive to (r,y) non-inclusive
440 vals should point at (r-l) pixels.
442 l should never be less than zero (to avoid confusion about where to
443 get the pixels in vals).
445 Returns the number of pixels copied (eg. if r, l or y is out of range)
451 i_plinf_d(i_img *im, int l, int r, int y, const i_fcolor *vals) {
454 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
457 data = im->idata + (l+y*im->xsize) * im->channels;
459 for (i = 0; i < count; ++i) {
460 for (ch = 0; ch < im->channels; ++ch) {
461 if (im->ch_mask & (1 << ch))
462 *data = SampleFTo8(vals[i].channel[ch]);
474 =item i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps, int *chans, int chan_count)
476 Reads sample values from im for the horizontal line (l, y) to (r-1,y)
477 for the channels specified by chans, an array of int with chan_count
480 Returns the number of samples read (which should be (r-l) * bits_set(chan_mask)
486 i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps,
487 const int *chans, int chan_count) {
491 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
494 data = im->idata + (l+y*im->xsize) * im->channels;
499 /* make sure we have good channel numbers */
500 for (ch = 0; ch < chan_count; ++ch) {
501 if (chans[ch] < 0 || chans[ch] >= im->channels) {
502 i_push_errorf(0, "No channel %d in this image", chans[ch]);
506 for (i = 0; i < w; ++i) {
507 for (ch = 0; ch < chan_count; ++ch) {
508 *samps++ = data[chans[ch]];
511 data += im->channels;
515 if (chan_count <= 0 || chan_count > im->channels) {
516 i_push_errorf(0, "chan_count %d out of range, must be >0, <= channels",
520 for (i = 0; i < w; ++i) {
521 for (ch = 0; ch < chan_count; ++ch) {
525 data += im->channels;
537 =item i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps, int *chans, int chan_count)
539 Reads sample values from im for the horizontal line (l, y) to (r-1,y)
540 for the channels specified by chan_mask, where bit 0 is the first
543 Returns the number of samples read (which should be (r-l) * bits_set(chan_mask)
549 i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps,
550 const int *chans, int chan_count) {
553 for (ch = 0; ch < chan_count; ++ch) {
554 if (chans[ch] < 0 || chans[ch] >= im->channels) {
555 i_push_errorf(0, "No channel %d in this image", chans[ch]);
558 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
561 data = im->idata + (l+y*im->xsize) * im->channels;
566 /* make sure we have good channel numbers */
567 for (ch = 0; ch < chan_count; ++ch) {
568 if (chans[ch] < 0 || chans[ch] >= im->channels) {
569 i_push_errorf(0, "No channel %d in this image", chans[ch]);
573 for (i = 0; i < w; ++i) {
574 for (ch = 0; ch < chan_count; ++ch) {
575 *samps++ = Sample8ToF(data[chans[ch]]);
578 data += im->channels;
582 if (chan_count <= 0 || chan_count > im->channels) {
583 i_push_errorf(0, "chan_count %d out of range, must be >0, <= channels",
587 for (i = 0; i < w; ++i) {
588 for (ch = 0; ch < chan_count; ++ch) {
589 *samps++ = Sample8ToF(data[ch]);
592 data += im->channels;
607 Arnar M. Hrafnkelsson <addi@umich.edu>
609 Tony Cook <tony@develop-help.com>