[rt #69261] fix incorrect image size and color calculations for rotate()
authorTony Cook <tony@develop-help.com>
Fri, 20 Jan 2012 11:16:47 +0000 (22:16 +1100)
committerTony Cook <tony@develop-help.com>
Fri, 20 Jan 2012 11:16:47 +0000 (22:16 +1100)
and matrix_transform().

For rotate() the calculation used integer abs() instead of fabs() when
calculating the size of the new image.

This made the image a little too small, hiding a bug at the corners
where a very low coverage pixel would reveal another bug where bad
rounding of the output level could result in all samples being maxed
out (8-bit images only.)

Changes
rotate.im

diff --git a/Changes b/Changes
index 1a26886..0cc8f85 100644 (file)
--- a/Changes
+++ b/Changes
@@ -8,6 +8,15 @@ Imager release history.  Older releases can be found in Changes.old
  - update the change notes for 0.77_01 to indicate that libungif
    support was removed.
 
+Bug fixes:
+
+ - correctly calculate the size of a rotated image
+   https://rt.cpan.org/Ticket/Display.html?id=69261
+
+ - fix incorrect rounding of color values for matrix_transform() and
+   rotate().
+   https://rt.cpan.org/Ticket/Display.html?id=69261
+
 Imager 0.87 - 03 Jan 2012
 ===========
 
index e6d1d11..ce8cefc 100644 (file)
--- a/rotate.im
+++ b/rotate.im
@@ -145,7 +145,7 @@ static i_color interp_i_color(i_color before, i_color after, double pos,
 
       for (ch = 0; ch < channels-1; ++ch) {
        int out_level = ((1-pos) * before.channel[ch] * before_alpha + 
-                        pos * after.channel[ch] * after_alpha + 0.5) / total_alpha;
+                        pos * after.channel[ch] * after_alpha) / total_alpha + 0.5;
 
        out.channel[ch] = I_LIMIT_8(out_level);
       }
@@ -419,10 +419,10 @@ i_img *i_rotate_exact_bg(i_img *src, double amount,
   rotate[7] = 0;
   rotate[8] = 1;
 
-  x1 = ceil(i_abs(src->xsize * rotate[0] + src->ysize * rotate[1]));
-  x2 = ceil(i_abs(src->xsize * rotate[0] - src->ysize * rotate[1]));
-  y1 = ceil(i_abs(src->xsize * rotate[3] + src->ysize * rotate[4]));
-  y2 = ceil(i_abs(src->xsize * rotate[3] - src->ysize * rotate[4]));
+  x1 = ceil(fabs(src->xsize * rotate[0] + src->ysize * rotate[1]));
+  x2 = ceil(fabs(src->xsize * rotate[0] - src->ysize * rotate[1]));
+  y1 = ceil(fabs(src->xsize * rotate[3] + src->ysize * rotate[4]));
+  y2 = ceil(fabs(src->xsize * rotate[3] - src->ysize * rotate[4]));
   newxsize = x1 > x2 ? x1 : x2;
   newysize = y1 > y2 ? y1 : y2;
   /* translate the centre back to the center of the image */