bits_image_fetch_pixel_convolution(): Make sure channels are signed
authorSøren Sandmann Pedersen <ssp@redhat.com>
Thu, 5 Apr 2012 04:52:21 +0000 (00:52 -0400)
committerSøren Sandmann Pedersen <ssp@redhat.com>
Fri, 20 Apr 2012 14:17:13 +0000 (10:17 -0400)
In the computation:

    srtot += RED_8 (pixel) * f

RED_8 (pixel) is an unsigned quantity, which means the signed filter
coefficient f gets converted to an unsigned integer before the
multiplication. We get away with this because when the 32 bit unsigned
result is converted to int32_t, the correct sign is produced. But if
srtot had been an int64_t, the result would have been a very large
positive number.

Fix this by explicitly casting the channels to int.

pixman/pixman-bits-image.c

index d105d2f..1f6897c 100644 (file)
@@ -381,11 +381,11 @@ bits_image_fetch_pixel_convolution (bits_image_t   *image,
     int y_off = (params[1] - pixman_fixed_1) >> 1;
     int32_t cwidth = pixman_fixed_to_int (params[0]);
     int32_t cheight = pixman_fixed_to_int (params[1]);
-    int32_t srtot, sgtot, sbtot, satot;
     int32_t i, j, x1, x2, y1, y2;
     pixman_repeat_t repeat_mode = image->common.repeat;
     int width = image->width;
     int height = image->height;
+    int srtot, sgtot, sbtot, satot;
 
     params += 2;
 
@@ -421,10 +421,10 @@ bits_image_fetch_pixel_convolution (bits_image_t   *image,
                    pixel = get_pixel (image, rx, ry, TRUE);
                }
 
-               srtot += RED_8 (pixel) * f;
-               sgtot += GREEN_8 (pixel) * f;
-               sbtot += BLUE_8 (pixel) * f;
-               satot += ALPHA_8 (pixel) * f;
+               srtot += (int)RED_8 (pixel) * f;
+               sgtot += (int)GREEN_8 (pixel) * f;
+               sbtot += (int)BLUE_8 (pixel) * f;
+               satot += (int)ALPHA_8 (pixel) * f;
            }
 
            params++;