diff --git a/blur.h b/blur.h index 06ae8cb..1e77819 100644 --- a/blur.h +++ b/blur.h @@ -1,4 +1,8 @@ +#ifndef BLUR_H +#define BLUR_H LIQ_PRIVATE void liq_blur(unsigned char *src, unsigned char *tmp, unsigned char *dst, unsigned int width, unsigned int height, unsigned int size); LIQ_PRIVATE void liq_max3(unsigned char *src, unsigned char *dst, unsigned int width, unsigned int height); LIQ_PRIVATE void liq_min3(unsigned char *src, unsigned char *dst, unsigned int width, unsigned int height); + +#endif diff --git a/kmeans.c b/kmeans.c index 7ee273d..c8630ae 100644 --- a/kmeans.c +++ b/kmeans.c @@ -73,8 +73,13 @@ LIQ_PRIVATE double kmeans_do_iteration(histogram *hist, colormap *const map, kme const int hist_size = hist->size; double total_diff=0; +#if __GNUC__ >= 9 + #pragma omp parallel for if (hist_size > 2000) \ + schedule(static) default(none) shared(achv,average_color,callback,hist_size,map,n) reduction(+:total_diff) +#else #pragma omp parallel for if (hist_size > 2000) \ schedule(static) default(none) shared(average_color,callback) reduction(+:total_diff) +#endif for(int j=0; j < hist_size; j++) { float diff; unsigned int match = nearest_search(n, &achv[j].acolor, achv[j].tmp.likely_colormap_index, &diff); diff --git a/libimagequant.c b/libimagequant.c index 3506564..ba9dc0a 100644 --- a/libimagequant.c +++ b/libimagequant.c @@ -566,7 +566,7 @@ LIQ_NONNULL static bool liq_image_use_low_memory(liq_image *img) LIQ_NONNULL static bool liq_image_should_use_low_memory(liq_image *img, const bool low_memory_hint) { - return img->width * img->height > (low_memory_hint ? LIQ_HIGH_MEMORY_LIMIT/8 : LIQ_HIGH_MEMORY_LIMIT) / sizeof(f_pixel); // Watch out for integer overflow + return (size_t)img->width * (size_t)img->height > (low_memory_hint ? LIQ_HIGH_MEMORY_LIMIT/8 : LIQ_HIGH_MEMORY_LIMIT) / sizeof(f_pixel); // Watch out for integer overflow } static liq_image *liq_image_create_internal(const liq_attr *attr, rgba_pixel* rows[], liq_image_get_rgba_row_callback *row_callback, void *row_callback_user_info, int width, int height, double gamma) @@ -647,7 +647,7 @@ LIQ_EXPORT LIQ_NONNULL liq_error liq_image_set_importance_map(liq_image *img, un if (!CHECK_STRUCT_TYPE(img, liq_image)) return LIQ_INVALID_POINTER; if (!CHECK_USER_POINTER(importance_map)) return LIQ_INVALID_POINTER; - const size_t required_size = img->width * img->height; + const size_t required_size = (size_t)img->width * (size_t)img->height; if (buffer_size < required_size) { return LIQ_BUFFER_TOO_SMALL; } @@ -1030,7 +1030,7 @@ LIQ_EXPORT LIQ_NONNULL liq_error liq_set_dithering_level(liq_result *res, float res->remapping = NULL; } - if (res->dither_level < 0 || res->dither_level > 1.0f) return LIQ_VALUE_OUT_OF_RANGE; + if (dither_level < 0 || dither_level > 1.0f) return LIQ_VALUE_OUT_OF_RANGE; res->dither_level = dither_level; return LIQ_OK; } @@ -1276,8 +1276,13 @@ LIQ_NONNULL static float remap_to_palette(liq_image *const input_image, unsigned LIQ_ARRAY(kmeans_state, average_color, (KMEANS_CACHE_LINE_GAP+map->colors) * max_threads); kmeans_init(map, max_threads, average_color); +#if __GNUC__ >= 9 + #pragma omp parallel for if (rows*cols > 3000) \ + schedule(static) default(none) shared(acolormap,average_color,cols,input_image,map,n,output_pixels,rows,transparent_index) reduction(+:remapping_error) +#else #pragma omp parallel for if (rows*cols > 3000) \ schedule(static) default(none) shared(acolormap) shared(average_color) reduction(+:remapping_error) +#endif for(int row = 0; row < rows; ++row) { const f_pixel *const row_pixels = liq_image_get_row_f(input_image, row); const f_pixel *const bg_pixels = input_image->background && acolormap[transparent_index].acolor.a < 1.f/256.f ? liq_image_get_row_f(input_image->background, row) : NULL; @@ -2078,7 +2083,7 @@ LIQ_EXPORT LIQ_NONNULL liq_error liq_write_remapped_image(liq_result *result, li return LIQ_INVALID_POINTER; } - const size_t required_size = input_image->width * input_image->height; + const size_t required_size = (size_t)input_image->width * (size_t)input_image->height; if (buffer_size < required_size) { return LIQ_BUFFER_TOO_SMALL; } diff --git a/libimagequant.h b/libimagequant.h index c8f84b5..9280deb 100644 --- a/libimagequant.h +++ b/libimagequant.h @@ -13,8 +13,8 @@ #define LIQ_EXPORT extern #endif -#define LIQ_VERSION 21200 -#define LIQ_VERSION_STRING "2.12.2" +#define LIQ_VERSION 21206 +#define LIQ_VERSION_STRING "2.12.6" #ifndef LIQ_PRIVATE #if defined(__GNUC__) || defined (__llvm__) diff --git a/mediancut.c b/mediancut.c index 447a4af..ee11902 100644 --- a/mediancut.c +++ b/mediancut.c @@ -195,8 +195,13 @@ static double prepare_sort(struct box *b, hist_item achv[]) const unsigned int ind1 = b->ind; const unsigned int colors = b->colors; +#if __GNUC__ >= 9 + #pragma omp parallel for if (colors > 25000) \ + schedule(static) default(none) shared(achv, channels, colors, ind1) +#else #pragma omp parallel for if (colors > 25000) \ schedule(static) default(none) shared(achv, channels) +#endif for(unsigned int i=0; i < colors; i++) { const float *chans = (const float *)&achv[ind1 + i].acolor; // Only the first channel really matters. When trying median cut many times @@ -311,9 +316,7 @@ static void box_init(struct box *box, const hist_item *achv, const unsigned int box->total_error = -1; box->color = averagepixels(colors, &achv[ind]); - #pragma omp task if (colors > 5000) box->variance = box_variance(achv, box); - #pragma omp task if (colors > 8000) box->max_error = box_max_error(achv, box); } @@ -331,17 +334,12 @@ LIQ_PRIVATE colormap *mediancut(histogram *hist, unsigned int newcolors, const d /* ** Set up the initial box. */ - #pragma omp parallel - #pragma omp single { double sum = 0; for(unsigned int i=0; i < hist->size; i++) { sum += achv[i].adjusted_weight; } - #pragma omp taskgroup - { - box_init(&bv[0], achv, 0, hist->size, sum); - } + box_init(&bv[0], achv, 0, hist->size, sum); /* @@ -386,11 +384,8 @@ LIQ_PRIVATE colormap *mediancut(histogram *hist, unsigned int newcolors, const d double lowersum = 0; for(unsigned int i=0; i < break_at; i++) lowersum += achv[indx + i].adjusted_weight; - #pragma omp taskgroup - { - box_init(&bv[bi], achv, indx, break_at, lowersum); - box_init(&bv[boxes], achv, indx + break_at, clrs - break_at, sm - lowersum); - } + box_init(&bv[bi], achv, indx, break_at, lowersum); + box_init(&bv[boxes], achv, indx + break_at, clrs - break_at, sm - lowersum); ++boxes; diff --git a/mediancut.h b/mediancut.h index d97696c..9a4cb53 100644 --- a/mediancut.h +++ b/mediancut.h @@ -1,2 +1,6 @@ +#ifndef MEDIANCUT_H +#define MEDIANCUT_H LIQ_PRIVATE colormap *mediancut(histogram *hist, unsigned int newcolors, const double target_mse, const double max_mse, void* (*malloc)(size_t), void (*free)(void*)); + +#endif diff --git a/nearest.h b/nearest.h index e20233b..10a0a2c 100644 --- a/nearest.h +++ b/nearest.h @@ -2,7 +2,13 @@ // nearest.h // pngquant // + +#ifndef NEAREST_H +#define NEAREST_H + struct nearest_map; LIQ_PRIVATE struct nearest_map *nearest_init(const colormap *palette); LIQ_PRIVATE unsigned int nearest_search(const struct nearest_map *map, const f_pixel *px, const int palette_index_guess, float *diff); LIQ_PRIVATE void nearest_free(struct nearest_map *map); + +#endif diff --git a/pam.c b/pam.c index 660f829..6e36222 100644 --- a/pam.c +++ b/pam.c @@ -225,6 +225,9 @@ LIQ_PRIVATE histogram *pam_acolorhashtoacolorhist(const struct acolorhash_table } hist->size = j; hist->total_perceptual_weight = total_weight; + for(unsigned int k=0; k < hist->size; k++) { + hist->achv[k].tmp.likely_colormap_index = 0; + } if (!j) { pam_freeacolorhist(hist); return NULL; diff --git a/pam.h b/pam.h index 2ca4327..5a7d50e 100644 --- a/pam.h +++ b/pam.h @@ -16,6 +16,12 @@ #ifndef PAM_H #define PAM_H +// accidental debug assertions make color search much slower, +// so force assertions off if there's no explicit setting +#if !defined(NDEBUG) && !defined(DEBUG) +#define NDEBUG +#endif + #include #include #include