[gs-commits] rev 11862 - in trunk/gs: base doc

robin at ghostscript.com robin at ghostscript.com
Wed Oct 27 19:48:02 UTC 2010


Author: robin
Date: 2010-10-27 19:48:01 +0000 (Wed, 27 Oct 2010)
New Revision: 11862

Modified:
   trunk/gs/base/gdevfax.c
   trunk/gs/base/gdevfax.h
   trunk/gs/base/gdevtfax.c
   trunk/gs/base/gdevtfnx.c
   trunk/gs/base/gdevtifs.c
   trunk/gs/base/gdevtifs.h
   trunk/gs/base/gdevtsep.c
   trunk/gs/base/minftrsz.c
   trunk/gs/base/minftrsz.h
   trunk/gs/doc/Devices.htm
Log:
Add new version of tiffscaled device, that supports -dMinFeatureSize=2.
(Solves bug 691718).

Also add support for AdjustWidth in tiffscaled device.

Also update documentation.

No expected differences.



Modified: trunk/gs/base/gdevfax.c
===================================================================
--- trunk/gs/base/gdevfax.c	2010-10-27 12:45:49 UTC (rev 11861)
+++ trunk/gs/base/gdevfax.c	2010-10-27 19:48:01 UTC (rev 11862)
@@ -110,20 +110,6 @@
     return code;
 }
 
-int
-gdev_fax_adjusted_width(int width)
-{
-    /* Adjust the page width to a legal value for fax systems. */
-    if (width >= 1680 && width <= 1736)
-        /* Adjust width for A4 paper. */
-        return 1728;
-    else if (width >= 2000 && width <= 2056)
-        /* Adjust width for B4 paper. */
-        return 2048;
-    else
-        return width;
-}
-
 /* Initialize the stream state with a set of default parameters. */
 /* These select the same defaults as the CCITTFaxEncode filter, */
 /* except we set BlackIs1 = true. */
@@ -137,7 +123,7 @@
     ss->Rows = fdev->height;
     ss->BlackIs1 = true;
     if (adjust_width > 0)
-        ss->Columns = gdev_fax_adjusted_width(ss->Columns);
+        ss->Columns = fax_adjusted_width(ss->Columns);
 }
 
 void

Modified: trunk/gs/base/gdevfax.h
===================================================================
--- trunk/gs/base/gdevfax.h	2010-10-27 12:45:49 UTC (rev 11861)
+++ trunk/gs/base/gdevfax.h	2010-10-27 19:48:01 UTC (rev 11862)
@@ -49,7 +49,6 @@
 extern const gx_device_procs gdev_fax_std_procs;
 
 /* Other procedures */
-int gdev_fax_adjusted_width(int width);
 void gdev_fax_init_state(stream_CFE_state *ss, const gx_device_fax *fdev);
 void gdev_fax_init_fax_state(stream_CFE_state *ss,
 			     const gx_device_fax *fdev);

Modified: trunk/gs/base/gdevtfax.c
===================================================================
--- trunk/gs/base/gdevtfax.c	2010-10-27 12:45:49 UTC (rev 11861)
+++ trunk/gs/base/gdevtfax.c	2010-10-27 19:48:01 UTC (rev 11862)
@@ -246,7 +246,7 @@
 
 
 /* Forward references */
-static int tfax_begin_page(gx_device_tfax * tfdev, FILE * file, int width);
+static int tfax_begin_page(gx_device_tfax * tfdev, FILE * file);
 
 static void
 tfax_set_fields(gx_device_tfax *tfdev)
@@ -269,9 +269,7 @@
 {
     gx_device_tfax *tfdev = (gx_device_tfax *)dev;
 
-    tfax_begin_page(tfdev, prn_stream,
-                    (tfdev->AdjustWidth > 0 ?
-                     gdev_fax_adjusted_width(dev->width) : dev->width));
+    tfax_begin_page(tfdev, prn_stream);
 
     tfax_set_fields(tfdev);
 
@@ -283,9 +281,7 @@
 {
     gx_device_tfax *tfdev = (gx_device_tfax *)dev;
 
-    tfax_begin_page(tfdev, prn_stream,
-                    (tfdev->AdjustWidth > 0 ?
-                     gdev_fax_adjusted_width(dev->width) : dev->width));
+    tfax_begin_page(tfdev, prn_stream);
 
     tfax_set_fields(tfdev);
     if (tfdev->Compression == COMPRESSION_CCITTFAX3)
@@ -299,9 +295,7 @@
 {
     gx_device_tfax *tfdev = (gx_device_tfax *)dev;
 
-    tfax_begin_page(tfdev, prn_stream,
-                    (tfdev->AdjustWidth > 0 ?
-                     gdev_fax_adjusted_width(dev->width) : dev->width));
+    tfax_begin_page(tfdev, prn_stream);
 
     tfax_set_fields(tfdev);
     if (tfdev->Compression == COMPRESSION_CCITTFAX3)
@@ -315,9 +309,7 @@
 {
     gx_device_tfax *tfdev = (gx_device_tfax *)dev;
 
-    tfax_begin_page(tfdev, prn_stream,
-                    (tfdev->AdjustWidth > 0 ?
-                     gdev_fax_adjusted_width(dev->width) : dev->width));
+    tfax_begin_page(tfdev, prn_stream);
 
     tfax_set_fields(tfdev);
     if (tfdev->Compression == COMPRESSION_CCITTFAX4)
@@ -332,9 +324,7 @@
 {
     gx_device_tfax *const tfdev = (gx_device_tfax *)dev;
 
-    tfax_begin_page(tfdev, prn_stream,
-                    (tfdev->AdjustWidth > 0 ?
-                     gdev_fax_adjusted_width(dev->width) : dev->width));
+    tfax_begin_page(tfdev, prn_stream);
     tfax_set_fields(tfdev);
     TIFFSetField(tfdev->tif, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB);
 
@@ -347,9 +337,7 @@
 {
     gx_device_tfax *const tfdev = (gx_device_tfax *)dev;
 
-    tfax_begin_page(tfdev, prn_stream,
-                    (tfdev->AdjustWidth > 0 ?
-                     gdev_fax_adjusted_width(dev->width) : dev->width));
+    tfax_begin_page(tfdev, prn_stream);
     tfax_set_fields(tfdev);
     TIFFSetField(tfdev->tif, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB);
 
@@ -358,11 +346,9 @@
 
 /* Begin a TIFF fax page. */
 static int
-tfax_begin_page(gx_device_tfax * tfdev, FILE * file, int width)
+tfax_begin_page(gx_device_tfax * tfdev, FILE * file)
 {
     gx_device_printer *const pdev = (gx_device_printer *)tfdev;
-    /* Patch the width to reflect fax page width adjustment. */
-    int save_width = tfdev->width;
     int code;
 
     /* open the TIFF device */
@@ -372,8 +358,6 @@
 	    return_error(gs_error_invalidfileaccess);
     }
 
-    tfdev->width = width;
-    code = tiff_set_fields_for_printer(pdev, tfdev->tif, 1);
-    tfdev->width = save_width;
+    code = tiff_set_fields_for_printer(pdev, tfdev->tif, 1, tfdev->AdjustWidth);
     return code;
 }

Modified: trunk/gs/base/gdevtfnx.c
===================================================================
--- trunk/gs/base/gdevtfnx.c	2010-10-27 12:45:49 UTC (rev 11861)
+++ trunk/gs/base/gdevtfnx.c	2010-10-27 19:48:01 UTC (rev 11862)
@@ -50,7 +50,9 @@
     arch_is_big_endian          /* default to native endian (i.e. use big endian iff the platform is so*/,
     COMPRESSION_NONE,
     TIFF_DEFAULT_STRIP_SIZE,
-    TIFF_DEFAULT_DOWNSCALE
+    TIFF_DEFAULT_DOWNSCALE,
+    0, /* Adjust size */
+    1  /* MinFeatureSize */
 };
 
 const gx_device_tiff gs_tiff24nc_device = {
@@ -62,7 +64,9 @@
     arch_is_big_endian          /* default to native endian (i.e. use big endian iff the platform is so*/,
     COMPRESSION_NONE,
     TIFF_DEFAULT_STRIP_SIZE,
-    TIFF_DEFAULT_DOWNSCALE
+    TIFF_DEFAULT_DOWNSCALE,
+    0, /* Adjust size */
+    1  /* MinFeatureSize */
 };
 
 const gx_device_tiff gs_tiff48nc_device = {
@@ -74,7 +78,9 @@
     arch_is_big_endian          /* default to native endian (i.e. use big endian iff the platform is so*/,
     COMPRESSION_NONE,
     TIFF_DEFAULT_STRIP_SIZE,
-    TIFF_DEFAULT_DOWNSCALE
+    TIFF_DEFAULT_DOWNSCALE,
+    0, /* Adjust size */
+    1  /* MinFeatureSize */
 };
 
 /* ------ Private functions ------ */

Modified: trunk/gs/base/gdevtifs.c
===================================================================
--- trunk/gs/base/gdevtifs.c	2010-10-27 12:45:49 UTC (rev 11861)
+++ trunk/gs/base/gdevtifs.c	2010-10-27 19:48:01 UTC (rev 11862)
@@ -123,6 +123,10 @@
     }
     if ((code = param_write_long(plist, "MaxStripSize", &tfdev->MaxStripSize)) < 0)
         ecode = code;
+    if ((code = param_write_long(plist, "AdjustWidth", &tfdev->AdjustWidth)) < 0)
+        ecode = code;
+    if ((code = param_write_long(plist, "MinFeatureSize", &tfdev->MinFeatureSize)) < 0)
+        ecode = code;
     return ecode;
 }
 
@@ -150,6 +154,8 @@
     gs_param_string comprstr;
     long downscale = tfdev->DownScaleFactor;
     long mss = tfdev->MaxStripSize;
+    long aw = tfdev->AdjustWidth;
+    long mfs = tfdev->MinFeatureSize;
 
     /* Read BigEndian option as bool */
     switch (code = param_read_bool(plist, (param_name = "BigEndian"), &big_endian)) {
@@ -164,7 +170,7 @@
     switch (code = param_read_string(plist, (param_name = "Compression"), &comprstr)) {
         case 0:
             if ((ecode = tiff_compression_id(&compr, &comprstr)) < 0 ||
-                !tiff_compression_allowed(compr, dev->color_info.depth))
+                !tiff_compression_allowed(compr, (which & 1 ? 1 : dev->color_info.depth)))
                 param_signal_error(plist, param_name, ecode);
             break;
         case 1:
@@ -205,6 +211,28 @@
         case 1:
             break;
     }
+    switch (code = param_read_long(plist, (param_name = "AdjustWidth"), &aw)) {
+        case 0:
+            if (aw != 0)
+                aw = 1;
+            break;
+        default:
+            ecode = code;
+            param_signal_error(plist, param_name, ecode);
+        case 1:
+            break;
+    }
+    switch (code = param_read_long(plist, (param_name = "MinFeatureSize"), &mfs)) {
+        case 0:
+            if ((mfs >= 0) && (mfs <= 4))
+                break;
+            code = gs_error_rangecheck;
+        default:
+            ecode = code;
+            param_signal_error(plist, param_name, ecode);
+        case 1:
+            break;
+    }
 
     if (ecode < 0)
         return ecode;
@@ -216,6 +244,8 @@
     tfdev->Compression = compr;
     tfdev->MaxStripSize = mss;
     tfdev->DownScaleFactor = downscale;
+    tfdev->AdjustWidth = aw;
+    tfdev->MinFeatureSize = mfs;
     return code;
 }
 
@@ -260,7 +290,8 @@
             return_error(gs_error_invalidfileaccess);
     }
 
-    return tiff_set_fields_for_printer(pdev, tfdev->tif, tfdev->DownScaleFactor);
+    return tiff_set_fields_for_printer(pdev, tfdev->tif, tfdev->DownScaleFactor,
+                                       tfdev->AdjustWidth);
 }
 
 int tiff_set_compression(gx_device_printer *pdev,
@@ -286,9 +317,13 @@
 
 int tiff_set_fields_for_printer(gx_device_printer *pdev,
                                 TIFF              *tif,
-                                int                factor)
+                                int                factor,
+                                int                adjustWidth)
 {
-    TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, (pdev->width + factor-1)/factor);
+    int width = (pdev->width + factor-1)/factor;
+    if (adjustWidth)
+        width = fax_adjusted_width(width);
+    TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
     TIFFSetField(tif, TIFFTAG_IMAGELENGTH, (pdev->height + factor-1)/factor);
     TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
     TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
@@ -399,14 +434,29 @@
  * moving left to right we read from entries 2->width+1 (inclusive), and
  * write to 1->width. When moving right to left we read from width->1 and
  * write to width+1->2.
+ *
+ * Minimum feature size data is stored in the mfs_data block.
+ * We have 1 extra entry at the end to avoid overflow. When moving left to
+ * right we read from entries 1->width (inclusive), and write to 0->width-1.
+ * When moving right to left we read from width-1->0 and write to width->1.
  */
+
+enum {
+    mfs_clear           = 0,
+    mfs_force_off       = 1,
+    mfs_above_is_0      = 2,
+    mfs_above_left_is_0 = 4,
+};
+
 static void down_and_out(TIFF *tif,
                          byte *data,
                          int   max_size,
                          int   factor,
                          int   row,
                          int   width,
-                         int  *errors)
+                         int  *errors,
+                         byte *mfs_data,
+                         int   padWhite)
 {
     int x, xx, y, value;
     byte *outp;
@@ -416,9 +466,21 @@
     const int threshold = factor*factor*128;
     const int max_value = factor*factor*255;
 
+    if (padWhite)
+    {
+        outp = data + (width - padWhite)*factor;
+        for (y = factor; y > 0; y--)
+        {
+            memset(outp, 0xFF, padWhite*factor);
+            outp += max_size;
+        }
+    }
+
+    if (mfs_data == NULL)
+    {
     if ((row & 1) == 0)
     {
-        /* Left to Right pass */
+            /* Left to Right pass (no min feature size) */
         const int back = max_size * factor -1;
         errors += 2;
         outp = inp;
@@ -455,7 +517,7 @@
     }
     else
     {
-        /* Right to Left pass */
+            /* Right to Left pass (no min feature size) */
         const int back = max_size * factor + 1;
         errors += width;
         inp += width*factor-1;
@@ -491,6 +553,139 @@
         }
         outp++;
     }
+    }
+    else
+    {
+        if ((row & 1) == 0)
+        {
+            /* Left to Right pass (with min feature size = 2) */
+            const int back = max_size * factor -1;
+            byte mfs, force_forward = 0;
+            errors += 2;
+            outp = inp;
+            *mfs_data++ = mfs_clear;
+            for (x = width; x > 0; x--)
+            {
+                value = e_forward + *errors;
+                for (xx = factor; xx > 0; xx--)
+                {
+                    for (y = factor; y > 0; y--)
+                    {
+                        value += *inp;
+                        inp += max_size;
+                    }
+                    inp -= back;
+                }
+                mfs = *mfs_data;
+                *mfs_data++ = mfs_clear;
+                if ((mfs & mfs_force_off) || force_forward)
+                {
+                    /* We are being forced to be 0 */
+                    *outp++ = 0;
+                    force_forward = 0;
+                }
+                else if (value < threshold)
+                {
+                    /* We want to be 0 anyway */
+                    *outp++ = 0;
+                    if ((mfs & (mfs_above_is_0 | mfs_above_left_is_0))
+                            != (mfs_above_is_0 | mfs_above_left_is_0))
+                    {
+                        /* We aren't in a group anyway, so must force other
+                         * pixels. */
+                        mfs_data[-2] |= mfs_force_off;
+                        mfs_data[-1] |= mfs_force_off;
+                        force_forward = 1;
+                    }
+                    else
+                    {
+                        /* No forcing, but we need to tell other pixels that
+                         * we were 0. */
+                        mfs_data[-2] |= mfs_above_is_0;
+                        mfs_data[-1] |= mfs_above_left_is_0;
+                    }
+                }
+                else
+                {
+                    *outp++ = 1;
+                    value -= max_value;
+                }
+                e_forward  = value * 7/16;
+                e_downleft = value * 3/16;
+                e_down     = value * 5/16;
+                value     -= e_forward + e_downleft + e_down;
+                errors[-2] += e_downleft;
+                errors[-1] += e_down;
+                *errors++   = value;
+            }
+            outp -= width;
+        }
+        else
+        {
+            /* Right to Left pass (with min feature size = 2) */
+            const int back = max_size * factor + 1;
+            byte mfs, force_forward = 0;
+            errors += width;
+            mfs_data += width;
+            inp += width*factor-1;
+            outp = inp;
+            *mfs_data-- = 0;
+            for (x = width; x > 0; x--)
+            {
+                value = e_forward + *errors;
+                for (xx = factor; xx > 0; xx--)
+                {
+                    for (y = factor; y > 0; y--)
+                    {
+                        value += *inp;
+                        inp += max_size;
+                    }
+                    inp -= back;
+                }
+                mfs = *mfs_data;
+                *mfs_data-- = mfs_clear;
+                if ((mfs & mfs_force_off) || force_forward)
+                {
+                    /* We are being forced to be 0 */
+                    *outp-- = 0;
+                    force_forward = 0;
+                }
+                else if (value < threshold)
+                {
+                    *outp-- = 0;
+                    if ((mfs & (mfs_above_is_0 | mfs_above_left_is_0))
+                            != (mfs_above_is_0 | mfs_above_left_is_0))
+                    {
+                        /* We aren't in a group anyway, so must force other
+                         * pixels. */
+                        mfs_data[1] |= mfs_force_off;
+                        mfs_data[2] |= mfs_force_off;
+                        force_forward = 1;
+                    }
+                    else
+                    {
+                        /* No forcing, but we need to tell other pixels that
+                         * we were 0. */
+                        mfs_data[1] |= mfs_above_is_0;
+                        mfs_data[2] |= mfs_above_left_is_0;
+                    }
+                }
+                else
+                {
+                    *outp-- = 1;
+                    value -= max_value;
+                }
+                e_forward  = value * 7/16;
+                e_downleft = value * 3/16;
+                e_down     = value * 5/16;
+                value     -= e_forward + e_downleft + e_down;
+                errors[2] += e_downleft;
+                errors[1] += e_down;
+                *errors--   = value;
+            }
+            outp++;
+        }
+    }
     /* Now pack the data pointed to by outp into byte form */
     data = inp = outp;
     outp--;
@@ -514,17 +709,29 @@
 /* Special version, called with 8 bit grey input to be downsampled to 1bpp
  * output. */
 int
-tiff_downscale_and_print_page(gx_device_printer *dev, TIFF *tif, int factor)
+tiff_downscale_and_print_page(gx_device_printer *dev, TIFF *tif, int factor,
+                              int mfs, int aw)
 {
     int code = 0;
-    byte *data;
-    int *errors;
+    byte *data = NULL;
+    byte *mfs_data = NULL;
+    int *errors = NULL;
     int size = gdev_mem_bytes_per_scan_line((gx_device *)dev);
-    int max_size = max(size, TIFFScanlineSize(tif)) + factor-1;
+    int max_size;
     int row;
     int n;
     int width = (dev->width + factor-1)/factor;
+    int awidth = width;
+    int padWhite;
 
+    if (aw > 0)
+        awidth = fax_adjusted_width(awidth);
+    padWhite = awidth - width;
+    if (padWhite < 0)
+        padWhite = 0;
+
+    max_size = max(size + padWhite*factor, TIFFScanlineSize(tif)) + factor-1;
+
     data = gs_alloc_bytes(dev->memory,
                           max_size * factor,
                           "tiff_print_page(data)");
@@ -532,18 +739,32 @@
         return_error(gs_error_VMerror);
 
     errors = (int *)gs_alloc_bytes(dev->memory,
-                                   (width+3) * sizeof(int),
+                                   (awidth+3) * sizeof(int),
                                    "tiff_print_page(errors)");
     if (errors == NULL)
     {
-        gs_free_object(dev->memory, data, "tiff_print_page(data)");
-        return_error(gs_error_VMerror);
+        code = gs_note_error(gs_error_VMerror);
+        goto cleanup;
     }
+    if (mfs > 1) {
+        mfs = 2;
+        mfs_data = (byte *)gs_alloc_bytes(dev->memory,
+                                          (awidth+1),
+                                          "tiff_print_page(mfs)");
+        if (mfs_data == NULL)
+        {
+            code = gs_note_error(gs_error_VMerror);
+            goto cleanup;
+        }
+    } else
+        mfs = 1;
 
     TIFFCheckpointDirectory(tif);
 
-    memset(data, 0, max_size * factor);
-    memset(errors, 0, (width+3) * sizeof(int));
+    memset(data, 0xFF, max_size * factor);
+    memset(errors, 0, (awidth+3) * sizeof(int));
+    if (mfs_data)
+        memset(mfs_data, 0, awidth+1);
     n = 0;
     for (row = 0; row < dev->height; row++) {
         code = gdev_prn_copy_scan_lines(dev, row, data + max_size*n, size);
@@ -554,7 +775,8 @@
         {
             /* Do the downsample */
             n = 0;
-            down_and_out(tif, data, max_size, factor, row/factor, width, errors);
+            down_and_out(tif, data, max_size, factor, row/factor, awidth,
+                         errors, mfs_data, padWhite);
         }
     }
     if (n != 0)
@@ -562,17 +784,20 @@
         row--;
         while (n != factor)
         {
-            memset(data + max_size * n, 0, max_size);
+            memset(data + max_size * n, 0xFF, max_size);
             n++;
             row++;
         }
-        down_and_out(tif, data, max_size, factor, row/factor, width, errors);
+        down_and_out(tif, data, max_size, factor, row/factor, awidth, errors,
+                     mfs_data, padWhite);
     }
 
+    TIFFWriteDirectory(tif);
+cleanup:
+    gs_free_object(dev->memory, mfs_data, "tiff_print_page(mfs)");
     gs_free_object(dev->memory, errors, "tiff_print_page(errors)");
     gs_free_object(dev->memory, data, "tiff_print_page(data)");
 
-    TIFFWriteDirectory(tif);
     return code;
 }
 

Modified: trunk/gs/base/gdevtifs.h
===================================================================
--- trunk/gs/base/gdevtifs.h	2010-10-27 12:45:49 UTC (rev 11861)
+++ trunk/gs/base/gdevtifs.h	2010-10-27 19:48:01 UTC (rev 11862)
@@ -31,6 +31,8 @@
     uint16 Compression;		/* same values as TIFFTAG_COMPRESSION */
     long MaxStripSize;
     long DownScaleFactor;
+    long AdjustWidth;            /* 0 = no adjust, 1 = adjust to fax values */
+    long MinFeatureSize;         /* < 2 == no darkening */
     TIFF *tif;			/* TIFF file opened on gx_device_common.file */
 } gx_device_tiff;
 
@@ -49,7 +51,8 @@
 
 int tiff_print_page(gx_device_printer *dev, TIFF *tif, int min_feature_size);
 
-int tiff_downscale_and_print_page(gx_device_printer *dev, TIFF *tif, int factor);
+int tiff_downscale_and_print_page(gx_device_printer *dev, TIFF *tif,
+                                  int factor, int msf, int aw);
 
 /*
  * Sets the compression tag for TIFF and updates the rows_per_strip tag to
@@ -64,7 +67,8 @@
 			 uint compression,
 			 long max_strip_size);
 
-int tiff_set_fields_for_printer(gx_device_printer *pdev, TIFF *tif, int factor);
+int tiff_set_fields_for_printer(gx_device_printer *pdev, TIFF *tif, int factor,
+                                int adjustWidth);
 
 int gdev_tiff_begin_page(gx_device_tiff *tfdev, FILE *file);
 

Modified: trunk/gs/base/gdevtsep.c
===================================================================
--- trunk/gs/base/gdevtsep.c	2010-10-27 12:45:49 UTC (rev 11861)
+++ trunk/gs/base/gdevtsep.c	2010-10-27 19:48:01 UTC (rev 11862)
@@ -62,7 +62,9 @@
     arch_is_big_endian          /* default to native endian (i.e. use big endian iff the platform is so*/,
     COMPRESSION_NONE,
     TIFF_DEFAULT_STRIP_SIZE,
-    TIFF_DEFAULT_DOWNSCALE
+    TIFF_DEFAULT_DOWNSCALE,
+    0, /* Adjust size */
+    1  /* MinFeatureSize */
 };
 
 /* ------ The tiffscaled device ------ */
@@ -92,7 +94,9 @@
     arch_is_big_endian,/* default to native endian (i.e. use big endian iff the platform is so */
     COMPRESSION_NONE,
     TIFF_DEFAULT_STRIP_SIZE,
-    TIFF_DEFAULT_DOWNSCALE
+    TIFF_DEFAULT_DOWNSCALE,
+    0, /* Adjust size */
+    1  /* MinFeatureSize */
 };
 
 
@@ -145,7 +149,10 @@
 
     tiff_set_gray_fields(pdev, tfdev->tif, 1, tfdev->Compression, tfdev->MaxStripSize);
 
-    return tiff_downscale_and_print_page(pdev, tfdev->tif, tfdev->DownScaleFactor);
+    return tiff_downscale_and_print_page(pdev, tfdev->tif,
+                                         tfdev->DownScaleFactor,
+                                         tfdev->MinFeatureSize,
+                                         tfdev->AdjustWidth);
 }
 
 /* ------ The cmyk devices ------ */
@@ -173,7 +180,9 @@
     arch_is_big_endian          /* default to native endian (i.e. use big endian iff the platform is so*/,
     COMPRESSION_NONE,
     TIFF_DEFAULT_STRIP_SIZE,
-    TIFF_DEFAULT_DOWNSCALE
+    TIFF_DEFAULT_DOWNSCALE,
+    0, /* Adjust size */
+    1  /* MinFeatureSize */
 };
 
 /* 16-bit-per-plane separated CMYK color. */
@@ -191,7 +200,9 @@
     arch_is_big_endian          /* default to native endian (i.e. use big endian iff the platform is so*/,
     COMPRESSION_NONE,
     TIFF_DEFAULT_STRIP_SIZE,
-    TIFF_DEFAULT_DOWNSCALE
+    TIFF_DEFAULT_DOWNSCALE,
+    0, /* Adjust size */
+    1  /* MinFeatureSize */
 };
 
 /* ------ Private functions ------ */
@@ -1423,7 +1434,7 @@
         if (!tfdev->tiff_comp)
             return_error(gs_error_invalidfileaccess);
     }
-    code = tiff_set_fields_for_printer(pdev, tfdev->tiff_comp, 1);
+    code = tiff_set_fields_for_printer(pdev, tfdev->tiff_comp, 1, 0);
     tiff_set_cmyk_fields(pdev, tfdev->tiff_comp, 8, COMPRESSION_NONE, tfdev->MaxStripSize);
     pdev->color_info.depth = save_depth;
     if (code < 0)
@@ -1465,7 +1476,7 @@
         if (pdev->height > (max_long - ftell(file))/(pdev->width)) /* note width is never 0 in print_page */
             return_error(gs_error_rangecheck);  /* this will overflow max_long */
 
-        code = tiff_set_fields_for_printer(pdev, tfdev->tiff[comp_num], 1);
+        code = tiff_set_fields_for_printer(pdev, tfdev->tiff[comp_num], 1, 0);
         tiff_set_gray_fields(pdev, tfdev->tiff[comp_num], 8, tfdev->Compression, tfdev->MaxStripSize);
         pdev->color_info.depth = save_depth;
         if (code < 0)
@@ -1638,7 +1649,7 @@
         }
 
         pdev->color_info.depth = 8;     /* Create files for 8 bit gray */
-        code = tiff_set_fields_for_printer(pdev, tfdev->tiff[comp_num], 1);
+        code = tiff_set_fields_for_printer(pdev, tfdev->tiff[comp_num], 1, 0);
         tiff_set_gray_fields(pdev, tfdev->tiff[comp_num], 1, tfdev->Compression, tfdev->MaxStripSize);
         pdev->color_info.depth = save_depth;
         if (code < 0)

Modified: trunk/gs/base/minftrsz.c
===================================================================
--- trunk/gs/base/minftrsz.c	2010-10-27 12:45:49 UTC (rev 11861)
+++ trunk/gs/base/minftrsz.c	2010-10-27 19:48:01 UTC (rev 11862)
@@ -333,3 +333,18 @@
     }
     return count_out;
 }
+
+int
+fax_adjusted_width(int width)
+{
+    /* Adjust the page width to a legal value for fax systems. */
+    if (width >= 1680 && width <= 1736)
+        /* Adjust width for A4 paper. */
+        return 1728;
+    else if (width >= 2000 && width <= 2056)
+        /* Adjust width for B4 paper. */
+        return 2048;
+    else
+        return width;
+}
+

Modified: trunk/gs/base/minftrsz.h
===================================================================
--- trunk/gs/base/minftrsz.h	2010-10-27 12:45:49 UTC (rev 11861)
+++ trunk/gs/base/minftrsz.h	2010-10-27 19:48:01 UTC (rev 11862)
@@ -25,4 +25,6 @@
 
 int min_feature_size_process(byte *line, void *min_feature_data);
 
+int fax_adjusted_width(int width);
+
 #endif /* minftrsz_INCLUDED */

Modified: trunk/gs/doc/Devices.htm
===================================================================
--- trunk/gs/doc/Devices.htm	2010-10-27 12:45:49 UTC (rev 11861)
+++ trunk/gs/doc/Devices.htm	2010-10-27 19:48:01 UTC (rev 11862)
@@ -531,8 +531,7 @@
 <code>tiffsep1</code> device.
 
 <p>
-The black-and-white TIFF drivers (not including <tt>tiffscaled</tt>) also
-provide the following parameters:
+The black-and-white TIFF devices also provide the following parameters:
 
 <blockquote><dl>
 <dt><code>-dAdjustWidth=<em>state</em></code> (0 or 1; default = 1)
@@ -540,10 +539,13 @@
 of either 1680..1736 or 2000..2056 columns, set the page width to A4
 (1728 columns) or B4 (2048 columns) respectively.
 This behavior is the default for all the fax based devices (i.e. all the black
-and white devices except <tt>tifflzw</tt> and <tt>tiffpack</tt>). Pass
-<tt>-dAdjustWidth=0</tt> to force this behaviour off, and
-<tt>-dAdjustWidth=1</tt> to force it on.
+and white devices except <tt>tifflzw</tt>, <tt>tiffpack</tt> and
+<tt>tiffscaled</tt>). Pass <tt>-dAdjustWidth=0</tt> to force this behaviour
+off, and <tt>-dAdjustWidth=1</tt> to force it on.
 
+<dd>When using this option with <tt>tiffscaled</tt> it is the downsampled size
+that triggers the adjustment.
+
 <dt><code>-dMinFeatureSize=<em>state</em></code> (0 to 4; default = 1)
 <dd>This option allows a minimum feature size to be set; if any output pixel
 appears on its own, or as part of a group of pixels smaller than
@@ -556,6 +558,11 @@
 as specified. 3 and 4 currently expand pixels correctly horizontally, but
 only expand vertically to the 2 pixel size.
 
+<dd>The mechanism by which <tt>MinFeatureSize</tt> is implemented for
+<tt>tiffscaled</tt> is different, in that it is done as part of the error
+diffusion. Values of 0 to 2 work as expected, but values 3 and 4 (while
+accepted for compatibility) will behave as for 2.
+
 </dl></blockquote>
 
 <p>



More information about the gs-commits mailing list