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-----

Reply via email to