Exemplo n.º 1
0
LIQ_PRIVATE double viter_do_iteration(histogram *hist, colormap *const map, const float min_opaque_val, viter_callback callback, const bool fast_palette)
{
    const unsigned int max_threads = omp_get_max_threads();
    // viter_state average_color[(VITER_CACHE_LINE_GAP+map->colors) * max_threads];
	viter_state *average_color = (viter_state *)malloc((VITER_CACHE_LINE_GAP+map->colors) * max_threads);
    viter_init(map, max_threads, average_color);
    struct nearest_map *const n = nearest_init(map, fast_palette);
    hist_item *const achv = hist->achv;
    const int hist_size = hist->size;

    double total_diff=0;
    #pragma omp parallel for if (hist_size > 3000) \
        schedule(static) default(none) shared(average_color,callback) reduction(+:total_diff)
    for(int j=0; j < hist_size; j++) {
        float diff;
        unsigned int match = nearest_search(n, achv[j].acolor, achv[j].likely_colormap_index, min_opaque_val, &diff);
        achv[j].likely_colormap_index = match;
        total_diff += diff * achv[j].perceptual_weight;

        viter_update_color(achv[j].acolor, achv[j].perceptual_weight, map, match, omp_get_thread_num(), average_color);

        if (callback) callback(&achv[j], diff);
    }

    nearest_free(n);
    viter_finalize(map, max_threads, average_color);
	free(average_color);
    return total_diff / hist->total_perceptual_weight;
}
Exemplo n.º 2
0
void viter_finalize(colormap *map, const int max_threads, const viter_state average_color[])
{
    for (int i=0; i < map->colors; i++) {
        double a=0, r=0, g=0, b=0, total=0;

        // Aggregate results from all threads
        for(int t=0; t < max_threads; t++) {
            const int offset = map->colors * t + i;

            a += average_color[offset].a;
            r += average_color[offset].r;
            g += average_color[offset].g;
            b += average_color[offset].b;
            total += average_color[offset].total;
        }

        if (total) {
            map->palette[i].acolor = (f_pixel){
                .a = a / total,
                .r = r / total,
                .g = g / total,
                .b = b / total,
            };
        }
        map->palette[i].popularity = total;
    }
}

double viter_do_iteration(histogram *hist, colormap *const map, const float min_opaque_val, viter_callback callback)
{
    const int max_threads = omp_get_max_threads();
    viter_state average_color[map->colors * max_threads];
    viter_init(map, max_threads, average_color);
    struct nearest_map *const n = nearest_init(map);
    hist_item *const achv = hist->achv;
    const int hist_size = hist->size;

    double total_diff=0;
    #pragma omp parallel for if (hist_size > 3000) \
        default(none) shared(average_color,callback) reduction(+:total_diff)
    for(int j=0; j < hist_size; j++) {
        float diff;
        int match = nearest_search(n, achv[j].acolor, min_opaque_val, &diff);
        total_diff += diff * achv[j].perceptual_weight;

        viter_update_color(achv[j].acolor, achv[j].perceptual_weight, map, match, omp_get_thread_num(), average_color);

        if (callback) callback(&achv[j], diff);
    }

    nearest_free(n);
    viter_finalize(map, max_threads, average_color);

    return total_diff / hist->total_perceptual_weight;
}
Exemplo n.º 3
0
void viter_finalize(colormap *map, f_pixel *average_color, float *average_color_count)
{
    for (int i=0; i < map->colors; i++) {
        if (average_color_count[i]) {
            map->palette[i].acolor = (f_pixel){
                .a = (average_color[i].a) / average_color_count[i],
                .r = (average_color[i].r) / average_color_count[i],
                .g = (average_color[i].g) / average_color_count[i],
                .b = (average_color[i].b) / average_color_count[i],
            };
        }
        map->palette[i].popularity = average_color_count[i];
    }
}

double viter_do_iteration(const hist *hist, colormap *map, float min_opaque_val)
{
    f_pixel average_color[map->colors];
    float average_color_count[map->colors];

    hist_item *achv = hist->achv;
    viter_init(map, average_color,average_color_count);
    struct nearest_map *n = nearest_init(map);

    double total_diff=0;
    for(int j=0; j < hist->size; j++) {
        float diff;
        int match = nearest_search(n, achv[j].acolor, min_opaque_val, &diff);
        total_diff += diff * achv[j].perceptual_weight;

        viter_update_color(achv[j].acolor, achv[j].perceptual_weight, map, match, average_color,average_color_count);
    }

    nearest_free(n);
    viter_finalize(map, average_color,average_color_count);

    return total_diff / hist->total_perceptual_weight;
}