/* ppmoquant.h - options, types and prototypes for ppmoquant.c */ /* Last edited on 2006-11-22 13:41:38 by stolfi */ #include #include #include #define MAXCOLORS 32767 /* COMMAND-LINE OPTIONS */ typedef int (*matchfn)( long br, long bg, long bb, long wr, long wg, long wb, int maxval, ppm_cmapx_hist_vector cm, int ncolors, int mapmaxval ); /* A function that finds the best (opaque) match to the color interval [r1_r2]x[g1_g2]x[b1_b2] in the colormap cm. Note that the interval may be somewhat outside the color cube. */ typedef struct options_t { bool_t floyd; matchfn match; rgb_pixel_t transp; int transpmaxval; char *cmapname; char *bimgname; char *wimgname; } options_t; /* Prototypes */ int main(int argc, char* argv[]); options_t *parse_options(int argc, char **argv); rgb_pixel_t my_parsecolor(char *colorspec, int *maxvalp); /* Parses a colorspec, returns the pixel value and stores its respective maxval in (*maxvalp). Syntax is the same as in ppm_parsecolor, but also accepts an RGB pixel in the format "(R,G,B)". These are decimal coordinates, relative to the colormap's maxval. The parameter (*maxvalp) is set to zero to denote this fact. All other formats are relative to some format-dependent maxval, which gets assigned to (*maxvalp). */ static rgb_pixel_t adjust_transp_color(rgb_pixel_t p, int oldmaxval, int newmaxval); /* Rescales the pixel p from [0..oldmaxval] to [0..newmaxval], unless oldmaxval = 0 (when p itself is returned). */ static rgb_pixel_t* find_color( rgb_pixel_t p, ppm_cmapx_hist_vector cm, int ncolors ); /* Looks for an exact match to p in cm[0..ncolors-1]. Returns pointer to pixel if found, NULL if not found. */ static ppm_cmapx_hist_vector collect_colors(pnm_image_t *map, int *ncolorsp); /* Turn map->pixels into a colormap. */ static void floyd_quantize_ppm_images( pnm_image_t *bimg, pnm_image_t *wimg, ppm_cmapx_hist_vector cm, int ncolors, rgb_pixel_t transp, int mapmaxval, matchfn match ); /* Replaces each pixel in bimg by a pixel from the given colormap, or the "transp" (transparent) pixel, by comparing the two colors. */ typedef struct { long* thisr; long* nextr; long* thisg; long* nextg; long* thisb; long* nextb; } fs_errors; static void floyd_alloc_error_vectors(fs_errors *ep, int cols); static void floyd_propagate_error_opaque( long br, long bg, long bb, long wr, long wg, long wb, rgb_pixel_t *newp, float coef, fs_errors *bep, fs_errors *wep, int col, int fs_direction ); /* Propagates Floyd-Steinberg error terms for opaque pixel choice. The old pixels are br, bg, bb, wr, wg, wb. The new pixel is (*newp). Assumes coef = FS_SCALE*(oldmaxval/newmaxval). */ static void floyd_propagate_error_transp( long br, long bg, long bb, long wr, long wg, long wb, int maxval, fs_errors *bep, fs_errors *wep, int col, int fs_direction ); /* Propagates Floyd-Steinberg error terms for transparent pixel choice. The old pixels are br, bg, bb, wr, wg, wb. */ static void floyd_swap_error_vectors(fs_errors *ep); static void plain_quantize_ppm_images( pnm_image_t *bimg, pnm_image_t *wimg, ppm_cmapx_hist_vector cm, int ncolors, rgb_pixel_t transp, int mapmaxval, matchfn match ); static rgb_pixel_t* choose_color ( long r0, long g0, long b0, long r1, long g1, long b1, int maxval, ppm_cmapx_hist_vector cm, int ncolors, int mapmaxval, matchfn match ); /* Finds best match to the color interval (r0,g0,b0)--(r1,g1,b1) in colormap cm plus the "transparent" color. Returns NULL if the best match is "transparent". */ static int rgb_match_range ( long br, long bg, long bb, long wr, long wg, long wb, int maxval, ppm_cmapx_hist_vector cm, int ncolors, int mapmaxval ); /* Search colormap for closest match to given color range. */