int main(int argc, char *const argv[]) { char *map_output_file = NULL; if (argc < 3) { usage(argv[0]); return 1; } opterr = 0; int c; while((c = getopt(argc, argv, "ho:")) != -1) { switch (c) { case 'h': usage(argv[0]); return 0; case 'o': map_output_file = optarg; break; default: fprintf(stderr, "Unknown option\n"); return 1; } } if (optind+1 >= argc) { fprintf(stderr, "You must specify at least 2 files to compare\n"); return 1; } const char *file1 = argv[optind]; png24_image image1 = {}; int retval = read_image(file1, &image1); if (retval) { fprintf(stderr, "Can't read %s\n", file1); return retval; } dssim_image *original = dssim_create_image(image1.row_pointers, DSSIM_RGBA, image1.width, image1.height, image1.gamma); free(image1.row_pointers); free(image1.rgba_data); for (int arg = optind+1; arg < argc; arg++) { const char *file2 = argv[arg]; png24_image image2 = {}; retval = read_image(file2, &image2); if (retval) { fprintf(stderr, "Can't read %s\n", file2); break; } if (image1.width != image2.width || image1.height != image2.height) { fprintf(stderr, "Image %s has different size than %s\n", file2, file1); break; } dssim_image *modified = dssim_create_image(image2.row_pointers, DSSIM_RGBA, image2.width, image2.height, image2.gamma); free(image2.row_pointers); free(image2.rgba_data); float *map = NULL; double dssim = dssim_compare(original, modified, map_output_file ? &map : NULL); dssim_dealloc_image(modified); printf("%.6f\t%s\n", dssim, file2); if (map) { dssim_rgba *out = (dssim_rgba*)map; for(int i=0; i < image2.width*image2.height; i++) { const float max = 1.0 - map[i]; const float maxsq = max * max; out[i] = (dssim_rgba) { .r = to_byte(max * 3.0), .g = to_byte(maxsq * 3.0), .b = to_byte((max-0.5) * 2.0f), .a = 255, }; } if (write_image(map_output_file, out, image2.width, image2.height)) { fprintf(stderr, "Can't write %s\n", map_output_file); free(map); return 1; } free(map); } } dssim_dealloc_image(original); return retval; }
int main(int argc, char *const argv[]) { char *map_output_file = NULL; if (argc < 3) { usage(argv[0]); return 1; } opterr = 0; int c; while((c = getopt(argc, argv, "ho:")) != -1) { switch (c) { case 'h': usage(argv[0]); return 0; case 'o': map_output_file = optarg; break; default: fprintf(stderr, "Unknown option\n"); return 1; } } if (optind+1 >= argc) { fprintf(stderr, "You must specify at least 2 files to compare\n"); return 1; } const char *file1 = argv[optind]; png24_image image1 = {}; int retval = read_image(file1, &image1); if (retval) { fprintf(stderr, "Can't read %s (%d)\n", file1, retval); return retval; } dssim_attr *attr = dssim_create_attr(); dssim_image *original = dssim_create_image(attr, image1.row_pointers, DSSIM_RGBA, image1.width, image1.height, get_gamma(&image1)); free(image1.row_pointers); free(image1.rgba_data); for (int arg = optind+1; arg < argc; arg++) { const char *file2 = argv[arg]; png24_image image2 = {}; retval = read_image(file2, &image2); if (retval) { fprintf(stderr, "Can't read %s (%d)\n", file2, retval); break; } if (image1.width != image2.width || image1.height != image2.height) { fprintf(stderr, "Image %s has different size than %s\n", file2, file1); retval = 4; break; } dssim_image *modified = dssim_create_image(attr, image2.row_pointers, DSSIM_RGBA, image2.width, image2.height, get_gamma(&image2)); free(image2.row_pointers); free(image2.rgba_data); if (!modified) { fprintf(stderr, "Unable to process image %s\n", file2); retval = 4; break; } if (map_output_file) { dssim_set_save_ssim_maps(attr, 1, 1); } double dssim = dssim_compare(attr, original, modified); dssim_dealloc_image(modified); printf("%.8f\t%s\n", dssim, file2); if (map_output_file) { dssim_ssim_map map_meta = dssim_pop_ssim_map(attr, 0, 0); dssim_px_t *map = map_meta.data; dssim_rgba *out = (dssim_rgba*)map; for(int i=0; i < map_meta.width*map_meta.height; i++) { const dssim_px_t max = 1.0 - map[i]; const dssim_px_t maxsq = max * max; out[i] = (dssim_rgba) { .r = to_byte(max * 3.0), .g = to_byte(maxsq * 6.0), .b = to_byte(max / ((1.0 - map_meta.dssim) * 4.0)), .a = 255, }; } if (write_image(map_output_file, out, map_meta.width, map_meta.height)) { fprintf(stderr, "Can't write %s\n", map_output_file); free(map); return 1; } free(map); } } dssim_dealloc_image(original); dssim_dealloc_attr(attr); return retval; }