1 #include <stdio.h>
2 #include <stdlib.h>
3
4 #include "gd.h"
5 #include "gdtest.h"
6
7 #define WIDTH 300
8 #define HEIGHT 200
9 #define LX (WIDTH/2) // Line X
10 #define LY (HEIGHT/2) // Line Y
11 #define HT 3 // Half of line-thickness
12
13 #define CLOSE_ENOUGH 0
14 #define PIXEL_CLOSE_ENOUGH 0
15
16
17 void
save(gdImagePtr im,const char * filename)18 save(gdImagePtr im, const char *filename) {
19 #if 0 // set TRUE to write out some intermediate images
20 FILE *out;
21
22 out = fopen(filename, "wb");
23 gdImagePng(im, out);
24 fclose(out);
25 #else
26 (void)im, (void)filename;
27 #endif
28 }/* save*/
29
30
31 /* Test gdImageScale() with bicubic interpolation on a simple
32 * all-white image. */
33
mkwhite(int x,int y)34 gdImagePtr mkwhite(int x, int y)
35 {
36 gdImagePtr im;
37
38 im = gdImageCreateTrueColor(x, y);
39 gdImageFilledRectangle(im, 0, 0, x-1, y-1,
40 gdImageColorExactAlpha(im, 255, 255, 255, 0));
41
42 gdTestAssert(im != NULL);
43
44 gdImageSetInterpolationMethod(im, GD_BICUBIC); // FP interp'n
45
46 return im;
47 }/* mkwhite*/
48
49
50 /* Fill with almost-black. */
mkblack(gdImagePtr ptr)51 void mkblack(gdImagePtr ptr)
52 {
53 gdImageFilledRectangle(ptr, 0, 0, ptr->sx - 1, ptr->sy - 1,
54 gdImageColorExactAlpha(ptr, 2, 2, 2, 0));
55 }/* mkblack*/
56
57
mkcross()58 gdImagePtr mkcross() {
59 gdImagePtr im;
60 int fg, n;
61
62 im = mkwhite(WIDTH, HEIGHT);
63 fg = gdImageColorAllocate(im, 0, 0, 0);
64
65 for (n = -HT; n < HT; n++) {
66 gdImageLine(im, LX-n, 0, LX-n, HEIGHT-1, fg);
67 gdImageLine(im, 0, LY-n, WIDTH-1, LY-n, fg);
68 }/* for */
69
70 return im;
71 }/* mkcross*/
72
73
74
blurblank(gdImagePtr im,int radius,double sigma)75 void blurblank(gdImagePtr im, int radius, double sigma) {
76 gdImagePtr result;
77
78 result = gdImageCopyGaussianBlurred(im, radius, sigma);
79 gdTestAssert(!!result);
80 if (!result) return;
81
82 gdTestAssert(gdMaxPixelDiff(im, result) <= CLOSE_ENOUGH);
83
84 gdImageDestroy(result);
85 }/* blurblank*/
86
87
do_test()88 void do_test()
89 {
90 gdImagePtr im, imref;
91
92 im = mkwhite(WIDTH, HEIGHT);
93 imref = mkwhite(WIDTH, HEIGHT);
94
95 /* Blur a plain white image to various radii and ensure they're
96 * still similar enough. */
97 blurblank(im, 1, 0.0);
98 blurblank(im, 2, 0.0);
99 blurblank(im, 4, 0.0);
100 blurblank(im, 8, 0.0);
101 blurblank(im, 16, 0.0);
102
103 /* Ditto a black image. */
104 mkblack(im);
105 gdTestAssert(gdMaxPixelDiff(im, imref) >= 240); /* Leaves a little wiggle room */
106
107 blurblank(im, 1, 0.0);
108 blurblank(im, 2, 0.0);
109 blurblank(im, 4, 0.0);
110 blurblank(im, 8, 0.0);
111 blurblank(im, 16, 0.0);
112
113 gdImageDestroy(im);
114 gdImageDestroy(imref);
115 }/* do_test*/
116
117 /* Ensure that RGB values are equal, then return r (which is therefore
118 * the whiteness.) */
getwhite(gdImagePtr im,int x,int y)119 int getwhite(gdImagePtr im, int x, int y)
120 {
121 int px, r, g, b;
122
123 px = gdImageGetPixel(im, x, y);
124 r = gdImageRed(im, px);
125 g = gdImageGreen(im, px);
126 b = gdImageBlue(im, px);
127
128 gdTestAssert(r == g && r == b);
129
130 return r;
131 }/* getrgb*/
132
whitecmp(gdImagePtr im1,gdImagePtr im2,int x,int y)133 int whitecmp(gdImagePtr im1, gdImagePtr im2, int x, int y) {
134 int w1, w2;
135
136 w1 = getwhite(im1, x, y);
137 w2 = getwhite(im2, x, y);
138
139 return abs(w1 - w2);
140 }/* whitediff*/
141
do_crosstest()142 void do_crosstest()
143 {
144 gdImagePtr im = mkcross();
145 gdImagePtr blurred;
146 const int RADIUS = 16;
147
148 gdTestAssert(!!im);
149
150 save(im, "cross.png");
151
152 blurred = gdImageCopyGaussianBlurred(im, RADIUS, 0.0);
153 gdTestAssert(blurred != NULL);
154 save(blurred, "blurredcross.png");
155
156 /* These spots shouldn't be affected. */
157 gdTestAssert(whitecmp(im, blurred, 5, 5) <= PIXEL_CLOSE_ENOUGH);
158 gdTestAssert(whitecmp(im, blurred, WIDTH-5, 5) <= PIXEL_CLOSE_ENOUGH);
159 gdTestAssert(whitecmp(im, blurred, 5, HEIGHT-5) <= PIXEL_CLOSE_ENOUGH);
160 gdTestAssert(whitecmp(im, blurred, WIDTH-5, HEIGHT-5) <= PIXEL_CLOSE_ENOUGH);
161
162 // printf("%d %d %d %d\n", whitecmp(im, blurred, 0, 0), whitecmp(im, blurred, WIDTH-1, 0),
163 // whitecmp(im, blurred, 0, HEIGHT-1), whitecmp(im, blurred, WIDTH-1, HEIGHT-1));
164
165 /* Ditto these, right in the corners */
166 gdTestAssert(whitecmp(im, blurred, 0, 0) <= PIXEL_CLOSE_ENOUGH);
167 gdTestAssert(whitecmp(im, blurred, WIDTH-1, 0) <= PIXEL_CLOSE_ENOUGH);
168 gdTestAssert(whitecmp(im, blurred, 0, HEIGHT-1) <= PIXEL_CLOSE_ENOUGH);
169 gdTestAssert(whitecmp(im, blurred, WIDTH-1, HEIGHT-1) <= PIXEL_CLOSE_ENOUGH);
170
171 /* Now, poking let's poke around the blurred lines. */
172
173 /* Vertical line gets darker when approached from the left. */
174 gdTestAssert(getwhite(blurred, 1, 1) > getwhite(blurred, LX - (HT - 1), 1));
175 gdTestAssert(getwhite(blurred, LX - 2, 1) > getwhite(blurred, LX - 1, 1));
176
177 /* ...and lighter when moving away to the right. */
178 gdTestAssert(getwhite(blurred, LX + 2, 1) >= getwhite(blurred, LX + 1, 1));
179 gdTestAssert(getwhite(blurred, LX + 3, 1) >= getwhite(blurred, LX + 2, 1));
180 gdTestAssert(getwhite(blurred, WIDTH - 1, 1) > getwhite(blurred, LX + 1, 1));
181
182 /* And the same way, vertically */
183 gdTestAssert(getwhite(blurred, 1, 1) > getwhite(blurred, 1, LY - (HT - 1)));
184 gdTestAssert(getwhite(blurred, 1, LY - (HT - 1)) > getwhite(blurred, 1, LY - (HT - 2)));
185
186 gdTestAssert(getwhite(blurred, 1, LY) <= getwhite(blurred, 1, LY + 1));
187 gdTestAssert(getwhite(blurred, 1, LY + 1) < getwhite(blurred, 1, LY + 3));
188 gdTestAssert(getwhite(blurred, 1, LY + 3) < getwhite(blurred, 1, HEIGHT-1));
189 gdImageDestroy(blurred);
190 gdImageDestroy(im);
191 }/* do_crosstest*/
192
193
main()194 int main()
195 {
196
197 do_test();
198 do_crosstest();
199
200 return gdNumFailures();
201 }
202