int main(int argc, char **argv) { if (argc < 3) { printf("Image comparison tool\n" "Usage:\n" " %s <image1> <image2>\n", argv[0]); exit(1); } image *m1 = load_tga_image(argv[1]); image *m2 = load_tga_image(argv[2]); if (!m1) { printf("Failed to load image %s\n", argv[1]); exit(1); } if (!m2) { printf("Failed to load image %s\n", argv[2]); exit(1); } if (m1->xsize != m2->xsize || m1->ysize != m2->ysize) { printf("Image dimension mismatch:\n" "%s: %dx%d %s: %dx%d\n", argv[1], m1->xsize, m1->ysize, argv[2], m2->xsize, m2->ysize); exit(1); } compute_psnr(m1, m2); }
gboolean utils_gdk_pixbuf_similar_to (GdkPixbuf *i1, GdkPixbuf *i2) { gdouble MSE = compute_mse (i1, i2); if (MSE < 0.01) { #ifdef DEBUG g_debug ("Same images..."); #endif return TRUE; } gdouble PSNR = compute_psnr (MSE, 255); #ifdef DEBUG g_debug ("PSNR: %g", PSNR); #endif return PSNR >= 11; }
int psnr(const char *ref_path, const char *dis_path, int w, int h, const char *fmt) { double score = 0; number_t *ref_buf = 0; number_t *dis_buf = 0; number_t *temp_buf = 0; FILE *ref_rfile = 0; FILE *dis_rfile = 0; size_t data_sz; int stride; int ret = 1; if (w <= 0 || h <= 0 || (size_t)w > ALIGN_FLOOR(INT_MAX) / sizeof(number_t)) { goto fail_or_end; } stride = ALIGN_CEIL(w * sizeof(number_t)); if ((size_t)h > SIZE_MAX / stride) { goto fail_or_end; } data_sz = (size_t)stride * h; if (!(ref_buf = aligned_malloc(data_sz, MAX_ALIGN))) { printf("error: aligned_malloc failed for ref_buf.\n"); fflush(stdout); goto fail_or_end; } if (!(dis_buf = aligned_malloc(data_sz, MAX_ALIGN))) { printf("error: aligned_malloc failed for dis_buf.\n"); fflush(stdout); goto fail_or_end; } if (!(temp_buf = aligned_malloc(data_sz * 2, MAX_ALIGN))) { printf("error: aligned_malloc failed for temp_buf.\n"); fflush(stdout); goto fail_or_end; } if (!(ref_rfile = fopen(ref_path, "rb"))) { printf("error: fopen ref_path %s failed\n", ref_path); fflush(stdout); goto fail_or_end; } if (!(dis_rfile = fopen(dis_path, "rb"))) { printf("error: fopen dis_path %s failed.\n", dis_path); fflush(stdout); goto fail_or_end; } size_t offset; if (!strcmp(fmt, "yuv420p") || !strcmp(fmt, "yuv420p10le")) { if ((w * h) % 2 != 0) { printf("error: (w * h) %% 2 != 0, w = %d, h = %d.\n", w, h); fflush(stdout); goto fail_or_end; } offset = w * h / 2; } else if (!strcmp(fmt, "yuv422p") || !strcmp(fmt, "yuv422p10le")) { offset = w * h; } else if (!strcmp(fmt, "yuv444p") || !strcmp(fmt, "yuv444p10le")) { offset = w * h * 2; } else { printf("error: unknown format %s.\n", fmt); fflush(stdout); goto fail_or_end; } int frm_idx = 0; while ((!feof(ref_rfile)) && (!feof(dis_rfile))) { // read ref y if (!strcmp(fmt, "yuv420p") || !strcmp(fmt, "yuv422p") || !strcmp(fmt, "yuv444p")) { ret = read_image_b(ref_rfile, ref_buf, 0, w, h, stride); } else if (!strcmp(fmt, "yuv420p10le") || !strcmp(fmt, "yuv422p10le") || !strcmp(fmt, "yuv444p10le")) { ret = read_image_w(ref_rfile, ref_buf, 0, w, h, stride); } else { printf("error: unknown format %s.\n", fmt); fflush(stdout); goto fail_or_end; } if (ret) { goto fail_or_end; } // read dis y if (!strcmp(fmt, "yuv420p") || !strcmp(fmt, "yuv422p") || !strcmp(fmt, "yuv444p")) { ret = read_image_b(dis_rfile, dis_buf, 0, w, h, stride); } else if (!strcmp(fmt, "yuv420p10le") || !strcmp(fmt, "yuv422p10le") || !strcmp(fmt, "yuv444p10le")) { ret = read_image_w(dis_rfile, dis_buf, 0, w, h, stride); } else { printf("error: unknown format %s.\n", fmt); fflush(stdout); goto fail_or_end; } if (ret) { goto fail_or_end; } // compute if (!strcmp(fmt, "yuv420p") || !strcmp(fmt, "yuv422p") || !strcmp(fmt, "yuv444p")) { // max psnr 60.0 for 8-bit per Ioannis ret = compute_psnr(ref_buf, dis_buf, w, h, stride, stride, &score, 255.0, 60.0); } else if (!strcmp(fmt, "yuv420p10le") || !strcmp(fmt, "yuv422p10le") || !strcmp(fmt, "yuv444p10le")) { // 10 bit gets normalized to 8 bit, peak is 1023 / 4.0 = 255.75 // max psnr 72.0 for 10-bit per Ioannis ret = compute_psnr(ref_buf, dis_buf, w, h, stride, stride, &score, 255.75, 72.0); } else { printf("error: unknown format %s.\n", fmt); fflush(stdout); goto fail_or_end; } if (ret) { printf("error: compute_psnr failed.\n"); fflush(stdout); goto fail_or_end; } // print printf("psnr: %d %f\n", frm_idx, score); fflush(stdout); // ref skip u and v if (!strcmp(fmt, "yuv420p") || !strcmp(fmt, "yuv422p") || !strcmp(fmt, "yuv444p")) { if (fread(temp_buf, 1, offset, ref_rfile) != (size_t)offset) { printf("error: ref fread u and v failed.\n"); fflush(stdout); goto fail_or_end; } } else if (!strcmp(fmt, "yuv420p10le") || !strcmp(fmt, "yuv422p10le") || !strcmp(fmt, "yuv444p10le")) { if (fread(temp_buf, 2, offset, ref_rfile) != (size_t)offset) { printf("error: ref fread u and v failed.\n"); fflush(stdout); goto fail_or_end; } } else { printf("error: unknown format %s.\n", fmt); fflush(stdout); goto fail_or_end; } // dis skip u and v if (!strcmp(fmt, "yuv420p") || !strcmp(fmt, "yuv422p") || !strcmp(fmt, "yuv444p")) { if (fread(temp_buf, 1, offset, dis_rfile) != (size_t)offset) { printf("error: dis fread u and v failed.\n"); fflush(stdout); goto fail_or_end; } } else if (!strcmp(fmt, "yuv420p10le") || !strcmp(fmt, "yuv422p10le") || !strcmp(fmt, "yuv444p10le")) { if (fread(temp_buf, 2, offset, dis_rfile) != (size_t)offset) { printf("error: dis fread u and v failed.\n"); fflush(stdout); goto fail_or_end; } } else { printf("error: unknown format %s.\n", fmt); fflush(stdout); goto fail_or_end; } frm_idx++; } ret = 0; fail_or_end: if (ref_rfile) { fclose(ref_rfile); } if (dis_rfile) { fclose(dis_rfile); } aligned_free(ref_buf); aligned_free(dis_buf); aligned_free(temp_buf); return ret; }
virtual void run(void) { _res = compute_psnr(_ref, _cmp, _sz); }