Re: DSC parser updates

Ray Johnston <[email protected]>
Newsgroups gmane.comp.printing.ghostscript.patches
Organization Artifex Software Inc.
Message-ID <[email protected]>
Russell,

Even though we are officially in code freeze for 8.11, I think that
the risk of this doing serious harm is slight, and it would be nice
to have this in 8.11.

Please commit.

Regards,
Ray
_____________________________________________________________________

Russell Lang wrote:

> Ray,
> 
> The following changes are not expected to impact any current use 
> of the DSC parser by Ghostscript.  This patch is simply to keep 
> the DSC parser in sync with GSview.  I recently added the 
> ability to add/remove PICT previews from EPS files.
> 
> Log Message:
> 
> Update DSC parser to latest version from GSview.
> 
> DETAILS:
> Recognise MacBinary or AppleSingle files and process the data
> fork only, similar to DOS EPS files.
> Handle DCS2 files that contravene the spec by putting the TIFF
> preview between the composite and the separations.
> Recognise CMYK and RGB names if separations are renamed using
> epstool.
> 
> Russell Lang                   [email protected]
> Ghostgum Software Pty Ltd      http://www.ghostgum.com.au/
> 
> 
> 
> 
> 
> ------------------------------------------------------------------------
> 
> --- gs/src/dscparse.h	2003-01-22 18:51:31.000000000 +1100
> +++ gsview/src/dscparse.h	2003-08-09 09:58:14.000000000 +1000
> @@ -272,6 +273,14 @@
>      GSWORD checksum;
>  } CDSCDOSEPS;
>  
> +/* macbinary header */
> +typedef struct CDSCMACBIN_S {
> +    GSDWORD data_begin;		/* EPS */
> +    GSDWORD data_length;
> +    GSDWORD resource_begin;	/* PICT */
> +    GSDWORD resource_length;
> +} CDSCMACBIN;
> +
>  /* rather than allocated every string with malloc, we allocate
>   * chunks of 4k and place the (usually) short strings in these
>   * chunks.
> @@ -316,11 +325,11 @@
>      char *name;
>      CDSC_COLOUR_TYPE type;
>      CDSC_CUSTOM_COLOUR custom;
> -    /* If custom is CDSC_COLOUR_RGB, the next three are correct */
> +    /* If custom is CDSC_CUSTOM_COLOUR_RGB, the next three are correct */
>      float red;
>      float green;
>      float blue;
> -    /* If colourtype is CDSC_COLOUR_CMYK, the next four are correct */
> +    /* If colourtype is CDSC_CUSTOM_COLOUR_CMYK, the next four are correct */
>      float cyan;
>      float magenta;
>      float yellow;
> @@ -488,6 +497,10 @@
>      /* private data */
>      /* Added 2002-03-30 */
>      int ref_count;
> +
> +    /* public data */
> +    /* Added 2003-07-15 */
> +    CDSCMACBIN *macbin;		/* Mac Binary header */
>  };
>  
>  
> --- gs/src/dscparse.c	2003-01-22 18:51:31.000000000 +1100
> +++ gsview/src/dscparse.c	2003-08-09 09:58:14.000000000 +1000
> @@ -85,12 +86,15 @@
>  dsc_private void dsc_section_join(DSC_OFFSET begin, DSC_OFFSET *pend, DSC_OFFSET **pplast);
>  dsc_private int dsc_read_line(CDSC *dsc);
>  dsc_private int dsc_read_doseps(CDSC *dsc);
> +dsc_private int dsc_read_macbin(CDSC *dsc);
>  dsc_private char * dsc_alloc_string(CDSC *dsc, const char *str, int len);
>  dsc_private char * dsc_add_line(CDSC *dsc, const char *line, unsigned int len);
>  dsc_private char * dsc_copy_string(char *str, unsigned int slen, 
>      char *line, unsigned int len, unsigned int *offset);
>  dsc_private GSDWORD dsc_get_dword(const unsigned char *buf);
>  dsc_private GSWORD dsc_get_word(const unsigned char *buf);
> +dsc_private GSDWORD dsc_get_bigendian_dword(const unsigned char *buf);
> +dsc_private GSWORD dsc_get_bigendian_word(const unsigned char *buf);
>  dsc_private int dsc_get_int(const char *line, unsigned int len, unsigned int *offset);
>  dsc_private float dsc_get_real(const char *line, unsigned int len, 
>      unsigned int *offset);
> @@ -357,7 +361,9 @@
>  	    }
>  	    if (dsc->doseps_end && 
>  		(dsc->data_offset + dsc->data_index > dsc->doseps_end)) {
> -		/* have read past end of DOS EPS PostScript section */
> +		/* have read past end of DOS EPS or Mac Binary 
> +		 * PostScript section
> +		 */
>  		return CDSC_OK;	/* ignore */
>  	    }
>  	    if (dsc->eof)
> @@ -955,6 +961,10 @@
>  	}
>  	dsc->colours = NULL;
>      }
> +
> +    if (dsc->macbin)
> +	dsc_memfree(dsc, dsc->macbin);
> +    dsc->macbin = NULL;
>  }
>  
>  /* 
> @@ -1214,7 +1224,7 @@
>      return FALSE;
>  }
>  
> -
> +/* Get little-endian DWORD, used for DOS EPS files */
>  dsc_private GSDWORD
>  dsc_get_dword(const unsigned char *buf)
>  {
> @@ -1235,6 +1245,27 @@
>      return w;
>  }
>  
> +/* Get big-endian DWORD, used for Mac Binary files */
> +dsc_private GSDWORD
> +dsc_get_bigendian_dword(const unsigned char *buf)
> +{
> +    GSDWORD dw;
> +    dw = (GSDWORD)buf[3];
> +    dw += ((GSDWORD)buf[2])<<8;
> +    dw += ((GSDWORD)buf[1])<<16;
> +    dw += ((GSDWORD)buf[0])<<24;
> +    return dw;
> +}
> +
> +dsc_private GSWORD
> +dsc_get_bigendian_word(const unsigned char *buf)
> +{
> +    GSWORD w;
> +    w = (GSWORD)buf[1];
> +    w |= (GSWORD)(buf[0]<<8);
> +    return w;
> +}
> +
>  dsc_private int
>  dsc_read_doseps(CDSC *dsc)
>  {
> @@ -1279,6 +1310,97 @@
>  }
>  
>  
> +dsc_private int
> +dsc_read_macbin(CDSC *dsc)
> +{
> +    unsigned char *line = (unsigned char *)dsc->line;
> +    if ((dsc->macbin = 
> +	(CDSCMACBIN *)dsc_memalloc(dsc, sizeof(CDSCMACBIN))) == NULL)
> +	return CDSC_ERROR;	/* no memory */
> +	
> +    dsc->macbin->data_begin = 128;
> +    dsc->macbin->data_length = dsc_get_bigendian_dword(line+83);
> +    dsc->macbin->resource_begin = 
> +	(dsc->macbin->data_begin + dsc->macbin->data_length + 127 ) & ~127;
> +    dsc->macbin->resource_length = dsc_get_bigendian_dword(line+87);
> +
> +    if (dsc->file_length && 
> +	(((dsc->macbin->resource_begin + dsc->macbin->resource_length 
> +	  + 127) & ~127) > dsc->file_length)) {
> +	return CDSC_ERROR;
> +    }
> +
> +    dsc->doseps_end = dsc->macbin->data_begin + dsc->macbin->data_length;
> +
> +    /* move data_index to byte after Mac Binary header */
> +    dsc->data_index -= dsc->line_length - 128;
> +    /* we haven't read a line of PostScript code yet */
> +    dsc->line_count = 0;
> +
> +    dsc->preview = CDSC_PICT;
> +
> +    return CDSC_OK;
> +}
> +
> +
> +dsc_private int
> +dsc_read_applesingle(CDSC *dsc)
> +{
> +    GSDWORD EntryID;
> +    GSDWORD Offset;
> +    GSDWORD Length;
> +    GSWORD entries;
> +    int index;
> +    int header;
> +    int i;
> +
> +    unsigned char *line = (unsigned char *)dsc->line;
> +    if ((dsc->macbin = 
> +	(CDSCMACBIN *)dsc_memalloc(dsc, sizeof(CDSCMACBIN))) == NULL)
> +	return CDSC_ERROR;	/* no memory */
> +    entries = dsc_get_bigendian_word(line+24);
> +    for (i=0; i<(int)entries; i++) {
> +	index = 26 + i * 12;
> +	EntryID = dsc_get_bigendian_dword(line+index);
> +	Offset = dsc_get_bigendian_dword(line+index+4);
> +	Length = dsc_get_bigendian_dword(line+index+8);
> +	if (EntryID == 1) {
> +	    /* data fork */
> +	    dsc->macbin->data_begin = Offset;
> +	    dsc->macbin->data_length = Length;
> +	}
> +	else if (EntryID == 2) {
> +	    /* resource fork */
> +	    dsc->macbin->resource_begin = Offset;
> +	    dsc->macbin->resource_length = Length;
> +	}
> +    }
> +	
> +    if (dsc->file_length && 
> +	(dsc->macbin->resource_begin + dsc->macbin->resource_length
> +	  > dsc->file_length)) {
> +	return CDSC_ERROR;
> +    }
> +    if (dsc->file_length && 
> +	(dsc->macbin->data_begin + dsc->macbin->data_length 
> +	  > dsc->file_length)) {
> +	return CDSC_ERROR;
> +    }
> +
> +    dsc->doseps_end = dsc->macbin->data_begin + dsc->macbin->data_length;
> +
> +    header = 26 + entries * 12;
> +    /* move data_index to byte after AppleSingle/AppleDouble header */
> +    dsc->data_index -= dsc->line_length - header;
> +    /* we haven't read a line of PostScript code yet */
> +    dsc->line_count = 0;
> +    /* skip from current position to start of PostScript section */
> +    dsc->skip_bytes = dsc->macbin->data_begin - header;
> +
> +    dsc->preview = CDSC_PICT;
> +
> +    return CDSC_OK;
> +}
>  
>  dsc_private int 
>  dsc_parse_pages(CDSC *dsc)
> @@ -1950,8 +2072,15 @@
>  	}
>      }
>  
> +    if ((line[0]==0x0) && (length < 2))
> +	return CDSC_NEEDMORE;	/* Could be Mac Binary EPSF */
> +    if ((line[0]==0x0) && (line[1] >= 1) && (line[1] <= 63) && (length < 128))
> +	return CDSC_NEEDMORE;	/* Could be Mac Binary EPSF */
> +    if ((line[0]==0x0) && (line[1] == 0x5) && (length < 4))
> +	return CDSC_NEEDMORE;	/* Could be Mac AppleSingle/AppleDouble */
>      if ((line[0]==0xc5) && (length < 4))
> -	return CDSC_NEEDMORE;
> +	return CDSC_NEEDMORE;	/* Could be DOS EPS */
> +
>      if ((line[0]==0xc5) && (line[1]==0xd0) && 
>  	 (line[2]==0xd3) && (line[3]==0xc6) ) {
>  	/* id is "EPSF" with bit 7 set */
> @@ -1962,6 +2091,33 @@
>  	if (dsc_read_doseps(dsc))
>  	    return CDSC_ERROR;
>      }
> +    else if ((line[0]==0x0) && (line[1]==0x05) && 
> +	 (line[2]==0x16) && ((line[3]==0x0) || (line[3] == 0x07))) {
> +	/* Mac AppleSingle or AppleDouble */
> +	GSDWORD version;
> +	GSWORD entries;
> +	if (length < 26)
> +	    return CDSC_NEEDMORE;
> +	version = dsc_get_bigendian_dword(line+4);
> +	entries = dsc_get_bigendian_word(line+24);
> +	if ((version == 0x00010000) || (version == 0x00020000)) {
> +	    if (length < (int)(26 + entries * 12))
> +		return CDSC_NEEDMORE;
> +	    dsc->line = (char *)line;
> +	    if (dsc_read_applesingle(dsc))
> +		return CDSC_ERROR;
> +	}
> +    }
> +    else if ((line[0]==0x0) && 
> +	(line[1] >= 1) && (line[1] <= 63) && 
> +        (line[74]==0x0) && 
> +        (line[65]=='E') && (line[66]=='P') && 
> +        (line[67]=='S') && (line[68]=='F')) {
> +	/* Mac Binary EPSF */
> +	dsc->line = (char *)line;
> +	if (dsc_read_macbin(dsc))
> +	    return CDSC_ERROR;
> +    }
>      else {
>  	if (length < 2)
>  	    return CDSC_NEEDMORE;
> @@ -2860,7 +3016,7 @@
>  	    if (dsc->file_length) {
>  		if ((!dsc->doseps && 
>  			((DSC_END(dsc) + 32768) < dsc->file_length)) ||
> -		     ((dsc->doseps) && 
> +		     ((dsc->doseps_end) && 
>  			((DSC_END(dsc) + 32768) < dsc->doseps_end))) {
>  		    int rc = dsc_error(dsc, CDSC_MESSAGE_EARLY_TRAILER, 
>  			dsc->line, dsc->line_length);
> @@ -2897,7 +3053,7 @@
>  		dsc->page[dsc->page_count-1].end = DSC_START(dsc);
>  	    if (dsc->file_length) {
>  		if ((DSC_END(dsc)+100 < dsc->file_length) ||
> -		    (dsc->doseps && (DSC_END(dsc) + 100 < dsc->doseps_end))) {
> +		  (dsc->doseps_end && (DSC_END(dsc) + 100 < dsc->doseps_end))) {
>  		    int rc = dsc_error(dsc, CDSC_MESSAGE_EARLY_EOF, 
>  			dsc->line, dsc->line_length);
>  		    switch (rc) {
> @@ -3722,6 +3878,17 @@
>  	/* end of composite is start of first separation */
>  	if (end != 0)
>  	    *pend = end;
> +	/* According to the DCS2 specification, the size of the composite 
> +	 * section can be determined by the smallest #offset.
> +	 * Some incorrect DCS2 files don't put the separations inside
> +	 * the DOS EPS PostScript section, and have a TIFF separation
> +	 * between the composite and the first separation.  This
> +	 * contravenes the DCS2 specification.  If we see one of these 
> + 	 * files, bring the end of the composite back to the end of 
> +	 * the DOS EPS PostScript section.
> +	 */
> +	if (dsc->doseps_end && (*pend > dsc->doseps_end))
> +	    *pend = dsc->doseps_end;
>      }
>      return 0;
>  }
> @@ -4009,6 +4176,41 @@
>  		    }
>  		}
>  	        pcolour->type = CDSC_COLOUR_PROCESS;
> +		if (dsc_stricmp(colourname, "Cyan")==0) {
> +		    pcolour->custom = CDSC_CUSTOM_COLOUR_CMYK;
> +		    pcolour->cyan = 1.0;
> +		    pcolour->magenta = pcolour->yellow = pcolour->black = 0.0;
> +		}
> +		else if (dsc_stricmp(colourname, "Magenta")==0) {
> +		    pcolour->custom = CDSC_CUSTOM_COLOUR_CMYK;
> +		    pcolour->magenta = 1.0;
> +		    pcolour->cyan = pcolour->yellow = pcolour->black = 0.0;
> +		}
> +		else if (dsc_stricmp(colourname, "Yellow")==0) {
> +		    pcolour->custom = CDSC_CUSTOM_COLOUR_CMYK;
> +		    pcolour->yellow = 1.0;
> +		    pcolour->cyan = pcolour->magenta = pcolour->black = 0.0;
> +		}
> +		else if (dsc_stricmp(colourname, "Black")==0) {
> +		    pcolour->custom = CDSC_CUSTOM_COLOUR_CMYK;
> +		    pcolour->black = 1.0;
> +		    pcolour->cyan = pcolour->magenta = pcolour->yellow = 0.0;
> +		}
> +		else if (dsc_stricmp(colourname, "Red")==0) {
> +		    pcolour->custom = CDSC_CUSTOM_COLOUR_RGB;
> +		    pcolour->red = 1.0;
> +		    pcolour->green = pcolour->blue = 0.0;
> +		}
> +		else if (dsc_stricmp(colourname, "Green")==0) {
> +		    pcolour->custom = CDSC_CUSTOM_COLOUR_RGB;
> +		    pcolour->green = 1.0;
> +		    pcolour->red = pcolour->blue = 0.0;
> +		}
> +		else if (dsc_stricmp(colourname, "Blue")==0) {
> +		    pcolour->custom = CDSC_CUSTOM_COLOUR_RGB;
> +		    pcolour->blue = 1.0;
> +		    pcolour->red = pcolour->green = 0.0;
> +		}
>  	    }
>  	} while (i != 0);
>      }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.