summaryrefslogtreecommitdiff
path: root/Build/source/libs/gd/libgd-src/tests/gdimagefilter/gdCopyBlurred.c
blob: 69ca06133bc67c4662a5aeaba9812121542f2f6c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
#include <stdio.h>
#include <stdlib.h>

#include "gd.h"
#include "gdtest.h"

#define WIDTH 300
#define HEIGHT 200
#define LX (WIDTH/2)    // Line X
#define LY (HEIGHT/2)   // Line Y
#define HT 3            // Half of line-thickness

#define CLOSE_ENOUGH 0
#define PIXEL_CLOSE_ENOUGH 0


void
save(gdImagePtr im, const char *filename) {
#if 0   // set TRUE to write out some intermediate images
    FILE *out;

    out = fopen(filename, "wb");
    gdImagePng(im, out);
    fclose(out);
#else
    im, filename;
#endif
}/* save*/


/* 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*/


gdImagePtr mkcross() {
    gdImagePtr im;
    int fg, n;

    im = mkwhite(WIDTH, HEIGHT);
    fg = gdImageColorAllocate(im, 0, 0, 0);

    for (n = -HT; n < HT; n++) {
        gdImageLine(im, LX-n, 0, LX-n, HEIGHT-1, fg);
        gdImageLine(im, 0, LY-n, WIDTH-1, LY-n, fg);
    }/* for */

    return im;
}/* mkcross*/



void blurblank(gdImagePtr im, int radius, double sigma) {
    gdImagePtr result;

    result = gdImageCopyGaussianBlurred(im, radius, sigma);
    gdTestAssert(!!result);
    if (!result) return;

    gdTestAssert(gdMaxPixelDiff(im, result) <= CLOSE_ENOUGH);

    gdImageDestroy(result);
}/* blurblank*/


void do_test()
{
	gdImagePtr im, imref, tmp;
    gdImagePtr same, same2;

	im = mkwhite(WIDTH, HEIGHT);
    imref = mkwhite(WIDTH, HEIGHT);

    /* Blur a plain white image to various radii and ensure they're
     * still similar enough. */
    blurblank(im, 1, 0.0);
    blurblank(im, 2, 0.0);
    blurblank(im, 4, 0.0);
    blurblank(im, 8, 0.0);
    blurblank(im, 16, 0.0);

    /* Ditto a black image. */
    mkblack(im);
    gdTestAssert(gdMaxPixelDiff(im, imref) >= 240); /* Leaves a little wiggle room */

    blurblank(im, 1, 0.0);
    blurblank(im, 2, 0.0);
    blurblank(im, 4, 0.0);
    blurblank(im, 8, 0.0);
    blurblank(im, 16, 0.0);
}/* do_test*/

/* Ensure that RGB values are equal, then return r (which is therefore
 * the whiteness.) */
int getwhite(gdImagePtr im, int x, int y)
{
    int px, r, g, b;

    px = gdImageGetPixel(im, x, y);
    r = gdImageRed(im, px);
    g = gdImageGreen(im, px);
    b = gdImageBlue(im, px);

    gdTestAssert(r == g && r == b);

    return r;
}/* getrgb*/

int whitecmp(gdImagePtr im1, gdImagePtr im2, int x, int y) {
    int w1, w2;

    w1 = getwhite(im1, x, y);
    w2 = getwhite(im2, x, y);

    return abs(w1 - w2);
}/* whitediff*/

void do_crosstest()
{
    gdImagePtr im = mkcross();
    gdImagePtr blurred;
    const int RADIUS = 16; 

    gdTestAssert(!!im);

    save(im, "cross.png");

    blurred = gdImageCopyGaussianBlurred(im, RADIUS, 0.0);
	gdTestAssert(blurred != NULL);
    save(blurred, "blurredcross.png");

    /* These spots shouldn't be affected. */
    gdTestAssert(whitecmp(im, blurred, 5, 5) <= PIXEL_CLOSE_ENOUGH);
    gdTestAssert(whitecmp(im, blurred, WIDTH-5, 5) <= PIXEL_CLOSE_ENOUGH);
    gdTestAssert(whitecmp(im, blurred, 5, HEIGHT-5) <= PIXEL_CLOSE_ENOUGH);
    gdTestAssert(whitecmp(im, blurred, WIDTH-5, HEIGHT-5) <= PIXEL_CLOSE_ENOUGH);

//    printf("%d %d %d %d\n", whitecmp(im, blurred, 0, 0), whitecmp(im, blurred, WIDTH-1, 0),
//         whitecmp(im, blurred, 0, HEIGHT-1), whitecmp(im, blurred, WIDTH-1, HEIGHT-1));

    /* Ditto these, right in the corners */
    gdTestAssert(whitecmp(im, blurred, 0, 0) <= PIXEL_CLOSE_ENOUGH);
    gdTestAssert(whitecmp(im, blurred, WIDTH-1, 0) <= PIXEL_CLOSE_ENOUGH);
    gdTestAssert(whitecmp(im, blurred, 0, HEIGHT-1) <= PIXEL_CLOSE_ENOUGH);
    gdTestAssert(whitecmp(im, blurred, WIDTH-1, HEIGHT-1) <= PIXEL_CLOSE_ENOUGH);

    /* Now, poking let's poke around the blurred lines. */

    /* Vertical line gets darker when approached from the left. */
    gdTestAssert(getwhite(blurred, 1, 1) > getwhite(blurred, LX - (HT - 1), 1));
    gdTestAssert(getwhite(blurred, LX - 2, 1) > getwhite(blurred, LX - 1, 1));

    /* ...and lighter when moving away to the right. */
    gdTestAssert(getwhite(blurred, LX + 2, 1) >= getwhite(blurred, LX + 1, 1));
    gdTestAssert(getwhite(blurred, LX + 3, 1) >= getwhite(blurred, LX + 2, 1));
    gdTestAssert(getwhite(blurred, WIDTH - 1, 1) > getwhite(blurred, LX + 1, 1));

    /* And the same way, vertically */
    gdTestAssert(getwhite(blurred, 1, 1) > getwhite(blurred, 1, LY - (HT - 1)));
    gdTestAssert(getwhite(blurred, 1, LY - (HT - 1)) > getwhite(blurred, 1, LY - (HT - 2)));

    gdTestAssert(getwhite(blurred, 1, LY)     <= getwhite(blurred, 1, LY + 1));
    gdTestAssert(getwhite(blurred, 1, LY + 1) <  getwhite(blurred, 1, LY + 3));
    gdTestAssert(getwhite(blurred, 1, LY + 3) <  getwhite(blurred, 1, HEIGHT-1));
	gdImageDestroy(blurred);
}/* do_crosstest*/


int main(int argc, char **argv)
{

    do_test();
    do_crosstest();

    return gdNumFailures();
}