File ghostscript-9.00-bjc.dif of Package ghostscript-library.887

--- base/gdevbjc.h
+++ base/gdevbjc.h	2008-07-28 13:55:39.000000000 +0000
@@ -41,11 +41,11 @@
 #define BJC_BJC600		"bjc600"
 #define BJC_BJC800		"bjc800"
 
-#define BJC_BJC600_VERSION	2.1700
-#define BJC_BJC600_VERSIONSTR	"2.17.00 5/23/96 Yves Arrouye"
+#define BJC_BJC600_VERSION	2.1801
+#define BJC_BJC600_VERSIONSTR	"2.18.01 6/7/96 Yves Arrouye"
 
-#define BJC_BJC800_VERSION	2.1700
-#define BJC_BJC800_VERSIONSTR	"2.17.00 5/23/96 Yves Arrouye"
+#define BJC_BJC800_VERSION	2.1801
+#define BJC_BJC800_VERSIONSTR	"2.18.01 6/7/96 Yves Arrouye"
 
 /*
  * Hardware limits. May be adjusted eventually.
@@ -149,6 +149,7 @@
 
 /* Some compilers complain if this is a floating point value.... */
 #define BJC_RESOLUTION_BASE		90
+#define BJC_RESOLUTION_SPECIAL_BASE	75
 
 #define BJC_RESOLUTION_LOW		(1 * BJC_RESOLUTION_BASE)
 #define BJC_RESOLUTION_MEDIUM		(2 * BJC_RESOLUTION_BASE)
--- base/gdevcdj.c
+++ base/gdevcdj.c	2010-09-28 12:37:12.559926366 +0000
@@ -152,17 +152,16 @@
   {\
   case 0:\
 	if ( pa.size != psize )\
-	  code = gs_error_rangecheck;\
+	  ncode = gs_note_error(gs_error_rangecheck);\
 	else {
 /* The body of the processing code goes here. */
 /* If it succeeds, it should do a 'break'; */
-/* if it fails, it should set ecode and fall through. */
+/* if it fails, it should set ncode and fall through. */
 #define END_PARAM(pa, e)\
 	}\
 	goto e;\
   default:\
-	code = ncode;\
-e:	param_signal_error(plist, oname, code);\
+e:	param_signal_error(plist, oname, code = ncode);\
   case 1:\
 	pa.data = 0;		/* mark as not filled */\
   }
@@ -249,6 +248,7 @@ static int cdj_param_check_float(gs_para
 /* Colour mapping procedures */
 static dev_proc_map_cmyk_color (gdev_cmyk_map_cmyk_color);
 static dev_proc_map_rgb_color (gdev_cmyk_map_rgb_color);
+static dev_proc_map_color_rgb (gdev_cmyk_map_color_rgb);
 
 static dev_proc_map_rgb_color (gdev_pcl_map_rgb_color);
 static dev_proc_map_color_rgb (gdev_pcl_map_color_rgb);
@@ -422,7 +422,7 @@ typedef struct {
     prn_colour_device_body(dtype, procs, dev_name,\
     DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS, x_dpi, y_dpi, 0, 0, 0, 0,\
     ((bpp == 1 || bpp == 4) ? 1 : 4), bpp,\
-    (bpp > 8 ? 255 : 1), (1 << (bpp >> 2)) - 1, /* max_gray, max_color */\
+    (bpp > 8 ? 255 : 1), (bpp > 1 ? (1 << (bpp >> 2)) - 1 : 0), /* max_gray, max_color */\
     (bpp > 8 ? 256 : 2), (bpp > 8 ? 256 : bpp > 1 ? 2 : 0),\
     print_page, 1 /* cmyk */, correct)
 
@@ -478,7 +478,7 @@ typedef struct {
 	gdev_prn_output_page,\
 	gdev_prn_close,\
 	NULL /* map_rgb_color */,\
-	NULL /* map_color_rgb */,\
+	gdev_cmyk_map_color_rgb,\
 	NULL /* fill_rectangle */,\
 	NULL /* tile_rectangle */,\
 	NULL /* copy_mono */,\
@@ -487,44 +487,7 @@ typedef struct {
 	gx_default_get_bits,\
 	proc_get_params,\
 	proc_put_params,\
-        gdev_cmyk_map_cmyk_color,\
-	NULL,	/* get_xfont_procs */\
-	NULL,	/* get_xfont_device */\
-	NULL,	/* map_rgb_alpha_color */\
-	NULL,	/* get_page_device */\
-	NULL,	/* get_alpha_bits */\
-	NULL,	/* copy_alpha */\
-	NULL,	/* get_band */\
-	NULL,	/* copy_rop */\
-	NULL,	/* fill_path */\
-	NULL,	/* stroke_path */\
-	NULL,	/* fill_mask */\
-	NULL,	/* fill_trapezoid */\
-	NULL,	/* fill_parallelogram */\
-	NULL,	/* fill_triangle */\
-	NULL,	/* draw_thin_line */\
-	NULL,	/* begin_image */\
-	NULL,	/* image_data */\
-	NULL,	/* end_image */\
-	NULL,	/* strip_tile_rectangle */\
-	NULL,	/* strip_copy_rop */\
-	NULL,	/* get_clipping_box */\
-	NULL,	/* begin_typed_image */\
-	NULL,	/* get_bits_rectangle */\
-	NULL,	/* map_color_rgb_alpha */\
-	NULL,	/* create_compositor */\
-	NULL,	/* get_hardware_params */\
-	NULL,	/* text_begin */\
-	NULL,	/* finish_copydevice */\
-	NULL,	/* begin_transparency_group */\
-	NULL,	/* end_transparency_group */\
-	NULL,	/* begin_transparency_mask */\
-	NULL,	/* end_transparency_mask */\
-	NULL,	/* discard_transparency_layer */\
-	NULL,	/* get_color_mapping_procs */\
-	NULL,	/* get_color_comp_index */\
-	gdev_cmyk_map_cmyk_color,	/* encode_color */\
-	gdev_cmyk_map_color_cmyk	/* decode_color */\
+	gdev_cmyk_map_cmyk_color\
 }
 
 static gx_device_procs cdj500_procs =
@@ -567,11 +530,11 @@ cdj_device(cdj500_procs, "cdjmono", 300,
 	   dj500c_print_page, 4, 0, 1);
 
 gx_device_cdj far_data gs_cdeskjet_device =
-cdj_device(cdj500_procs, "cdeskjet", 300, 300, 3,
+cdj_device(cdj500_procs, "cdeskjet", 300, 300, BITSPERPIXEL,
 	   dj500c_print_page, 4, 2, 1);
 
 gx_device_cdj far_data gs_cdjcolor_device =
-cdj_device(cdj500_procs, "cdjcolor", 300, 300, 24,
+cdj_device(cdj500_procs, "cdjcolor", 300, 300, BITSPERPIXEL,
 	   dj500c_print_page, 4, 2, 1);
 
 gx_device_cdj far_data gs_cdj500_device =
@@ -684,6 +647,17 @@ static int cdj_set_bpp(gx_device *, int,
 static void cdj_expand_line(word *, int, short, int, int);
 static int bjc_fscmyk(byte**, byte*[4][4], int**, int, int);
 
+typedef struct var_input_media_s {
+	float PageSize[4];
+	const char *MediaColor;
+	float MediaWeight;
+	const char *MediaType;
+} var_input_media;
+
+int gdev_prn_input_var_media(int, gs_param_dict *, const var_input_media*);
+static int gdev_prn_finish_media(gs_param_list *, gs_param_name, const char *);
+int gdev_prn_input_var_page_size(int, gs_param_dict *, floatp, floatp);
+
 /* String parameters manipulation */
 
 typedef struct {
@@ -769,6 +743,7 @@ hp_colour_open(gx_device *pdev, int ptyp
   static float bjc_a4[4] = { BJC_MARGINS_A4 };		/* Not const! */
 
   const float *m = (float *) 0;
+  float *bjm = (float *) 0;
 
   /* Set up colour params if put_params has not already done so */
   if (pdev->color_info.num_components == 0)
@@ -807,35 +782,37 @@ hp_colour_open(gx_device *pdev, int ptyp
     switch (gdev_pcl_paper_size(pdev)) {
 	case PAPER_SIZE_LEGAL:
 	case PAPER_SIZE_LETTER:
-	    m = bjc_letter;
+	    bjm = bjc_letter;
 	    break;
 
 	case PAPER_SIZE_A0:
 	case PAPER_SIZE_A1:
 	case PAPER_SIZE_A3:
-	    m = bjc_a3;
+	    bjm = bjc_a3;
 	    break;
 
 	default:
-	    m = bjc_a4;
+	    bjm = bjc_a4;
     }
 
 #ifndef USE_FIXED_MARGINS
     if (ptype == BJC800) {
-	((float *) m)[1] = (float)BJC_HARD_LOWER_LIMIT;
+	((float *) bjm)[1] = (float)BJC_HARD_LOWER_LIMIT;
     }
 #endif
 
-    bjc->printLimit = m[3];		/* The real hardware limit. */
+    bjc->printLimit = bjm[3];		/* The real hardware limit. */
 
 #ifdef BJC_DEFAULT_CENTEREDAREA
-    if (m[3] < m[1]) {
-	((float *) m)[3] = m[1];  	/* Top margin = bottom one. */
+    if (bjm[3] < bjm[1]) {
+	((float *) bjm)[3] = bjm[1];  	/* Top margin = bottom one. */
     } else {
-	((float *) m)[1] = m[3];  	/* Bottom margin = top one. */
+	((float *) bjm)[1] = bjm[3];  	/* Bottom margin = top one. */
     }
 #endif
 
+    m = bjm;
+
     break;
 
     /*NOTREACHED*/
@@ -847,16 +824,14 @@ hp_colour_open(gx_device *pdev, int ptyp
      */
 
     /**/ {
-	float *bjcm = (float *) m;
-
 	byte pdimen = (byte)
 	    (pdev->height / pdev->y_pixels_per_inch * 10.
-	     - bjcm[3] * 10. - bjcm[1] * 10. + .5) + 1;
+	     - bjm[3] * 10. - bjm[1] * 10. + .5) + 1;
 	do {
 	    --pdimen;
-	    bjcm[1] = pdev->height / pdev->y_pixels_per_inch
-	        - bjcm[3] - (float) pdimen / 10.;
-	} while (bjcm[1] < BJC_LOWER_LIMIT);
+	    bjm[1] = pdev->height / pdev->y_pixels_per_inch
+	        - bjm[3] - (float) pdimen / 10.;
+	} while (bjm[1] < BJC_LOWER_LIMIT);
     }
 
     break;
@@ -1018,6 +993,8 @@ bjc_get_params(gx_device *pdev, gs_param
     gs_param_string pquality;
     gs_param_string dithering;
 
+    gs_param_dict iattributes;
+
     if (code < 0) return_error(code);
 
     if ((ncode = param_write_bool(plist, BJC_OPTION_MANUALFEED,
@@ -1025,15 +1002,31 @@ bjc_get_params(gx_device *pdev, gs_param
 	code = ncode;
     }
 
-    code = get_param_string(plist, (unsigned char *)BJC_OPTION_MEDIATYPE, &pmedia,
+    gdev_begin_input_media(plist, &iattributes, 1);
+    switch (bjc->ptype) {
+	case BJC800:
+	    ncode = gdev_prn_input_var_page_size(0, &iattributes, 842, 1224);
+	    break;
+
+	default:
+	    ncode = gdev_prn_input_var_page_size(0, &iattributes, 612, 842);
+	    break;
+    }
+    gdev_end_input_media(plist, &iattributes);
+
+    if (ncode < 0) {
+	code = ncode;
+    }
+
+    code = get_param_string(plist, (const byte *)BJC_OPTION_MEDIATYPE, &pmedia,
         bjc_mediaTypeStrings, bjcparams.mediaType, true, code);
 
-    code = get_param_string(plist, (unsigned char *)BJC_OPTION_PRINTQUALITY, &pquality,
+    code = get_param_string(plist, (const byte *)BJC_OPTION_PRINTQUALITY, &pquality,
         (bjc->ptype == BJC800 ? bjc800_printQualityStrings :
 	bjc600_printQualityStrings), bjcparams.printQuality,
 	true, code);
 
-    code = get_param_string(plist, (unsigned char *)BJC_OPTION_DITHERINGTYPE, &dithering,
+    code = get_param_string(plist, (const byte *)BJC_OPTION_DITHERINGTYPE, &dithering,
         bjc_ditheringTypeStrings, bjcparams.ditheringType, true, code);
 
     if ((ncode = param_write_int(plist, BJC_OPTION_PRINTCOLORS,
@@ -1062,9 +1055,9 @@ bjc_get_params(gx_device *pdev, gs_param
 	bool bTrue = true;
 
 	version = bjcversion(pdev);
-	versionString.data = (byte *)bjcversionstring(pdev);
+	versionString.data = (const byte *)bjcversionstring(pdev);
 
-	versionString.size = strlen((char *)versionString.data);
+	versionString.size = strlen((const char *)versionString.data);
 	versionString.persistent = true;
 
 	if ((ncode = param_write_float(plist, BJC_DEVINFO_VERSION,
@@ -1124,7 +1117,7 @@ bjc_put_params(gx_device *pdev, gs_param
         bpp = pdev->color_info.depth;
     }
 
-    if ((code = put_param_string(plist, (unsigned char *)"ProcessColorModel",
+    if ((code = put_param_string(plist, (const byte *)"ProcessColorModel",
 	&pprocesscolors, bjc_processColorsStrings, &ccomps, code)) != 1) {
         ccomps = pdev->color_info.num_components;
     }
@@ -1134,13 +1127,13 @@ bjc_put_params(gx_device *pdev, gs_param
 	param_signal_error(plist, oname, code = ncode);
     }
 
-    code = put_param_string(plist, (unsigned char *)BJC_OPTION_MEDIATYPE, &pmedia,
+    code = put_param_string(plist, (const byte *)BJC_OPTION_MEDIATYPE, &pmedia,
         bjc_mediaTypeStrings, &params->mediaType, code);
 
     code = cdj_put_param_int(plist, BJC_OPTION_PRINTCOLORS,
 	&params->printColors, 0, 15, code);
 
-    code = put_param_string(plist, (unsigned char *)BJC_OPTION_PRINTQUALITY, &pquality,
+    code = put_param_string(plist, (const byte *)BJC_OPTION_PRINTQUALITY, &pquality,
 	(bjc->ptype == BJC800 ? bjc800_printQualityStrings :
 	bjc600_printQualityStrings), &params->printQuality, code);
 
@@ -1200,52 +1193,63 @@ mwe:   	    param_signal_error(plist, on
 
     BEGIN_ARRAY_PARAM(param_read_float_array, "HWResolution", hwra, 2, hwre)
 	if ( hwra.data[0] <= 0 || hwra.data[1] <= 0 ||
-	     hwra.data[0] != hwra.data[1] )
-	    ncode = gs_error_rangecheck;
-	else {
+	     hwra.data[0] != hwra.data[1] ) {
+	    ncode = gs_note_error(gs_error_rangecheck);
+	} else {
 #ifdef BJC_STRICT
 	    if (hwra.data[0] != BJC_RESOLUTION_LOW &&
 		hwra.data[0] != BJC_RESOLUTION_NORMAL &&
 		hwra.data[0] != BJC_RESOLUTION_HIGH) {
-		ncode = gs_error_rangecheck;
+		ncode = gs_note_error(gs_error_rangecheck);
 	    }
 #else
 	    /* A small hack for checking resolution without logarithms. */
 
 	    /**/ {
 		int n;
+		int maxn = 4;
 
-		for (n = 0; n < 8 * sizeof(n) / BJC_RESOLUTION_BASE; ++n) {
+		for (n = 0; n < maxn; ++n) {
 		    float res = (float)(BJC_RESOLUTION_BASE * (1 << n));
+		    float RES = (float)(BJC_RESOLUTION_SPECIAL_BASE * (1 << n));
 
 		    if (res == hwra.data[0]) break;
 
-		    if (res > hwra.data[0]) {
-			ncode = gs_error_rangecheck;
+		    if ((bjc->ptype == BJC800) && n &&
+			(RES == hwra.data[0]))
+			break;
+
+		    if (res > hwra.data[0] || RES > res) {
+			ncode = gs_note_error(gs_error_rangecheck);
+			break;
 		    }
 		}
 
-		if (n == 8 * sizeof(n)) {
-		    ncode = gs_error_rangecheck;
+		if (n == maxn) {
+		    ncode = gs_note_error(gs_error_rangecheck);
 		}
 	    }
 #endif
-	    if (ncode < 0) {
-		code = ncode;
-	    } else {
+	    if (ncode >= 0) {
 		break;
 	    }
 	}
     END_PARAM(hwra, hwre)
 
+#ifdef BJC_DEBUG_CI
+    fprintf(stderr, "debug: cdj_put_param_bpp(%p, %p, %d, %d, %d)\n",
+	    pdev, plist, bpp, bpp, ccomps);
+#endif
+
     if ((ncode = cdj_put_param_bpp(pdev, plist, bpp, bpp, ccomps)) < 0) {
 	code = ncode;
     }
 
-    if (code < 0)
+    if (code < 0) {
 	return code;
+    }
 
-    if (bpp == 1) {
+    if (pdev->color_info.depth == 1) {
 	params->ditheringType = BJC_DITHER_NONE;
     }
 
@@ -1666,6 +1670,7 @@ static int
 bjc_init_page(gx_device_printer* pdev, FILE* f)
 {
     byte pagemargins[3], resolution[4], paperloading[2];
+    byte one = '\001';
 
     /* Compute page margins. */
 
@@ -1709,7 +1714,7 @@ bjc_init_page(gx_device_printer* pdev, F
 
     /* Set page mode on (ignore data at end of page) */
 
-    bjc_cmd('a', 1, (byte*) "\001", pdev, f);
+    bjc_cmd('a', 1, &one, pdev, f);
 
     /* Set page margins */
 
@@ -1717,7 +1722,7 @@ bjc_init_page(gx_device_printer* pdev, F
 
     /* Set compression on (this is PackBits compression a la TIFF/Mac) */
 
-    bjc_cmd('b', 1, (byte*) "\001", pdev, f);
+    bjc_cmd('b', 1, &one, pdev, f);
 
     /* Set paper loading. */
 
@@ -1782,8 +1787,10 @@ bjc_v_skip(int n, gx_device_printer* pde
 static int
 bjc_finish_page(gx_device_printer* pdev, FILE* f)
 {
-    bjc_cmd('a', 1, (byte*) "\000", pdev, f);
-    bjc_cmd('b', 1, (byte*) "\000", pdev, f);
+    byte zero = 0;
+
+    bjc_cmd('a', 1, &zero, pdev, f);
+    bjc_cmd('b', 1, &zero, pdev, f);
     fputc('\014', f);
     fputs("\033@", f);
 
@@ -1799,7 +1806,6 @@ bjc_compress(const byte *row, const byte
   register const byte *exam = row;
   register byte *cptr = compressed; /* output pointer into compressed bytes */
 
-
   while ( exam < end_row ) {
     /* Search ahead in the input looking for a run */
     /* of at least 4 identical bytes. */
@@ -1816,7 +1822,6 @@ bjc_compress(const byte *row, const byte
       test = test2;
     }
 
-
     /* Find out how long the run is */
     end_dis = exam - 1;
     if ( exam == end_row ) { /* no run */
@@ -2583,6 +2588,7 @@ hp_colour_print_page(gx_device_printer *
 	      default:
 		  FSDline(scan, i, j, plane_size, cErr, mErr, yErr, kErr,
 			  cP, mP, yP, kP, 1);
+		  break;
 	  }
 	  break;
 	case 24:
@@ -2691,7 +2697,7 @@ hp_colour_print_page(gx_device_printer *
 	  case LJ4DITH:
 	    { const byte *plane = plane_data[scan][i];
 	      byte *prev_plane = plane_data[1 - scan][i];
-	      const word *row = (word *)plane;
+	      const word *row = (const word*) plane;
 	      const word *end_row = row + plane_size/W;
 	      int count2 = gdev_pcl_mode2compress(row, end_row, out_row_alt);
 	      int count3 = gdev_pcl_mode3compress(plane_size, plane, prev_plane, out_row);
@@ -2927,22 +2933,73 @@ gdev_cmyk_map_color_cmyk(gx_device *pdev
 	   }
 
 	default: {
-	    unsigned long bcyan, bmagenta, byellow, black;
+	    gx_color_value bcyan, bmagenta, byellow, black;
 	    int nbits = pdev->color_info.depth;
 
 	    gx_value_cmyk_bits(color, bcyan, bmagenta, byellow, black,
 	        nbits >> 2);
 
-	    prgb[0] = bcyan;
-	    prgb[1] = bmagenta;
-	    prgb[2] = byellow;
-	    prgb[3] = black;
+	    if (!(bcyan | bmagenta | byellow)) {
+		/* Just gray */
+		prgb[0] = prgb[1] = prgb[2] = gx_max_color_value - black;
+		break;
+	    }
+
+	    /* R = (1.0 - C) * (1.0 - K), etc. */
+
+	    prgb[0] = (gx_color_value)
+	      ((ulong)(gx_max_color_value - bcyan) *
+	       (gx_max_color_value - black) / gx_max_color_value);
+	    prgb[1] = (gx_color_value)
+	      ((ulong)(gx_max_color_value - bmagenta) *
+	       (gx_max_color_value - black) / gx_max_color_value);
+	    prgb[2] = (gx_color_value)
+	      ((ulong)(gx_max_color_value - byellow) *
+	       (gx_max_color_value - black) / gx_max_color_value);
 	}
     }
 
     return 0;
 }
 
+static int
+gdev_cmyk_map_color_rgb(gx_device *pdev, gx_color_index color, gx_color_value prgb[3])
+{
+    switch (pdev->color_info.depth) {
+	case 1:
+	   prgb[0] = prgb[1] = prgb[2] = gx_max_color_value * (1 - color);
+	   break;
+
+	case 8:
+	   if (pdev->color_info.num_components == 1) {
+	       gx_color_value value = (gx_color_value) color ^ 0xff;
+
+	       prgb[0] = prgb[1] = prgb[2] = (value << 8) + value;
+
+	       break;
+	   }
+
+	default: {
+	    gx_color_value bcyan, bmagenta, byellow, black;
+	    int nbits = pdev->color_info.depth;
+	    gx_value_cmyk_bits(color, bcyan, bmagenta, byellow, black, nbits >> 2);
+
+	    /* R = (1.0 - C) * (1.0 - K), etc. */
+
+	    prgb[0] = (gx_color_value)
+	      ((ulong)(gx_max_color_value - bcyan) *
+	       (gx_max_color_value - black) / gx_max_color_value);
+	    prgb[1] = (gx_color_value)
+	      ((ulong)(gx_max_color_value - bmagenta) *
+	       (gx_max_color_value - black) / gx_max_color_value);
+	    prgb[2] = (gx_color_value)
+	      ((ulong)(gx_max_color_value - byellow) *
+	       (gx_max_color_value - black) / gx_max_color_value);
+	}
+    }
+
+    return 0;
+}
 /*
  * Map a r-g-b color to a color index.
  * We complement the colours, since we're using cmy anyway, and
@@ -3268,16 +3325,6 @@ cdj_set_bpp(gx_device *pdev, int bpp, in
       bpp = ci->depth;		/* Use the current setting. */
   }
 
-  if (cprn_device->cmyk < 0) {
-
-      /* Reset procedures because we may have been in another mode. */
-
-      dev_proc(pdev, encode_color) = gdev_cmyk_map_cmyk_color;
-      dev_proc(pdev, map_rgb_color) = NULL;
-      dev_proc(pdev, decode_color) = gdev_cmyk_map_color_cmyk;
-
-      if (pdev->is_open) gs_closedevice(pdev);
-  }
 
   /* Check for valid bpp values */
 
@@ -3317,47 +3364,47 @@ cdj_set_bpp(gx_device *pdev, int bpp, in
 	}
 
     case 1:
-       if (ccomps != 1) goto bppe;
+       if (ccomps && ccomps != 1) goto bppe;
 
-       if (cprn_device->cmyk && bpp != pdev->color_info.depth) {
-	   dev_proc(pdev, map_cmyk_color) = NULL;
-	   dev_proc(pdev, map_rgb_color) = gdev_cmyk_map_rgb_color;
-
-	   if (pdev->is_open) {
-	       gs_closedevice(pdev);
-	   }
-       }
        break;
 
     case 3:
-	if (!cprn_device->cmyk) {
+	if (!cprn_device->cmyk)
 	    break;
-	}
 
     default:
 bppe:  return gs_error_rangecheck;
     }
 
 
-    if (cprn_device->cmyk == -1) {
-	dev_proc(pdev, map_cmyk_color) = NULL;
-	dev_proc(pdev, map_rgb_color) = gdev_pcl_map_rgb_color;
-	dev_proc(pdev, map_color_rgb) = gdev_pcl_map_color_rgb;
-
-	if (pdev->is_open) {
-	    gs_closedevice(pdev);
-	}
-	if (pdev->is_open) {
-	    int				code;	/* Return code */
-	    gdev_prn_space_params	sp;	/* Space parameter data */
+    if (cprn_device->cmyk != 1) {
+	set_dev_proc(pdev, encode_color,     NULL);
+	set_dev_proc(pdev, decode_color,     NULL);
+	set_dev_proc(pdev, map_rgb_color,    gdev_pcl_map_rgb_color);
+	set_dev_proc(pdev, map_cmyk_color,   NULL);
+	set_dev_proc(pdev, map_color_rgb,    gdev_pcl_map_color_rgb);
+    } else {
+	if (bpp < 8) {
+	    set_dev_proc(pdev, encode_color, NULL);
+	    set_dev_proc(pdev, decode_color, NULL);
+	} else {
+	    set_dev_proc(pdev, encode_color, gdev_cmyk_map_cmyk_color);
+	    set_dev_proc(pdev, decode_color, gdev_cmyk_map_color_cmyk);
+	}
+	set_dev_proc(pdev, map_rgb_color,    gdev_cmyk_map_rgb_color);
+	set_dev_proc(pdev, map_cmyk_color,   gdev_cmyk_map_cmyk_color);
+	set_dev_proc(pdev, map_color_rgb,    gdev_cmyk_map_color_rgb);
+    }
+    if (pdev->is_open) {
+	int			code;	/* Return code */
+	gdev_prn_space_params	sp;	/* Space parameter data */
 
-	    /* Reallocate memory for device */
-	    sp = ((gx_device_printer *)pdev)->space_params;
+	/* Reallocate memory for device */
+	sp = ((gx_device_printer *)pdev)->space_params;
 
-	    if ((code = gdev_prn_reallocate_memory(pdev, &sp, pdev->width,
-						   pdev->height)) < 0)
+	if ((code = gdev_prn_reallocate_memory(pdev, &sp, pdev->width,
+					       pdev->height)) < 0)
 	        return (code);
-	}
     }
 
   switch (ccomps) {
@@ -3383,24 +3430,31 @@ cce:  default: return gs_error_rangechec
   }
 
   if (cprn_device->cmyk) {
+      int nc;
+      gx_color_value mg, mc, dg, dc;
+
       if (cprn_device->cmyk > 0) {
-	  ci->num_components = ccomps ? ccomps : (bpp < 8 ? 1 : 4);
+	  nc = ccomps ? ccomps : (bpp < 8 ? 1 : 4);
       } else {
-	  ci->num_components = ccomps ? ccomps : (bpp < 8 ? 1 : 3);
+	  nc = ccomps ? ccomps : (bpp < 8 ? 1 : 3);
       }
-      if (bpp != 1 && ci->num_components == 1) { /* We do dithered grays. */
+      if (bpp != 1 && nc == 1) { /* We do dithered grays. */
 	  bpp = bpp < 8 ? 8 : bpp;
       }
 
-      ci->max_color = (1 << (bpp >> 2)) - 1;
-      ci->max_gray = (bpp >= 8 ? 255 : 1);
+      mc = (bpp > 1 ? (1 << (bpp >> 2)) - 1 : 0);
+      mg = (bpp >= 8 ? 255 : 1);
 
-      if (ci->num_components == 1) {
-	  ci->dither_grays = (bpp >= 8 ? 256 : 2);
-	  ci->dither_colors = (bpp >= 8 ? 256 : bpp > 1 ? 2 : 0);
+      if (nc == 1) {
+	  dg = (bpp >= 8 ? 256 : 2);
+	  dc = (bpp >= 8 ? 256 : bpp > 1 ? 2 : 0);
       } else {
-	  ci->dither_grays = (bpp > 8 ? 256 : 2);
-	  ci->dither_colors = (bpp > 8 ? 256 : bpp > 1 ? 2 : 0);
+	  dg = (bpp > 8 ? 256 : 2);
+	  dc = (bpp > 8 ? 256 : bpp > 1 ? 2 : 0);
+      }
+      {
+	  gx_device_color_info tmp = dci_values(nc, (byte)bpp, mg, mc, dg, dc);
+	  memcpy(ci, &tmp, sizeof(gx_device_color_info));
       }
   } else {
       ci->num_components = (bpp == 1 || bpp == 8 ? 1 : 3);
@@ -3412,6 +3466,15 @@ cce:  default: return gs_error_rangechec
 
   ci->depth = ((bpp > 1) && (bpp < 8) ? 8 : bpp);
 
+#ifdef BJC_DEBUG_CI
+  fprintf(stderr, "debug: num_components = %d, depth = %d\n",
+	ci->num_components, ci->depth);
+  fprintf(stderr, "debug: max_color = %d, max_gray = %d\n",
+	ci->max_color, ci->max_gray);
+  fprintf(stderr, "debug: dither_colors = %d, dither_grays = %d\n",
+	ci->dither_colors, ci->dither_grays);
+#endif
+
   return 0;
 }
 
@@ -3459,18 +3522,6 @@ cdj_put_param_bpp(gx_device *pdev, gs_pa
 	  }
 }
 
-/* This returns either the number of pixels in a scan line, or the number
- * of bytes required to store the line, both clipped to the page margins */
-static uint
-gdev_prn_rasterwidth(const gx_device_printer *pdev, int pixelcount)
-{
-  ulong raster_width = (ulong)(pdev->width -
-    pdev->x_pixels_per_inch * (dev_l_margin(pdev) + dev_r_margin(pdev)));
-  return (pixelcount ?
-          (uint)raster_width :
-          (uint)((raster_width * pdev->color_info.depth + 7) >> 3));
-}
-
 /* Functions for manipulation params strings */
 
 static const byte*
@@ -3492,7 +3543,7 @@ paramStringValue(const stringParamDescri
 {
 
     for (; params->p_name; ++params) {
-	if (strncmp(params->p_name, (char *)name, namelen) == 0 &&
+	if (strncmp(params->p_name, (const char *)name, namelen) == 0 &&
 	    params->p_name[namelen] == 0) {
 	    *value = params->p_value;
 	    return 1;
@@ -3510,8 +3561,8 @@ put_param_string(gs_param_list* plist,
 
     int ncode;
 
-    if ((ncode = param_read_string(plist, (char *)pname, pstring)) < 0) {
-	param_signal_error(plist, (char *)pname, code = ncode);
+    if ((ncode = param_read_string(plist, (const char *)pname, pstring)) < 0) {
+	param_signal_error(plist, (const char *)pname, code = ncode);
     } else if (ncode == 1) {
 	pstring->data = 0, pstring->size = 0;
     } else {
@@ -3519,7 +3570,7 @@ put_param_string(gs_param_list* plist,
 
 	if (paramStringValue(params, pstring->data, pstring->size,
             &value) == 0) {
-	    param_signal_error(plist, (char *)pname, code = gs_error_rangecheck);
+	    param_signal_error(plist, (const char *)pname, code = gs_error_rangecheck);
 	} else {
 	    *pvalue = value;
 	}
@@ -3539,19 +3590,21 @@ get_param_string(gs_param_list* plist,
     pstring->data = paramValueToString(params, pvalue);
 
     if (pstring->data == (byte*) 0) {
-	param_signal_error(plist, (char *)pname, ncode = gs_error_unknownerror);
+	param_signal_error(plist, (const char *)pname, ncode = gs_error_unknownerror);
     } else {
-        pstring->size = strlen((char *)pstring->data);
+        pstring->size = strlen((const char *)pstring->data);
 	pstring->persistent = persist;
     }
 
-    if ((ncode = param_write_string(plist, (char *)pname, pstring)) < 0) {
+    if ((ncode = param_write_string(plist, (const char *)pname, pstring)) < 0) {
 	code = ncode;
     }
 
     return code;
 }
 
+/* The following functions should (IMHO) be available to all drivers. */
+
 /*
  * This taken from gsdparam.c. I hope it will be useable directly some day.
  *
@@ -3606,6 +3659,88 @@ e:              param_signal_error(plist
         return code;
 }
 
+/* Put InputAttributes and OutputAttributes. */
+int
+gdev_prn_input_var_page_size(int index, gs_param_dict *pdict,
+  floatp width_points, floatp height_points)
+{	var_input_media media;
+	media.PageSize[0] = media.PageSize[1] = 0;
+	media.PageSize[2] = width_points;
+	media.PageSize[3] = height_points;
+	media.MediaColor = 0;
+	media.MediaWeight = 0;
+	media.MediaType = 0;
+	return gdev_prn_input_var_media(index, pdict, &media);
+}
+static int
+gdev_prn_finish_media(gs_param_list *mlist, gs_param_name key, const char *media_type)
+{	int code = 0;
+	if ( media_type != 0 )
+	  {	gs_param_string as;
+		param_string_from_string(as, media_type);
+		code = param_write_string(mlist, key, &as);
+	  }
+	return code;
+}
+int
+gdev_prn_input_var_media(int index, gs_param_dict *pdict, const var_input_media *pim)
+{	char key[25];
+	gs_param_dict mdict;
+	int code;
+	gs_param_string as;
+
+	sprintf(key, "%d", index);
+	mdict.size = 4;
+	code = param_begin_write_dict(pdict->list, key, &mdict, false);
+	if ( code < 0 )
+	  return code;
+	if ( pim->PageSize[2] != 0 && pim->PageSize[3] != 0
+	    && pim->PageSize[0] < pim->PageSize[2]
+	    && pim->PageSize[1] < pim->PageSize[3])
+	  {	gs_param_float_array psa;
+		psa.data = pim->PageSize, psa.size = 4, psa.persistent = false;
+		code = param_write_float_array(mdict.list, "PageSize",
+					       &psa);
+		if ( code < 0 )
+		  return code;
+	  }
+	if ( pim->MediaColor != 0 )
+	  {	param_string_from_string(as, pim->MediaColor);
+		code = param_write_string(mdict.list, "MediaColor",
+					  &as);
+		if ( code < 0 )
+		  return code;
+	  }
+	if ( pim->MediaWeight != 0 )
+	  {	/* We do the following silly thing in order to avoid */
+		/* having to work around the 'const' in the arg list. */
+		float weight = pim->MediaWeight;
+		code = param_write_float(mdict.list, "MediaWeight",
+					 &weight);
+		if ( code < 0 )
+		  return code;
+	  }
+	code = gdev_prn_finish_media(mdict.list, "MediaType", pim->MediaType);
+	if ( code < 0 )
+	  return code;
+	return param_end_write_dict(pdict->list, key, &mdict);
+}
+
+/* This returns either the number of pixels in a scan line, or the number
+ * of bytes required to store the line, both clipped to the page margins */
+static uint
+gdev_prn_rasterwidth(const gx_device_printer *pdev, int pixelcount)
+{
+  ulong raster_width =
+    pdev->width - pdev->x_pixels_per_inch * (dev_l_margin(pdev)
+	+ dev_r_margin(pdev));
+  return (pixelcount ?
+	(uint)raster_width :
+	(uint)((raster_width * pdev->color_info.depth + 7) >> 3));
+}
+
+/* End of generic functions. */
+
 /* The following dithering algorithm has been kindly given to me (YA) by
  * Klaus-Gunther Hess, I just adapted it for use with the code here. */
 
openSUSE Build Service is sponsored by