Commits

Chris Reuter committed f5e681e

Added a test case for gdImageScaleTwoPass().

This testcase does some basic resizing using bicubic
interpolation and ensures the result is sane. It does
not verify image quality, just that the functions return
acceptible values.

  • Participants
  • Parent commits 2a1267c

Comments (0)

Files changed (3)

File src/gd_interpolation.c

 {
 	unsigned int ndx;
 
-	for (ndx = 0; ndx < dst_len - 1; ndx++) {
+	for (ndx = 0; ndx < dst_len; ndx++) {
 		register unsigned char r = 0, g = 0, b = 0, a = 0;
 		const int left = contrib->ContribRow[ndx].Left;
 		const int right = contrib->ContribRow[ndx].Right;
 	}
 
 	/* Scale each line */
-    for (line_ndx = 0; line_ndx < num_lines - 1; line_ndx++) {
+    for (line_ndx = 0; line_ndx < num_lines; line_ndx++) {
         _gdScaleOneAxis(pSrc, pDst, dst_len, line_ndx, contrib, axis);
 	}
 	_gdContributionsFree (contrib);
 			im_scaled = gdImageScaleTwoPass(src, new_width, new_height);
 			break;
 	}
+
 	return im_scaled;
 }
 

File tests/Makefile.am

 	gif/gif_null \
 	gif/bug00181 \
 	gif/bug00227 \
-	bmp/bmp_null
+	bmp/bmp_null \
+	gdinterpolatedscale/gdTrivialResize
 
 EXTRA_PROGRAMS = \
 	gdimagestringft/gdimagestringft_bbox \

File tests/gdinterpolatedscale/gdTrivialResize.c

+#include <stdio.h>
+
+#include "gd.h"
+#include "gdtest.h"
+
+/* Test gdImageScale() with bicubic interpolation on a simple
+ * all-white image. */
+
+gdImagePtr mkwhite(int x, int y)
+{
+    gdImagePtr im;
+
+	im = gdImageCreateTrueColor(x, y);
+	gdImageFilledRectangle(im, 0, 0, x-1, y-1,
+                           gdImageColorExactAlpha(im, 255, 255, 255, 0));
+
+    gdTestAssert(im != NULL);
+
+    gdImageSetInterpolationMethod(im, GD_BICUBIC);    // FP interp'n
+
+    return im;
+}/* mkwhite*/
+
+
+/* Fill with almost-black. */
+void mkblack(gdImagePtr ptr)
+{
+    gdImageFilledRectangle(ptr, 0, 0, ptr->sx - 1, ptr->sy - 1,
+                           gdImageColorExactAlpha(ptr, 2, 2, 2, 0));
+}/* mkblack*/
+
+
+#define CLOSE_ENOUGH 15
+
+void scaletest(int x, int y, int nx, int ny)
+{
+    gdImagePtr im, imref, tmp, same;
+
+	imref = mkwhite(x, y);
+    im = mkwhite(x, y);
+    tmp = gdImageScale(im, nx, ny);
+    same = gdImageScale(tmp, x, y);
+
+    /* Test the result to insure that it's close enough to the
+     * original. */
+    gdTestAssert(gdMaxPixelDiff(im, same) < CLOSE_ENOUGH);
+
+    /* Modify the original and test for a change again.  (I.e. test
+     * for accidentally shared memory.) */
+    mkblack(tmp);
+    gdTestAssert(gdMaxPixelDiff(imref, same) < CLOSE_ENOUGH);
+
+    gdImageDestroy(im);
+    gdImageDestroy(tmp);
+    gdImageDestroy(same);
+}/* scaletest*/
+
+void do_test(int x, int y, int nx, int ny)
+{
+	gdImagePtr im, imref, tmp;
+    gdImagePtr same, same2;
+
+	im = mkwhite(x, y);
+    imref = mkwhite(x, y);
+
+    same = gdImageScale(im, x, y);
+
+    /* Trivial resize should be a straight copy. */
+    gdTestAssert(im != same);
+    gdTestAssert(gdMaxPixelDiff(im, same) == 0);
+    gdTestAssert(gdMaxPixelDiff(imref, same) == 0);
+
+    /* Ensure that modifying im doesn't modify same (i.e. see if we
+     * can catch them accidentally sharing the same pixel buffer.) */
+    mkblack(im);
+    gdTestAssert(gdMaxPixelDiff(imref, same) == 0);
+
+    gdImageDestroy(same);
+    gdImageDestroy(im);
+
+    /* Scale horizontally, vertically and both. */
+    scaletest(x, y, nx, y);
+    scaletest(x, y, x, ny);
+    scaletest(x, y, nx, ny);
+}
+
+int main(int argc, char **argv)
+{
+
+    do_test(300, 300, 600, 600);
+    do_test(3200, 2133, 640, 427);
+
+    return gdNumFailures();
+}