AWARE [SYSTEMS] Imaging expertise for the Delphi developer
AWare Systems, Imaging expertise for the Delphi developer, Home TIFF and LibTiff Mailing List Archive

LibTiff Mailing List

TIFF and LibTiff Mailing List Archive
April 1994

Previous Thread
Next Thread

Previous by Thread
Next by Thread

Previous by Date
Next by Date

Contact

The TIFF Mailing List Homepage
This list is run by Frank Warmerdam
Archive maintained by AWare Systems



Valid HTML 4.01!



1994.04.16 23:19 "ASCII85 encoding in tiff2ps (incl. source code)", by Andreas Vogel

Hello Sam,

Thank you very much for providing such nice packages like libtiff and
flexfax.

I've worked a lot with tiff2ps and I've found a considerable inprovement.
In all level2 PostScript implementations (including the current version
of ghostscript) there is also a filter named ASCII85. Therefore, instead
of encoding in HEX the ASCII85 encoding saves a huge amount of bytes.

I've implemented the ASCII85 encoding in the program tiff2ps and it works
fine. I've appended a context diff to this mail. You're free to do with
it whatever you want. It's just a donation to your wonderful work.

I'd appreciate if you could send me a short message wether you'll
add my code and/or what do you think of it.

BTW, the diff is against version tiff-3.3b2 and I'm running the whole
stuff on an i486 SVR4.

Thank you very much,

-- 
Andreas Vogel               Bahnhofstr. 13 / 73728 Esslingen / Germany
			    Voice:  +49-711/3967133
			    E-Mail: av@ssw.de


--- CUT HERE --- CUT HERE --- CUT HERE --- CUT HERE --- CUT HERE --- CUT HERE ---

*** tiff2ps.c.ORIG	Wed Mar 16 17:39:23 1994
--- tiff2ps.c	Wed Mar 16 23:22:25 1994
***************
*** 39,44 ****
--- 39,45 ----
  #define	TRUE	1
  #define	FALSE	0
  
+ int     ascii85 = TRUE;                 /* use ASCII85 encoding */
  int	level2 = FALSE;			/* generate PostScript level 2 */
  int	printAll = FALSE;		/* print all images in file */
  int	generateEPSF = TRUE;		/* generate Encapsulated PostScript */
***************
*** 103,113 ****
--- 104,119 ----
  		case '2':
  			level2 = TRUE;
  			break;
+ 		case '8':
+ 			ascii85 = !ascii85;
+ 			break;
  		case '?':
  			usage(-1);
  		}
  	if (argc - optind < 1)
  		usage(-2);
+ 	if (!level2)
+ 	    ascii85 = FALSE;
  	tif = TIFFOpen(filename = argv[optind], "r");
  	if (tif != NULL) {
  		if (dirnum != -1 && !TIFFSetDirectory(tif, dirnum))
***************
*** 383,389 ****
  			int rawdata;
  			fprintf(fd, "%lu %lu %d\n", w, h, bitspersample);
  			fprintf(fd, "[%lu 0 0 -%lu 0 %lu]\n", w, h, h);
! 			fprintf(fd, "currentfile /ASCIIHexDecode filter\n");
  			fprintf(fd, "dup 6 1 roll\n");
  			rawdata = emitPSLevel2FilterFunction(fd, tif, w, h);
  			fprintf(fd, "{image flushfile flushfile} cvx exec\n");
--- 389,398 ----
  			int rawdata;
  			fprintf(fd, "%lu %lu %d\n", w, h, bitspersample);
  			fprintf(fd, "[%lu 0 0 -%lu 0 %lu]\n", w, h, h);
! 			if (ascii85)
! 			    fprintf(fd, "currentfile /ASCII85Decode filter\n");
! 			else
! 			    fprintf(fd, "currentfile /ASCIIHexDecode filter\n");
  			fprintf(fd, "dup 6 1 roll\n");
  			rawdata = emitPSLevel2FilterFunction(fd, tif, w, h);
  			fprintf(fd, "{image flushfile flushfile} cvx exec\n");
***************
*** 391,397 ****
  				PSRawDataBW(fd, tif, w, h);
  			else
  				PSDataBW(fd, tif, w, h);
! 			putc('>', fd);
  		} else {
  			fprintf(fd, "/scanLine %d string def\n",ps_bytesperrow);
  			fprintf(fd, "%lu %lu %d\n", w, h, bitspersample);
--- 400,407 ----
  				PSRawDataBW(fd, tif, w, h);
  			else
  				PSDataBW(fd, tif, w, h);
! 			if (!ascii85)
! 			    putc('>', fd);
  		} else {
  			fprintf(fd, "/scanLine %d string def\n",ps_bytesperrow);
  			fprintf(fd, "%lu %lu %d\n", w, h, bitspersample);
***************
*** 607,612 ****
--- 617,716 ----
  	free((char *) tf_buf);
  }
  
+ 
+ static unsigned char   ascii85buf[10];
+ static int             ascii85count;
+ static int             ascii85breaklen;
+ 
+ static void Ascii85Init ()
+ {
+     ascii85breaklen = 75;
+     ascii85count = 0;
+ }
+ 
+ static char *Ascii85Encode (unsigned char *buf)
+ {
+     static char     retbuf[6];
+     unsigned long   word;
+ 
+     word = ((unsigned long) (((unsigned int) buf[0] << 8) + buf[1]) << 16)
+ 	    + (((unsigned int) buf[2] << 8) + buf[3]);
+ 
+     if (word == 0L)
+ 	retbuf[0] = 'z', retbuf[1] = 0;
+     else
+     {
+ 	unsigned long   q;
+ 	unsigned short  w1;
+ 
+ 	q = word / (85L*85*85*85);  /* actually only a byte */
+ 	retbuf[0] = q + '!';
+ 
+ 	word -= q * (85L*85*85*85); q = word / (85L*85*85);
+ 	retbuf[1] = q + '!';
+ 
+ 	word -= q * (85L*85*85); q = word / (85*85);
+ 	retbuf[2] = q + '!';
+ 
+ 	w1 = (unsigned short) (word - q * (85L*85));
+ 	retbuf[3] = (w1 / 85) + '!';
+ 	retbuf[4] = (w1 % 85) + '!';
+ 	retbuf[5] = 0;
+     }
+ 
+     return (retbuf);
+ }
+ 
+ 
+ static void Ascii85Put (unsigned char code, FILE *fd)
+ {
+     unsigned char       *p;
+     unsigned char       *cp;
+     int                 count;
+ 
+     ascii85buf[ascii85count++] = code;
+     if (ascii85count < 4)
+ 	return;
+ 
+     count = ascii85count;
+     p     = ascii85buf;
+ 
+     while (count >= 4)
+     {
+ 	for (cp = Ascii85Encode (p); *cp; cp++)
+ 	{
+ 	    fputc (*cp, fd);
+ 	    if ((ascii85breaklen -= 1) <= 0)
+ 	    {
+ 		fputc ('\n', fd);
+ 		ascii85breaklen = 75;
+ 	    }
+ 	}
+ 	count -= 4, p += 4;
+     }
+ 
+     memcpy (ascii85buf, p, count);
+     ascii85count = count;
+ }
+ 
+ static void Ascii85Exit (FILE *fd)
+ {
+     /*
+     **  Handle leftover bytes.  1 <= ascii85count <= 3.
+     */
+     if (ascii85count > 0)
+     {
+ 	char    *res;
+ 
+ 	memset (&ascii85buf[ascii85count], 0, 3);
+ 	res = Ascii85Encode (ascii85buf);
+ 	fputs (res[0] == 'z' ? "!!!!" : res, fd);
+     }
+     fputs ("~>\n", fd);
+ }
+ 
+ 
+ 
  void
  PSDataBW(FILE* fd, TIFF* tif, uint32 w, uint32 h)
  {
***************
*** 615,620 ****
--- 719,727 ----
  	unsigned char *tf_buf;
  	unsigned char *cp, c;
  
+ 	if (ascii85)
+ 	    Ascii85Init ();
+ 
  	tf_buf = (unsigned char *) malloc(tf_bytesperrow);
  	if (tf_buf == NULL) {
  		TIFFError(filename, "No space for scanline buffer");
***************
*** 624,639 ****
  		if (TIFFReadScanline(tif, tf_buf, row, 0) < 0)
  			break;
  		for (cp = tf_buf, cc = 0; cc < tf_bytesperrow; cc++) {
- 			DOBREAK(breaklen, 1, fd);
  			c = *cp++;
  			if (photometric == PHOTOMETRIC_MINISWHITE)
  				c = ~c;
! 			PUTHEX(c, fd);
  		}
  	}
  	free((char *) tf_buf);
  }
  
  void
  PSRawDataBW(FILE* fd, TIFF* tif, uint32 w, uint32 h)
  {
--- 731,757 ----
  		if (TIFFReadScanline(tif, tf_buf, row, 0) < 0)
  			break;
  		for (cp = tf_buf, cc = 0; cc < tf_bytesperrow; cc++) {
  			c = *cp++;
  			if (photometric == PHOTOMETRIC_MINISWHITE)
  				c = ~c;
! 			if (ascii85)
! 			{
! 			    Ascii85Put (c, fd);
! 			}
! 			else
! 			{
! 			    DOBREAK(breaklen, 1, fd);
! 			    PUTHEX(c, fd);
! 			}
  		}
  	}
  	free((char *) tf_buf);
+ 
+ 	if (ascii85)
+ 	    Ascii85Exit (fd);
  }
  
+ 
  void
  PSRawDataBW(FILE* fd, TIFF* tif, uint32 w, uint32 h)
  {
***************
*** 645,650 ****
--- 763,771 ----
  	unsigned char *cp, c;
  	tstrip_t s;
  
+ 	if (ascii85)
+ 	    Ascii85Init ();
+ 
  	TIFFGetField(tif, TIFFTAG_FILLORDER, &fillorder);
  	TIFFGetField(tif, TIFFTAG_STRIPBYTECOUNTS, &bc);
  	bufsize = bc[0];
***************
*** 672,681 ****
--- 793,812 ----
  		if (fillorder == FILLORDER_LSB2MSB)
  			TIFFReverseBits(tf_buf, cc);
  		for (cp = tf_buf; cc > 0; cc--) {
+ 		    if (ascii85)
+ 		    {
+ 			Ascii85Put (*cp++, fd);
+ 		    }
+ 		    else
+ 		    {
  			DOBREAK(breaklen, 1, fd);
  			c = *cp++;
  			PUTHEX(c, fd);
+ 		    }
  		}
  	}
  	free((char *) tf_buf);
+ 
+ 	if (ascii85)
+ 	    Ascii85Exit (fd);
  }