diff options
Diffstat (limited to 'lib/libpamcolor.c')
-rw-r--r-- | lib/libpamcolor.c | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/lib/libpamcolor.c b/lib/libpamcolor.c new file mode 100644 index 00000000..e11415ca --- /dev/null +++ b/lib/libpamcolor.c @@ -0,0 +1,102 @@ +/*---------------------------------------------------------------------------- + libpamcolor.c +------------------------------------------------------------------------------ + These are the library functions, which belong in the libnetpbm library, + that deal with colors in the PAM image format. +-----------------------------------------------------------------------------*/ + +/* See libpbm.c for the complicated explanation of this 32/64 bit file + offset stuff. +*/ +#define _FILE_OFFSET_BITS 64 +#define _LARGE_FILES + +#include <limits.h> + +#include "pm_c_util.h" +#include "pam.h" +#include "ppm.h" + + +tuple +pnm_parsecolor(const char * const colorname, + sample const maxval) { + + tuple retval; + pixel color; + struct pam pam; + + pam.len = PAM_STRUCT_SIZE(bytes_per_sample); + pam.depth = 3; + pam.maxval = maxval; + pam.bytes_per_sample = pnm_bytespersample(maxval); + + retval = pnm_allocpamtuple(&pam); + + color = ppm_parsecolor(colorname, maxval); + + retval[PAM_RED_PLANE] = PPM_GETR(color); + retval[PAM_GRN_PLANE] = PPM_GETG(color); + retval[PAM_BLU_PLANE] = PPM_GETB(color); + + return retval; +} + + + +double pnm_lumin_factor[3] = {PPM_LUMINR, PPM_LUMING, PPM_LUMINB}; + +void +pnm_YCbCrtuple(tuple const tuple, + double * const YP, + double * const CbP, + double * const CrP) { +/*---------------------------------------------------------------------------- + Assuming that the tuple 'tuple' is of tupletype RGB, return the + Y/Cb/Cr representation of the color represented by the tuple. +-----------------------------------------------------------------------------*/ + int const red = (int)tuple[PAM_RED_PLANE]; + int const grn = (int)tuple[PAM_GRN_PLANE]; + int const blu = (int)tuple[PAM_BLU_PLANE]; + + *YP = (+ PPM_LUMINR * red + PPM_LUMING * grn + PPM_LUMINB * blu); + *CbP = (- 0.16874 * red - 0.33126 * grn + 0.50000 * blu); + *CrP = (+ 0.50000 * red - 0.41869 * grn - 0.08131 * blu); +} + + + +void +pnm_YCbCr_to_rgbtuple(const struct pam * const pamP, + tuple const tuple, + double const Y, + double const Cb, + double const Cr, + int * const overflowP) { + + double rgb[3]; + unsigned int plane; + bool overflow; + + rgb[PAM_RED_PLANE] = Y + 1.4022 * Cr + .5; + rgb[PAM_GRN_PLANE] = Y - 0.7145 * Cr - 0.3456 * Cb + .5; + rgb[PAM_BLU_PLANE] = Y + 1.7710 * Cb + .5; + + overflow = FALSE; /* initial assumption */ + + for (plane = 0; plane < 3; ++plane) { + if (rgb[plane] > pamP->maxval) { + overflow = TRUE; + tuple[plane] = pamP->maxval; + } else if (rgb[plane] < 0.0) { + overflow = TRUE; + tuple[plane] = 0; + } else + tuple[plane] = (sample)rgb[plane]; + } + if (overflowP) + *overflowP = overflow; +} + + + |