5 =item i_copyto(C<dest>, C<src>, C<x1>, C<y1>, C<x2>, C<y2>, C<tx>, C<ty>)
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.
13 If C<x1> > C<x2> or C<y1> > C<y2> then the corresponding co-ordinates
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;
23 if (x2<x1) { t=x1; x1=x2; x2=t; }
24 if (y2<y1) { t=y1; y1=y2; y2=t; }
26 /* adjust everything equally */
36 if (x1 >= src->xsize || y1 >= src->ysize)
37 return; /* nothing to do */
42 if (x1 == x2 || y1 == y2)
43 return; /* nothing to do */
45 mm_log((1,"i_copyto(im* %p, src %p, p1(" i_DFp "), p2(" i_DFp "), t("
47 im, src, i_DFcp(x1, y1), i_DFcp(x2, y2), i_DFcp(tx, ty)));
49 #code im->bits == i_8_bits
50 IM_COLOR *row = mymalloc(sizeof(IM_COLOR) * (x2-x1));
52 for(y=y1; y<y2; y++) {
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);
71 (int out_channels, int in_channels, IM_COLOR *colors,
73 if (out_channels == in_channels)
78 switch (out_channels) {
81 switch (in_channels) {
83 /* apply alpha against a black background */
85 colors->channel[0] = colors->channel[0] * colors->channel[1] / IM_SAMPLE_MAX;
94 colors->channel[0] = IM_ROUND(color_to_grey(colors));
102 colors->channel[0] = IM_ROUND(color_to_grey(colors) * colors->channel[3] / IM_SAMPLE_MAX);
109 i_fatal(3, "i_adapt_colors: in_channels of %d invalid\n", in_channels);
110 return; /* avoid warnings */
116 switch (in_channels) {
119 colors->channel[1] = IM_SAMPLE_MAX;
127 colors->channel[0] = IM_ROUND(color_to_grey(colors));
128 colors->channel[1] = IM_SAMPLE_MAX;
136 colors->channel[0] = IM_ROUND(color_to_grey(colors));
137 colors->channel[1] = colors->channel[3];
144 i_fatal(3, "i_adapt_colors: in_channels of %d invalid\n", in_channels);
145 return; /* avoid warnings */
151 switch (in_channels) {
154 colors->channel[1] = colors->channel[2] = colors->channel[0];
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);
172 int alpha = colors->channel[3];
174 IM_ROUND(colors->channel[0] * alpha / IM_SAMPLE_MAX);
176 IM_ROUND(colors->channel[1] * alpha / IM_SAMPLE_MAX);
178 IM_ROUND(colors->channel[2] * alpha / IM_SAMPLE_MAX);
185 i_fatal(3, "i_adapt_colors: in_channels of %d invalid\n", in_channels);
186 return; /* avoid warnings */
192 switch (in_channels) {
195 colors->channel[1] = colors->channel[2] = colors->channel[0];
196 colors->channel[3] = IM_SAMPLE_MAX;
204 colors->channel[3] = colors->channel[1];
205 colors->channel[1] = colors->channel[2] = colors->channel[0];
213 colors->channel[3] = IM_SAMPLE_MAX;
220 i_fatal(3, "i_adapt_colors: in_channels of %d invalid\n", in_channels);
221 return; /* avoid warnings */
226 i_fatal(3, "i_adapt_colors: out_channels of %d invalid\n", out_channels);
227 return; /* avoid warnings */
237 (int out_channels, int in_channels, IM_COLOR *colors,
238 size_t count, IM_COLOR const *bg) {
239 if (out_channels == in_channels)
244 switch (out_channels) {
247 IM_ADAPT_COLORS(out_channels, in_channels, colors, count);
251 switch (in_channels) {
253 IM_ADAPT_COLORS(out_channels, in_channels, colors, count);
258 /* apply alpha against our given background */
259 IM_WORK_T grey_bg = IM_ROUND(color_to_grey(bg));
262 (colors->channel[0] * colors->channel[1] +
263 grey_bg * (IM_SAMPLE_MAX - colors->channel[1])) / IM_SAMPLE_MAX;
272 IM_WORK_T grey_bg = IM_ROUND(color_to_grey(bg));
274 IM_WORK_T src_grey = IM_ROUND(color_to_grey(colors));
276 (src_grey * colors->channel[3]
277 + grey_bg * (IM_SAMPLE_MAX - colors->channel[3])) / IM_SAMPLE_MAX;
287 switch (in_channels) {
289 IM_ADAPT_COLORS(out_channels, in_channels, colors, count);
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))
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))
332 =item i_gsamp_bg(im, l, r, y, samples, out_channels, background)
336 Like C<i_gsampf()> but applies the source image color over a supplied
339 This is intended for output to image formats that don't support alpha
344 =item i_gsampf_bg(im, l, r, y, samples, out_channels, background)
348 Like C<i_gsampf()> but applies the source image color over a supplied
351 This is intended for output to image formats that don't support alpha
362 (i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, IM_SAMPLE_T *samples,
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);
367 switch (out_channels) {
369 switch (im->channels) {
373 IM_SAMPLE_T *inp = samples, *outp = samples;
374 IM_WORK_T grey_bg = IM_ROUND(color_to_grey(bg));
377 count = IM_GSAMP(im, l, r, y, samples, NULL, im->channels);
381 for (x = l; x < r; ++x) {
382 *outp++ = ( inp[0] * inp[1] +
383 grey_bg * (IM_SAMPLE_MAX - inp[1])) / IM_SAMPLE_MAX;
392 i_fatal(0, "i_gsamp_bg() can only remove alpha channels");
397 switch (im->channels) {
400 int channels[3] = { 0, 0, 0 };
401 return IM_GSAMP(im, l, r, y, samples, channels, out_channels);
407 IM_SAMPLE_T *inp = samples, *outp = samples;
409 int channels[4] = { 0, 0, 0, 1 };
411 count = IM_GSAMP(im, l, r, y, samples, channels, im->channels);
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;
431 IM_SAMPLE_T *inp = samples, *outp = samples;
434 count = IM_GSAMP(im, l, r, y, samples, NULL, im->channels);
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;
451 i_fatal(0, "i_gsamp_bg() can only remove alpha channels");
457 i_fatal(0, "i_gsamp_bg() can only remove alpha channels");