[Gs-code-review] Better PCL Mode 2 Compression

Scott Marovich marovich at hpmarov.hpl.hp.com
Fri Feb 15 15:34:27 PST 2002


I think that I might have found a small opportunity for further optimization in
the way "gdev_pcl_mode2compress_padded()" (file "gdevpcl.c") does TIFF-style
("packbits") compression for HP DeskJet and LaserJet PCL.  This subroutine
currently encodes up to 127 literal or repeated bytes in each PCL command, but
PCL allows up to 128 bytes per command, permitting a slight reduction in output-
file length.  I tried the following change on some older DeskJets available to
me, and it seems to work fine; did someone once discover a model for which this
doesn't work, or does the current code simply represent an oversight or
misunderstanding?  At any rate, here's my suggested change for whatever it might
be worth.
--
Scott Marovich               Hewlett-Packard Laboratories M/S 1198
E-mail: marovich at hpl.hp.com  P.O. Box 10490 (1501 Page Mill Road)
HP TELNET 857-2998           Palo Alto CA 94303-0971 U.S.A.
Tel. (650)857-2998           FAX (650)857-7724

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*** gdevpcl.c.orig	Sat Jul 14 23:38:38 2001
--- gdevpcl.c	Sat Jul 14 23:38:38 2001
***************
*** 124,135 ****
  /*
   * Mode 2 Row compression routine for the HP DeskJet & LaserJet IIp.
   * Compresses data from row up to end_row, storing the result
   * starting at compressed.  Returns the number of bytes stored.
!  * Runs of K<=127 literal bytes are encoded as K-1 followed by
!  * the bytes; runs of 2<=K<=127 identical bytes are encoded as
   * 257-K followed by the byte.
!  * In the worst case, the result is N+(N/127)+1 bytes long,
   * where N is the original byte count (end_row - row).
   * To speed up the search, we examine an entire word at a time.
   * We will miss a few blocks of identical bytes; tant pis.
   */
--- 124,135 ----
  /*
   * Mode 2 Row compression routine for the HP DeskJet & LaserJet IIp.
   * Compresses data from row up to end_row, storing the result
   * starting at compressed.  Returns the number of bytes stored.
!  * Runs of K<=128 literal bytes are encoded as K-1 followed by
!  * the bytes; runs of 2<=K<=128 identical bytes are encoded as
   * 257-K followed by the byte.
!  * In the worst case, the result is N+(N/128)+1 bytes long,
   * where N is the original byte count (end_row - row).
   * To speed up the search, we examine an entire word at a time.
   * We will miss a few blocks of identical bytes; tant pis.
   */
***************
*** 185,193 ****
  	/* Now [compr..end_dis) should be encoded as dissimilar, */
  	/* and [end_dis..next) should be encoded as similar. */
  	/* Note that either of these ranges may be empty. */
  
! 	for (;;) {		/* Encode up to 127 dissimilar bytes */
  	    uint count = end_dis - compr;	/* uint for faster switch */
  
  	    switch (count) {	/* Use memcpy only if it's worthwhile. */
  		case 6:
--- 185,193 ----
  	/* Now [compr..end_dis) should be encoded as dissimilar, */
  	/* and [end_dis..next) should be encoded as similar. */
  	/* Note that either of these ranges may be empty. */
  
! 	for (;;) {		/* Encode up to 128 dissimilar bytes */
  	    uint count = end_dis - compr;	/* uint for faster switch */
  
  	    switch (count) {	/* Use memcpy only if it's worthwhile. */
  		case 6:
***************
*** 206,215 ****
  		    cptr += count + 1;
  		case 0:	/* all done */
  		    break;
  		default:
! 		    if (count > 127)
! 			count = 127;
  		    *cptr++ = count - 1;
  		    memcpy(cptr, compr, count);
  		    cptr += count, compr += count;
  		    continue;
--- 206,215 ----
  		    cptr += count + 1;
  		case 0:	/* all done */
  		    break;
  		default:
! 		    if (count > 128)
! 			count = 128;
  		    *cptr++ = count - 1;
  		    memcpy(cptr, compr, count);
  		    cptr += count, compr += count;
  		    continue;
***************
*** 216,234 ****
  	    }
  	    break;
  	}
  
! 	{			/* Encode up to 127 similar bytes. */
! 	    /* Note that count may be <0 at end of row. */
  	    int count = (const byte *)next - end_dis;
  
! 	    while (count > 0) {
! 		int this = (count > 127 ? 127 : count);
  
  		*cptr++ = 257 - this;
  		*cptr++ = (byte) test;
  		count -= this;
  	    }
  	    exam = next;
  	}
      }
      return (cptr - compressed);
--- 216,236 ----
  	    }
  	    break;
  	}
  
! 	{			/* Encode similar bytes. */
  	    int count = (const byte *)next - end_dis;
  
! 	    while (count > 1) { /* Encode 2-128 similar bytes. */
! 		int this;
  
+ 		if ((this = count) > 128) this = 128;
  		*cptr++ = 257 - this;
  		*cptr++ = (byte) test;
  		count -= this;
  	    }
+ 	    /* If there's 1 byte left over, encode as "dissimilar" repetition */
+ 	    if (count) { *cptr++ = 0; *cptr++ = (byte) test; }
  	    exam = next;
  	}
      }
      return (cptr - compressed);
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



More information about the gs-code-review mailing list