1 // BEGIN_COPYRIGHT -*- glean -*-
3 // Copyright (C) 1999 Allen Akin All Rights Reserved.
5 // Permission is hereby granted, free of charge, to any person
6 // obtaining a copy of this software and associated documentation
7 // files (the "Software"), to deal in the Software without
8 // restriction, including without limitation the rights to use,
9 // copy, modify, merge, publish, distribute, sublicense, and/or
10 // sell copies of the Software, and to permit persons to whom the
11 // Software is furnished to do so, subject to the following
14 // The above copyright notice and this permission notice shall be
15 // included in all copies or substantial portions of the
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
19 // KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
20 // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
21 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ALLEN AKIN BE
22 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 // AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
24 // OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 // DEALINGS IN THE SOFTWARE.
29 // trgbtris.cpp: example image-based test to show use of TIFF images
59 logStats(GLEAN::BasicStats
& stats
, GLEAN::Environment
* env
) {
60 env
->log
<< "\t\tmin = " << stats
.min() << ", max = " << stats
.max()
61 << "\n\t\tmean = " << stats
.mean() << ", standard deviation = "
62 << stats
.deviation() << '\n';
65 } // anonymous namespace
69 ///////////////////////////////////////////////////////////////////////////////
70 // runOne: Run a single test case
71 ///////////////////////////////////////////////////////////////////////////////
73 RGBTriStripTest::runOne(RGBTriStripResult
& r
, Window
& w
) {
74 static int this_config
= 0;
75 r
.imageNumber
= ++this_config
;
77 GLUtils::useScreenCoords(drawingSize
+ 2, drawingSize
+ 2);
79 int nPoints
= 20; // Exact value doesn't really matter.
80 RandomDouble
vRand(142857);
81 RandomMesh2D
v(1.0, drawingSize
, nPoints
, 1.0, drawingSize
, nPoints
,
84 RandomDouble
cRand(271828);
86 glClear(GL_COLOR_BUFFER_BIT
);
87 glShadeModel(GL_SMOOTH
);
89 for (int row
= 0; row
< nPoints
- 1; ++row
) {
90 glBegin(GL_TRIANGLE_STRIP
);
91 for (int col
= 0; col
< nPoints
; ++col
) {
92 float r
= cRand
.next();
93 float g
= cRand
.next();
94 float b
= cRand
.next();
96 glVertex2fv(v(row
, col
));
101 glVertex2fv(v(row
+ 1, col
));
107 Image
image(drawingSize
+ 2, drawingSize
+ 2, GL_RGB
, GL_FLOAT
);
108 image
.read(0, 0); // Invoke glReadPixels to read the image.
109 image
.writeTIFF(env
->imageFileName(name
, r
.imageNumber
));
112 } // RGBTriStripTest::runOne
114 ///////////////////////////////////////////////////////////////////////////////
115 // logOne: Log a single test case
116 ///////////////////////////////////////////////////////////////////////////////
118 RGBTriStripTest::logOne(RGBTriStripResult
& r
) {
119 env
->log
<< name
<< ": NOTE "
120 << r
.config
->conciseDescription() << '\n'
121 << "\tImage number " << r
.imageNumber
<< '\n';
122 if (env
->options
.verbosity
)
124 "\tThis test does not check its result. Please view\n"
125 "\tthe image to verify that the result is correct, or\n"
126 "\tcompare it to a known-good result from a different\n"
128 } // RGBTriStripTest::logOne
130 ///////////////////////////////////////////////////////////////////////////////
131 // compareOne: Compare results for a single test case
132 ///////////////////////////////////////////////////////////////////////////////
134 RGBTriStripTest::compareOne(RGBTriStripResult
& oldR
, RGBTriStripResult
& newR
) {
135 // Fetch the old and new images:
137 oldI
.readTIFF(env
->image1FileName(name
, oldR
.imageNumber
));
139 newI
.readTIFF(env
->image2FileName(name
, newR
.imageNumber
));
141 // Register the images, and gather statistics about the differences
142 // for each color channel:
143 Image::Registration
reg(oldI
.reg(newI
));
145 // Compute worst-case tolerance (1 LSB in the shallowest drawing
146 // surface configuration) for each color channel:
147 double rTol
= 1.0 / (1 << min(oldR
.config
->r
, newR
.config
->r
));
148 double gTol
= 1.0 / (1 << min(oldR
.config
->g
, newR
.config
->g
));
149 double bTol
= 1.0 / (1 << min(oldR
.config
->b
, newR
.config
->b
));
151 // We'll conclude that the images are the ``same'' if the maximum
152 // absolute error is no more than 1 LSB (in the shallowest config):
153 if (reg
.stats
[0].max() <= rTol
&& reg
.stats
[1].max() <= gTol
154 && reg
.stats
[2].max() <= bTol
) {
155 if (env
->options
.verbosity
) {
156 env
->log
<< name
<< ": SAME "
157 << newR
.config
->conciseDescription() << '\n';
158 if (reg
.stats
[0].max() == 0 && reg
.stats
[1].max() == 0
159 && reg
.stats
[1].max() == 0)
160 env
->log
<< "\tImages are exactly equal\n";
162 env
->log
<< "\tImages are approximately equal\n";
165 env
->log
<< name
<< ": DIFF "
166 << newR
.config
->conciseDescription() << '\n'
167 << "\tDifference exceeds 1 LSB in at least one "
170 if (env
->options
.verbosity
) {
171 env
->log
<< "\tred:\n";
172 logStats(reg
.stats
[0], env
);
173 env
->log
<< "\tgreen:\n";
174 logStats(reg
.stats
[1], env
);
175 env
->log
<< "\tblue:\n";
176 logStats(reg
.stats
[2], env
);
178 } // RGBTriStripTest::compareOne
180 ///////////////////////////////////////////////////////////////////////////////
181 // The test object itself:
182 ///////////////////////////////////////////////////////////////////////////////
183 RGBTriStripTest
rgbTriStripTest("rgbTriStrip", "window, rgb",
185 "The best approach when designing a test is to make it\n"
186 "self-checking; that is, the test itself should determine\n"
187 "whether the image or other data structure that it produces is\n"
188 "correct. However, some tests are difficult to design in this\n"
189 "way, and for some other tests (like stress tests or regression\n"
190 "tests concerning previously-reported bugs) it may be\n"
191 "unnecessary. For such tests, glean provides mechanisms to\n"
192 "save images and compare them to images generated from other\n"
193 "runs. This test simply exercises those mechanisms.\n");