diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2019-03-09 00:13:15 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2019-03-09 00:13:15 +0000 |
commit | 1eeb6948a31c87e40477c911795e09f4643c52ff (patch) | |
tree | fc68687f4736f337289a4a6a1bae270640d376e8 /converter | |
parent | 9febf050e9c421127601c62b3e539a4132d34820 (diff) | |
download | netpbm-mirror-1eeb6948a31c87e40477c911795e09f4643c52ff.tar.gz netpbm-mirror-1eeb6948a31c87e40477c911795e09f4643c52ff.tar.xz netpbm-mirror-1eeb6948a31c87e40477c911795e09f4643c52ff.zip |
Fix sBit chunk, bit shift value
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@3562 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'converter')
-rw-r--r-- | converter/other/pamtopng.c | 121 |
1 files changed, 87 insertions, 34 deletions
diff --git a/converter/other/pamtopng.c b/converter/other/pamtopng.c index ece94c86..b4896125 100644 --- a/converter/other/pamtopng.c +++ b/converter/other/pamtopng.c @@ -333,6 +333,62 @@ parseAndScaleColor(const char * const colorString, +static png_color_8 +sigBitsFmImgType(unsigned int const pnmBitDepth, + int const pngColorType) { +/*---------------------------------------------------------------------------- + A representation used in PNG of color resolutions in an original image. +-----------------------------------------------------------------------------*/ + png_color_8 retval; + + /* Initial values */ + if (pnmBitDepth < 8) { + switch (pngColorType) { + case PNG_COLOR_TYPE_RGB: + retval.red = pnmBitDepth; + retval.green = pnmBitDepth; + retval.blue = pnmBitDepth; + retval.gray = 0; + retval.alpha = 0; + break; + case PNG_COLOR_TYPE_RGB_ALPHA: + retval.red = pnmBitDepth; + retval.green = pnmBitDepth; + retval.blue = pnmBitDepth; + retval.gray = 0; + retval.alpha = pnmBitDepth; + break; + case PNG_COLOR_TYPE_GRAY: + /* PNG can (so presumably will) use original bit depth */ + retval.red = 0; + retval.green = 0; + retval.blue = 0; + retval.gray = 0; + retval.alpha = 0; + break; + case PNG_COLOR_TYPE_GRAY_ALPHA: + retval.red = 0; + retval.green = 0; + retval.blue = 0; + retval.gray = pnmBitDepth; + retval.alpha = pnmBitDepth; + break; + default: + assert(false); + } + } else { + /* PNG can (so presumably will) use original bit depth */ + retval.red = 0; + retval.green = 0; + retval.blue = 0; + retval.gray = 0; + retval.alpha = 0; + } + return retval; +} + + + static void doTrnsChunk(const struct pam * const pamP, struct pngx * const pngxP, @@ -399,30 +455,12 @@ doGamaChunk(struct pngx * const pngxP, static void doSbitChunk(const struct pam * const pamP, - struct pngx * const pngxP) { - - unsigned int const pnmBitDepth = pm_maxvaltobits(pamP->maxval); - - /* A restriction on the PAM input: must power of 2 minus 1 maxval: */ - assert(pm_bitstomaxval(pnmBitDepth) == pamP->maxval); + struct pngx * const pngxP, + png_color_8 const sigBits) { - /* create SBIT chunk in case of 1,2,4 bit deep images stored in 8 bit - format PNG files - */ - if (pngx_colorType(pngxP) != PNG_COLOR_TYPE_GRAY && pnmBitDepth < 8) { - png_color_8 sBit; - - if (pngx_colorType(pngxP) == PNG_COLOR_TYPE_RGB || - pngx_colorType(pngxP) == PNG_COLOR_TYPE_RGB_ALPHA) { - sBit.red = sBit.green = sBit.blue = pnmBitDepth; - } else { - sBit.gray = pnmBitDepth; - } - if (pngx_colorType(pngxP) == PNG_COLOR_TYPE_RGB_ALPHA || - pngx_colorType(pngxP) == PNG_COLOR_TYPE_GRAY_ALPHA) { - sBit.alpha = pnmBitDepth; - } - pngx_setSbit(pngxP, sBit); + if (sigBits.red + sigBits.green + sigBits.blue + + sigBits.gray + sigBits.alpha > 0) { + pngx_setSbit(pngxP, sigBits); } } @@ -661,7 +699,8 @@ pngBitDepth(unsigned int const pnmBitDepth, static void addAncillaryChunks(struct pam * const pamP, struct pngx * const pngxP, - struct CmdlineInfo const cmdline) { + struct CmdlineInfo const cmdline, + png_color_8 const sigBits) { /*---------------------------------------------------------------------------- Where requested, add ancillary chunks. -----------------------------------------------------------------------------*/ @@ -676,7 +715,7 @@ addAncillaryChunks(struct pam * const pamP, /* no iccp */ - doSbitChunk(pamP, pngxP); + doSbitChunk(pamP, pngxP, sigBits); if (cmdline.srgbintentSpec) doSrgbChunk(pngxP, cmdline.srgbintent); @@ -709,15 +748,29 @@ addAncillaryChunks(struct pam * const pamP, static void +setShift(struct pngx * const pngxP, + png_color_8 const sigBits) { + + if (sigBits.red + sigBits.green + sigBits.blue + + sigBits.gray + sigBits.alpha > 0) { + + /* Move the 1, 2, 4 bits to most significant bits */ + pngx_setShift(pngxP, sigBits); + } +} + + + +static void pamtopng(FILE * const ifP, FILE * const ofP, struct CmdlineInfo const cmdline) { - unsigned int pnmBitDepth; - int pngColorType; + unsigned int pnmBitDepth; + int pngColorType; struct pngx * pngxP; - png_color_8 sBit; - struct pam pam; + png_color_8 sigBits; + struct pam pam; pnm_readpaminit(ifP, &pam, PAM_STRUCT_SIZE(tuple_type)); @@ -737,12 +790,12 @@ pamtopng(FILE * const ifP, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); - addAncillaryChunks(&pam, pngxP, cmdline); + sigBits = sigBitsFmImgType(pnmBitDepth, pngColorType); + + addAncillaryChunks(&pam, pngxP, cmdline, sigBits); + + setShift(pngxP, sigBits); - if (pngColorType != PNG_COLOR_TYPE_GRAY && pnmBitDepth < 8) { - /* Move the 1, 2, 4 bits to most significant bits */ - pngx_setShift(pngxP, sBit); - } if ((pngColorType == PNG_COLOR_TYPE_GRAY) && (pnmBitDepth < 8)) { /* Pack multiple pixels in a byte */ pngx_setPacking(pngxP); |