]> git.imager.perl.org - imager.git/blob - convert.c
was sizeof(int *)
[imager.git] / convert.c
1 /*
2 =head1 NAME
3
4   convert.c - image conversions
5
6 =head1 SYNOPSIS
7
8   i_convert(outimage, srcimage, coeff, outchans, inchans)
9
10 =head1 DESCRIPTION
11
12 Converts images from one format to another, typically in this case for
13 converting from RGBA to greyscale and back.
14
15 =over
16
17 =cut
18 */
19
20 #include "image.h"
21
22
23 /*
24 =item i_convert(im, src, coeff, outchan, inchan)
25
26 Converts the image src into another image.
27
28 coeff contains the co-efficients of an outchan x inchan matrix, for
29 each output pixel:
30
31               coeff[0], coeff[1] ...
32   im[x,y] = [ coeff[inchan], coeff[inchan+1]...        ] * [ src[x,y], 1]
33               ...              coeff[inchan*outchan-1]
34
35 If im has the wrong number of channels or is the wrong size then
36 i_convert() will re-create it.
37
38 =cut
39 */
40
41 int
42 i_convert(i_img *im, i_img *src, float *coeff, int outchan, int inchan)
43 {
44   i_color *vals;
45   int x, y;
46   int i, j;
47   int ilimit;
48   double work[MAXCHANNELS];
49
50   mm_log((1,"i_convert(im* 0x%x, src, 0x%x, coeff 0x%x,outchan %d, inchan %d)\n",im,src, coeff,outchan, inchan));
51  
52   i_clear_error();
53
54   ilimit = inchan;
55   if (ilimit > src->channels)
56     ilimit = src->channels;
57   if (outchan > MAXCHANNELS) {
58     i_push_error(0, "cannot have outchan > MAXCHANNELS");
59     return 0;
60   }
61
62   /* first check the output image */
63   if (im->channels != outchan || im->xsize != src->xsize 
64       || im->ysize != src->ysize) {
65     i_img_empty_ch(im, src->xsize, src->ysize, outchan);
66   }
67   vals = mymalloc(sizeof(i_color) * src->xsize);
68   for (y = 0; y < src->ysize; ++y) {
69     i_glin(src, 0, src->xsize, y, vals);
70     for (x = 0; x < src->xsize; ++x) {
71       for (j = 0; j < outchan; ++j) {
72         work[j] = 0;
73         for (i = 0; i < ilimit; ++i) {
74           work[j] += coeff[i+inchan*j] * vals[x].channel[i];
75         }
76         if (i < inchan) {
77           work[j] += coeff[i+inchan*j] * 255.9;
78         }
79       }
80       for (j = 0; j < outchan; ++j) {
81         if (work[j] < 0)
82           vals[x].channel[j] = 0;
83         else if (work[j] >= 256)
84           vals[x].channel[j] = 255;
85         else
86           vals[x].channel[j] = work[j];
87       }
88     }
89     i_plin(im, 0, src->xsize, y, vals);
90   }
91   myfree(vals);
92   return 1;
93 }
94
95 /*
96 =back
97
98 =head1 SEE ALSO
99
100 Imager(3)
101
102 =head1 AUTHOR
103
104 Tony Cook <tony@develop-help.com>
105
106 =cut
107 */