Fix for 687324, Group 4 Compression creates TIFFs with Reverse Bit Order

Alex Cherepanov <[email protected]> Sat, 26 Feb 2005 07:44:27 -0500
Newsgroups gmane.comp.printing.ghostscript.patches
Organization Coscript Software
Message-ID <[email protected]>
Add FillOrder device parameter to TIFF fax devices and document the
changes in Devices.htm .
Fix bug 687324

DETAILS :

This fix changes the default from FillOrder = 2 to FillOrder = 1.
According to the TIFF 6.0 specification, Section 8, page 32, support of
FillOrder = 2 is not required in a Baseline TIFF compliant reader.

Support of FillOrder will be addressed to tiffpack and tifflzw devices as
a part of bug 614298 resolution.

EXPECTED DIFFERENCES :

TIFF devices are not tested by the regression test.

_______________________________________________
gs-code-review mailing list
[email protected]
http://www.ghostscript.com/mailman/listinfo/gs-code-review
687324.diff (text/plain, 4.2 KB)
Index: gs/src/gdevtfax.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevtfax.c,v
retrieving revision 1.8
diff -b -u -r1.8 gdevtfax.c
--- gs/src/gdevtfax.c	12 Oct 2004 23:08:30 -0000	1.8
+++ gs/src/gdevtfax.c	26 Feb 2005 11:45:18 -0000
@@ -39,6 +39,8 @@
     gx_prn_device_common;
     gx_fax_device_common;
     long MaxStripSize;		/* 0 = no limit, other is UNCOMPRESSED limit */
+                                /* The type and range of FillOrder follows TIFF 6 spec  */
+    int  FillOrder;             /* 1 = lowest column in the high-order bit, 2 = reverse */
     gdev_tiff_state tiff;	/* for TIFF output only */
 };
 typedef struct gx_device_tfax_s gx_device_tfax;
@@ -51,7 +53,8 @@
 #define TFAX_DEVICE(dname, print_page)\
 {\
     FAX_DEVICE_BODY(gx_device_tfax, gdev_tfax_std_procs, dname, print_page),\
-    0				/* unlimited strip size byte count */\
+    0				/* unlimited strip size byte count */,\
+    1                           /* lowest column in the high-order bit */\
 }
 
 const gx_device_tfax gs_tiffcrle_device =
@@ -76,6 +79,8 @@
 
     if ((code = param_write_long(plist, "MaxStripSize", &tfdev->MaxStripSize)) < 0)
         ecode = code;
+    if ((code = param_write_int(plist, "FillOrder", &tfdev->FillOrder)) < 0)
+        ecode = code;
     return ecode;
 }
 private int
@@ -85,6 +90,7 @@
     int ecode = 0;
     int code;
     long mss = tfdev->MaxStripSize;
+    int fill_order = tfdev->FillOrder;
     const char *param_name;
 
     switch (code = param_read_long(plist, (param_name = "MaxStripSize"), &mss)) {
@@ -104,6 +110,19 @@
 	    break;
     }
 
+    /* Following TIFF spec, FillOrder is integer */ 
+    switch (code = param_read_int(plist, (param_name = "FillOrder"), &fill_order)) {
+        case 0:
+	    if (fill_order == 1 || fill_order == 2)
+	        break;
+	    code = gs_error_rangecheck;
+	default:
+	    ecode = code;
+	    param_signal_error(plist, param_name, ecode);
+	case 1:
+	    break;
+    }
+
     if (ecode < 0)
 	return ecode;
     code = gdev_fax_put_params(dev, plist);
@@ -111,6 +130,7 @@
 	return code;
 
     tfdev->MaxStripSize = mss;
+    tfdev->FillOrder = fill_order;
     return code;
 }
 
@@ -210,7 +230,7 @@
     {TIFFTAG_BitsPerSample, TIFF_SHORT, 1, 1},
     {TIFFTAG_Compression, TIFF_SHORT, 1, Compression_CCITT_T4},
     {TIFFTAG_Photometric, TIFF_SHORT, 1, Photometric_min_is_white},
-    {TIFFTAG_FillOrder, TIFF_SHORT, 1, FillOrder_LSB2MSB},
+    {TIFFTAG_FillOrder, TIFF_SHORT, 1, FillOrder_MSB2LSB},
     {TIFFTAG_SamplesPerPixel, TIFF_SHORT, 1, 1},
     {TIFFTAG_T4Options, TIFF_LONG, 1, 0},
 	/* { TIFFTAG_CleanFaxData,      TIFF_SHORT, 1, CleanFaxData_clean }, */
@@ -228,8 +248,9 @@
     gx_device_tfax *const tfdev = (gx_device_tfax *)dev;
     int code;
 
+    pdir->FillOrder.value = tfdev->FillOrder;
     tfax_begin_page(tfdev, prn_stream, pdir, pstate->Columns);
-    pstate->FirstBitLowOrder = true;	/* decoders prefer this */
+    pstate->FirstBitLowOrder = tfdev->FillOrder == 2;
     code = gdev_fax_print_page_stripped(dev, prn_stream, pstate, tfdev->tiff.rows);
     gdev_tiff_end_page(&tfdev->tiff, prn_stream);
     return code;
Index: gs/doc/Devices.htm
===================================================================
RCS file: /cvs/ghostscript/gs/doc/Devices.htm,v
retrieving revision 1.84
diff -b -u -r1.84 Devices.htm
--- gs/doc/Devices.htm	10 Dec 2004 23:28:54 -0000	1.84
+++ gs/doc/Devices.htm	26 Feb 2005 11:45:18 -0000
@@ -464,6 +464,22 @@
 If the value of MaxStripSize is 0 (the default), then the entire image will
 be a single strip.
 
+<p>
+Since v. 8.51 the logical order of bits within a byte, FillOrder, tag = 266 is
+controlled by a parameter:
+
+<blockquote>
+<dl>
+<dt><b><tt>-dFillOrder=</tt><em>1 | 2 </em></b> (default = 1)
+<dd>If this option set to 2 then pixels are arranged within a byte such that pixels
+with lower column values are stored in the lower-order bits of the byte; otherwise
+pixels are arranged in reverse order.
+</dl></blockquote>
+
+Earlier versions of Ghostscript always generated TIFF files with FillOrder = 2.
+According to the TIFF 6.0 specification, Section 8, page 32, support of
+FillOrder = 2 is not required in a Baseline TIFF compliant reader
+
 <h3><a name="fax"></a>FAX</h3>
 
 <p>