X-Git-Url: http://git.imager.perl.org/imager.git/blobdiff_plain/6e4af7d46933dd3b56d496798a4de860e19e7cd9..f388cd372ce445f7839aefdb0a8e4ac9898f75ad:/paste.im diff --git a/paste.im b/paste.im index 45305df3..8cd2b710 100644 --- a/paste.im +++ b/paste.im @@ -1,22 +1,24 @@ #include "imager.h" +#include "imageri.h" /* -=item i_copyto(dest, src, x1, y1, x2, y2, tx, ty) +=item i_copyto(C, C, C, C, C, C, C, C) =category Image -Copies image data from the area (x1,y1)-[x2,y2] in the source image to -a rectangle the same size with it's top-left corner at (tx,ty) in the -destination image. +Copies image data from the area (C,C)-[C,C] in the +source image to a rectangle the same size with it's top-left corner at +(C,C) in the destination image. -If x1 > x2 or y1 > y2 then the corresponding co-ordinates are swapped. +If C > C or C > C then the corresponding co-ordinates +are swapped. =cut */ void -i_copyto(i_img *im, i_img *src, int x1, int y1, int x2, int y2, int tx, int ty) { - int x, y, t, ttx, tty; +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) { + i_img_dim y, t, ttx, tty; if (x2bits == i_8_bits IM_COLOR *row = mymalloc(sizeof(IM_COLOR) * (x2-x1)); @@ -58,8 +61,6 @@ i_copyto(i_img *im, i_img *src, int x1, int y1, int x2, int y2, int tx, int ty) #/code } -#define color_to_grey(col) ((col)->rgb.r * 0.222 + (col)->rgb.g * 0.707 + (col)->rgb.b * 0.071) - #code void #ifdef IM_EIGHT_BIT @@ -69,7 +70,6 @@ i_adapt_fcolors #endif (int out_channels, int in_channels, IM_COLOR *colors, size_t count) { - int i; if (out_channels == in_channels) return; if (count == 0) @@ -326,7 +326,138 @@ i_adapt_fcolors_bg } break; } +} + +/* +=item i_gsamp_bg(im, l, r, y, samples, out_channels, background) + +=category Drawing + +Like C but applies the source image color over a supplied +background color. + +This is intended for output to image formats that don't support alpha +channels. + +=cut + +=item i_gsampf_bg(im, l, r, y, samples, out_channels, background) + +=category Drawing + +Like C but applies the source image color over a supplied +background color. + +This is intended for output to image formats that don't support alpha +channels. + +=cut +*/ +int +#ifdef IM_EIGHT_BIT +i_gsamp_bg +#else +i_gsampf_bg +#endif +(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, IM_SAMPLE_T *samples, + int out_channels, IM_COLOR const *bg) { + if (out_channels == im->channels) + return IM_GSAMP(im, l, r, y, samples, NULL, im->channels); + + switch (out_channels) { + case 1: + switch (im->channels) { + case 2: + { + i_img_dim x; + IM_SAMPLE_T *inp = samples, *outp = samples; + IM_WORK_T grey_bg = IM_ROUND(color_to_grey(bg)); + i_img_dim count; + + count = IM_GSAMP(im, l, r, y, samples, NULL, im->channels); + if (!count) + return 0; + + for (x = l; x < r; ++x) { + *outp++ = ( inp[0] * inp[1] + + grey_bg * (IM_SAMPLE_MAX - inp[1])) / IM_SAMPLE_MAX; + inp += 2; + } + + return count; + } + break; + + default: + i_fatal(0, "i_gsamp_bg() can only remove alpha channels"); + break; + } + break; + case 3: + switch (im->channels) { + case 1: + { + int channels[3] = { 0, 0, 0 }; + return IM_GSAMP(im, l, r, y, samples, channels, out_channels); + } + case 2: + { + i_img_dim x; + int ch; + IM_SAMPLE_T *inp = samples, *outp = samples; + i_img_dim count; + int channels[4] = { 0, 0, 0, 1 }; + + count = IM_GSAMP(im, l, r, y, samples, channels, im->channels); + if (!count) + return 0; + + for (x = l; x < r; ++x) { + IM_WORK_T alpha = inp[3]; + for (ch = 0; ch < 3; ++ch) { + *outp++ = ( *inp++ * alpha + + bg->channel[ch] * (IM_SAMPLE_MAX - alpha)) / IM_SAMPLE_MAX; + } + ++inp; + } + + return count; + } + + case 4: + { + i_img_dim x; + int ch; + IM_SAMPLE_T *inp = samples, *outp = samples; + i_img_dim count; + + count = IM_GSAMP(im, l, r, y, samples, NULL, im->channels); + if (!count) + return 0; + + for (x = l; x < r; ++x) { + IM_WORK_T alpha = inp[3]; + for (ch = 0; ch < 3; ++ch) { + *outp++ = ( *inp++ * alpha + + bg->channel[ch] * (IM_SAMPLE_MAX - alpha)) / IM_SAMPLE_MAX; + } + ++inp; + } + + return count; + } + break; + default: + i_fatal(0, "i_gsamp_bg() can only remove alpha channels"); + break; + } + break; + + default: + i_fatal(0, "i_gsamp_bg() can only remove alpha channels"); + } + return 0; } #/code