Yuriy M. Kaminskiy wrote: > Problem was lack of proper handling for EXTRASAMPLE_UNASSOCALPHA in tiff2ps. > Attached patch should fix this and related issues (should be applicable to > 3.9.latest and 4.0.latest) > Warning: only minimal testing passed, likely should be forwarded to and > handled > by upstream.
Sorry, previous patch (completely) incorrectly handled PLANARCONFIG_SEPARATE (however, that has not introduced regression, it was broken before too). Better patch attached (I've dropped *lvl2 changes, as they would require much more to make it work and was not directly related to this bug). And I noticed that this bug is actually duplicate of https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=552382 (which is also fixed by this patch).
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 NotDashEscaped: You need GnuPG to verify this message From: Yuriy M. Kaminskiy <yum...@gmail.com> Subject: [PATCH][v3] tiff2ps: fix grayscale with unassociated alpha (and other extrasamples != 0) See: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=611141 Note: this patch only fixes postscript level 1 output from grayscale source. While fixing this bug, I've found a lot of other broken cases: a) postscript 2+ from any PLANARCONFIG_SEPARATE source (/MultipleDataSources does not work this way, and I doubt in can be used in tiff2ps at all) b) postscript 2+ from compressed source with alpha c) postscript 1 from compressed color source with PLANARCONFIG_SEPARATE d) postscript 1 from jbig compressed tiff Index: tiff-4.0.x-20141215/tools/tiff2ps.c =================================================================== --- tiff-4.0.x-20141215.orig/tools/tiff2ps.c 2014-12-28 01:35:28.548097063 +0300 +++ tiff-4.0.x-20141215/tools/tiff2ps.c 2014-12-28 01:39:03.720095721 +0300 @@ -41,6 +41,7 @@ #endif #include "tiffio.h" +#include "tiffiop.h" /* TIFFSafeMultiply */ /* * Revision history @@ -2595,6 +2596,11 @@ PSDataBW(FILE* fd, TIFF* tif, uint32 w, unsigned char* cp; tsize_t stripsize = TIFFStripSize(tif); tstrip_t s; + int sp = samplesperpixel; + int nc = samplesperpixel - extrasamples; + tstrip_t ns = TIFFNumberOfStrips(tif); + tsize_t buf_size = stripsize; + tstrip_t strip_offset = 0; #if defined( EXP_ASCII85ENCODER ) tsize_t ascii85_l; /* Length, in bytes, of ascii85_p[] data */ @@ -2602,7 +2608,19 @@ PSDataBW(FILE* fd, TIFF* tif, uint32 w, #endif (void) w; (void) h; - tf_buf = (unsigned char *) _TIFFmalloc(stripsize); + + if (planarconfiguration == PLANARCONFIG_SEPARATE) { + if (sp > 1) { + ns = TIFFComputeStrip(tif, 0, 1); /* ns / sp */ + strip_offset = nc == 1 ? ns : TIFFComputeStrip(tif, 0, nc); /* nc * ns */ + sp = 1; + } + nc = stripsize; + if (alpha) /* space for alpha strip */ + buf_size = TIFFSafeMultiply(tsize_t, stripsize, 2); + } + + tf_buf = (unsigned char *) _TIFFmalloc(buf_size); if (tf_buf == NULL) { TIFFError(filename, "No space for scanline buffer"); return; @@ -2636,12 +2654,20 @@ PSDataBW(FILE* fd, TIFF* tif, uint32 w, if (ascii85) Ascii85Init(); - for (s = 0; s < TIFFNumberOfStrips(tif); s++) { + for (s = 0; s < ns; s++) { tmsize_t cc = TIFFReadEncodedStrip(tif, s, tf_buf, stripsize); if (cc < 0) { TIFFError(filename, "Can't read strip"); break; } + if (alpha && strip_offset) { + if (TIFFReadEncodedStrip(tif, s + strip_offset, + tf_buf + stripsize, + stripsize) != cc) { + TIFFError(filename, "Can't read alpha strip"); + break; + } + } cp = tf_buf; if (photometric == PHOTOMETRIC_MINISWHITE) { for (cp += cc; --cp >= tf_buf;) @@ -2657,13 +2683,19 @@ PSDataBW(FILE* fd, TIFF* tif, uint32 w, } if (ascii85) { #if defined( EXP_ASCII85ENCODER ) - if (alpha) { - int adjust, i; - for (i = 0; i < cc; i+=2) { - adjust = 255 - cp[i + 1]; - cp[i / 2] = cp[i] + adjust; + if (alpha && sp != nc) { + int adjust, i, j = 0; + for (i = 0; i < cc; i += sp) { + adjust = 255 - cp[i + nc]; + cp[j++] = cp[i] + adjust; } - cc /= 2; + cc = j; + } else if (sp != 1) { + int i, j = 0; + for (i = 0; i < cc; i += sp) { + cp[j++] = cp[i]; + } + cc = j; } ascii85_l = Ascii85EncodeBlock( ascii85_p, 1, cp, cc ); @@ -2671,15 +2703,15 @@ PSDataBW(FILE* fd, TIFF* tif, uint32 w, if ( ascii85_l > 0 ) fwrite( ascii85_p, ascii85_l, 1, fd ); #else - while (cc-- > 0) - Ascii85Put(*cp++, fd); + for (; cc > 0; cc -= sp, cp += sp) + Ascii85Put(*cp, fd); #endif /* EXP_ASCII85_ENCODER */ } else { unsigned char c; if (alpha) { int adjust; - while (cc-- > 0) { + for ( ; cc >= sp; cc -= sp, cp += sp) { DOBREAK(breaklen, 1, fd); /* * For images with alpha, matte against @@ -2687,13 +2719,12 @@ PSDataBW(FILE* fd, TIFF* tif, uint32 w, * Cback * (1 - Aimage) * where Cback = 1. */ - adjust = 255 - cp[1]; - c = *cp++ + adjust; PUTHEX(c,fd); - cp++, cc--; + adjust = 255 - cp[nc]; + c = *cp + adjust; PUTHEX(c,fd); } } else { - while (cc-- > 0) { - c = *cp++; + for (; cc >= sp; cc -= sp, cp += sp) { + c = *cp; DOBREAK(breaklen, 1, fd); PUTHEX(c, fd); } -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iF4EAREIAAYFAlSfOKUACgkQKZn9iF16KMOB9gD/f1w4d6udFWyaDIJ+ZL2vSARg qnCW6pWIleyQ9ir9mqQBAImK7U1sEQHsYobdCuB0b0qcRPpur9H0opP7ti9vMR6u =GmJZ -----END PGP SIGNATURE-----