1*7dd7cddfSDavid du Colombier /* Copyright (C) 1991, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved. 2*7dd7cddfSDavid du Colombier 3*7dd7cddfSDavid du Colombier This file is part of Aladdin Ghostscript. 4*7dd7cddfSDavid du Colombier 5*7dd7cddfSDavid du Colombier Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author 6*7dd7cddfSDavid du Colombier or distributor accepts any responsibility for the consequences of using it, 7*7dd7cddfSDavid du Colombier or for whether it serves any particular purpose or works at all, unless he 8*7dd7cddfSDavid du Colombier or she says so in writing. Refer to the Aladdin Ghostscript Free Public 9*7dd7cddfSDavid du Colombier License (the "License") for full details. 10*7dd7cddfSDavid du Colombier 11*7dd7cddfSDavid du Colombier Every copy of Aladdin Ghostscript must include a copy of the License, 12*7dd7cddfSDavid du Colombier normally in a plain ASCII text file named PUBLIC. The License grants you 13*7dd7cddfSDavid du Colombier the right to copy, modify and redistribute Aladdin Ghostscript, but only 14*7dd7cddfSDavid du Colombier under certain conditions described in the License. Among other things, the 15*7dd7cddfSDavid du Colombier License requires that the copyright notice and this notice be preserved on 16*7dd7cddfSDavid du Colombier all copies. 17*7dd7cddfSDavid du Colombier */ 18*7dd7cddfSDavid du Colombier 19*7dd7cddfSDavid du Colombier /*$Id: gdevbit.c,v 1.1 2000/03/09 08:40:40 lpd Exp $ */ 20*7dd7cddfSDavid du Colombier /* "Plain bits" devices to measure rendering time. */ 21*7dd7cddfSDavid du Colombier #include "math_.h" 22*7dd7cddfSDavid du Colombier #include "gdevprn.h" 23*7dd7cddfSDavid du Colombier #include "gsparam.h" 24*7dd7cddfSDavid du Colombier #include "gscrd.h" 25*7dd7cddfSDavid du Colombier #include "gscrdp.h" 26*7dd7cddfSDavid du Colombier #include "gxlum.h" 27*7dd7cddfSDavid du Colombier #include "gdevdcrd.h" 28*7dd7cddfSDavid du Colombier 29*7dd7cddfSDavid du Colombier /* Define the device parameters. */ 30*7dd7cddfSDavid du Colombier #ifndef X_DPI 31*7dd7cddfSDavid du Colombier # define X_DPI 72 32*7dd7cddfSDavid du Colombier #endif 33*7dd7cddfSDavid du Colombier #ifndef Y_DPI 34*7dd7cddfSDavid du Colombier # define Y_DPI 72 35*7dd7cddfSDavid du Colombier #endif 36*7dd7cddfSDavid du Colombier 37*7dd7cddfSDavid du Colombier /* The device descriptor */ 38*7dd7cddfSDavid du Colombier private dev_proc_map_rgb_color(bit_mono_map_rgb_color); 39*7dd7cddfSDavid du Colombier private dev_proc_map_rgb_color(bit_forcemono_map_rgb_color); 40*7dd7cddfSDavid du Colombier private dev_proc_map_color_rgb(bit_map_color_rgb); 41*7dd7cddfSDavid du Colombier private dev_proc_map_cmyk_color(bit_map_cmyk_color); 42*7dd7cddfSDavid du Colombier private dev_proc_get_params(bit_get_params); 43*7dd7cddfSDavid du Colombier private dev_proc_put_params(bit_put_params); 44*7dd7cddfSDavid du Colombier private dev_proc_print_page(bit_print_page); 45*7dd7cddfSDavid du Colombier 46*7dd7cddfSDavid du Colombier #define bit_procs(map_rgb_color, map_cmyk_color)\ 47*7dd7cddfSDavid du Colombier { gdev_prn_open,\ 48*7dd7cddfSDavid du Colombier gx_default_get_initial_matrix,\ 49*7dd7cddfSDavid du Colombier NULL, /* sync_output */\ 50*7dd7cddfSDavid du Colombier gdev_prn_output_page,\ 51*7dd7cddfSDavid du Colombier gdev_prn_close,\ 52*7dd7cddfSDavid du Colombier map_rgb_color,\ 53*7dd7cddfSDavid du Colombier bit_map_color_rgb,\ 54*7dd7cddfSDavid du Colombier NULL, /* fill_rectangle */\ 55*7dd7cddfSDavid du Colombier NULL, /* tile_rectangle */\ 56*7dd7cddfSDavid du Colombier NULL, /* copy_mono */\ 57*7dd7cddfSDavid du Colombier NULL, /* copy_color */\ 58*7dd7cddfSDavid du Colombier NULL, /* draw_line */\ 59*7dd7cddfSDavid du Colombier NULL, /* get_bits */\ 60*7dd7cddfSDavid du Colombier bit_get_params,\ 61*7dd7cddfSDavid du Colombier bit_put_params,\ 62*7dd7cddfSDavid du Colombier map_cmyk_color,\ 63*7dd7cddfSDavid du Colombier NULL, /* get_xfont_procs */\ 64*7dd7cddfSDavid du Colombier NULL, /* get_xfont_device */\ 65*7dd7cddfSDavid du Colombier NULL, /* map_rgb_alpha_color */\ 66*7dd7cddfSDavid du Colombier gx_page_device_get_page_device /* get_page_device */\ 67*7dd7cddfSDavid du Colombier } 68*7dd7cddfSDavid du Colombier 69*7dd7cddfSDavid du Colombier /* 70*7dd7cddfSDavid du Colombier * The following macro is used in get_params and put_params to determine the 71*7dd7cddfSDavid du Colombier * num_components for the current device. It works using the device name 72*7dd7cddfSDavid du Colombier * character after "bit" which is either '\0', 'r', or 'c'. Any new devices 73*7dd7cddfSDavid du Colombier * that are added to this module must modify this macro to return the 74*7dd7cddfSDavid du Colombier * correct num_components. This is needed to support the ForceMono 75*7dd7cddfSDavid du Colombier * parameter, which alters dev->num_components. 76*7dd7cddfSDavid du Colombier */ 77*7dd7cddfSDavid du Colombier #define REAL_NUM_COMPONENTS(dev) (dev->dname[3] == 'c' ? 4 : \ 78*7dd7cddfSDavid du Colombier dev->dname[3] == 'r' ? 3 : 1) 79*7dd7cddfSDavid du Colombier 80*7dd7cddfSDavid du Colombier private const gx_device_procs bitmono_procs = 81*7dd7cddfSDavid du Colombier bit_procs(bit_mono_map_rgb_color, NULL); 82*7dd7cddfSDavid du Colombier const gx_device_printer gs_bit_device = 83*7dd7cddfSDavid du Colombier {prn_device_body(gx_device_printer, bitmono_procs, "bit", 84*7dd7cddfSDavid du Colombier DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS, 85*7dd7cddfSDavid du Colombier X_DPI, Y_DPI, 86*7dd7cddfSDavid du Colombier 0, 0, 0, 0, /* margins */ 87*7dd7cddfSDavid du Colombier 1, 1, 1, 0, 2, 1, bit_print_page) 88*7dd7cddfSDavid du Colombier }; 89*7dd7cddfSDavid du Colombier 90*7dd7cddfSDavid du Colombier private const gx_device_procs bitrgb_procs = 91*7dd7cddfSDavid du Colombier bit_procs(gx_default_rgb_map_rgb_color, NULL); 92*7dd7cddfSDavid du Colombier const gx_device_printer gs_bitrgb_device = 93*7dd7cddfSDavid du Colombier {prn_device_body(gx_device_printer, bitrgb_procs, "bitrgb", 94*7dd7cddfSDavid du Colombier DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS, 95*7dd7cddfSDavid du Colombier X_DPI, Y_DPI, 96*7dd7cddfSDavid du Colombier 0, 0, 0, 0, /* margins */ 97*7dd7cddfSDavid du Colombier 3, 4, 1, 1, 2, 2, bit_print_page) 98*7dd7cddfSDavid du Colombier }; 99*7dd7cddfSDavid du Colombier 100*7dd7cddfSDavid du Colombier private const gx_device_procs bitcmyk_procs = 101*7dd7cddfSDavid du Colombier bit_procs(bit_forcemono_map_rgb_color, bit_map_cmyk_color); 102*7dd7cddfSDavid du Colombier const gx_device_printer gs_bitcmyk_device = 103*7dd7cddfSDavid du Colombier {prn_device_body(gx_device_printer, bitcmyk_procs, "bitcmyk", 104*7dd7cddfSDavid du Colombier DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS, 105*7dd7cddfSDavid du Colombier X_DPI, Y_DPI, 106*7dd7cddfSDavid du Colombier 0, 0, 0, 0, /* margins */ 107*7dd7cddfSDavid du Colombier 4, 4, 1, 1, 2, 2, bit_print_page) 108*7dd7cddfSDavid du Colombier }; 109*7dd7cddfSDavid du Colombier 110*7dd7cddfSDavid du Colombier /* Map gray to color. */ 111*7dd7cddfSDavid du Colombier /* Note that 1-bit monochrome is a special case. */ 112*7dd7cddfSDavid du Colombier private gx_color_index 113*7dd7cddfSDavid du Colombier bit_mono_map_rgb_color(gx_device * dev, gx_color_value red, 114*7dd7cddfSDavid du Colombier gx_color_value green, gx_color_value blue) 115*7dd7cddfSDavid du Colombier { 116*7dd7cddfSDavid du Colombier int bpc = dev->color_info.depth; 117*7dd7cddfSDavid du Colombier int drop = sizeof(gx_color_value) * 8 - bpc; 118*7dd7cddfSDavid du Colombier gx_color_value gray = 119*7dd7cddfSDavid du Colombier (red * (unsigned long)lum_red_weight + 120*7dd7cddfSDavid du Colombier green * (unsigned long)lum_green_weight + 121*7dd7cddfSDavid du Colombier blue * (unsigned long)lum_blue_weight + 122*7dd7cddfSDavid du Colombier (lum_all_weights / 2)) 123*7dd7cddfSDavid du Colombier / lum_all_weights; 124*7dd7cddfSDavid du Colombier 125*7dd7cddfSDavid du Colombier return (bpc == 1 ? gx_max_color_value - gray : gray) >> drop; 126*7dd7cddfSDavid du Colombier } 127*7dd7cddfSDavid du Colombier 128*7dd7cddfSDavid du Colombier /* Map RGB to gray shade. */ 129*7dd7cddfSDavid du Colombier /* Only used in CMYK mode when put_params has set ForceMono=1 */ 130*7dd7cddfSDavid du Colombier private gx_color_index 131*7dd7cddfSDavid du Colombier bit_forcemono_map_rgb_color(gx_device * dev, gx_color_value red, 132*7dd7cddfSDavid du Colombier gx_color_value green, gx_color_value blue) 133*7dd7cddfSDavid du Colombier { 134*7dd7cddfSDavid du Colombier gx_color_value color; 135*7dd7cddfSDavid du Colombier int bpc = dev->color_info.depth / 4; /* This function is used in CMYK mode */ 136*7dd7cddfSDavid du Colombier int drop = sizeof(gx_color_value) * 8 - bpc; 137*7dd7cddfSDavid du Colombier gx_color_value gray = red; 138*7dd7cddfSDavid du Colombier 139*7dd7cddfSDavid du Colombier if ((red != green) || (green != blue)) 140*7dd7cddfSDavid du Colombier gray = (red * (unsigned long)lum_red_weight + 141*7dd7cddfSDavid du Colombier green * (unsigned long)lum_green_weight + 142*7dd7cddfSDavid du Colombier blue * (unsigned long)lum_blue_weight + 143*7dd7cddfSDavid du Colombier (lum_all_weights / 2)) 144*7dd7cddfSDavid du Colombier / lum_all_weights; 145*7dd7cddfSDavid du Colombier 146*7dd7cddfSDavid du Colombier color = (gx_max_color_value - gray) >> drop; /* color is in K channel */ 147*7dd7cddfSDavid du Colombier return color; 148*7dd7cddfSDavid du Colombier } 149*7dd7cddfSDavid du Colombier 150*7dd7cddfSDavid du Colombier /* Map color to RGB. This has 3 separate cases, but since it is rarely */ 151*7dd7cddfSDavid du Colombier /* used, we do a case test rather than providing 3 separate routines. */ 152*7dd7cddfSDavid du Colombier private int 153*7dd7cddfSDavid du Colombier bit_map_color_rgb(gx_device * dev, gx_color_index color, gx_color_value rgb[3]) 154*7dd7cddfSDavid du Colombier { 155*7dd7cddfSDavid du Colombier int depth = dev->color_info.depth; 156*7dd7cddfSDavid du Colombier int ncomp = REAL_NUM_COMPONENTS(dev); 157*7dd7cddfSDavid du Colombier int bpc = depth / ncomp; 158*7dd7cddfSDavid du Colombier uint mask = (1 << bpc) - 1; 159*7dd7cddfSDavid du Colombier 160*7dd7cddfSDavid du Colombier #define cvalue(c) ((gx_color_value)((ulong)(c) * gx_max_color_value / mask)) 161*7dd7cddfSDavid du Colombier 162*7dd7cddfSDavid du Colombier switch (ncomp) { 163*7dd7cddfSDavid du Colombier case 1: /* gray */ 164*7dd7cddfSDavid du Colombier rgb[0] = rgb[1] = rgb[2] = 165*7dd7cddfSDavid du Colombier (depth == 1 ? (color ? 0 : gx_max_color_value) : 166*7dd7cddfSDavid du Colombier cvalue(color)); 167*7dd7cddfSDavid du Colombier break; 168*7dd7cddfSDavid du Colombier case 3: /* RGB */ 169*7dd7cddfSDavid du Colombier { 170*7dd7cddfSDavid du Colombier gx_color_index cshift = color; 171*7dd7cddfSDavid du Colombier 172*7dd7cddfSDavid du Colombier rgb[2] = cvalue(cshift & mask); 173*7dd7cddfSDavid du Colombier cshift >>= bpc; 174*7dd7cddfSDavid du Colombier rgb[1] = cvalue(cshift & mask); 175*7dd7cddfSDavid du Colombier rgb[0] = cvalue(cshift >> bpc); 176*7dd7cddfSDavid du Colombier } 177*7dd7cddfSDavid du Colombier break; 178*7dd7cddfSDavid du Colombier case 4: /* CMYK */ 179*7dd7cddfSDavid du Colombier /* Map CMYK back to RGB. */ 180*7dd7cddfSDavid du Colombier { 181*7dd7cddfSDavid du Colombier gx_color_index cshift = color; 182*7dd7cddfSDavid du Colombier uint c, m, y, k; 183*7dd7cddfSDavid du Colombier 184*7dd7cddfSDavid du Colombier k = cshift & mask; 185*7dd7cddfSDavid du Colombier cshift >>= bpc; 186*7dd7cddfSDavid du Colombier y = cshift & mask; 187*7dd7cddfSDavid du Colombier cshift >>= bpc; 188*7dd7cddfSDavid du Colombier m = cshift & mask; 189*7dd7cddfSDavid du Colombier c = cshift >> bpc; 190*7dd7cddfSDavid du Colombier /* We use our improved conversion rule.... */ 191*7dd7cddfSDavid du Colombier rgb[0] = cvalue((mask - c) * (mask - k) / mask); 192*7dd7cddfSDavid du Colombier rgb[1] = cvalue((mask - m) * (mask - k) / mask); 193*7dd7cddfSDavid du Colombier rgb[2] = cvalue((mask - y) * (mask - k) / mask); 194*7dd7cddfSDavid du Colombier } 195*7dd7cddfSDavid du Colombier break; 196*7dd7cddfSDavid du Colombier } 197*7dd7cddfSDavid du Colombier return 0; 198*7dd7cddfSDavid du Colombier #undef cvalue 199*7dd7cddfSDavid du Colombier } 200*7dd7cddfSDavid du Colombier 201*7dd7cddfSDavid du Colombier /* Map CMYK to color. */ 202*7dd7cddfSDavid du Colombier private gx_color_index 203*7dd7cddfSDavid du Colombier bit_map_cmyk_color(gx_device * dev, gx_color_value cyan, 204*7dd7cddfSDavid du Colombier gx_color_value magenta, gx_color_value yellow, gx_color_value black) 205*7dd7cddfSDavid du Colombier { 206*7dd7cddfSDavid du Colombier int bpc = dev->color_info.depth / 4; 207*7dd7cddfSDavid du Colombier int drop = sizeof(gx_color_value) * 8 - bpc; 208*7dd7cddfSDavid du Colombier gx_color_index color = 209*7dd7cddfSDavid du Colombier ((((((cyan >> drop) << bpc) + 210*7dd7cddfSDavid du Colombier (magenta >> drop)) << bpc) + 211*7dd7cddfSDavid du Colombier (yellow >> drop)) << bpc) + 212*7dd7cddfSDavid du Colombier (black >> drop); 213*7dd7cddfSDavid du Colombier 214*7dd7cddfSDavid du Colombier return (color == gx_no_color_index ? color ^ 1 : color); 215*7dd7cddfSDavid du Colombier } 216*7dd7cddfSDavid du Colombier 217*7dd7cddfSDavid du Colombier /* Get parameters. We provide a default CRD. */ 218*7dd7cddfSDavid du Colombier private int 219*7dd7cddfSDavid du Colombier bit_get_params(gx_device * pdev, gs_param_list * plist) 220*7dd7cddfSDavid du Colombier { 221*7dd7cddfSDavid du Colombier int code, ecode; 222*7dd7cddfSDavid du Colombier /* 223*7dd7cddfSDavid du Colombier * The following is a hack to get the original num_components. 224*7dd7cddfSDavid du Colombier * See comment above. 225*7dd7cddfSDavid du Colombier */ 226*7dd7cddfSDavid du Colombier int real_ncomps = REAL_NUM_COMPONENTS(pdev); 227*7dd7cddfSDavid du Colombier int ncomps = pdev->color_info.num_components; 228*7dd7cddfSDavid du Colombier int forcemono = (ncomps == real_ncomps ? 0 : 1); 229*7dd7cddfSDavid du Colombier 230*7dd7cddfSDavid du Colombier /* 231*7dd7cddfSDavid du Colombier * Temporarily set num_components back to the "real" value to avoid 232*7dd7cddfSDavid du Colombier * confusing those that rely on it. 233*7dd7cddfSDavid du Colombier */ 234*7dd7cddfSDavid du Colombier pdev->color_info.num_components = real_ncomps; 235*7dd7cddfSDavid du Colombier 236*7dd7cddfSDavid du Colombier ecode = gdev_prn_get_params(pdev, plist); 237*7dd7cddfSDavid du Colombier code = sample_device_crd_get_params(pdev, plist, "CRDDefault"); 238*7dd7cddfSDavid du Colombier if (code < 0) 239*7dd7cddfSDavid du Colombier ecode = code; 240*7dd7cddfSDavid du Colombier if ((code = param_write_int(plist, "ForceMono", &forcemono)) < 0) { 241*7dd7cddfSDavid du Colombier ecode = code; 242*7dd7cddfSDavid du Colombier } 243*7dd7cddfSDavid du Colombier 244*7dd7cddfSDavid du Colombier /* Restore the working num_components */ 245*7dd7cddfSDavid du Colombier pdev->color_info.num_components = ncomps; 246*7dd7cddfSDavid du Colombier 247*7dd7cddfSDavid du Colombier return ecode; 248*7dd7cddfSDavid du Colombier } 249*7dd7cddfSDavid du Colombier 250*7dd7cddfSDavid du Colombier /* Set parameters. We allow setting the number of bits per component. */ 251*7dd7cddfSDavid du Colombier /* Also, ForceMono=1 forces monochrome output from RGB/CMYK devices. */ 252*7dd7cddfSDavid du Colombier private int 253*7dd7cddfSDavid du Colombier bit_put_params(gx_device * pdev, gs_param_list * plist) 254*7dd7cddfSDavid du Colombier { 255*7dd7cddfSDavid du Colombier gx_device_color_info save_info; 256*7dd7cddfSDavid du Colombier int ncomps = pdev->color_info.num_components; 257*7dd7cddfSDavid du Colombier int real_ncomps = REAL_NUM_COMPONENTS(pdev); 258*7dd7cddfSDavid du Colombier int bpc = pdev->color_info.depth / real_ncomps; 259*7dd7cddfSDavid du Colombier int v; 260*7dd7cddfSDavid du Colombier int ecode = 0; 261*7dd7cddfSDavid du Colombier int code; 262*7dd7cddfSDavid du Colombier static const byte depths[4][8] = { 263*7dd7cddfSDavid du Colombier {1, 2, 0, 4, 8, 0, 0, 8}, 264*7dd7cddfSDavid du Colombier {0}, 265*7dd7cddfSDavid du Colombier {4, 8, 0, 16, 16, 0, 0, 24}, 266*7dd7cddfSDavid du Colombier {4, 8, 0, 16, 32, 0, 0, 32} 267*7dd7cddfSDavid du Colombier }; 268*7dd7cddfSDavid du Colombier const char *vname; 269*7dd7cddfSDavid du Colombier 270*7dd7cddfSDavid du Colombier /* 271*7dd7cddfSDavid du Colombier * Temporarily set num_components back to the "real" value to avoid 272*7dd7cddfSDavid du Colombier * confusing those that rely on it. 273*7dd7cddfSDavid du Colombier */ 274*7dd7cddfSDavid du Colombier pdev->color_info.num_components = real_ncomps; 275*7dd7cddfSDavid du Colombier 276*7dd7cddfSDavid du Colombier if ((code = param_read_int(plist, (vname = "GrayValues"), &v)) != 1 || 277*7dd7cddfSDavid du Colombier (code = param_read_int(plist, (vname = "RedValues"), &v)) != 1 || 278*7dd7cddfSDavid du Colombier (code = param_read_int(plist, (vname = "GreenValues"), &v)) != 1 || 279*7dd7cddfSDavid du Colombier (code = param_read_int(plist, (vname = "BlueValues"), &v)) != 1 280*7dd7cddfSDavid du Colombier ) { 281*7dd7cddfSDavid du Colombier if (code < 0) 282*7dd7cddfSDavid du Colombier ecode = code; 283*7dd7cddfSDavid du Colombier else 284*7dd7cddfSDavid du Colombier switch (v) { 285*7dd7cddfSDavid du Colombier case 2: bpc = 1; break; 286*7dd7cddfSDavid du Colombier case 4: bpc = 2; break; 287*7dd7cddfSDavid du Colombier case 16: bpc = 4; break; 288*7dd7cddfSDavid du Colombier case 32: bpc = 5; break; 289*7dd7cddfSDavid du Colombier case 256: bpc = 8; break; 290*7dd7cddfSDavid du Colombier default: 291*7dd7cddfSDavid du Colombier param_signal_error(plist, vname, 292*7dd7cddfSDavid du Colombier ecode = gs_error_rangecheck); 293*7dd7cddfSDavid du Colombier } 294*7dd7cddfSDavid du Colombier } 295*7dd7cddfSDavid du Colombier 296*7dd7cddfSDavid du Colombier switch (code = param_read_int(plist, (vname = "ForceMono"), &v)) { 297*7dd7cddfSDavid du Colombier case 0: 298*7dd7cddfSDavid du Colombier if (v == 1) { 299*7dd7cddfSDavid du Colombier ncomps = 1; 300*7dd7cddfSDavid du Colombier break; 301*7dd7cddfSDavid du Colombier } 302*7dd7cddfSDavid du Colombier else if (v == 0) { 303*7dd7cddfSDavid du Colombier ncomps = real_ncomps; 304*7dd7cddfSDavid du Colombier break; 305*7dd7cddfSDavid du Colombier } 306*7dd7cddfSDavid du Colombier code = gs_error_rangecheck; 307*7dd7cddfSDavid du Colombier default: 308*7dd7cddfSDavid du Colombier ecode = code; 309*7dd7cddfSDavid du Colombier param_signal_error(plist, vname, ecode); 310*7dd7cddfSDavid du Colombier case 1: 311*7dd7cddfSDavid du Colombier break; 312*7dd7cddfSDavid du Colombier } 313*7dd7cddfSDavid du Colombier if (ecode < 0) 314*7dd7cddfSDavid du Colombier return ecode; 315*7dd7cddfSDavid du Colombier 316*7dd7cddfSDavid du Colombier /* 317*7dd7cddfSDavid du Colombier * Save the color_info in case gdev_prn_put_params fails, and for 318*7dd7cddfSDavid du Colombier * comparison. Note that depth is computed from real_ncomps. 319*7dd7cddfSDavid du Colombier */ 320*7dd7cddfSDavid du Colombier save_info = pdev->color_info; 321*7dd7cddfSDavid du Colombier pdev->color_info.depth = depths[real_ncomps - 1][bpc - 1]; 322*7dd7cddfSDavid du Colombier pdev->color_info.max_gray = pdev->color_info.max_color = 323*7dd7cddfSDavid du Colombier (pdev->color_info.dither_grays = 324*7dd7cddfSDavid du Colombier pdev->color_info.dither_colors = 325*7dd7cddfSDavid du Colombier (1 << bpc)) - 1; 326*7dd7cddfSDavid du Colombier ecode = gdev_prn_put_params(pdev, plist); 327*7dd7cddfSDavid du Colombier if (ecode < 0) { 328*7dd7cddfSDavid du Colombier pdev->color_info = save_info; 329*7dd7cddfSDavid du Colombier return ecode; 330*7dd7cddfSDavid du Colombier } 331*7dd7cddfSDavid du Colombier /* Now restore/change num_components. This is done after other */ 332*7dd7cddfSDavid du Colombier /* processing since it is used in gx_default_put_params */ 333*7dd7cddfSDavid du Colombier pdev->color_info.num_components = ncomps; 334*7dd7cddfSDavid du Colombier if (pdev->color_info.depth != save_info.depth || 335*7dd7cddfSDavid du Colombier pdev->color_info.num_components != save_info.num_components 336*7dd7cddfSDavid du Colombier ) { 337*7dd7cddfSDavid du Colombier gs_closedevice(pdev); 338*7dd7cddfSDavid du Colombier } 339*7dd7cddfSDavid du Colombier /* Reset the map_cmyk_color procedure if appropriate. */ 340*7dd7cddfSDavid du Colombier if (dev_proc(pdev, map_cmyk_color) == cmyk_1bit_map_cmyk_color || 341*7dd7cddfSDavid du Colombier dev_proc(pdev, map_cmyk_color) == cmyk_8bit_map_cmyk_color || 342*7dd7cddfSDavid du Colombier dev_proc(pdev, map_cmyk_color) == bit_map_cmyk_color) { 343*7dd7cddfSDavid du Colombier set_dev_proc(pdev, map_cmyk_color, 344*7dd7cddfSDavid du Colombier pdev->color_info.depth == 4 ? cmyk_1bit_map_cmyk_color : 345*7dd7cddfSDavid du Colombier pdev->color_info.depth == 32 ? cmyk_8bit_map_cmyk_color : 346*7dd7cddfSDavid du Colombier bit_map_cmyk_color); 347*7dd7cddfSDavid du Colombier } 348*7dd7cddfSDavid du Colombier return 0; 349*7dd7cddfSDavid du Colombier } 350*7dd7cddfSDavid du Colombier 351*7dd7cddfSDavid du Colombier /* Send the page to the printer. */ 352*7dd7cddfSDavid du Colombier private int 353*7dd7cddfSDavid du Colombier bit_print_page(gx_device_printer * pdev, FILE * prn_stream) 354*7dd7cddfSDavid du Colombier { /* Just dump the bits on the file. */ 355*7dd7cddfSDavid du Colombier /* If the file is 'nul', don't even do the writes. */ 356*7dd7cddfSDavid du Colombier int line_size = gdev_mem_bytes_per_scan_line((gx_device *) pdev); 357*7dd7cddfSDavid du Colombier byte *in = gs_alloc_bytes(pdev->memory, line_size, "bit_print_page(in)"); 358*7dd7cddfSDavid du Colombier byte *data; 359*7dd7cddfSDavid du Colombier int nul = !strcmp(pdev->fname, "nul"); 360*7dd7cddfSDavid du Colombier int lnum = 0, bottom = pdev->height; 361*7dd7cddfSDavid du Colombier 362*7dd7cddfSDavid du Colombier if (in == 0) 363*7dd7cddfSDavid du Colombier return_error(gs_error_VMerror); 364*7dd7cddfSDavid du Colombier for (; lnum < bottom; ++lnum) { 365*7dd7cddfSDavid du Colombier gdev_prn_get_bits(pdev, lnum, in, &data); 366*7dd7cddfSDavid du Colombier if (!nul) 367*7dd7cddfSDavid du Colombier fwrite(data, 1, line_size, prn_stream); 368*7dd7cddfSDavid du Colombier } 369*7dd7cddfSDavid du Colombier gs_free_object(pdev->memory, in, "bit_print_page(in)"); 370*7dd7cddfSDavid du Colombier return 0; 371*7dd7cddfSDavid du Colombier } 372