e750894847
- png_diff.{h,cpp}: pixel_diff_ratio(path_a, path_b, channel_threshold) con
stb_image. Devuelve PngDiffResult con pixels_total, pixels_different y
diff_ratio. Si dimensiones difieren, diff_ratio=1.0.
- test_visual.cpp: invoca primitives_gallery --capture sobre tmpdir, compara
cada PNG vs cpp/tests/golden/<demo>.png con tolerancia 1% pixels distintos
(threshold 5/255 por canal). SKIPea con WARN si:
* golden dir vacio (no hay goldens todavia)
* binario primitives_gallery no construido
* el binario falla al capturar (entorno sin GL)
- CMakeLists: registra test_visual con FN_TEST_GOLDEN_DIR, FN_TEST_GALLERY_BIN,
FN_TEST_TMP_DIR y FN_TEST_REPO_ROOT (para que la captura corra desde la
raiz del repo y resuelva paths relativos como sql_workbench's registry.db).
- golden/: 41 PNGs iniciales generados en este entorno (WSL +
LIBGL_ALWAYS_SOFTWARE=1). Pueden regenerarse con cpp/scripts/update_goldens.sh.
Issue 0048.
65 lines
1.9 KiB
C++
65 lines
1.9 KiB
C++
#include "png_diff.h"
|
|
|
|
#include "stb_image.h"
|
|
|
|
#include <cstdlib>
|
|
|
|
namespace fn_test {
|
|
|
|
PngDiffResult pixel_diff_ratio(const std::string& path_a,
|
|
const std::string& path_b,
|
|
int channel_threshold) {
|
|
PngDiffResult r;
|
|
int wa = 0, ha = 0, ca = 0;
|
|
int wb = 0, hb = 0, cb = 0;
|
|
unsigned char* a = stbi_load(path_a.c_str(), &wa, &ha, &ca, 4);
|
|
unsigned char* b = stbi_load(path_b.c_str(), &wb, &hb, &cb, 4);
|
|
r.loaded_a = (a != nullptr);
|
|
r.loaded_b = (b != nullptr);
|
|
r.width_a = wa; r.height_a = ha;
|
|
r.width_b = wb; r.height_b = hb;
|
|
|
|
if (!r.loaded_a || !r.loaded_b) {
|
|
if (a) stbi_image_free(a);
|
|
if (b) stbi_image_free(b);
|
|
return r;
|
|
}
|
|
|
|
if (wa != wb || ha != hb) {
|
|
// Dimensiones no coinciden — diff total.
|
|
const long area_a = (long)wa * ha;
|
|
const long area_b = (long)wb * hb;
|
|
r.pixels_total = area_a > area_b ? area_a : area_b;
|
|
r.pixels_different = r.pixels_total;
|
|
r.diff_ratio = 1.0;
|
|
stbi_image_free(a);
|
|
stbi_image_free(b);
|
|
return r;
|
|
}
|
|
|
|
const long area = (long)wa * ha;
|
|
long diffs = 0;
|
|
for (long i = 0; i < area; ++i) {
|
|
const unsigned char* pa = a + i * 4;
|
|
const unsigned char* pb = b + i * 4;
|
|
const int dr = std::abs((int)pa[0] - (int)pb[0]);
|
|
const int dg = std::abs((int)pa[1] - (int)pb[1]);
|
|
const int db_ = std::abs((int)pa[2] - (int)pb[2]);
|
|
const int da = std::abs((int)pa[3] - (int)pb[3]);
|
|
if (dr > channel_threshold || dg > channel_threshold ||
|
|
db_ > channel_threshold || da > channel_threshold) {
|
|
++diffs;
|
|
}
|
|
}
|
|
|
|
r.pixels_total = area;
|
|
r.pixels_different = diffs;
|
|
r.diff_ratio = (area > 0) ? (double)diffs / (double)area : 0.0;
|
|
|
|
stbi_image_free(a);
|
|
stbi_image_free(b);
|
|
return r;
|
|
}
|
|
|
|
} // namespace fn_test
|