commit changes from draw branch
[imager.git] / paste.im
CommitLineData
9b1ec2b8
TC
1#include "imager.h"
2
3/*
4=item i_copyto(dest, src, x1, y1, x2, y2, tx, ty)
5
6=category Image
7
8Copies image data from the area (x1,y1)-[x2,y2] in the source image to
9a rectangle the same size with it's top-left corner at (tx,ty) in the
10destination image.
11
12If x1 > x2 or y1 > y2 then the corresponding co-ordinates are swapped.
13
14=cut
15*/
16
17void
18i_copyto(i_img *im, i_img *src, int x1, int y1, int x2, int y2, int tx, int ty) {
19 int x, y, t, ttx, tty;
20
21 if (x2<x1) { t=x1; x1=x2; x2=t; }
22 if (y2<y1) { t=y1; y1=y2; y2=t; }
23 if (tx < 0) {
24 /* adjust everything equally */
25 x1 += -tx;
26 x2 += -tx;
27 tx = 0;
28 }
29 if (ty < 0) {
30 y1 += -ty;
31 y2 += -ty;
32 ty = 0;
33 }
34 if (x1 >= src->xsize || y1 >= src->ysize)
35 return; /* nothing to do */
36 if (x2 > src->xsize)
37 x2 = src->xsize;
38 if (y2 > src->ysize)
39 y2 = src->ysize;
40 if (x1 == x2 || y1 == y2)
41 return; /* nothing to do */
42
43 mm_log((1,"i_copyto(im* %p, src %p, x1 %d, y1 %d, x2 %d, y2 %d, tx %d, ty %d)\n",
44 im, src, x1, y1, x2, y2, tx, ty));
45
46#code im->bits == i_8_bits
47 IM_COLOR *row = mymalloc(sizeof(IM_COLOR) * (x2-x1));
48 tty = ty;
49 for(y=y1; y<y2; y++) {
50 ttx = tx;
51 IM_GLIN(src, x1, x2, y, row);
52 if (src->channels != im->channels)
53 IM_ADAPT_COLORS(im->channels, src->channels, row, x2-x1);
54 IM_PLIN(im, tx, tx+x2-x1, tty, row);
55 tty++;
56 }
57 myfree(row);
58#/code
59}
60
61#define color_to_grey(col) ((col)->rgb.r * 0.222 + (col)->rgb.g * 0.707 + (col)->rgb.b * 0.071)
62
63#code
64void
65#ifdef IM_EIGHT_BIT
66i_adapt_colors
67#else
68i_adapt_fcolors
69#endif
70(int out_channels, int in_channels, IM_COLOR *colors,
71 size_t count) {
72 int i;
73 if (out_channels == in_channels)
74 return;
75 if (count == 0)
76 return;
77
78 switch (out_channels) {
79 case 1:
80 {
81 switch (in_channels) {
82 case 2:
83 /* apply alpha against a black background */
84 while (count) {
85 colors->channel[0] = colors->channel[0] * colors->channel[1] / IM_SAMPLE_MAX;
86 ++colors;
87 --count;
88 }
89 return;
90
91 case 3:
92 /* convert to grey */
93 while (count) {
94 colors->channel[0] = IM_ROUND(color_to_grey(colors));
95 ++colors;
96 --count;
97 }
98 return;
99
100 case 4:
101 while (count) {
102 colors->channel[0] = IM_ROUND(color_to_grey(colors) * colors->channel[3] / IM_SAMPLE_MAX);
103 ++colors;
104 --count;
105 }
106 return;
107
108 default:
109 i_fatal(3, "i_adapt_colors: in_channels of %d invalid\n", in_channels);
110 return; /* avoid warnings */
111 }
112 }
113
114 case 2:
115 {
116 switch (in_channels) {
117 case 1:
118 while (count) {
119 colors->channel[1] = IM_SAMPLE_MAX;
120 ++colors;
121 --count;
122 }
123 return;
124
125 case 3:
126 while (count) {
127 colors->channel[0] = IM_ROUND(color_to_grey(colors));
128 colors->channel[1] = IM_SAMPLE_MAX;
129 ++colors;
130 --count;
131 }
132 return;
133
134 case 4:
135 while (count) {
136 colors->channel[0] = IM_ROUND(color_to_grey(colors));
137 colors->channel[1] = colors->channel[3];
138 ++colors;
139 --count;
140 }
141 return;
142
143 default:
144 i_fatal(3, "i_adapt_colors: in_channels of %d invalid\n", in_channels);
145 return; /* avoid warnings */
146 }
147 }
148
149 case 3:
150 {
151 switch (in_channels) {
152 case 1:
153 while (count) {
154 colors->channel[1] = colors->channel[2] = colors->channel[0];
155 ++colors;
156 --count;
157 }
158 return;
159
160 case 2:
161 while (count) {
162 int alpha = colors->channel[1];
163 colors->channel[0] = colors->channel[1] = colors->channel[2] =
164 IM_ROUND(colors->channel[0] * alpha / IM_SAMPLE_MAX);
165 ++colors;
166 --count;
167 }
168 return;
169
170 case 4:
171 while (count) {
172 int alpha = colors->channel[3];
173 colors->channel[0] =
174 IM_ROUND(colors->channel[0] * alpha / IM_SAMPLE_MAX);
175 colors->channel[1] =
176 IM_ROUND(colors->channel[1] * alpha / IM_SAMPLE_MAX);
177 colors->channel[2] =
178 IM_ROUND(colors->channel[2] * alpha / IM_SAMPLE_MAX);
179 ++colors;
180 --count;
181 }
182 return;
183
184 default:
185 i_fatal(3, "i_adapt_colors: in_channels of %d invalid\n", in_channels);
186 return; /* avoid warnings */
187 }
188 }
189
190 case 4:
191 {
192 switch (in_channels) {
193 case 1:
194 while (count) {
195 colors->channel[1] = colors->channel[2] = colors->channel[0];
196 colors->channel[3] = IM_SAMPLE_MAX;
197 ++colors;
198 --count;
199 }
200 return;
201
202 case 2:
203 while (count) {
204 colors->channel[3] = colors->channel[1];
205 colors->channel[1] = colors->channel[2] = colors->channel[0];
206 ++colors;
207 --count;
208 }
209 return;
210
211 case 3:
212 while (count) {
213 colors->channel[3] = IM_SAMPLE_MAX;
214 ++colors;
215 --count;
216 }
217 return;
218
219 default:
220 i_fatal(3, "i_adapt_colors: in_channels of %d invalid\n", in_channels);
221 return; /* avoid warnings */
222 }
223 }
224
225 default:
226 i_fatal(3, "i_adapt_colors: out_channels of %d invalid\n", out_channels);
227 return; /* avoid warnings */
228 }
229}
230
231#/code
232