Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 465 lines (403 sloc) 9.446 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
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
20 i_copyto(i_img *im, i_img *src, i_img_dim x1, i_img_dim y1, i_img_dim x2, i_img_dim y2, i_img_dim tx, i_img_dim ty) {
21 i_img_dim 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
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
45 mm_log((1,"i_copyto(im* %p, src %p, p1(" i_DFp "), p2(" i_DFp "), t("
46 i_DFp "))\n",
47 im, src, i_DFcp(x1, y1), i_DFcp(x2, y2), i_DFcp(tx, ty)));
9b1ec2b commit changes from draw branch
Tony Cook authored
48
49 #code im->bits == i_8_bits
50 IM_COLOR *row = mymalloc(sizeof(IM_COLOR) * (x2-x1));
51 tty = ty;
52 for(y=y1; y<y2; y++) {
53 ttx = tx;
54 IM_GLIN(src, x1, x2, y, row);
55 if (src->channels != im->channels)
56 IM_ADAPT_COLORS(im->channels, src->channels, row, x2-x1);
57 IM_PLIN(im, tx, tx+x2-x1, tty, row);
58 tty++;
59 }
60 myfree(row);
61 #/code
62 }
63
64 #code
65 void
66 #ifdef IM_EIGHT_BIT
67 i_adapt_colors
68 #else
69 i_adapt_fcolors
70 #endif
71 (int out_channels, int in_channels, IM_COLOR *colors,
72 size_t count) {
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
6e4af7d - writing a 2 or 4 channel image to a JPEG will now write that image as
Tony Cook authored
231 void
232 #ifdef IM_EIGHT_BIT
233 i_adapt_colors_bg
234 #else
235 i_adapt_fcolors_bg
236 #endif
237 (int out_channels, int in_channels, IM_COLOR *colors,
238 size_t count, IM_COLOR const *bg) {
239 if (out_channels == in_channels)
240 return;
241 if (count == 0)
242 return;
243
244 switch (out_channels) {
245 case 2:
246 case 4:
247 IM_ADAPT_COLORS(out_channels, in_channels, colors, count);
248 return;
249
250 case 1:
251 switch (in_channels) {
252 case 3:
253 IM_ADAPT_COLORS(out_channels, in_channels, colors, count);
254 return;
255
256 case 2:
257 {
258 /* apply alpha against our given background */
259 IM_WORK_T grey_bg = IM_ROUND(color_to_grey(bg));
260 while (count) {
261 colors->channel[0] =
262 (colors->channel[0] * colors->channel[1] +
263 grey_bg * (IM_SAMPLE_MAX - colors->channel[1])) / IM_SAMPLE_MAX;
264 ++colors;
265 --count;
266 }
267 }
268 break;
269
270 case 4:
271 {
272 IM_WORK_T grey_bg = IM_ROUND(color_to_grey(bg));
273 while (count) {
274 IM_WORK_T src_grey = IM_ROUND(color_to_grey(colors));
275 colors->channel[0] =
276 (src_grey * colors->channel[3]
277 + grey_bg * (IM_SAMPLE_MAX - colors->channel[3])) / IM_SAMPLE_MAX;
278 ++colors;
279 --count;
280 }
281 }
282 break;
283 }
284 break;
285
286 case 3:
287 switch (in_channels) {
288 case 1:
289 IM_ADAPT_COLORS(out_channels, in_channels, colors, count);
290 return;
291
292 case 2:
293 {
294 while (count) {
295 int ch;
296 IM_WORK_T src_grey = colors->channel[0];
297 IM_WORK_T src_alpha = colors->channel[1];
298 for (ch = 0; ch < 3; ++ch) {
299 colors->channel[ch] =
300 (src_grey * src_alpha
301 + bg->channel[ch] * (IM_SAMPLE_MAX - src_alpha))
302 / IM_SAMPLE_MAX;
303 }
304 ++colors;
305 --count;
306 }
307 }
308 break;
309
310 case 4:
311 {
312 while (count) {
313 int ch;
314 IM_WORK_T src_alpha = colors->channel[3];
315 for (ch = 0; ch < 3; ++ch) {
316 colors->channel[ch] =
317 (colors->channel[ch] * src_alpha
318 + bg->channel[ch] * (IM_SAMPLE_MAX - src_alpha))
319 / IM_SAMPLE_MAX;
320 }
321 ++colors;
322 --count;
323 }
324 }
325 break;
326 }
327 break;
328 }
2a31a4b add i_gsamp_bg/i_gsampf_bg functions, sample based versions of
Tony Cook authored
329 }
330
331 /*
797a9f9 move JPEG into it's own module
Tony Cook authored
332 =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
333
797a9f9 move JPEG into it's own module
Tony Cook authored
334 =category Drawing
2a31a4b add i_gsamp_bg/i_gsampf_bg functions, sample based versions of
Tony Cook authored
335
797a9f9 move JPEG into it's own module
Tony Cook authored
336 Like C<i_gsampf()> but applies the source image color over a supplied
337 background color.
2a31a4b add i_gsamp_bg/i_gsampf_bg functions, sample based versions of
Tony Cook authored
338
797a9f9 move JPEG into it's own module
Tony Cook authored
339 This is intended for output to image formats that don't support alpha
340 channels.
341
50c7538 Move freetype 2 support into its own module
Tony Cook authored
342 =cut
343
797a9f9 move JPEG into it's own module
Tony Cook authored
344 =item i_gsampf_bg(im, l, r, y, samples, out_channels, background)
345
346 =category Drawing
347
348 Like C<i_gsampf()> but applies the source image color over a supplied
349 background color.
350
351 This is intended for output to image formats that don't support alpha
352 channels.
2a31a4b add i_gsamp_bg/i_gsampf_bg functions, sample based versions of
Tony Cook authored
353
354 =cut
355 */
356 int
357 #ifdef IM_EIGHT_BIT
358 i_gsamp_bg
359 #else
360 i_gsampf_bg
361 #endif
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
362 (i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, IM_SAMPLE_T *samples,
2a31a4b add i_gsamp_bg/i_gsampf_bg functions, sample based versions of
Tony Cook authored
363 int out_channels, IM_COLOR const *bg) {
364 if (out_channels == im->channels)
365 return IM_GSAMP(im, l, r, y, samples, NULL, im->channels);
366
367 switch (out_channels) {
368 case 1:
369 switch (im->channels) {
370 case 2:
371 {
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
372 i_img_dim x;
2a31a4b add i_gsamp_bg/i_gsampf_bg functions, sample based versions of
Tony Cook authored
373 IM_SAMPLE_T *inp = samples, *outp = samples;
374 IM_WORK_T grey_bg = IM_ROUND(color_to_grey(bg));
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
375 i_img_dim count;
2a31a4b add i_gsamp_bg/i_gsampf_bg functions, sample based versions of
Tony Cook authored
376
377 count = IM_GSAMP(im, l, r, y, samples, NULL, im->channels);
378 if (!count)
379 return 0;
380
381 for (x = l; x < r; ++x) {
382 *outp++ = ( inp[0] * inp[1] +
383 grey_bg * (IM_SAMPLE_MAX - inp[1])) / IM_SAMPLE_MAX;
384 inp += 2;
385 }
386
387 return count;
388 }
389 break;
390
391 default:
392 i_fatal(0, "i_gsamp_bg() can only remove alpha channels");
393 break;
394 }
395 break;
396 case 3:
397 switch (im->channels) {
398 case 1:
399 {
400 int channels[3] = { 0, 0, 0 };
401 return IM_GSAMP(im, l, r, y, samples, channels, out_channels);
402 }
403 case 2:
404 {
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
405 i_img_dim x;
406 int ch;
2a31a4b add i_gsamp_bg/i_gsampf_bg functions, sample based versions of
Tony Cook authored
407 IM_SAMPLE_T *inp = samples, *outp = samples;
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
408 i_img_dim count;
2a31a4b add i_gsamp_bg/i_gsampf_bg functions, sample based versions of
Tony Cook authored
409 int channels[4] = { 0, 0, 0, 1 };
410
411 count = IM_GSAMP(im, l, r, y, samples, channels, im->channels);
412 if (!count)
413 return 0;
414
415 for (x = l; x < r; ++x) {
416 IM_WORK_T alpha = inp[3];
417 for (ch = 0; ch < 3; ++ch) {
418 *outp++ = ( *inp++ * alpha +
419 bg->channel[ch] * (IM_SAMPLE_MAX - alpha)) / IM_SAMPLE_MAX;
420 }
421 ++inp;
422 }
423
424 return count;
425 }
426
427 case 4:
428 {
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
429 i_img_dim x;
430 int ch;
2a31a4b add i_gsamp_bg/i_gsampf_bg functions, sample based versions of
Tony Cook authored
431 IM_SAMPLE_T *inp = samples, *outp = samples;
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
432 i_img_dim count;
2a31a4b add i_gsamp_bg/i_gsampf_bg functions, sample based versions of
Tony Cook authored
433
434 count = IM_GSAMP(im, l, r, y, samples, NULL, im->channels);
435 if (!count)
436 return 0;
437
438 for (x = l; x < r; ++x) {
439 IM_WORK_T alpha = inp[3];
440 for (ch = 0; ch < 3; ++ch) {
441 *outp++ = ( *inp++ * alpha +
442 bg->channel[ch] * (IM_SAMPLE_MAX - alpha)) / IM_SAMPLE_MAX;
443 }
444 ++inp;
445 }
446
447 return count;
448 }
449 break;
450 default:
451 i_fatal(0, "i_gsamp_bg() can only remove alpha channels");
452 break;
453 }
454 break;
455
456 default:
457 i_fatal(0, "i_gsamp_bg() can only remove alpha channels");
458 }
6e4af7d - writing a 2 or 4 channel image to a JPEG will now write that image as
Tony Cook authored
459
2a31a4b add i_gsamp_bg/i_gsampf_bg functions, sample based versions of
Tony Cook authored
460 return 0;
6e4af7d - writing a 2 or 4 channel image to a JPEG will now write that image as
Tony Cook authored
461 }
462
9b1ec2b commit changes from draw branch
Tony Cook authored
463 #/code
464
Something went wrong with that request. Please try again.