Atlas - SDL_test_compare.c

Home / ext / SDL / src / test Lines: 1 | Size: 12393 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2025 Sam Lantinga <[email protected]> 4 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any damages 7 arising from the use of this software. 8 9 Permission is granted to anyone to use this software for any purpose, 10 including commercial applications, and to alter it and redistribute it 11 freely, subject to the following restrictions: 12 13 1. The origin of this software must not be misrepresented; you must not 14 claim that you wrote the original software. If you use this software 15 in a product, an acknowledgment in the product documentation would be 16 appreciated but is not required. 17 2. Altered source versions must be plainly marked as such, and must not be 18 misrepresented as being the original software. 19 3. This notice may not be removed or altered from any source distribution. 20*/ 21 22/* 23 24 Based on automated SDL_Surface tests originally written by Edgar Simo 'bobbens'. 25 26 Rewritten for test lib by Andreas Schiffler. 27 28*/ 29#include <SDL3/SDL_test.h> 30 31#define FILENAME_SIZE 128 32 33/* Counter for _CompareSurface calls; used for filename creation when comparisons fail */ 34static int _CompareSurfaceCount = 0; 35 36/* Compare surfaces */ 37int SDLTest_CompareSurfaces(SDL_Surface *surface, SDL_Surface *referenceSurface, int allowable_error) 38{ 39 int ret; 40 int i, j; 41 int dist; 42 int sampleErrorX = 0, sampleErrorY = 0, sampleDist = 0; 43 SDL_Color sampleReference = { 0, 0, 0, 0 }; 44 SDL_Color sampleActual = { 0, 0, 0, 0 }; 45 Uint8 R, G, B, A; 46 Uint8 Rd, Gd, Bd, Ad; 47 char imageFilename[FILENAME_SIZE]; 48 char referenceFilename[FILENAME_SIZE]; 49 50 /* Validate input surfaces */ 51 if (!surface) { 52 SDLTest_LogError("Cannot compare NULL surface"); 53 return -1; 54 } 55 56 if (!referenceSurface) { 57 SDLTest_LogError("Cannot compare NULL reference surface"); 58 return -1; 59 } 60 61 /* Make sure surface size is the same. */ 62 if ((surface->w != referenceSurface->w) || (surface->h != referenceSurface->h)) { 63 SDLTest_LogError("Expected %dx%d surface, got %dx%d", referenceSurface->w, referenceSurface->h, surface->w, surface->h); 64 return -2; 65 } 66 67 /* Sanitize input value */ 68 if (allowable_error < 0) { 69 allowable_error = 0; 70 } 71 72 SDL_LockSurface(surface); 73 SDL_LockSurface(referenceSurface); 74 75 ret = 0; 76 /* Compare image - should be same format. */ 77 for (j = 0; j < surface->h; j++) { 78 for (i = 0; i < surface->w; i++) { 79 int temp; 80 81 temp = SDL_ReadSurfacePixel(surface, i, j, &R, &G, &B, &A); 82 if (!temp) { 83 SDLTest_LogError("Failed to retrieve pixel (%d,%d): %s", i, j, SDL_GetError()); 84 ret++; 85 continue; 86 } 87 88 temp = SDL_ReadSurfacePixel(referenceSurface, i, j, &Rd, &Gd, &Bd, &Ad); 89 if (!temp) { 90 SDLTest_LogError("Failed to retrieve reference pixel (%d,%d): %s", i, j, SDL_GetError()); 91 ret++; 92 continue; 93 } 94 95 dist = 0; 96 dist += (R - Rd) * (R - Rd); 97 dist += (G - Gd) * (G - Gd); 98 dist += (B - Bd) * (B - Bd); 99 100 /* Allow some difference in blending accuracy */ 101 if (dist > allowable_error) { 102 ret++; 103 if (ret == 1) { 104 sampleErrorX = i; 105 sampleErrorY = j; 106 sampleDist = dist; 107 sampleReference.r = Rd; 108 sampleReference.g = Gd; 109 sampleReference.b = Bd; 110 sampleReference.a = Ad; 111 sampleActual.r = R; 112 sampleActual.g = G; 113 sampleActual.b = B; 114 sampleActual.a = A; 115 } 116 } 117 } 118 } 119 120 SDL_UnlockSurface(surface); 121 SDL_UnlockSurface(referenceSurface); 122 123 /* Save test image and reference for analysis on failures */ 124 _CompareSurfaceCount++; 125 if (ret != 0) { 126 SDLTest_LogError("Comparison of pixels with allowable error of %i failed %i times.", allowable_error, ret); 127 SDLTest_LogError("Reference surface format: %s", SDL_GetPixelFormatName(referenceSurface->format)); 128 SDLTest_LogError("Actual surface format: %s", SDL_GetPixelFormatName(surface->format)); 129 SDLTest_LogError("First detected occurrence at position %i,%i with a squared RGB-difference of %i.", sampleErrorX, sampleErrorY, sampleDist); 130 SDLTest_LogError("Reference pixel: R=%u G=%u B=%u A=%u", sampleReference.r, sampleReference.g, sampleReference.b, sampleReference.a); 131 SDLTest_LogError("Actual pixel : R=%u G=%u B=%u A=%u", sampleActual.r, sampleActual.g, sampleActual.b, sampleActual.a); 132 (void)SDL_snprintf(imageFilename, FILENAME_SIZE - 1, "CompareSurfaces%04d_TestOutput.bmp", _CompareSurfaceCount); 133 SDL_SaveBMP(surface, imageFilename); 134 (void)SDL_snprintf(referenceFilename, FILENAME_SIZE - 1, "CompareSurfaces%04d_Reference.bmp", _CompareSurfaceCount); 135 SDL_SaveBMP(referenceSurface, referenceFilename); 136 SDLTest_LogError("Surfaces from failed comparison saved as '%s' and '%s'", imageFilename, referenceFilename); 137 } 138 139 return ret; 140} 141 142int SDLTest_CompareSurfacesIgnoreTransparentPixels(SDL_Surface *surface, SDL_Surface *referenceSurface, int allowable_error) 143{ 144 int ret; 145 int i, j; 146 int dist; 147 int sampleErrorX = 0, sampleErrorY = 0, sampleDist = 0; 148 SDL_Color sampleReference = { 0, 0, 0, 0 }; 149 SDL_Color sampleActual = { 0, 0, 0, 0 }; 150 Uint8 R, G, B, A; 151 Uint8 Rd, Gd, Bd, Ad; 152 char imageFilename[FILENAME_SIZE]; 153 char referenceFilename[FILENAME_SIZE]; 154 155 /* Validate input surfaces */ 156 if (!surface) { 157 SDLTest_LogError("Cannot compare NULL surface"); 158 return -1; 159 } 160 161 if (!referenceSurface) { 162 SDLTest_LogError("Cannot compare NULL reference surface"); 163 return -1; 164 } 165 166 /* Make sure surface size is the same. */ 167 if ((surface->w != referenceSurface->w) || (surface->h != referenceSurface->h)) { 168 SDLTest_LogError("Expected %dx%d surface, got %dx%d", referenceSurface->w, referenceSurface->h, surface->w, surface->h); 169 return -2; 170 } 171 172 /* Sanitize input value */ 173 if (allowable_error < 0) { 174 allowable_error = 0; 175 } 176 177 SDL_LockSurface(surface); 178 SDL_LockSurface(referenceSurface); 179 180 ret = 0; 181 /* Compare image - should be same format. */ 182 for (j = 0; j < surface->h; j++) { 183 for (i = 0; i < surface->w; i++) { 184 int temp; 185 186 temp = SDL_ReadSurfacePixel(surface, i, j, &R, &G, &B, &A); 187 if (!temp) { 188 SDLTest_LogError("Failed to retrieve pixel (%d,%d): %s", i, j, SDL_GetError()); 189 ret++; 190 continue; 191 } 192 193 temp = SDL_ReadSurfacePixel(referenceSurface, i, j, &Rd, &Gd, &Bd, &Ad); 194 if (!temp) { 195 SDLTest_LogError("Failed to retrieve reference pixel (%d,%d): %s", i, j, SDL_GetError()); 196 ret++; 197 continue; 198 } 199 if (Ad == SDL_ALPHA_TRANSPARENT) { 200 continue; 201 } 202 203 dist = 0; 204 dist += (R - Rd) * (R - Rd); 205 dist += (G - Gd) * (G - Gd); 206 dist += (B - Bd) * (B - Bd); 207 208 /* Allow some difference in blending accuracy */ 209 if (dist > allowable_error) { 210 ret++; 211 if (ret == 1) { 212 sampleErrorX = i; 213 sampleErrorY = j; 214 sampleDist = dist; 215 sampleReference.r = Rd; 216 sampleReference.g = Gd; 217 sampleReference.b = Bd; 218 sampleReference.a = Ad; 219 sampleActual.r = R; 220 sampleActual.g = G; 221 sampleActual.b = B; 222 sampleActual.a = A; 223 } 224 } 225 } 226 } 227 228 SDL_UnlockSurface(surface); 229 SDL_UnlockSurface(referenceSurface); 230 231 /* Save test image and reference for analysis on failures */ 232 _CompareSurfaceCount++; 233 if (ret != 0) { 234 SDLTest_LogError("Comparison of pixels with allowable error of %i failed %i times.", allowable_error, ret); 235 SDLTest_LogError("Reference surface format: %s", SDL_GetPixelFormatName(referenceSurface->format)); 236 SDLTest_LogError("Actual surface format: %s", SDL_GetPixelFormatName(surface->format)); 237 SDLTest_LogError("First detected occurrence at position %i,%i with a squared RGB-difference of %i.", sampleErrorX, sampleErrorY, sampleDist); 238 SDLTest_LogError("Reference pixel: R=%u G=%u B=%u A=%u", sampleReference.r, sampleReference.g, sampleReference.b, sampleReference.a); 239 SDLTest_LogError("Actual pixel : R=%u G=%u B=%u A=%u", sampleActual.r, sampleActual.g, sampleActual.b, sampleActual.a); 240 (void)SDL_snprintf(imageFilename, FILENAME_SIZE - 1, "CompareSurfaces%04d_TestOutput.bmp", _CompareSurfaceCount); 241 SDL_SaveBMP(surface, imageFilename); 242 (void)SDL_snprintf(referenceFilename, FILENAME_SIZE - 1, "CompareSurfaces%04d_Reference.bmp", _CompareSurfaceCount); 243 SDL_SaveBMP(referenceSurface, referenceFilename); 244 SDLTest_LogError("Surfaces from failed comparison saved as '%s' and '%s'", imageFilename, referenceFilename); 245 } 246 247 return ret; 248} 249 250int SDLTest_CompareMemory(const void *actual, size_t size_actual, const void *reference, size_t size_reference) { 251#define WIDTH 16 252 253 const size_t size_max = SDL_max(size_actual, size_reference); 254 size_t i; 255 struct { 256 const char *header; 257 const Uint8 *data; 258 size_t size; 259 } columns[] = { 260 { 261 "actual", 262 actual, 263 size_actual, 264 }, 265 { 266 "reference", 267 reference, 268 size_reference, 269 }, 270 }; 271 char line_buffer[16 + SDL_arraysize(columns) * (4 * WIDTH + 1) + (SDL_arraysize(columns) - 1) * 2 + 1]; 272 273 SDLTest_AssertCheck(size_actual == size_reference, "Sizes of memory blocks must be equal (actual=%" SDL_PRIu64 " expected=%" SDL_PRIu64 ")", (Uint64)size_actual, (Uint64)size_reference); 274 if (size_actual == size_reference) { 275 int equals; 276 equals = SDL_memcmp(actual, reference, size_max) == 0; 277 SDLTest_AssertCheck(equals, "Memory blocks contain the same data"); 278 if (equals) { 279 return 0; 280 } 281 } 282 283 SDL_memset(line_buffer, ' ', sizeof(line_buffer)); 284 line_buffer[sizeof(line_buffer) - 1] = '\0'; 285 for (i = 0; i < SDL_arraysize(columns); i++) { 286 SDL_memcpy(line_buffer + 16 + 1 + i * (4 * WIDTH + 3), columns[i].header, SDL_strlen(columns[i].header)); 287 } 288 SDLTest_LogError("%s", line_buffer); 289 290 for (i = 0; i < size_max; i += WIDTH) { 291 size_t pos = 0; 292 size_t col; 293 294 pos += SDL_snprintf(line_buffer + pos, SDL_arraysize(line_buffer) - pos, "%016" SDL_PRIx64 , (Uint64)i); 295 296 for (col = 0; col < SDL_arraysize(columns); col++) { 297 size_t j; 298 299 for (j = 0; j < WIDTH; j++) { 300 if (i + j < columns[col].size) { 301 pos += SDL_snprintf(line_buffer + pos, SDL_arraysize(line_buffer) - pos, " %02x", columns[col].data[i + j]); 302 } else { 303 pos += SDL_snprintf(line_buffer + pos, SDL_arraysize(line_buffer) - pos, " "); 304 } 305 } 306 pos += SDL_snprintf(line_buffer + pos, SDL_arraysize(line_buffer) - pos, " "); 307 for (j = 0; j < WIDTH; j++) { 308 char c = ' '; 309 if (i + j < columns[col].size) { 310 c = columns[col].data[i + j]; 311 if (!SDL_isprint(c)) { 312 c = '.'; 313 } 314 } 315 pos += SDL_snprintf(line_buffer + pos, SDL_arraysize(line_buffer) - pos, "%c", c); 316 } 317 if (col < SDL_arraysize(columns) - 1) { 318 pos += SDL_snprintf(line_buffer + pos, SDL_arraysize(line_buffer), " |"); 319 } 320 } 321 SDLTest_LogError("%s", line_buffer); 322 SDL_assert(pos == SDL_arraysize(line_buffer) - 1); 323 } 324#undef WIDTH 325 return 1; 326} 327
[FILE END]
(C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.