Пример #1
0
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;
}
Пример #2
0
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;
}