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

robin at ghostscript.com robin at ghostscript.com
Wed Oct 13 16:01:51 UTC 2010


Author: robin
Date: 2010-10-13 16:01:51 +0000 (Wed, 13 Oct 2010)
New Revision: 11797

Modified:
   trunk/gs/base/configure.ac
   trunk/gs/base/devs.mak
   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/macos-mcp.mak
   trunk/gs/base/openvms.mak
   trunk/gs/base/unix-gcc.mak
   trunk/gs/base/unixansi.mak
   trunk/gs/doc/Devices.htm
   trunk/gs/psi/msvc32.mak
Log:
Add new tiffscaled device. This renders internally as tiffgray, but then
downsamples by an integer scale factor (specified by -dDownScaleFactor=n)
and error diffuses to 1bpp output.

This device is also included in pcl builds (windows ones at least), enabling
a solution for dropouts caused by rendering pcl at 200dpi. (Render at 600dpi
and scale down by a factor of 3). This should hopefully solve bug 690085.

Future work to consider: work on bringing libtiff based devices into unix PCL
builds, consider stochastic thresholding rather than FS error diffusion.



Modified: trunk/gs/base/configure.ac
===================================================================
--- trunk/gs/base/configure.ac	2010-10-13 10:48:04 UTC (rev 11796)
+++ trunk/gs/base/configure.ac	2010-10-13 16:01:51 UTC (rev 11797)
@@ -541,7 +541,7 @@
 					     [Force using the systems libtiff]),
 	    [], [with_system_libtiff=check])
 TIFFDEVS=''
-TIFFDEVS_ALL='$(DD)tiffs $(DD)tiff12nc $(DD)tiff24nc $(DD)tiff48nc $(DD)tiff32nc $(DD)tiff64nc $(DD)tiffcrle $(DD)tifflzw $(DD)tiffpack $(DD)tiffgray $(DD)tiffsep'
+TIFFDEVS_ALL='$(DD)tiffs $(DD)tiff12nc $(DD)tiff24nc $(DD)tiff48nc $(DD)tiff32nc $(DD)tiff64nc $(DD)tiffcrle $(DD)tifflzw $(DD)tiffpack $(DD)tiffgray $(DD)tiffsep $(DD)tiffscaled'
 case "x$with_system_libtiff" in
     xcheck)
 	if test -d tiff; then
@@ -993,7 +993,7 @@
 FAX_DEVS="cfax dfaxlow dfaxhigh fax tfax tiffg3 tiffg32d tiffg4 faxg3 faxg32d faxg4"
 JPEG_DEVS="jpeg jpeggray jpegcmyk"
 PNG_DEVS="png16 png16m png256 pngalpha pnggray pngmono"
-TIFF_DEVS="tiffs tiff12nc tiff24nc tiff48nc tiff32nc tiff64nc tiffcrle tifflzw tiffpack tiffgray tiffsep tiffsep1"
+TIFF_DEVS="tiffs tiff12nc tiff24nc tiff48nc tiff32nc tiff64nc tiffcrle tifflzw tiffpack tiffgray tiffsep tiffsep1 tiffscaled"
 PCX_DEVS="pcxmono pcxgray pcx16 pcx256 pcx24b pcxcmyk pcx2up"
 PBM_DEVS="pbm pbmraw pgm pgmraw pgnm pgnmraw pnm pnmraw ppm ppmraw pkm pkmraw pksm pksmraw pam"
 PS_DEVS="psdf psdcmyk psdrgb pdfwrite pswrite ps2write epswrite psgray psmono psrgb bbox"

Modified: trunk/gs/base/devs.mak
===================================================================
--- trunk/gs/base/devs.mak	2010-10-13 10:48:04 UTC (rev 11796)
+++ trunk/gs/base/devs.mak	2010-10-13 16:01:51 UTC (rev 11797)
@@ -183,6 +183,7 @@
 #	tiffsep1  Creates halftoned tiff 1-bit per pixel for each colorant
 #	tifflzw  TIFF LZW (tag = 5) (monochrome)
 #	tiffpack  TIFF PackBits (tag = 32773) (monochrome)
+#	tiffscaled  TIFF (monochrome output, integer downsampled and dithered from grayscale rendering)
 
 # Note that MS Windows-specific drivers are defined in pcwin.mak, not here,
 # because they have special compilation requirements that require defining
@@ -1691,7 +1692,7 @@
 
 # TIFF Gray, no compression
 
-tiffgray_=$(GLOBJ)gdevtsep.$(OBJ)
+tiffgray_=$(GLOBJ)gdevtsep.$(OBJ) $(GLOBJ)gsequivc.$(OBJ)
 
 $(DD)tiffgray.dev : $(DEVS_MAK) $(libtiff_dev) $(tiffgray_) $(DD)tiffs.dev
 	$(SETPDEV2) $(DD)tiffgray $(tiffgray_)
@@ -1701,6 +1702,14 @@
 	$(gdevdevn_h) $(gsequivc_h) $(stdio__h) $(ctype__h)
 	$(GLCC) $(I_)$(TI_)$(_I) $(GLO_)gdevtsep.$(OBJ) $(C_) $(GLSRC)gdevtsep.c
 
+# TIFF Scaled (downscaled gray -> mono), configurable compression
+
+tiffscaled_=$(tiffgray_) $(GLOBJ)gdevtsep.$(OBJ)
+
+$(DD)tiffscaled.dev : $(DEVS_MAK) $(libtiff_dev) $(tiffscaled_) $(DD)tiffs.dev
+	$(SETPDEV2) $(DD)tiffscaled $(tiffscaled_)
+	$(ADDMOD) $(DD)tiffscaled -include $(DD)tiffs $(tiff_i_)
+
 # TIFF RGB, no compression
 
 tiffrgb_=$(GLOBJ)gdevtfnx.$(OBJ)

Modified: trunk/gs/base/gdevtfax.c
===================================================================
--- trunk/gs/base/gdevtfax.c	2010-10-13 10:48:04 UTC (rev 11796)
+++ trunk/gs/base/gdevtfax.c	2010-10-13 16:01:51 UTC (rev 11797)
@@ -359,7 +359,7 @@
     }
 
     tfdev->width = width;
-    code = tiff_set_fields_for_printer(pdev, tfdev->tif);
+    code = tiff_set_fields_for_printer(pdev, tfdev->tif, 1);
     tfdev->width = save_width;
     return code;
 }

Modified: trunk/gs/base/gdevtfnx.c
===================================================================
--- trunk/gs/base/gdevtfnx.c	2010-10-13 10:48:04 UTC (rev 11796)
+++ trunk/gs/base/gdevtfnx.c	2010-10-13 16:01:51 UTC (rev 11797)
@@ -49,7 +49,8 @@
 			24, tiff12_print_page),
     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_STRIP_SIZE,
+    TIFF_DEFAULT_DOWNSCALE
 };
 
 const gx_device_tiff gs_tiff24nc_device = {
@@ -60,7 +61,8 @@
 			24, tiff_rgb_print_page),
     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_STRIP_SIZE,
+    TIFF_DEFAULT_DOWNSCALE
 };
 
 const gx_device_tiff gs_tiff48nc_device = {
@@ -71,7 +73,8 @@
 			48, tiff_rgb_print_page),
     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_STRIP_SIZE,
+    TIFF_DEFAULT_DOWNSCALE
 };
 
 /* ------ Private functions ------ */

Modified: trunk/gs/base/gdevtifs.c
===================================================================
--- trunk/gs/base/gdevtifs.c	2010-10-13 10:48:04 UTC (rev 11796)
+++ trunk/gs/base/gdevtifs.c	2010-10-13 16:01:51 UTC (rev 11797)
@@ -102,8 +102,8 @@
     return gdev_prn_close(pdev);
 }
 
-int
-tiff_get_params(gx_device * dev, gs_param_list * plist)
+static int
+tiff_get_some_params(gx_device * dev, gs_param_list * plist, int which)
 {
     gx_device_tiff *const tfdev = (gx_device_tiff *)dev;
     int code = gdev_prn_get_params(dev, plist);
@@ -115,14 +115,31 @@
     if ((code = tiff_compression_param_string(&comprstr, tfdev->Compression)) < 0 ||
 	(code = param_write_string(plist, "Compression", &comprstr)) < 0)
 	ecode = code;
+    if (which & 1)
+    {
+      if ((code = param_write_long(plist, "DownScaleFactor", &tfdev->DownScaleFactor)) < 0)
+          ecode = code;
+    }
     if ((code = param_write_long(plist, "MaxStripSize", &tfdev->MaxStripSize)) < 0)
         ecode = code;
     return ecode;
 }
 
 int
-tiff_put_params(gx_device * dev, gs_param_list * plist)
+tiff_get_params(gx_device * dev, gs_param_list * plist)
 {
+    return tiff_get_some_params(dev, plist, 0);
+}
+
+int
+tiff_get_params_downscale(gx_device * dev, gs_param_list * plist)
+{
+    return tiff_get_some_params(dev, plist, 1);
+}
+
+static int
+tiff_put_some_params(gx_device * dev, gs_param_list * plist, int which)
+{
     gx_device_tiff *const tfdev = (gx_device_tiff *)dev;
     int ecode = 0;
     int code;
@@ -130,6 +147,7 @@
     bool big_endian = tfdev->BigEndian;
     uint16 compr = tfdev->Compression;
     gs_param_string comprstr;
+    long downscale = tfdev->DownScaleFactor;
     long mss = tfdev->MaxStripSize;
 
     /* Read BigEndian option as bool */
@@ -154,7 +172,22 @@
 	    ecode = code;
 	    param_signal_error(plist, param_name, ecode);
     }
-
+    /* Read Downscale factor */
+    if (which & 1) {
+        switch (code = param_read_long(plist,
+                                       (param_name = "DownScaleFactor"),
+                                       &downscale)) {
+            case 0:
+                if (downscale <= 0)
+                    downscale = 1;
+                break;
+            case 1:
+                break;
+            default:
+                ecode = code;
+                param_signal_error(plist, param_name, ecode);
+        }
+    }
     switch (code = param_read_long(plist, (param_name = "MaxStripSize"), &mss)) {
         case 0:
 	    /*
@@ -181,9 +214,22 @@
     tfdev->BigEndian = big_endian;
     tfdev->Compression = compr;
     tfdev->MaxStripSize = mss;
+    tfdev->DownScaleFactor = downscale;
     return code;
 }
 
+int
+tiff_put_params(gx_device * dev, gs_param_list * plist)
+{
+    return tiff_put_some_params(dev, plist, 0);
+}
+
+int
+tiff_put_params_downscale(gx_device * dev, gs_param_list * plist)
+{
+    return tiff_put_some_params(dev, plist, 1);
+}
+
 TIFF *
 tiff_from_filep(const char *name, FILE *filep, int big_endian)
 {
@@ -213,7 +259,7 @@
 	    return_error(gs_error_invalidfileaccess);
     }
 
-    return tiff_set_fields_for_printer(pdev, tfdev->tif);
+    return tiff_set_fields_for_printer(pdev, tfdev->tif, tfdev->DownScaleFactor);
 }
 
 int tiff_set_compression(gx_device_printer *pdev,
@@ -237,16 +283,18 @@
     return 0;
 }
 
-int tiff_set_fields_for_printer(gx_device_printer *pdev, TIFF *tif)
+int tiff_set_fields_for_printer(gx_device_printer *pdev,
+                                TIFF              *tif,
+                                int                factor)
 {
-    TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, pdev->width);
-    TIFFSetField(tif, TIFFTAG_IMAGELENGTH, pdev->height);
+    TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, (pdev->width + factor-1)/factor);
+    TIFFSetField(tif, TIFFTAG_IMAGELENGTH, (pdev->height + factor-1)/factor);
     TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
     TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
 
     TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
-    TIFFSetField(tif, TIFFTAG_XRESOLUTION, (float)pdev->x_pixels_per_inch);
-    TIFFSetField(tif, TIFFTAG_YRESOLUTION, (float)pdev->y_pixels_per_inch);
+    TIFFSetField(tif, TIFFTAG_XRESOLUTION, (float)pdev->x_pixels_per_inch/factor);
+    TIFFSetField(tif, TIFFTAG_YRESOLUTION, (float)pdev->y_pixels_per_inch/factor);
 
     {
 	char revs[10];
@@ -318,7 +366,189 @@
     return code;
 }
 
+/* Error diffusion data is stored in errors block.
+ * We have 1 empty entry at each end to avoid overflow. When
+ * 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.
+ */
+static void down_and_out(TIFF *tif,
+                         byte *data,
+                         int   max_size,
+                         int   factor,
+                         int   row,
+                         int   width,
+                         int  *errors)
+{
+    int x, xx, y, value;
+    byte *outp;
+    byte *inp = data;
+    int mask;
+    int e_downleft, e_down, e_forward = 0;
+    const int threshold = factor*factor*128;
+    const int max_value = factor*factor*255;
 
+    if ((row & 1) == 0)
+    {
+        /* Left to Right pass */
+        const int back = max_size * factor -1;
+        errors += 2;
+        outp = inp;
+        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;
+            }
+            if (value >= threshold)
+            {
+                *outp++ = 1;
+                value -= max_value;
+            }
+            else
+            {
+                *outp++ = 0;
+            }
+            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 */
+        const int back = max_size * factor + 1;
+        errors += width;
+        inp += width*factor-1;
+        outp = inp;
+        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;
+            }
+            if (value >= threshold)
+            {
+                *outp-- = 1;
+                value -= max_value;
+            }
+            else
+            {
+                *outp-- = 0;
+            }
+            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--;
+    mask = 0;
+    for (x = width; x > 0; x--)
+    {
+        value = *inp++;
+        if (mask == 0)
+        {
+            mask = 128;
+            *++outp = 0;
+        }
+        if (value)
+            *outp |= mask;
+        mask >>= 1;
+    }
+
+    TIFFWriteScanline(tif, data, row, 0);
+}
+
+/* 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)
+{
+    int code;
+    byte *data;
+    int *errors;
+    int size = gdev_mem_bytes_per_scan_line((gx_device *)dev);
+    int max_size = max(size, TIFFScanlineSize(tif)) + factor-1;
+    int row;
+    int bpc = dev->color_info.depth / dev->color_info.num_components;
+    int n;
+    int width = (dev->width + factor-1)/factor;
+
+    data = gs_alloc_bytes(dev->memory,
+                          max_size * factor,
+                          "tiff_print_page(data)");
+    if (data == NULL)
+        return_error(gs_error_VMerror);
+
+    errors = (int *)gs_alloc_bytes(dev->memory,
+                                   (width+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);
+    }
+
+    TIFFCheckpointDirectory(tif);
+
+    memset(data, 0, max_size * factor);
+    memset(errors, 0, (width+3) * sizeof(int));
+    n = 0;
+    for (row = 0; row < dev->height; row++) {
+        code = gdev_prn_copy_scan_lines(dev, row, data + max_size*n, size);
+        if (code < 0)
+            break;
+        n++;
+        if (n == factor)
+        {
+            /* Do the downsample */
+            n = 0;
+            down_and_out(tif, data, max_size, factor, row/factor, width, errors);
+        }
+    }
+    if (n != 0)
+    {
+        while (n != factor)
+        {
+            memset(data + max_size * n, 0, max_size);
+            n++;
+            row++;
+        }
+        down_and_out(tif, data, max_size, factor, row/factor, width, errors);
+    }
+
+    gs_free_object(dev->memory, errors, "tiff_print_page(errors)");
+    gs_free_object(dev->memory, data, "tiff_print_page(data)");
+
+    TIFFWriteDirectory(tif);
+    return code;
+}
+
+
 static struct compression_string {
     uint16 id;
     const char *str;

Modified: trunk/gs/base/gdevtifs.h
===================================================================
--- trunk/gs/base/gdevtifs.h	2010-10-13 10:48:04 UTC (rev 11796)
+++ trunk/gs/base/gdevtifs.h	2010-10-13 16:01:51 UTC (rev 11797)
@@ -30,6 +30,7 @@
     bool  BigEndian;            /* true = big endian; false = little endian*/
     uint16 Compression;		/* same values as TIFFTAG_COMPRESSION */
     long MaxStripSize;
+    long DownScaleFactor;
     TIFF *tif;			/* TIFF file opened on gx_device_common.file */
 } gx_device_tiff;
 
@@ -37,7 +38,9 @@
 dev_proc_open_device(tiff_open);
 dev_proc_close_device(tiff_close);
 dev_proc_get_params(tiff_get_params);
+dev_proc_get_params(tiff_get_params_downscale);
 dev_proc_put_params(tiff_put_params);
+dev_proc_put_params(tiff_put_params_downscale);
 
 /*
  * Open a TIFF file for writing from a file descriptor.
@@ -46,18 +49,22 @@
 
 int tiff_print_page(gx_device_printer *dev, TIFF *tif);
 
+int tiff_downscale_and_print_page(gx_device_printer *dev, TIFF *tif, int factor);
+
 /*
  * Sets the compression tag for TIFF and updates the rows_per_strip tag to
  * reflect max_strip_size under the new compression scheme.
  */
 #define TIFF_DEFAULT_STRIP_SIZE 1048576
 
+#define TIFF_DEFAULT_DOWNSCALE 1
+
 int tiff_set_compression(gx_device_printer *pdev,
 			 TIFF *tif,
 			 uint compression,
 			 long max_strip_size);
 
-int tiff_set_fields_for_printer(gx_device_printer *pdev, TIFF *tif);
+int tiff_set_fields_for_printer(gx_device_printer *pdev, TIFF *tif, int factor);
 
 int gdev_tiff_begin_page(gx_device_tiff *tfdev, FILE *file);
 

Modified: trunk/gs/base/gdevtsep.c
===================================================================
--- trunk/gs/base/gdevtsep.c	2010-10-13 10:48:04 UTC (rev 11796)
+++ trunk/gs/base/gdevtsep.c	2010-10-13 16:01:51 UTC (rev 11797)
@@ -12,11 +12,14 @@
 */
 
 /* $Id$ */
-/* tiffgray device:  8-bit Gray uncompressed TIFF device */
-/* tiff32nc device:  32-bit CMYK uncompressed TIFF device */
-/* tiffsep device: Generate individual TIFF gray files for each separation */
-/*                 as well as a 'composite' 32-bit CMYK for the page.      */
-/* tiffsep1 device: Generate individual TIFF 1-bit files for each separation. */
+/* tiffgray device:  8-bit Gray uncompressed TIFF device
+ * tiff32nc device:  32-bit CMYK uncompressed TIFF device
+ * tiffsep device:   Generate individual TIFF gray files for each separation
+ *                   as well as a 'composite' 32-bit CMYK for the page.
+ * tiffsep1 device:  Generate individual TIFF 1-bit files for each separation
+ * tiffscaled device:Mono TIFF device (dithered downscaled output from
+ *                   8-bit Gray internal rendering)
+ */
 
 #include "stdint_.h"   /* for tiff.h */
 #include "gdevtifs.h"
@@ -58,10 +61,41 @@
 		    1, 8, 255, 0, 256, 0, tiffgray_print_page),
     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_STRIP_SIZE,
+    TIFF_DEFAULT_DOWNSCALE
 };
 
+/* ------ The tiffscaled device ------ */
 
+static dev_proc_print_page(tiffscaled_print_page);
+
+static const gx_device_procs tiffscaled_procs =
+prn_color_params_procs(tiff_open,
+                       tiff_output_page,
+                       tiff_close,
+                       gx_default_gray_map_rgb_color,
+                       gx_default_gray_map_color_rgb,
+                       tiff_get_params_downscale,
+                       tiff_put_params_downscale);
+
+const gx_device_tiff gs_tiffscaled_device = {
+    prn_device_body(gx_device_tiff,
+                    tiffscaled_procs,
+                    "tiffscaled",
+                    DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
+                    600, 600,   /* 600 dpi by default */
+                    0, 0, 0, 0, /* Margins */
+                    1,          /* num components */
+                    8,          /* bits per sample */
+                    255, 0, 256, 0,
+                    tiffscaled_print_page),
+    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
+};
+
+
 /* ------ Private functions ------ */
 
 static void
@@ -96,6 +130,24 @@
     return tiff_print_page(pdev, tfdev->tif);
 }
 
+static int
+tiffscaled_print_page(gx_device_printer * pdev, FILE * file)
+{
+    gx_device_tiff *const tfdev = (gx_device_tiff *)pdev;
+    int code;
+
+    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 = gdev_tiff_begin_page(tfdev, file);
+    if (code < 0)
+        return code;
+
+    tiff_set_gray_fields(pdev, tfdev->tif, 1, tfdev->Compression, tfdev->MaxStripSize);
+
+    return tiff_downscale_and_print_page(pdev, tfdev->tif, tfdev->DownScaleFactor);
+}
+
 /* ------ The cmyk devices ------ */
 
 static dev_proc_print_page(tiffcmyk_print_page);
@@ -120,7 +172,8 @@
 		    4, 32, 255, 255, 256, 256, tiffcmyk_print_page),
     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_STRIP_SIZE,
+    TIFF_DEFAULT_DOWNSCALE
 };
 
 /* 16-bit-per-plane separated CMYK color. */
@@ -137,7 +190,8 @@
 		    4, 64, 255, 255, 256, 256, tiffcmyk_print_page),
     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_STRIP_SIZE,
+    TIFF_DEFAULT_DOWNSCALE
 };
 
 /* ------ Private functions ------ */
@@ -1369,7 +1423,7 @@
 	if (!tfdev->tiff_comp)
 	    return_error(gs_error_invalidfileaccess);
     }
-    code = tiff_set_fields_for_printer(pdev, tfdev->tiff_comp);
+    code = tiff_set_fields_for_printer(pdev, tfdev->tiff_comp, 1);
     tiff_set_cmyk_fields(pdev, tfdev->tiff_comp, 8, COMPRESSION_NONE, tfdev->MaxStripSize);
     pdev->color_info.depth = save_depth;
     if (code < 0)
@@ -1411,7 +1465,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]);
+        code = tiff_set_fields_for_printer(pdev, tfdev->tiff[comp_num], 1);
 	tiff_set_gray_fields(pdev, tfdev->tiff[comp_num], 8, tfdev->Compression, tfdev->MaxStripSize);
 	pdev->color_info.depth = save_depth;
         if (code < 0)
@@ -1584,7 +1638,7 @@
 	}
 
 	pdev->color_info.depth = 8;	/* Create files for 8 bit gray */
-	code = tiff_set_fields_for_printer(pdev, tfdev->tiff[comp_num]);
+        code = tiff_set_fields_for_printer(pdev, tfdev->tiff[comp_num], 1);
 	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/macos-mcp.mak
===================================================================
--- trunk/gs/base/macos-mcp.mak	2010-10-13 10:48:04 UTC (rev 11796)
+++ trunk/gs/base/macos-mcp.mak	2010-10-13 16:01:51 UTC (rev 11797)
@@ -224,7 +224,7 @@
 DEVICE_DEVS8=$(DD)pcxmono.dev $(DD)pcxgray.dev $(DD)pcx16.dev $(DD)pcx256.dev $(DD)pcx24b.dev $(DD)pcxcmyk.dev
 DEVICE_DEVS9=$(DD)pbm.dev $(DD)pbmraw.dev $(DD)pgm.dev $(DD)pgmraw.dev $(DD)pgnm.dev $(DD)pgnmraw.dev $(DD)pnm.dev $(DD)pnmraw.dev $(DD)ppm.dev $(DD)ppmraw.dev $(DD)pkm.dev $(DD)pkmraw.dev $(DD)pksm.dev $(DD)pksmraw.dev $(DD)pamcmyk32.dev
 DEVICE_DEVS10=$(DD)tiffcrle.dev $(DD)tiffg3.dev $(DD)tiffg32d.dev $(DD)tiffg4.dev $(DD)tifflzw.dev $(DD)tiffpack.dev
-DEVICE_DEVS11=$(DD)tiff12nc.dev $(DD)tiff24nc.dev $(DD)tiffgray.dev $(DD)tiff32nc.dev $(DD)tiffsep.dev $(DD)tiffsep1.dev
+DEVICE_DEVS11=$(DD)tiff12nc.dev $(DD)tiff24nc.dev $(DD)tiffgray.dev $(DD)tiff32nc.dev $(DD)tiffsep.dev $(DD)tiffsep1.dev $(DD)tiffscaled.dev
 DEVICE_DEVS12=$(DD)psmono.dev $(DD)psgray.dev $(DD)psrgb.dev $(DD)bit.dev $(DD)bitrgb.dev $(DD)bitcmyk.dev
 DEVICE_DEVS13=$(DD)pngmono.dev $(DD)pnggray.dev $(DD)png16.dev $(DD)png256.dev $(DD)png16m.dev
 DEVICE_DEVS14=$(DD)jpeg.dev $(DD)jpeggray.dev $(DD)jpegcmyk.dev

Modified: trunk/gs/base/openvms.mak
===================================================================
--- trunk/gs/base/openvms.mak	2010-10-13 10:48:04 UTC (rev 11796)
+++ trunk/gs/base/openvms.mak	2010-10-13 16:01:51 UTC (rev 11797)
@@ -223,7 +223,7 @@
 DEVICE_DEVS8=$(DD)pcxmono.dev $(DD)pcxgray.dev $(DD)pcx16.dev $(DD)pcx256.dev $(DD)pcx24b.dev $(DD)pcxcmyk.dev
 DEVICE_DEVS9=$(DD)pbm.dev $(DD)pbmraw.dev $(DD)pgm.dev $(DD)pgmraw.dev $(DD)pgnm.dev $(DD)pgnmraw.dev
 DEVICE_DEVS10=$(DD)tiffcrle.dev $(DD)tiffg3.dev $(DD)tiffg32d.dev $(DD)tiffg4.dev $(DD)tifflzw.dev $(DD)tiffpack.dev
-DEVICE_DEVS11=$(DD)tiff12nc.dev $(DD)tiff24nc.dev $(DD)tiffgray.dev $(DD)tiff32nc.dev $(DD)tiffsep.dev $(DD)tiffsep1.dev
+DEVICE_DEVS11=$(DD)tiff12nc.dev $(DD)tiff24nc.dev $(DD)tiffgray.dev $(DD)tiff32nc.dev $(DD)tiffsep.dev $(DD)tiffsep1.dev $(DD)tiffscaled.dev
 DEVICE_DEVS12=$(DD)psmono.dev $(DD)psgray.dev $(DD)psrgb.dev $(DD)bit.dev $(DD)bitrgb.dev $(DD)bitcmyk.dev
 DEVICE_DEVS13=$(DD)pngmono.dev $(DD)pnggray.dev $(DD)png16.dev $(DD)png256.dev $(DD)png16m.dev $(DD)pngalpha.dev
 DEVICE_DEVS14=$(DD)jpeg.dev $(DD)jpeggray.dev $(DD)jpegcmyk.dev

Modified: trunk/gs/base/unix-gcc.mak
===================================================================
--- trunk/gs/base/unix-gcc.mak	2010-10-13 10:48:04 UTC (rev 11796)
+++ trunk/gs/base/unix-gcc.mak	2010-10-13 16:01:51 UTC (rev 11797)
@@ -397,7 +397,7 @@
 DEVICE_DEVS8=$(DD)pcxmono.dev $(DD)pcxgray.dev $(DD)pcx16.dev $(DD)pcx256.dev $(DD)pcx24b.dev $(DD)pcxcmyk.dev
 DEVICE_DEVS9=$(DD)pbm.dev $(DD)pbmraw.dev $(DD)pgm.dev $(DD)pgmraw.dev $(DD)pgnm.dev $(DD)pgnmraw.dev $(DD)pnm.dev $(DD)pnmraw.dev $(DD)ppm.dev $(DD)ppmraw.dev $(DD)pkm.dev $(DD)pkmraw.dev $(DD)pksm.dev $(DD)pksmraw.dev
 DEVICE_DEVS10=$(DD)tiffcrle.dev $(DD)tiffg3.dev $(DD)tiffg32d.dev $(DD)tiffg4.dev $(DD)tifflzw.dev $(DD)tiffpack.dev
-DEVICE_DEVS11=$(DD)tiff12nc.dev $(DD)tiff24nc.dev $(DD)tiff48nc.dev $(DD)tiffgray.dev $(DD)tiff32nc.dev $(DD)tiff64nc.dev $(DD)tiffsep.dev $(DD)tiffsep1.dev
+DEVICE_DEVS11=$(DD)tiff12nc.dev $(DD)tiff24nc.dev $(DD)tiff48nc.dev $(DD)tiffgray.dev $(DD)tiff32nc.dev $(DD)tiff64nc.dev $(DD)tiffsep.dev $(DD)tiffsep1.dev $(DD)tiffscaled.dev
 DEVICE_DEVS12=$(DD)psmono.dev $(DD)psgray.dev $(DD)psrgb.dev $(DD)bit.dev $(DD)bitrgb.dev $(DD)bitcmyk.dev
 DEVICE_DEVS13=$(DD)pngmono.dev $(DD)pnggray.dev $(DD)png16.dev $(DD)png256.dev $(DD)png16m.dev $(DD)pngalpha.dev
 DEVICE_DEVS14=$(DD)jpeg.dev $(DD)jpeggray.dev $(DD)jpegcmyk.dev

Modified: trunk/gs/base/unixansi.mak
===================================================================
--- trunk/gs/base/unixansi.mak	2010-10-13 10:48:04 UTC (rev 11796)
+++ trunk/gs/base/unixansi.mak	2010-10-13 16:01:51 UTC (rev 11797)
@@ -342,7 +342,7 @@
 DEVICE_DEVS8=$(DD)pcxmono.dev $(DD)pcxgray.dev $(DD)pcx16.dev $(DD)pcx256.dev $(DD)pcx24b.dev $(DD)pcxcmyk.dev
 DEVICE_DEVS9=$(DD)pbm.dev $(DD)pbmraw.dev $(DD)pgm.dev $(DD)pgmraw.dev $(DD)pgnm.dev $(DD)pgnmraw.dev
 DEVICE_DEVS10=$(DD)tiffcrle.dev $(DD)tiffg3.dev $(DD)tiffg32d.dev $(DD)tiffg4.dev $(DD)tifflzw.dev $(DD)tiffpack.dev
-DEVICE_DEVS11=$(DD)tiff12nc.dev $(DD)tiff24nc.dev $(DD)tiffgray.dev $(DD)tiff32nc.dev $(DD)tiffsep.dev $(DD)tiffsep1.dev
+DEVICE_DEVS11=$(DD)tiff12nc.dev $(DD)tiff24nc.dev $(DD)tiffgray.dev $(DD)tiff32nc.dev $(DD)tiffsep.dev $(DD)tiffsep1.dev $(DD)tiffscaled.dev
 DEVICE_DEVS12=$(DD)psmono.dev $(DD)psgray.dev $(DD)psrgb.dev $(DD)bit.dev $(DD)bitrgb.dev $(DD)bitcmyk.dev
 DEVICE_DEVS13=$(DD)pngmono.dev $(DD)pnggray.dev $(DD)png16.dev $(DD)png256.dev $(DD)png16m.dev $(DD)pngalpha.dev
 DEVICE_DEVS14=$(DD)jpeg.dev $(DD)jpeggray.dev $(DD)jpegcmyk.dev

Modified: trunk/gs/doc/Devices.htm
===================================================================
--- trunk/gs/doc/Devices.htm	2010-10-13 10:48:04 UTC (rev 11796)
+++ trunk/gs/doc/Devices.htm	2010-10-13 16:01:51 UTC (rev 11797)
@@ -430,6 +430,14 @@
 '.tif', then the suffix is removed prior to adding the component name in
 '(' and ').tif'.
 
+<a name="tiffscaled"></a><dt><code>tiffscaled</code>
+<dd>
+The tiffscaled device renders internally at the specified resolution to an
+8 bit greyscale image. This is then scaled down by an integer scale factor
+(set by -dDownScaleFactor= described below) and then error diffused to give
+1bpp output. The compression can be set using -sCompression= as described
+below.
+
 </dl>
 </blockquote>
 
@@ -529,9 +537,21 @@
 1680..1736 or 2000..2056 columns, set the page width to A4 (1728 columns)
 or B4 (2048 columns) respectively.
 This behavior is the default. Pass -dAdjustWidth=0 to turn off this behavior.
+
 </dl></blockquote>
 
+<p>
+The <tt>tiffscaled</tt> TIFF driver also provides this parameter:
 
+<blockquote><dl>
+<dt><code>-dDownScaleFactor=<em>factor</em></code> (small non-negative integer; default = 1)
+<dd>If this option set then the page is downscaled by the given factor on both
+axes before error diffusion takes place. For example rendering with
+<tt>-r600</tt> and then specifying <tt>-dDownScaleFactor=3</tt> will produce a
+200dpi image.
+</dl></blockquote>
+
+
 <h3><a name="fax"></a>FAX</h3>
 
 <p>

Modified: trunk/gs/psi/msvc32.mak
===================================================================
--- trunk/gs/psi/msvc32.mak	2010-10-13 10:48:04 UTC (rev 11796)
+++ trunk/gs/psi/msvc32.mak	2010-10-13 16:01:51 UTC (rev 11797)
@@ -715,7 +715,7 @@
 DEVICE_DEVS8=$(DD)pcxmono.dev $(DD)pcxgray.dev $(DD)pcx16.dev $(DD)pcx256.dev $(DD)pcx24b.dev $(DD)pcxcmyk.dev
 DEVICE_DEVS9=$(DD)pbm.dev $(DD)pbmraw.dev $(DD)pgm.dev $(DD)pgmraw.dev $(DD)pgnm.dev $(DD)pgnmraw.dev $(DD)pkmraw.dev
 DEVICE_DEVS10=$(DD)tiffcrle.dev $(DD)tiffg3.dev $(DD)tiffg32d.dev $(DD)tiffg4.dev $(DD)tifflzw.dev $(DD)tiffpack.dev
-DEVICE_DEVS11=$(DD)bmpmono.dev $(DD)bmpgray.dev $(DD)bmp16.dev $(DD)bmp256.dev $(DD)bmp16m.dev $(DD)tiff12nc.dev $(DD)tiff24nc.dev $(DD)tiff48nc.dev $(DD)tiffgray.dev $(DD)tiff32nc.dev $(DD)tiff64nc.dev $(DD)tiffsep.dev $(DD)tiffsep1.dev
+DEVICE_DEVS11=$(DD)bmpmono.dev $(DD)bmpgray.dev $(DD)bmp16.dev $(DD)bmp256.dev $(DD)bmp16m.dev $(DD)tiff12nc.dev $(DD)tiff24nc.dev $(DD)tiff48nc.dev $(DD)tiffgray.dev $(DD)tiff32nc.dev $(DD)tiff64nc.dev $(DD)tiffsep.dev $(DD)tiffsep1.dev $(DD)tiffscaled.dev
 DEVICE_DEVS12=$(DD)psmono.dev $(DD)bit.dev $(DD)bitrgb.dev $(DD)bitcmyk.dev
 DEVICE_DEVS13=$(DD)pngmono.dev $(DD)pnggray.dev $(DD)png16.dev $(DD)png256.dev $(DD)png16m.dev $(DD)pngalpha.dev
 DEVICE_DEVS14=$(DD)jpeg.dev $(DD)jpeggray.dev $(DD)jpegcmyk.dev



More information about the gs-commits mailing list