/*
 * http://pngquant.org
 */

#ifndef LIBIMAGEQUANT_H
#define LIBIMAGEQUANT_H

#ifdef __cplusplus
extern "C" {
#endif

#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199900L
#undef bool
#define bool int
#undef false
#define false 0
#undef true
#define true 1
#undef restrict
#define restrict
#endif

typedef struct liq_attr liq_attr;
typedef struct liq_image liq_image;
typedef struct liq_result liq_result;

typedef struct liq_color {
    unsigned char r, g, b, a;
} liq_color;

typedef struct liq_palette {
    unsigned int count;
    liq_color entries[256];
} liq_palette;

typedef enum liq_error {
    LIQ_OK = 0,
    LIQ_VALUE_OUT_OF_RANGE = 100,
    LIQ_OUT_OF_MEMORY,
    LIQ_NOT_READY,
    LIQ_BITMAP_NOT_AVAILABLE,
    LIQ_BUFFER_TOO_SMALL,
    LIQ_INVALID_POINTER,
    LIQ_HISTOGRAM_FAILED,
    LIQ_FREED_POINTER,
    LIQ_NULL_POINTER,
    LIQ_BAD_POINTER,
    LIQ_NEGATIVE_DIMENSIONS,
    LIQ_HUGE_DIMENSIONS,
    LIQ_BAD_USER_POINTER,
} liq_error;

enum liq_ownership {LIQ_OWN_ROWS=4, LIQ_OWN_PIXELS=8};

liq_error liq_invalid_attr (liq_attr *);
liq_error liq_invalid_image (liq_image *);
liq_error liq_invalid_result (liq_result *);

liq_attr* liq_attr_create(void);
liq_attr* liq_attr_create_with_allocator(void* (*malloc)(size_t), void (*free)(void*));
liq_attr* liq_attr_copy(liq_attr* orig);
liq_error liq_attr_destroy(liq_attr* attr);

liq_error liq_set_max_colors(liq_attr* attr, int colors);
liq_error liq_set_speed(liq_attr* attr, int speed);
liq_error liq_set_min_opacity(liq_attr* attr, int min);
liq_error liq_set_min_posterization(liq_attr* attr, int bits);
liq_error liq_set_quality(liq_attr* attr, int minimum, int maximum);
liq_error liq_get_quality(liq_attr* attr, int* minimum, int* maximum);
liq_error liq_set_last_index_transparent(liq_attr* attr, int is_last);

liq_error liq_get_max_colors_2(liq_attr* attr, int * colors);
liq_error liq_get_speed_2(liq_attr* attr, int * speed);
liq_error liq_get_min_opacity_2(liq_attr* attr, int *min);
liq_error liq_get_min_posterization_2(liq_attr* attr, int *bits);

typedef void liq_log_callback_function(const liq_attr*, const char* message, void* user_info);
typedef void liq_log_flush_callback_function(const liq_attr*, void* user_info);
liq_error liq_set_log_callback(liq_attr*, liq_log_callback_function*, void* user_info);
liq_error liq_set_log_flush_callback(liq_attr*, liq_log_flush_callback_function*, void* user_info);

liq_image* liq_image_create_rgba_rows(liq_attr* attr, void* rows[], int width, int height, double gamma);
liq_image* liq_image_create_rgba(liq_attr* attr, void* bitmap, int width, int height, double gamma);

    /* Perl-interface-only function. */

liq_error liq_image_create_rgba_rows_2(liq_attr *attr, void* rows[], int width, int height, double gamma, liq_image ** image);

typedef void liq_image_get_rgba_row_callback(liq_color row_out[], int row, int width, void* user_info);
liq_image* liq_image_create_custom(liq_attr* attr, liq_image_get_rgba_row_callback* row_callback, void* user_info, int width, int height, double gamma);

liq_error liq_image_set_memory_ownership(liq_image* image, int ownership_flags);
int liq_image_get_width(const liq_image* img);
int liq_image_get_height(const liq_image* img);
liq_error  liq_image_destroy(liq_image* img);

liq_result* liq_quantize_image(liq_attr* options, liq_image* input_image);

    /* Perl-interface-only function. */

liq_error liq_quantize_image_2(liq_attr *options, liq_image *input_image, liq_result ** result_ptr);

liq_error liq_set_dithering_level(liq_result* res, float dither_level);
liq_error liq_set_output_gamma(liq_result* res, double gamma);
liq_error liq_get_output_gamma(const liq_result* result, double * gamma);

const liq_palette* liq_get_palette(liq_result* result);

liq_error liq_write_remapped_image(liq_result* result, liq_image* input_image, void* buffer, size_t buffer_size);
liq_error liq_write_remapped_image_rows(liq_result* result, liq_image* input_image, unsigned char** row_pointers);

double liq_get_quantization_error(liq_result* result);
int liq_get_quantization_quality(liq_result* result);

liq_error liq_result_destroy(liq_result*);

#ifdef __cplusplus
}
#endif

#endif
