Commit | Line | Data |
---|---|---|
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 | ||
8 | Copies image data from the area (x1,y1)-[x2,y2] in the source image to | |
9 | a rectangle the same size with it's top-left corner at (tx,ty) in the | |
10 | destination image. | |
11 | ||
12 | If x1 > x2 or y1 > y2 then the corresponding co-ordinates are swapped. | |
13 | ||
14 | =cut | |
15 | */ | |
16 | ||
17 | void | |
18 | i_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 | |
64 | void | |
65 | #ifdef IM_EIGHT_BIT | |
66 | i_adapt_colors | |
67 | #else | |
68 | i_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 |