short psave;
i_color val,val1,val2;
i_img *new_img;
+ int has_alpha = i_img_has_alpha(im);
+ int color_chans = i_img_color_channels(im);
i_clear_error();
mm_log((1,"i_scaleaxis(im %p,Value %.2f,Axis %d)\n",im,Value,Axis));
-
if (Axis == XAXIS) {
hsize = (int)(0.5 + im->xsize * Value);
if (hsize < 1) {
i_gpix(im, Mx, i, &val1);
i_gpix(im, mx, i, &val2);
-
- for (k=0; k<im->channels; k++) {
- PictureValue[k] += l1[l] * val1.channel[k];
- PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
+
+ if (has_alpha) {
+ i_sample_t alpha1 = val1.channel[color_chans];
+ i_sample_t alpha2 = val2.channel[color_chans];
+ for (k=0; k < color_chans; k++) {
+ PictureValue[k] += l1[l] * val1.channel[k] * alpha1 / 255;
+ PictureValue[k] += l0[lMax-l-1] * val2.channel[k] * alpha2 / 255;
+ }
+ PictureValue[color_chans] += l1[l] * val1.channel[color_chans];
+ PictureValue[color_chans] += l0[lMax-l-1] * val2.channel[color_chans];
+ }
+ else {
+ for (k=0; k<im->channels; k++) {
+ PictureValue[k] += l1[l] * val1.channel[k];
+ PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
+ }
+ }
+ }
+
+ if (has_alpha) {
+ float fa = PictureValue[color_chans] / LanczosWidthFactor;
+ int alpha = minmax(0, 255, fa+0.5);
+ if (alpha) {
+ for (k = 0; k < color_chans; ++k) {
+ psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor * 255 / fa));
+ val.channel[k]=minmax(0,255,psave);
+ }
+ val.channel[color_chans] = alpha;
+ }
+ else {
+ /* zero alpha, so the pixel has no color */
+ for (k = 0; k < im->channels; ++k)
+ val.channel[k] = 0;
}
}
- for(k=0;k<im->channels;k++) {
- psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
- val.channel[k]=minmax(0,255,psave);
+ else {
+ for(k=0;k<im->channels;k++) {
+ psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
+ val.channel[k]=minmax(0,255,psave);
+ }
}
i_ppix(new_img, j, i, &val);
}
i_gpix(im, i, Mx, &val1);
i_gpix(im, i, mx, &val2);
- for (k=0; k<im->channels; k++) {
- PictureValue[k] += l1[l] * val1.channel[k];
- PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
+ if (has_alpha) {
+ i_sample_t alpha1 = val1.channel[color_chans];
+ i_sample_t alpha2 = val2.channel[color_chans];
+ for (k=0; k < color_chans; k++) {
+ PictureValue[k] += l1[l] * val1.channel[k] * alpha1 / 255;
+ PictureValue[k] += l0[lMax-l-1] * val2.channel[k] * alpha2 / 255;
+ }
+ PictureValue[color_chans] += l1[l] * val1.channel[color_chans];
+ PictureValue[color_chans] += l0[lMax-l-1] * val2.channel[color_chans];
+ }
+ else {
+ for (k=0; k<im->channels; k++) {
+ PictureValue[k] += l1[l] * val1.channel[k];
+ PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
+ }
}
}
- for (k=0; k<im->channels; k++) {
- psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
- val.channel[k] = minmax(0, 255, psave);
+ if (has_alpha) {
+ float fa = PictureValue[color_chans] / LanczosWidthFactor;
+ int alpha = minmax(0, 255, fa+0.5);
+ if (alpha) {
+ for (k = 0; k < color_chans; ++k) {
+ psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor * 255 / fa));
+ val.channel[k]=minmax(0,255,psave);
+ }
+ val.channel[color_chans] = alpha;
+ }
+ else {
+ for (k = 0; k < im->channels; ++k)
+ val.channel[k] = 0;
+ }
+ }
+ else {
+ for(k=0;k<im->channels;k++) {
+ psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
+ val.channel[k]=minmax(0,255,psave);
+ }
}
i_ppix(new_img, i, j, &val);
}
#!perl -w
use strict;
-use Test::More tests => 230;
+use Test::More tests => 232;
BEGIN { use_ok(Imager=>':all') }
-use Imager::Test qw(is_image is_color4);
+use Imager::Test qw(is_image is_color4 is_image_similar);
Imager::init('log'=>'testout/t40scale.log');
my $img=Imager->new();
pixels => 144);
}
-{ # check proper alpha handling
+{ # check proper alpha handling for mixing
my $im = Imager->new(xsize => 40, ysize => 40, channels => 4);
$im->box(filled => 1, color => 'C0C0C0');
my $rot = $im->rotate(degrees => -4)
$out->box(filled => 1, color => 'C0C0C0');
my $cmp = $out->copy;
$out->rubthrough(src => $sc);
- is_image($out, $cmp, "check we get the right image after scaling");
+ is_image($out, $cmp, "check we get the right image after scaling (mixing)");
+
+ # we now set alpha=0 pixels to zero on scaling
+ is_color4($sc->getpixel('x' => 39, 'y' => 39), 0, 0, 0, 0,
+ "check we set alpha=0 pixels to zero on scaling");
+}
+
+{ # check proper alpha handling for default scaling
+ my $im = Imager->new(xsize => 40, ysize => 40, channels => 4);
+ $im->box(filled => 1, color => 'C0C0C0');
+ my $rot = $im->rotate(degrees => -4)
+ or die;
+ my $sc = $rot->scale(qtype => "normal", xpixels => 40);
+ my $out = Imager->new(xsize => $sc->getwidth, ysize => $sc->getheight);
+ $out->box(filled => 1, color => 'C0C0C0');
+ my $cmp = $out->copy;
+ $out->rubthrough(src => $sc);
+ is_image_similar($out, $cmp, 100, "check we get the right image after scaling (normal)");
# we now set alpha=0 pixels to zero on scaling
is_color4($sc->getpixel('x' => 39, 'y' => 39), 0, 0, 0, 0,