Fix for 687718 The tiffsep device fails when the size of gx_color_index is 32 bits

"Dan Coby" <[email protected]> Wed, 29 Sep 2004 15:19:59 -0700
Newsgroups gmane.comp.printing.ghostscript.patches
Message-ID <[email protected]>
Fix for 687718 The tiffsep device fails when the size of gx_color_index is 32 bits

DETAILS:

The comments on bug 687705 "Compile of 8.31 fails on OS/2" point out that the 
tiffsep device fails during device initialization if the size of 
gx_color_index is 32 bits.

This is due to a recent change which made the default number of components for 
this device equal to 8.  This works if the size of gx_color_index is 64 bits.  
But it fails with 32 bits.

This fix changes the default number of components for this device to be
based upon the size of gx_color_index.  It also changes the psdcmyk device
to use the same logic for its default number of components.

This fix also includes changes to doc/Drivers.htm which explains that the number
of components will differ based upon the size of gx_color_index (and a link
giving more details on gx_color_index).  More information about the parameters
for the tiffsep device is given including an example command line.


Dan

_______________________________________________
gs-code-review mailing list
[email protected]
http://www.ghostscript.com/mailman/listinfo/gs-code-review
tiffsep.txt (text/plain, 14.2 KB)
Index: src/gdevtsep.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevtsep.c,v
retrieving revision 1.4
diff -u -r1.4 gdevtsep.c
--- src/gdevtsep.c	20 Sep 2004 21:42:12 -0000	1.4
+++ src/gdevtsep.c	29 Sep 2004 21:29:22 -0000
@@ -381,18 +381,24 @@
 	{ 0 }			/* separation files */
 
 /*
+ * Select the default number of components based upon the number of bits
+ * that we have in a gx_color_index
+ */
+#define NC ((sizeof(gx_color_index) <= 8) ? sizeof(gx_color_index) : 8)
+
+/*
  * TIFF device with CMYK process color model and spot color support.
  */
 private const gx_device_procs spot_cmyk_procs = device_procs;
 
 const tiffsep_device gs_tiffsep_device =
 {   
-    tiffsep_device_body(spot_cmyk_procs, "tiffsep", 8, GX_CINFO_POLARITY_SUBTRACTIVE, 64, MAX_COLOR_VALUE, MAX_COLOR_VALUE, "DeviceCMYK"),
+    tiffsep_device_body(spot_cmyk_procs, "tiffsep", NC, GX_CINFO_POLARITY_SUBTRACTIVE, NC * 8, MAX_COLOR_VALUE, MAX_COLOR_VALUE, "DeviceCMYK"),
     /* devn_params specific parameters */
-    { 8,	/* Bits per color - must match ncomp, depth, etc. above */
+    { 8,		/* Bits per color - must match ncomp, depth, etc. above */
       DeviceCMYKComponents,	/* Names of color model colorants */
       4,			/* Number colorants for CMYK */
-      8,			/* MaxSeparations:  our current limit is 8 bytes */
+      NC,			/* MaxSeparations:  our current limit is 8 bytes */
       {0},			/* SeparationNames */
       {0},			/* SeparationOrder names */
       {0, 1, 2, 3, 4, 5, 6, 7 }	/* Initial component SeparationOrder */
@@ -400,6 +406,8 @@
     { true },			/* equivalent CMYK colors for spot colors */
 };
 
+#undef NC
+
 /*
  * The following procedures are used to map the standard color spaces into
  * the color components for the tiffsep device.
Index: src/gdevpsd.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevpsd.c,v
retrieving revision 1.17
diff -u -r1.17 gdevpsd.c
--- src/gdevpsd.c	15 Sep 2004 11:46:41 -0000	1.17
+++ src/gdevpsd.c	29 Sep 2004 21:29:23 -0000
@@ -245,6 +245,12 @@
 };
 
 /*
+ * Select the default number of components based upon the number of bits
+ * that we have in a gx_color_index
+ */
+#define NC ((sizeof(gx_color_index) <= 8) ? sizeof(gx_color_index) : 8)
+
+/*
  * PSD device with CMYK process color model and spot color support.
  */
 private const gx_device_procs spot_cmyk_procs
@@ -252,7 +258,7 @@
 
 const psd_device gs_psdcmyk_device =
 {   
-    psd_device_body(spot_cmyk_procs, "psdcmyk", 4, GX_CINFO_POLARITY_SUBTRACTIVE, 32, 255, 255, "DeviceCMYK"),
+    psd_device_body(spot_cmyk_procs, "psdcmyk", NC, GX_CINFO_POLARITY_SUBTRACTIVE, NC * 8, 255, 255, "DeviceCMYK"),
     /* devn_params specific parameters */
     { 8,	/* Bits per color - must match ncomp, depth, etc. above */
       DeviceCMYKComponents,	/* Names of color model colorants */
@@ -267,6 +273,8 @@
     psd_DEVICE_CMYK,		/* Color model */
 };
 
+#undef NC
+
 /*
  * The following procedures are used to map the standard color spaces into
  * the color components for the psdrgb device.
Index: doc/Drivers.htm
===================================================================
RCS file: /cvs/ghostscript/gs/doc/Drivers.htm,v
retrieving revision 1.48
diff -u -r1.48 Drivers.htm
--- doc/Drivers.htm	28 Aug 2004 21:52:56 -0000	1.48
+++ doc/Drivers.htm	29 Sep 2004 21:29:26 -0000
@@ -2002,7 +2002,7 @@
 It fills a triangle with a linearly varying color.
 Arguments specify 3 points in the device space - vertices of a triangle, and their colors.
 The colors are represented as vectors of positive fractional numbers, each of which
-represents a color component value in the interval <b><tt>[0,1]</b></tt>.
+represents a color component value in the interval <b><tt>[0,1]</tt></b>.
 The number of components in a vector in the number of color
 components in the device (process) color model.
 <dd>
@@ -2016,37 +2016,37 @@
 paint any pixel. In this case the graphics library will perform a subdivision of the area
 into smaller triangles and call the function again with smaller areas.
 <dd>
-<b><em>Important note :</b></em> Do not try to decompose the area within
+<b><em>Important note :</em></b> Do not try to decompose the area within
 the implementation of <b><tt> fill_linear_color_triangle </tt></b>, because
 it can break the plane coverage contiguity and cause a dropout.
 Instead that request graphics library to perform the decomposition.
 The graphics libary is smart enough to do that properly.
 <dd>
-<b><em>Important note :</b></em>
+<b><em>Important note :</em></b>
 The implementation must handle a special case, when only 2 colors are specified.
-It happens if <b><tt>p3</b></tt> one is <b><tt>NULL</b></tt>. 
+It happens if <b><tt>p3</tt></b> one is <b><tt>NULL</tt></b>. 
 This means that the color does not depend on the X coordinate,
 i.e. it forms a linear gradient along the Y axis.
 The implementation must not reject (return 0) such cases.
 <dd>
-<b><em>Important note :</b></em>The device color component
+<b><em>Important note :</em></b>The device color component
 value 1 may be represented with several hexadecimal values :
-<b><tt>0x7FFF0000</b></tt>, <b><tt>0x7FFFF000</b></tt>, <b><tt>0x7FFFFF00</b></tt>, etc.,
+<b><tt>0x7FFF0000</tt></b>, <b><tt>0x7FFFF000</tt></b>, <b><tt>0x7FFFFF00</tt></b>, etc.,
 because the precision here exceeds the color precision of the device.
-To convert a <b><tt>frac31</b></tt> value into a device color component value,
+To convert a <b><tt>frac31</tt></b> value into a device color component value,
 fist drop (ignore) the sign bit, then drop least significant bits -
 so many ones as you need to fit the device color precision.
 <dd>
-<b><em>Important note :</b></em> The <b><tt>fa</b></tt> argument may contain
-the <b><tt>swap_axes</b></tt> bit set. In this case the implementation must swap (transpoze)
-<b><tt>X</b></tt> and <b><tt>Y</b></tt> axes.
-<dd>
-<b><em>Important note :</b></em> The implementation must not paint outside the
-clipping rectangle specified in the <b><tt>fa</b></tt> argument.
-If <b><tt>fa->swap_axes</b></tt> is true, the clipping rectangle is transposed.
+<b><em>Important note :</em></b> The <b><tt>fa</tt></b> argument may contain
+the <b><tt>swap_axes</tt></b> bit set. In this case the implementation must swap (transpoze)
+<b><tt>X</tt></b> and <b><tt>Y</tt></b> axes.
+<dd>
+<b><em>Important note :</em></b> The implementation must not paint outside the
+clipping rectangle specified in the <b><tt>fa</tt></b> argument.
+If <b><tt>fa->swap_axes</tt></b> is true, the clipping rectangle is transposed.
 <dd>
-See <b><tt> gx_default_fill_linear_color_triangle </b></tt>
-in <b><tt>gdevddrw.c</b></tt> as a sample code.
+See <b><tt> gx_default_fill_linear_color_triangle </tt></b>
+in <b><tt>gdevddrw.c</tt></b> as a sample code.
 </dl>
 
 
@@ -2067,7 +2067,7 @@
 <dd>
 Rather the prototype can specify a bilinear color,
 we assume that the implementation handles linear colors only.
-This means that the implementation can ignore any of <b><tt> c0, c1, c2, c3 </b></tt>.
+This means that the implementation can ignore any of <b><tt> c0, c1, c2, c3 </tt></b>.
 The graphics library takes a special care of the color linearity 
 when calling this function. The reason for passing all 4 color arguments
 is to avoid color precision problems.
@@ -2076,8 +2076,8 @@
 this function may be called with only 2 colors, and may reject too comple areas.
 All those important notes are applicable here.
 <dd>
-A sample code may be found in in <b><tt>gxdtfill.h</b></tt>, rather it's a kind of complicated.
-A linear color function is generated from it as <b><tt> gx_fill_trapezoid_ns_lc </b></tt>
+A sample code may be found in in <b><tt>gxdtfill.h</tt></b>, rather it's a kind of complicated.
+A linear color function is generated from it as <b><tt> gx_fill_trapezoid_ns_lc </tt></b>
 with the following template parametres :
 
 <pre>
@@ -2088,10 +2088,10 @@
 #define SWAP_AXES 0
 #define FILL_DIRECT 1
 </pre>
-See the helplers <b><tt>init_gradient</b></tt>,
-<b><tt>step_gradient</b></tt> (defined in in <b><tt>gdevddrw.c</b></tt>), how to manage colors.
-See <b><tt>check_gradient_overflow</b></tt>
-(defined in in <b><tt>gdevddrw.c</b></tt>), as an example of an area
+See the helplers <b><tt>init_gradient</tt></b>,
+<b><tt>step_gradient</tt></b> (defined in in <b><tt>gdevddrw.c</tt></b>), how to manage colors.
+See <b><tt>check_gradient_overflow</tt></b>
+(defined in in <b><tt>gdevddrw.c</tt></b>), as an example of an area
 that can't be painted paint in a single action due to 64-bits fixed overflows.
 
 </dl>
@@ -2114,41 +2114,41 @@
 <b><tt> fill_linear_color_trapezoid </tt></b> by own means,
 this function may be left unimplemented.
 <dd>
-<b><tt>i</b></tt> and <b><tt>j</b></tt> specify device coordinates (indices)
-of the starting pixel of the scanline, <b><tt>w</b></tt> specifies the 
+<b><tt>i</tt></b> and <b><tt>j</tt></b> specify device coordinates (indices)
+of the starting pixel of the scanline, <b><tt>w</tt></b> specifies the 
 width of the scanline, i.e. the number of pixels to be painted to the right from
 the starting pixel, including the starting pixel.
 <dd>
-<b><tt>c0</b></tt> specifies the color for the starting pixel
+<b><tt>c0</tt></b> specifies the color for the starting pixel
 as a vector of fraction values, each of which represents 
-a color value in the interval <b><tt>[0,1]</b></tt>.
+a color value in the interval <b><tt>[0,1]</tt></b>.
 <dd>
-<b><tt>c0_f</b></tt> specify a fraction part of the color for the starting pixel.
+<b><tt>c0_f</tt></b> specify a fraction part of the color for the starting pixel.
 See the formula below about using it.
 <dd>
-<b><tt>cg_num</b></tt> specify a numerator for the color gradient -
-a vector of values in <b><tt>[-1,1]</b></tt>, each of which correspond to a color component.
+<b><tt>cg_num</tt></b> specify a numerator for the color gradient -
+a vector of values in <b><tt>[-1,1]</tt></b>, each of which correspond to a color component.
 <dd>
-<b><tt>cg_den</b></tt> specify the denominator for the color gradient -
-a vector of values in <b><tt>[-1,1]</b></tt>, each of which correspond to a color component.
+<b><tt>cg_den</tt></b> specify the denominator for the color gradient -
+a vector of values in <b><tt>[-1,1]</tt></b>, each of which correspond to a color component.
 <dd>
-The color for the pixel <b><tt>[i + k, j]</b></tt> to be computed like this :
+The color for the pixel <b><tt>[i + k, j]</tt></b> to be computed like this :
 <pre><b><tt>
          (double)(c0[n] + (c0_f[n] + cg_num[n] * k) / cg_den) / (1 ^ 31 - 1)
-</b></tt></pre>
-<dd>where <b><tt>0 <= k <= w </b></tt>, and <b><tt>n</b></tt> is a device color component index.
+</tt></b></pre>
+<dd>where <b><tt>0 <= k <= w </tt></b>, and <b><tt>n</tt></b> is a device color component index.
 
 <dd>
-<b><em>Important note :</b></em> The <b><tt>fa</b></tt> argument may contain
-the <b><tt>swap_axes</b></tt> bit set. In this case the implementation must swap (transpose)
-<b><tt>X</b></tt> and <b><tt>Y</b></tt> axes.
+<b><em>Important note :</em></b> The <b><tt>fa</tt></b> argument may contain
+the <b><tt>swap_axes</tt></b> bit set. In this case the implementation must swap (transpose)
+<b><tt>X</tt></b> and <b><tt>Y</tt></b> axes.
 <dd>
-<b><em>Important note :</b></em> The implementation must not paint outside the
-clipping rectangle specified in the <b><tt>fa</b></tt> argument.
-If <b><tt>fa->swap_axes</b></tt> is true, the clipping rectangle is transposed.
+<b><em>Important note :</em></b> The implementation must not paint outside the
+clipping rectangle specified in the <b><tt>fa</tt></b> argument.
+If <b><tt>fa->swap_axes</tt></b> is true, the clipping rectangle is transposed.
 <dd>
-See <b><tt> gx_default_fill_linear_color_scanline</b></tt>
-in <b><tt>gdevdsha.c</b></tt> as a sample code.
+See <b><tt> gx_default_fill_linear_color_scanline</tt></b>
+in <b><tt>gdevdsha.c</tt></b> as a sample code.
 </dl>
 
 
@@ -2727,23 +2727,23 @@
 <h4><a name="Unicode"></a>Unicode support for high level devices</h4>
 
 <p>
-<p>Implementing a new high level device, one may need to translate <b><tt>Postscript</b></tt>
-character codes into <b><tt>Unicode</b></tt>. This can be done pretty simply.
+<p>Implementing a new high level device, one may need to translate <b><tt>Postscript</tt></b>
+character codes into <b><tt>Unicode</tt></b>. This can be done pretty simply.
 
-<p>For translating a <b><tt>Postscript</b></tt> text you need to inplement the device
-virtual function <b><tt>text_begin</b></tt>. It should create a new instance of
-<b><tt>gs_text_enum_t</b></tt> in the heap (let its pointer be <b><tt>pte</b></tt>),
-and assign a special function to <b><tt>gs_text_enum_t::procs.process</b></tt>.
-The function will receive <b><tt>pte</b></tt>. It should take the top level font from
-<b><tt>pte->orig_font</b></tt>,
-and iterate with <b><tt>font->procs.next_char_glyph(pte, ..., &glyph)</b></tt>.
-The last argument receives a <b><tt>gs_glyph</b></tt> value, which encodes a
-<b><tt>Postscript</b></tt> character name or CID (and also stores it into
-<b><tt>pte->returned.current_glyph</b></tt>).
-Then obtain the current subfont with <b><tt>gs_text_current_font(pte)</b></tt>
+<p>For translating a <b><tt>Postscript</tt></b> text you need to inplement the device
+virtual function <b><tt>text_begin</tt></b>. It should create a new instance of
+<b><tt>gs_text_enum_t</tt></b> in the heap (let its pointer be <b><tt>pte</tt></b>),
+and assign a special function to <b><tt>gs_text_enum_t::procs.process</tt></b>.
+The function will receive <b><tt>pte</tt></b>. It should take the top level font from
+<b><tt>pte->orig_font</tt></b>,
+and iterate with <b><tt>font->procs.next_char_glyph(pte, ..., &glyph)</tt></b>.
+The last argument receives a <b><tt>gs_glyph</tt></b> value, which encodes a
+<b><tt>Postscript</tt></b> character name or CID (and also stores it into
+<b><tt>pte->returned.current_glyph</tt></b>).
+Then obtain the current subfont with <b><tt>gs_text_current_font(pte)</tt></b>
 (it can differ from the font)
-and call <b><tt>subfont->procs.decode_glyph(subfont, glyph)</b></tt>.
-The return value will be an <b><tt>Unicode</b></tt> code, or <b><tt>GS_NO_CHAR</b></tt>
+and call <b><tt>subfont->procs.decode_glyph(subfont, glyph)</tt></b>.
+The return value will be an <b><tt>Unicode</tt></b> code, or <b><tt>GS_NO_CHAR</tt></b>
 if the glyph can't be translated to Unicode.
 
 <h3><a name="Reading_bits_back"></a>Reading bits back</h3>