4 =item i_copyto(dest, src, x1, y1, x2, y2, tx, ty)
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
12 If x1 > x2 or y1 > y2 then the corresponding co-ordinates are swapped.
18 i_copyto(i_img *im, i_img *src, int x1, int y1, int x2, int y2, int tx, int ty) {
21 if (x2<x1) { t=x1; x1=x2; x2=t; }
22 if (y2<y1) { t=y1; y1=y2; y2=t; }
24 /* adjust everything equally */
34 if (x1 >= src->xsize || y1 >= src->ysize)
35 return; /* nothing to do */
40 if (x1 == x2 || y1 == y2)
41 return; /* nothing to do */
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));
46 #code im->bits == i_8_bits
47 IM_COLOR *row = mymalloc(sizeof(IM_COLOR) * (x2-x1));
49 for(y=y1; y<y2; y++) {
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);
61 #define color_to_grey(col) ((col)->rgb.r * 0.222 + (col)->rgb.g * 0.707 + (col)->rgb.b * 0.071)
70 (int out_channels, int in_channels, IM_COLOR *colors,
72 if (out_channels == in_channels)
77 switch (out_channels) {
80 switch (in_channels) {
82 /* apply alpha against a black background */
84 colors->channel[0] = colors->channel[0] * colors->channel[1] / IM_SAMPLE_MAX;
93 colors->channel[0] = IM_ROUND(color_to_grey(colors));
101 colors->channel[0] = IM_ROUND(color_to_grey(colors) * colors->channel[3] / IM_SAMPLE_MAX);
108 i_fatal(3, "i_adapt_colors: in_channels of %d invalid\n", in_channels);
109 return; /* avoid warnings */
115 switch (in_channels) {
118 colors->channel[1] = IM_SAMPLE_MAX;
126 colors->channel[0] = IM_ROUND(color_to_grey(colors));
127 colors->channel[1] = IM_SAMPLE_MAX;
135 colors->channel[0] = IM_ROUND(color_to_grey(colors));
136 colors->channel[1] = colors->channel[3];
143 i_fatal(3, "i_adapt_colors: in_channels of %d invalid\n", in_channels);
144 return; /* avoid warnings */
150 switch (in_channels) {
153 colors->channel[1] = colors->channel[2] = colors->channel[0];
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);
171 int alpha = colors->channel[3];
173 IM_ROUND(colors->channel[0] * alpha / IM_SAMPLE_MAX);
175 IM_ROUND(colors->channel[1] * alpha / IM_SAMPLE_MAX);
177 IM_ROUND(colors->channel[2] * alpha / IM_SAMPLE_MAX);
184 i_fatal(3, "i_adapt_colors: in_channels of %d invalid\n", in_channels);
185 return; /* avoid warnings */
191 switch (in_channels) {
194 colors->channel[1] = colors->channel[2] = colors->channel[0];
195 colors->channel[3] = IM_SAMPLE_MAX;
203 colors->channel[3] = colors->channel[1];
204 colors->channel[1] = colors->channel[2] = colors->channel[0];
212 colors->channel[3] = IM_SAMPLE_MAX;
219 i_fatal(3, "i_adapt_colors: in_channels of %d invalid\n", in_channels);
220 return; /* avoid warnings */
225 i_fatal(3, "i_adapt_colors: out_channels of %d invalid\n", out_channels);
226 return; /* avoid warnings */
236 (int out_channels, int in_channels, IM_COLOR *colors,
237 size_t count, IM_COLOR const *bg) {
238 if (out_channels == in_channels)
243 switch (out_channels) {
246 IM_ADAPT_COLORS(out_channels, in_channels, colors, count);
250 switch (in_channels) {
252 IM_ADAPT_COLORS(out_channels, in_channels, colors, count);
257 /* apply alpha against our given background */
258 IM_WORK_T grey_bg = IM_ROUND(color_to_grey(bg));
261 (colors->channel[0] * colors->channel[1] +
262 grey_bg * (IM_SAMPLE_MAX - colors->channel[1])) / IM_SAMPLE_MAX;
271 IM_WORK_T grey_bg = IM_ROUND(color_to_grey(bg));
273 IM_WORK_T src_grey = IM_ROUND(color_to_grey(colors));
275 (src_grey * colors->channel[3]
276 + grey_bg * (IM_SAMPLE_MAX - colors->channel[3])) / IM_SAMPLE_MAX;
286 switch (in_channels) {
288 IM_ADAPT_COLORS(out_channels, in_channels, colors, count);
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))
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))
331 =item i_gsamp_bg(im, l, r, y, samples, out_channels, bg)
333 =item i_gsampf_bg(im, l, r, y, samples, out_channels, bg)
335 This is similar to i_adapt_colors_bg() except it can only strip an
336 alpha channel. It cannot be used to convert a source RGB image to
339 The samples parameter MUST include enough space for all samples of the
350 (i_img *im, int l, int r, int y, IM_SAMPLE_T *samples,
351 int out_channels, IM_COLOR const *bg) {
352 if (out_channels == im->channels)
353 return IM_GSAMP(im, l, r, y, samples, NULL, im->channels);
355 switch (out_channels) {
357 switch (im->channels) {
361 IM_SAMPLE_T *inp = samples, *outp = samples;
362 IM_WORK_T grey_bg = IM_ROUND(color_to_grey(bg));
365 count = IM_GSAMP(im, l, r, y, samples, NULL, im->channels);
369 for (x = l; x < r; ++x) {
370 *outp++ = ( inp[0] * inp[1] +
371 grey_bg * (IM_SAMPLE_MAX - inp[1])) / IM_SAMPLE_MAX;
380 i_fatal(0, "i_gsamp_bg() can only remove alpha channels");
385 switch (im->channels) {
388 int channels[3] = { 0, 0, 0 };
389 return IM_GSAMP(im, l, r, y, samples, channels, out_channels);
394 IM_SAMPLE_T *inp = samples, *outp = samples;
396 int channels[4] = { 0, 0, 0, 1 };
398 count = IM_GSAMP(im, l, r, y, samples, channels, im->channels);
402 for (x = l; x < r; ++x) {
403 IM_WORK_T alpha = inp[3];
404 for (ch = 0; ch < 3; ++ch) {
405 *outp++ = ( *inp++ * alpha +
406 bg->channel[ch] * (IM_SAMPLE_MAX - alpha)) / IM_SAMPLE_MAX;
417 IM_SAMPLE_T *inp = samples, *outp = samples;
420 count = IM_GSAMP(im, l, r, y, samples, NULL, im->channels);
424 for (x = l; x < r; ++x) {
425 IM_WORK_T alpha = inp[3];
426 for (ch = 0; ch < 3; ++ch) {
427 *outp++ = ( *inp++ * alpha +
428 bg->channel[ch] * (IM_SAMPLE_MAX - alpha)) / IM_SAMPLE_MAX;
437 i_fatal(0, "i_gsamp_bg() can only remove alpha channels");
443 i_fatal(0, "i_gsamp_bg() can only remove alpha channels");