#include "png_diff.h" #include "stb_image.h" #include 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