Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 462 lines (400 sloc) 9.311 kB
9b1ec2b commit changes from draw branch
Tony Cook authored
1 #include "imager.h"
6d068d3 @tonycoz [RT #68508] do error diffusion on gray scale if the supplied palette …
authored
2 #include "imageri.h"
9b1ec2b commit changes from draw branch
Tony Cook authored
3
4 /*
5715f7c huge spelling update and spell checking patch
Tony Cook authored
5 =item i_copyto(C<dest>, C<src>, C<x1>, C<y1>, C<x2>, C<y2>, C<tx>, C<ty>)
9b1ec2b commit changes from draw branch
Tony Cook authored
6
7 =category Image
8
5715f7c huge spelling update and spell checking patch
Tony Cook authored
9 Copies image data from the area (C<x1>,C<y1>)-[C<x2>,C<y2>] in the
10 source image to a rectangle the same size with it's top-left corner at
11 (C<tx>,C<ty>) in the destination image.
9b1ec2b commit changes from draw branch
Tony Cook authored
12
5715f7c huge spelling update and spell checking patch
Tony Cook authored
13 If C<x1> > C<x2> or C<y1> > C<y2> then the corresponding co-ordinates
14 are swapped.
9b1ec2b commit changes from draw branch
Tony Cook authored
15
16 =cut
17 */
18
19 void
20 i_copyto(i_img *im, i_img *src, int x1, int y1, int x2, int y2, int tx, int ty) {
a827f5b clean up some unused variables
Tony Cook authored
21 int y, t, ttx, tty;
9b1ec2b commit changes from draw branch
Tony Cook authored
22
23 if (x2<x1) { t=x1; x1=x2; x2=t; }
24 if (y2<y1) { t=y1; y1=y2; y2=t; }
25 if (tx < 0) {
26 /* adjust everything equally */
27 x1 += -tx;
28 x2 += -tx;
29 tx = 0;
30 }
31 if (ty < 0) {
32 y1 += -ty;
33 y2 += -ty;
34 ty = 0;
35 }
36 if (x1 >= src->xsize || y1 >= src->ysize)
37 return; /* nothing to do */
38 if (x2 > src->xsize)
39 x2 = src->xsize;
40 if (y2 > src->ysize)
41 y2 = src->ysize;
42 if (x1 == x2 || y1 == y2)
43 return; /* nothing to do */
44
45 mm_log((1,"i_copyto(im* %p, src %p, x1 %d, y1 %d, x2 %d, y2 %d, tx %d, ty %d)\n",
46 im, src, x1, y1, x2, y2, tx, ty));
47
48 #code im->bits == i_8_bits
49 IM_COLOR *row = mymalloc(sizeof(IM_COLOR) * (x2-x1));
50 tty = ty;
51 for(y=y1; y<y2; y++) {
52 ttx = tx;
53 IM_GLIN(src, x1, x2, y, row);
54 if (src->channels != im->channels)
55 IM_ADAPT_COLORS(im->channels, src->channels, row, x2-x1);
56 IM_PLIN(im, tx, tx+x2-x1, tty, row);
57 tty++;
58 }
59 myfree(row);
60 #/code
61 }
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 if (out_channels == in_channels)
73 return;
74 if (count == 0)
75 return;
76
77 switch (out_channels) {
78 case 1:
79 {
80 switch (in_channels) {
81 case 2:
82 /* apply alpha against a black background */
83 while (count) {
84 colors->channel[0] = colors->channel[0] * colors->channel[1] / IM_SAMPLE_MAX;
85 ++colors;
86 --count;
87 }
88 return;
89
90 case 3:
91 /* convert to grey */
92 while (count) {
93 colors->channel[0] = IM_ROUND(color_to_grey(colors));
94 ++colors;
95 --count;
96 }
97 return;
98
99 case 4:
100 while (count) {
101 colors->channel[0] = IM_ROUND(color_to_grey(colors) * colors->channel[3] / IM_SAMPLE_MAX);
102 ++colors;
103 --count;
104 }
105 return;
106
107 default:
108 i_fatal(3, "i_adapt_colors: in_channels of %d invalid\n", in_channels);
109 return; /* avoid warnings */
110 }
111 }
112
113 case 2:
114 {
115 switch (in_channels) {
116 case 1:
117 while (count) {
118 colors->channel[1] = IM_SAMPLE_MAX;
119 ++colors;
120 --count;
121 }
122 return;
123
124 case 3:
125 while (count) {
126 colors->channel[0] = IM_ROUND(color_to_grey(colors));
127 colors->channel[1] = IM_SAMPLE_MAX;
128 ++colors;
129 --count;
130 }
131 return;
132
133 case 4:
134 while (count) {
135 colors->channel[0] = IM_ROUND(color_to_grey(colors));
136 colors->channel[1] = colors->channel[3];
137 ++colors;
138 --count;
139 }
140 return;
141
142 default:
143 i_fatal(3, "i_adapt_colors: in_channels of %d invalid\n", in_channels);
144 return; /* avoid warnings */
145 }
146 }
147
148 case 3:
149 {
150 switch (in_channels) {
151 case 1:
152 while (count) {
153 colors->channel[1] = colors->channel[2] = colors->channel[0];
154 ++colors;
155 --count;
156 }
157 return;
158
159 case 2:
160 while (count) {
161 int alpha = colors->channel[1];
162 colors->channel[0] = colors->channel[1] = colors->channel[2] =
163 IM_ROUND(colors->channel[0] * alpha / IM_SAMPLE_MAX);
164 ++colors;
165 --count;
166 }
167 return;
168
169 case 4:
170 while (count) {
171 int alpha = colors->channel[3];
172 colors->channel[0] =
173 IM_ROUND(colors->channel[0] * alpha / IM_SAMPLE_MAX);
174 colors->channel[1] =
175 IM_ROUND(colors->channel[1] * alpha / IM_SAMPLE_MAX);
176 colors->channel[2] =
177 IM_ROUND(colors->channel[2] * alpha / IM_SAMPLE_MAX);
178 ++colors;
179 --count;
180 }
181 return;
182
183 default:
184 i_fatal(3, "i_adapt_colors: in_channels of %d invalid\n", in_channels);
185 return; /* avoid warnings */
186 }
187 }
188
189 case 4:
190 {
191 switch (in_channels) {
192 case 1:
193 while (count) {
194 colors->channel[1] = colors->channel[2] = colors->channel[0];
195 colors->channel[3] = IM_SAMPLE_MAX;
196 ++colors;
197 --count;
198 }
199 return;
200
201 case 2:
202 while (count) {
203 colors->channel[3] = colors->channel[1];
204 colors->channel[1] = colors->channel[2] = colors->channel[0];
205 ++colors;
206 --count;
207 }
208 return;
209
210 case 3:
211 while (count) {
212 colors->channel[3] = IM_SAMPLE_MAX;
213 ++colors;
214 --count;
215 }
216 return;
217
218 default:
219 i_fatal(3, "i_adapt_colors: in_channels of %d invalid\n", in_channels);
220 return; /* avoid warnings */
221 }
222 }
223
224 default:
225 i_fatal(3, "i_adapt_colors: out_channels of %d invalid\n", out_channels);
226 return; /* avoid warnings */
227 }
228 }
229
6e4af7d - writing a 2 or 4 channel image to a JPEG will now write that image as
Tony Cook authored
230 void
231 #ifdef IM_EIGHT_BIT
232 i_adapt_colors_bg
233 #else
234 i_adapt_fcolors_bg
235 #endif
236 (int out_channels, int in_channels, IM_COLOR *colors,
237 size_t count, IM_COLOR const *bg) {
238 if (out_channels == in_channels)
239 return;
240 if (count == 0)
241 return;
242
243 switch (out_channels) {
244 case 2:
245 case 4:
246 IM_ADAPT_COLORS(out_channels, in_channels, colors, count);
247 return;
248
249 case 1:
250 switch (in_channels) {
251 case 3:
252 IM_ADAPT_COLORS(out_channels, in_channels, colors, count);
253 return;
254
255 case 2:
256 {
257 /* apply alpha against our given background */
258 IM_WORK_T grey_bg = IM_ROUND(color_to_grey(bg));
259 while (count) {
260 colors->channel[0] =
261 (colors->channel[0] * colors->channel[1] +
262 grey_bg * (IM_SAMPLE_MAX - colors->channel[1])) / IM_SAMPLE_MAX;
263 ++colors;
264 --count;
265 }
266 }
267 break;
268
269 case 4:
270 {
271 IM_WORK_T grey_bg = IM_ROUND(color_to_grey(bg));
272 while (count) {
273 IM_WORK_T src_grey = IM_ROUND(color_to_grey(colors));
274 colors->channel[0] =
275 (src_grey * colors->channel[3]
276 + grey_bg * (IM_SAMPLE_MAX - colors->channel[3])) / IM_SAMPLE_MAX;
277 ++colors;
278 --count;
279 }
280 }
281 break;
282 }
283 break;
284
285 case 3:
286 switch (in_channels) {
287 case 1:
288 IM_ADAPT_COLORS(out_channels, in_channels, colors, count);
289 return;
290
291 case 2:
292 {
293 while (count) {
294 int ch;
295 IM_WORK_T src_grey = colors->channel[0];
296 IM_WORK_T src_alpha = colors->channel[1];
297 for (ch = 0; ch < 3; ++ch) {
298 colors->channel[ch] =
299 (src_grey * src_alpha
300 + bg->channel[ch] * (IM_SAMPLE_MAX - src_alpha))
301 / IM_SAMPLE_MAX;
302 }
303 ++colors;
304 --count;
305 }
306 }
307 break;
308
309 case 4:
310 {
311 while (count) {
312 int ch;
313 IM_WORK_T src_alpha = colors->channel[3];
314 for (ch = 0; ch < 3; ++ch) {
315 colors->channel[ch] =
316 (colors->channel[ch] * src_alpha
317 + bg->channel[ch] * (IM_SAMPLE_MAX - src_alpha))
318 / IM_SAMPLE_MAX;
319 }
320 ++colors;
321 --count;
322 }
323 }
324 break;
325 }
326 break;
327 }
2a31a4b add i_gsamp_bg/i_gsampf_bg functions, sample based versions of
Tony Cook authored
328 }
329
330 /*
797a9f9 move JPEG into it's own module
Tony Cook authored
331 =item i_gsamp_bg(im, l, r, y, samples, out_channels, background)
2a31a4b add i_gsamp_bg/i_gsampf_bg functions, sample based versions of
Tony Cook authored
332
797a9f9 move JPEG into it's own module
Tony Cook authored
333 =category Drawing
2a31a4b add i_gsamp_bg/i_gsampf_bg functions, sample based versions of
Tony Cook authored
334
797a9f9 move JPEG into it's own module
Tony Cook authored
335 Like C<i_gsampf()> but applies the source image color over a supplied
336 background color.
2a31a4b add i_gsamp_bg/i_gsampf_bg functions, sample based versions of
Tony Cook authored
337
797a9f9 move JPEG into it's own module
Tony Cook authored
338 This is intended for output to image formats that don't support alpha
339 channels.
340
50c7538 Move freetype 2 support into its own module
Tony Cook authored
341 =cut
342
797a9f9 move JPEG into it's own module
Tony Cook authored
343 =item i_gsampf_bg(im, l, r, y, samples, out_channels, background)
344
345 =category Drawing
346
347 Like C<i_gsampf()> but applies the source image color over a supplied
348 background color.
349
350 This is intended for output to image formats that don't support alpha
351 channels.
2a31a4b add i_gsamp_bg/i_gsampf_bg functions, sample based versions of
Tony Cook authored
352
353 =cut
354 */
355 int
356 #ifdef IM_EIGHT_BIT
357 i_gsamp_bg
358 #else
359 i_gsampf_bg
360 #endif
361 (i_img *im, int l, int r, int y, IM_SAMPLE_T *samples,
362 int out_channels, IM_COLOR const *bg) {
363 if (out_channels == im->channels)
364 return IM_GSAMP(im, l, r, y, samples, NULL, im->channels);
365
366 switch (out_channels) {
367 case 1:
368 switch (im->channels) {
369 case 2:
370 {
371 int x;
372 IM_SAMPLE_T *inp = samples, *outp = samples;
373 IM_WORK_T grey_bg = IM_ROUND(color_to_grey(bg));
374 int count;
375
376 count = IM_GSAMP(im, l, r, y, samples, NULL, im->channels);
377 if (!count)
378 return 0;
379
380 for (x = l; x < r; ++x) {
381 *outp++ = ( inp[0] * inp[1] +
382 grey_bg * (IM_SAMPLE_MAX - inp[1])) / IM_SAMPLE_MAX;
383 inp += 2;
384 }
385
386 return count;
387 }
388 break;
389
390 default:
391 i_fatal(0, "i_gsamp_bg() can only remove alpha channels");
392 break;
393 }
394 break;
395 case 3:
396 switch (im->channels) {
397 case 1:
398 {
399 int channels[3] = { 0, 0, 0 };
400 return IM_GSAMP(im, l, r, y, samples, channels, out_channels);
401 }
402 case 2:
403 {
404 int x, ch;
405 IM_SAMPLE_T *inp = samples, *outp = samples;
406 int count;
407 int channels[4] = { 0, 0, 0, 1 };
408
409 count = IM_GSAMP(im, l, r, y, samples, channels, im->channels);
410 if (!count)
411 return 0;
412
413 for (x = l; x < r; ++x) {
414 IM_WORK_T alpha = inp[3];
415 for (ch = 0; ch < 3; ++ch) {
416 *outp++ = ( *inp++ * alpha +
417 bg->channel[ch] * (IM_SAMPLE_MAX - alpha)) / IM_SAMPLE_MAX;
418 }
419 ++inp;
420 }
421
422 return count;
423 }
424
425 case 4:
426 {
427 int x, ch;
428 IM_SAMPLE_T *inp = samples, *outp = samples;
429 int count;
430
431 count = IM_GSAMP(im, l, r, y, samples, NULL, im->channels);
432 if (!count)
433 return 0;
434
435 for (x = l; x < r; ++x) {
436 IM_WORK_T alpha = inp[3];
437 for (ch = 0; ch < 3; ++ch) {
438 *outp++ = ( *inp++ * alpha +
439 bg->channel[ch] * (IM_SAMPLE_MAX - alpha)) / IM_SAMPLE_MAX;
440 }
441 ++inp;
442 }
443
444 return count;
445 }
446 break;
447 default:
448 i_fatal(0, "i_gsamp_bg() can only remove alpha channels");
449 break;
450 }
451 break;
452
453 default:
454 i_fatal(0, "i_gsamp_bg() can only remove alpha channels");
455 }
6e4af7d - writing a 2 or 4 channel image to a JPEG will now write that image as
Tony Cook authored
456
2a31a4b add i_gsamp_bg/i_gsampf_bg functions, sample based versions of
Tony Cook authored
457 return 0;
6e4af7d - writing a 2 or 4 channel image to a JPEG will now write that image as
Tony Cook authored
458 }
459
9b1ec2b commit changes from draw branch
Tony Cook authored
460 #/code
461
Something went wrong with that request. Please try again.