/* Interface header file for PPM-related functions in libnetpbm */ #ifndef _PPM_H_ #define _PPM_H_ #include #include #include #ifdef __cplusplus extern "C" { #endif #if 0 } /* to fake out automatic code indenters */ #endif typedef gray pixval; /* These are just for use in this header file */ #define PPM_MAX(a,b) ((a) > (b) ? (a) : (b)) #define PPM_MIN(a,b) ((a) < (b) ? (a) : (b)) #define PPM_OVERALLMAXVAL PGM_OVERALLMAXVAL #define PPM_MAXMAXVAL PGM_MAXMAXVAL #define ppm_unnormalize pgm_unnormalize typedef struct { pixval r, g, b; } pixel; #define PPM_GETR(p) ((p).r) #define PPM_GETG(p) ((p).g) #define PPM_GETB(p) ((p).b) /************* added definitions *****************/ #define PPM_PUTR(p,red) ((p).r = (red)) #define PPM_PUTG(p,grn) ((p).g = (grn)) #define PPM_PUTB(p,blu) ((p).b = (blu)) /**************************************************/ #define PPM_ASSIGN(p,red,grn,blu) \ do { (p).r = (red); (p).g = (grn); (p).b = (blu); } while (0) #define PPM_EQUAL(p,q) \ ( (p).r == (q).r && (p).g == (q).g && (p).b == (q).b ) /* Magic constants. */ #define PPM_MAGIC1 'P' #define PPM_MAGIC2 '3' #define RPPM_MAGIC2 '6' #define PPM_FORMAT (PPM_MAGIC1 * 256 + PPM_MAGIC2) #define RPPM_FORMAT (PPM_MAGIC1 * 256 + RPPM_MAGIC2) #define PPM_TYPE PPM_FORMAT #include /* Macro for turning a format number into a type number. */ #define PPM_FORMAT_TYPE(f) \ ((f) == PPM_FORMAT || (f) == RPPM_FORMAT ? PPM_TYPE : PGM_FORMAT_TYPE(f)) static __inline__ pixel ppm_whitepixel(pixval maxval) { pixel retval; PPM_ASSIGN(retval, maxval, maxval, maxval); return retval; } static __inline__ pixel ppm_blackpixel(void) { pixel const retval = {0, 0, 0}; return retval; } void ppm_init(int * const argcP, char ** const argv); #define ppm_allocarray(cols, rows) \ ((pixel**) pm_allocarray(cols, rows, sizeof(pixel))) pixel * ppm_allocrow(unsigned int const cols); #define ppm_freearray(pixels, rows) pm_freearray((char**) pixels, rows) #define ppm_freerow(pixelrow) pm_freerow(pixelrow); pixel** ppm_readppm(FILE * const fileP, int * const colsP, int * const rowsP, pixval * const maxvalP); void ppm_readppminit(FILE * const fileP, int * const colsP, int * const rowsP, pixval * const maxvalP, int * const formatP); void ppm_readppmrow(FILE* const fileP, pixel* const pixelrow, int const cols, pixval const maxval, int const format); void ppm_writeppm(FILE * const fileP, pixel** const pixels, int const cols, int const rows, pixval const maxval, int const forceplain); void ppm_writeppminit(FILE* const fileP, int const cols, int const rows, pixval const maxval, int const forceplain); void ppm_writeppmrow(FILE * const fileP, const pixel * const pixelrow, int const cols, pixval const maxval, int const forceplain); void ppm_check(FILE * const fileP, enum pm_check_type const check_type, int const format, int const cols, int const rows, pixval const maxval, enum pm_check_code * const retval_p); void ppm_nextimage(FILE * const fileP, int * const eofP); pixel ppm_parsecolor(const char * const colorname, pixval const maxval); pixel ppm_parsecolor2(const char * const colorname, pixval const maxval, int const closeOk); char* ppm_colorname(const pixel* const colorP, pixval const maxval, int const hexok); typedef struct { unsigned int version; const char ** name; /* malloced, and each entry malloced. Has space for at least 'size' entries. May be null if size == 0 */ pixel * color; /* malloced */ /* malloced. Has space for at least 'size' entries. May be null if size == 0 */ unsigned int size; /* allocated size of 'name' and 'color'. At least 'count' */ unsigned int count; /* number of entries used.*/ colorhash_table cht; /* Hash table mapping name[] to color[] */ } ppm_ColorDict; ppm_ColorDict * ppm_colorDict_new(const char * const fileName, int const mustOpen); void ppm_colorDict_destroy(ppm_ColorDict * colorDictP); void ppm_readcolordict2(const char * const fileName, int const mustOpen, ppm_ColorDict ** const colorDictP); void ppm_readcolordict(const char * const fileName, int const mustOpen, unsigned int * const nColorsP, const char *** const colornamesP, pixel ** const colorsP, colorhash_table * const chtP); void ppm_readcolornamefile(const char * const fileName, int const mustOpen, colorhash_table * const chtP, const char *** const colornamesP); void ppm_freecolornames(const char ** const colornames); #define PPM_ISGRAY(pixel) \ (PPM_GETR(pixel) == PPM_GETG(pixel) && PPM_GETR(pixel) == PPM_GETB(pixel)) /* Color scaling macro -- to make writing ppmtowhatever easier. */ #define PPM_DEPTH(newp,p,oldmaxval,newmaxval) \ PPM_ASSIGN( (newp), \ ( (int) PPM_GETR(p) * (newmaxval) + (oldmaxval) / 2 ) / (oldmaxval), \ ( (int) PPM_GETG(p) * (newmaxval) + (oldmaxval) / 2 ) / (oldmaxval), \ ( (int) PPM_GETB(p) * (newmaxval) + (oldmaxval) / 2 ) / (oldmaxval) ) #define PPM_SQR(x) (x)*(x) static __inline__ unsigned int PPM_DISTANCE(pixel const p1, pixel const p2) { return ( PPM_SQR(PPM_GETR(p1)-PPM_GETR(p2)) + PPM_SQR(PPM_GETG(p1)-PPM_GETG(p2)) + PPM_SQR(PPM_GETB(p1)-PPM_GETB(p2)) ); } #undef PPM_SQR /* Note that because a sample can be at most 1 << 16 - 1, PPM_DISTANCE is less than UINT_MAX. That means you can use UINT_MAX as an infinite distance in some applications. */ /* Luminance, Chrominance macros. */ /* The following are weights of the red, green, and blue components respectively in the luminance of a color. Actually, it's "luma," not luminance, the difference being that luminance would be a linear combination of intensities, whereas luma is a linear combination of gamma-adjusted intensities, as you would find in a Netpbm image. These are from ITU-R BT.601.5. */ #define PPM_LUMINR (0.2989) #define PPM_LUMING (0.5866) #define PPM_LUMINB (0.1145) #define PPM_LUMIN(p) ( PPM_LUMINR * PPM_GETR(p) \ + PPM_LUMING * PPM_GETG(p) \ + PPM_LUMINB * PPM_GETB(p) ) /* The coefficients in the following formulae are functions of PPM_LUMIN{R,G,B} and nothing else. */ #define PPM_CHROM_B(p) ( -0.168736 * PPM_GETR(p) \ - 0.331264 * PPM_GETG(p) \ + 0.5 * PPM_GETB(p) ) #define PPM_CHROM_R(p) ( 0.5 * PPM_GETR(p) \ - 0.418688 * PPM_GETG(p) \ - 0.081312 * PPM_GETB(p) ) pixel ppm_color_from_ycbcr(unsigned int const y, int const cb, int const cr); /* Hue/Saturation/Value calculations */ struct hsv { double h; /* hue (degrees) 0..360 */ double s; /* saturation (0-1) */ double v; /* value (0-1) */ }; pixel ppm_color_from_hsv(struct hsv const hsv, pixval const maxval); struct hsv ppm_hsv_from_color(pixel const color, pixval const maxval); static __inline__ pixval ppm_luminosity(pixel const p) { return (pixval)(PPM_LUMIN(p) + 0.5); } static __inline__ pixval ppm_colorvalue(pixel const p) { /*---------------------------------------------------------------------------- The color value (V is HSV) as a pixval -----------------------------------------------------------------------------*/ return PPM_MAX(PPM_GETR(p), PPM_MAX(PPM_GETG(p), PPM_GETB(p))); } static __inline__ pixval ppm_saturation(pixel const p, pixval const maxval) { /*---------------------------------------------------------------------------- The saturation, as a pixval (i.e. if saturation is 50% and maxval is 100, this is 50). -----------------------------------------------------------------------------*/ pixval const maxIntensity = PPM_MAX(PPM_GETR(p), PPM_MAX(PPM_GETG(p), PPM_GETB(p))); pixval const minIntensity = PPM_MIN(PPM_GETR(p), PPM_MIN(PPM_GETG(p), PPM_GETB(p))); pixval const range = maxIntensity - minIntensity; return (pixval)((unsigned long)range * maxval / maxIntensity); } typedef enum { /* A color from the set of universally understood colors developed by Brent Berlin and Paul Kay. Algorithms in libnetpbm depend on the numerical representations of these values being as follows. */ BKCOLOR_GRAY = 0, BKCOLOR_BROWN, BKCOLOR_ORANGE, BKCOLOR_RED, BKCOLOR_YELLOW, BKCOLOR_GREEN, BKCOLOR_BLUE, BKCOLOR_VIOLET, BKCOLOR_PURPLE, BKCOLOR_WHITE, BKCOLOR_BLACK } bk_color; #define BKCOLOR_COUNT (BKCOLOR_BLACK+1) bk_color ppm_bk_color_from_color(pixel const color, pixval const maxval); pixel ppm_color_from_bk_color(bk_color const bkColor, pixval const maxval); bk_color ppm_bk_color_from_name(const char * const name); const char * ppm_name_from_bk_color(bk_color const bkColor); #ifdef __cplusplus } #endif #undef PPM_MIN #undef PPM_MAX #endif /*_PPM_H_*/