1 /* BJC-210/240/250/265/1000 Bubble Jet Printer driver for GhostScript
2  * main subroutines for GS
3  *
4  * Copyright 2000, 2001, 2002 Gergely Sz�sz (Gergely Sza'sz)
5  * mailto://szaszg@hu.inter.net http://bjc250gs.sourceforge.net
6  *
7  *   This program may be distributed and/or modified under the terms of
8  *   the GNU General Public License as published by the Free Software
9  *   Foundation (the "GPL"); either version 2 of the GPL, or (at your option)
10  *   any later version.
11  *
12  *   When distributed under the terms of the GPL, this program is distributed
13  *   in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
14  *   even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  *   PURPOSE.  See the GPL for more details.
16  *
17  *   If this program is being distributed under the terms of the GPL, you
18  *   should have received a copy of the GPL along with this program, normally
19  *   in a plain ASCII text file named COPYING; if not, write to the Free
20  *   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111
21  *   U.S.A.
22  */
23 
24 /* Copyright (C) 1989, 2000 Aladdin Enterprises.  All rights reserved.
25 
26    This program may also be distributed as part of AFPL Ghostscript, under the
27    terms of the Aladdin Free Public License (the "License").
28 
29    AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No
30    author or distributor accepts any responsibility for the consequences of
31    using it, or for whether it serves any particular purpose or works at
32    all, unless he or she says so in writing.  Refer to the License for full
33    details.
34 
35    Every copy of AFPL Ghostscript must include a copy of the License,
36    normally in a plain ASCII text file named PUBLIC.  The License grants you
37    the right to copy, modify and redistribute AFPL Ghostscript, but only
38    under certain conditions described in the License.  Among other things,
39    the License requires that the copyright notice and this notice be
40    preserved on all copies.
41 */
42 
43 /* BJC printers drivers */
44 #include "gdevprn.h"
45 #include "gsparam.h"
46 #include "gdevbjc_.h"
47 
48 /* ------ The device descriptors ------ */
49 private dev_proc_print_page(bjc_print_page);
50 private dev_proc_print_page(bjc_print_page_mono);
51 private dev_proc_print_page(bjc_print_page_gray);
52 private dev_proc_print_page(bjc_print_page_cmyk);
53 private dev_proc_print_page(bjc_print_page_color);
54 private dev_proc_put_params(gdev_bjc_put_params);
55 private dev_proc_get_params(gdev_bjc_get_params);
56 const stringParamDescription *
57  paramValueToParam(P2(const stringParamDescription *, int));
58 const stringParamDescription *
59  paramStringToParam(P3(const stringParamDescription *, const char *, uint));
60 
61 BJL_command BJL_command_set[] = {
62     { "@Cleaning=1",            BJC_BJL_CLEANING,      11},
63     { "@PowerOff",              BJC_BJL_POWER_OFF,      9},
64     { "@RollerCleaning",        BJC_BJL_ROCLEANING,    15},
65     { "@TestPrint=NozzleCheck", BJC_BJL_NOZZLECHK,     22},
66     { "@TestPrint=A",           BJC_BJL_TESTA,         12},
67     { "@TestPrint=B",           BJC_BJL_TESTB,         12},
68     { "@TestPrint=C",           BJC_BJL_TESTC,         12},
69     { "@TestPrint=DemoPrint",   BJC_BJL_DEMO,          20},
70 
71 #define BJL_CMC_AP  "ControlMode=Common\012AutoPower"  //+28
72 
73     { BJL_CMC_AP "On=Enable",   BJC_BJL_ON_ENABLE,     37},
74     { BJL_CMC_AP "On=Disable",  BJC_BJL_ON_DISABLE,    38},
75     { BJL_CMC_AP "Off=1",       BJC_BJL_OFF_1MIN,      33},
76     { BJL_CMC_AP "Off=10",      BJC_BJL_OFF_10MIN,     34},
77     { BJL_CMC_AP "Off=30",      BJC_BJL_OFF_30MIN,     34},
78     { BJL_CMC_AP "Off=60",      BJC_BJL_OFF_60MIN,     34},
79     { BJL_CMC_AP "Off=Disable", BJC_BJL_OFF_DISABLE,   39},
80     { NULL }
81 };
82 
83 
84 /* String parameter definitions */
85 
86 stringParamDescription strPrinterType[] = {
87     { { "BJC-250",    7, false },   	0 },
88     { { "BJC-250ex",  9, false }, 	1 },
89     { { "BJC-1000",   8, false },  	2 },
90 
91     { { "250",   3, false },       	0 },
92     { { "250ex", 5, false },     	1 },
93     { { "1000",  4, false },      	2 },
94     { {0} }
95 };
96 
97 stringParamDescription strFeeder[] = {
98     { { "Manual",	6, false },    	0x11 },
99     { { "Auto",        	4, false },    	0x10 },
100 
101     { { "m",		1, false },    	0x11 },
102     { { "a",		1, false },    	0x10 },
103     { {0} }
104 };
105 
106 stringParamDescription strQuality[] = {
107     { { "Normal",	6, false },    	0 },
108     { { "High",        	4, false },    	1 },
109     { { "Draft",        5, false },    	2 },
110     { { "NonBleed",   	8, false },    	8 },
111 
112     { { "n",		1, false },    	0 },
113     { { "h",		1, false },    	1 },
114     { { "d",		1, false },    	2 },
115     { { "b",		1, false },    	8 },
116     { {0} }
117 };
118 
119 stringParamDescription strInk[] = {
120     { { "Black",	5, false },    	8 },
121     { { "Cyan",        	4, false },    	1 },
122     { { "Magenta",      7, false },    	2 },
123     { { "Yellow",   	6, false },    	4 },
124     { { "Red",        	3, false },    	6 },
125     { { "Green",        5, false },    	5 },
126     { { "Blue",   	4, false },    	3 },
127 
128     { { "K",		1, false },    	8 },
129     { { "C",		1, false },    	1 },
130     { { "M",		1, false },    	2 },
131     { { "Y",		1, false },    	4 },
132     { { "R",		1, false },    	6 },
133     { { "G",		1, false },    	5 },
134     { { "B",		1, false },    	3 },
135     { { "CK",		2, false },    	9 },
136     { { "MK",		2, false },    10 },
137     { { "YK",		2, false },    12 },
138     { { "RK",		2, false },    14 },
139     { { "GK",		2, false },    13 },
140     { { "BK",		2, false },    11 },
141     { { "CMY",		3, false },     7 },
142     { { "CMYK",		4, false },    15 },
143     { {0} }
144 };
145 
146 private stringParamDescription strMedia[] = {
147   {{"PlainPaper", 10, false}, 0},
148   {{"CoatedPaper", 11, false}, 1},
149   {{"TransparencyFilm", 16, false}, 2},
150   {{"BackprintFilm", 13, false}, 3},
151   {{"T-ShirtTransfer", 15, false}, 3},
152   {{"FabricSheet", 11, false}, 4},
153   {{"GlossyPaper", 11, false}, 5},
154   {{"GlossyPhotoPaper", 16, false}, 5},
155   {{"HighGlossPaper", 14, false}, 5},
156   {{"HighGlossyFilm", 14, false}, 6},
157   {{"Envelope", 8, false}, 7},
158   {{"OtherPaper", 10, false}, 8},
159   {{"HighResolutionPaper", 19, false}, 9},
160 /*    { { "HighResPaper",		12, false },    11 }, */
161   {{"GlossyPhotoCard", 15, false}, 10},
162 /*    { { "FullBleed",		 9, false },    12 }, */
163   {{"Banner", 6, false}, 11},
164 
165   {{"Plain", 5, false}, 0},
166   {{"Coated", 6, false}, 1},
167   {{"Trans", 5, false}, 2},
168   {{"Back", 4, false}, 3},
169   {{"Shirt", 4, false}, 3},
170 /*    { { "Lead",			 4, false },    4 }, */
171   {{"Fabric", 6, false}, 4},
172   {{"Glossy", 6, false}, 5},
173   {{"HGloss", 6, false}, 6},
174   {{"Env", 3, false}, 7},
175   {{"Oth", 3, false}, 8},
176   {{"HiRes", 5, false}, 9},
177 /*    { { "Bleed",		 5, false },    12 }, */
178   {{"Card", 4, false}, 10},
179   {{"Ban", 3, false}, 11},
180 
181   {{"p", 1, false}, 0},
182   {{"c", 1, false}, 1},
183   {{"t", 1, false}, 2},
184   {{"b", 1, false}, 3},
185   {{"s", 1, false}, 3},
186   {{"f", 1, false}, 4},
187   {{"g", 1, false}, 5},
188   {{"F", 1, false}, 6},
189   {{"e", 1, false}, 7},
190   {{"o", 1, false}, 8},
191   {{"h", 1, false}, 9},
192   {{"C", 1, false}, 10},
193   {{"B", 1, false}, 11},
194   {{0}}
195 };
196 
197 static media_t media_codes[] = {
198   {0x00, 0x00},			/* Plain paper */
199   {0x10, 0x10},			/* Coated paper */
200   {0x20, 0x20},			/* Transp */
201   {0x30, 0x30},			/* Backprint or T-shirt */
202   {0x50, 0x40},			/* Fabric */
203   {0x60, 0x50},			/* Glossy (Photo) Paper */
204   {0x70, 0x60},			/* High gloss film */
205   {0x80, 0x00},			/* Envelope */
206   {0x90, 0x10},			/* Other */
207   {0xb0, 0x70},			/* Hi Res */
208   {0xc0, 0x50},			/* Glossy Photo Cards */
209   {0xd0, 0x00},			/* Banner */
210 };
211 
212 /***************************************************************************/
213 /* ------------------------- 1 bit Monochrome ---------------------------- */
214 /***************************************************************************/
215 
216 private const gx_device_procs bjcmono_procs =
217 prn_color_params_procs(gdev_prn_open, gdev_prn_output_page, gdev_prn_close,
218 		 NULL, NULL,
219 		 gdev_bjc_get_params, gdev_bjc_put_params);
220 
221 const gx_device_bjc_printer gs_bjcmono_device =
222 bjc_device(bjcmono_procs, "bjcmono",
223 	   DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
224 	   X_DPI, Y_DPI,
225 	   //	   0, 0, 0, 0,		/* margins */
226            (3.4 / 25.4), (7.0 / 25.4), (3.4 / 25.4), (3.0 / 25.4),
227 	   1,                   /* num components */
228 	   1,                   /* depth  */
229 	   1,                   /* max gray */
230 	   0,                   /* max color */
231 	   2,                   /* dither gray */
232            0,                   /* dither color */
233            bjc_print_page_mono, INK_K);  /* printer rutin, default ink */
234 
235 
236 /***************************************************************************/
237 /* -------------------------- 8 bit Grayscale ---------------------------- */
238 /***************************************************************************/
239 
240 private const gx_device_procs bjcgray_procs =
241 prn_color_params_procs(gdev_prn_open, gdev_prn_output_page, gdev_prn_close,
242 		 gx_default_gray_map_rgb_color, gx_default_gray_map_color_rgb,
243 		 gdev_bjc_get_params, gdev_bjc_put_params);
244 
245 const gx_device_bjc_printer gs_bjcgray_device =
246 bjc_device(bjcgray_procs, "bjcgray",
247 	   DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
248 	   X_DPI, Y_DPI,
249 //	   0, 0, 0, 0,		/* margins */
250            (3.4 / 25.4), (7.0 / 25.4), (3.4 / 25.4), (3.0 / 25.4),
251 	   1,                   /* num components */
252 	   8,                   /* depth  */
253 	   255,                 /* max gray */
254 	   0,                   /* max color */
255 	   256,                 /* dither gray */
256 	   0,                   /* dither color */
257 	   bjc_print_page_gray, INK_K);
258 
259 
260 /***************************************************************************/
261 /* --------------------------- 3 bit CMYK Color -------------------------- */
262 /***************************************************************************/
263 
264 
265 
266 private const gx_device_procs bjc_cmykcolor_procs =
267 bjc_cmyk_param_procs(gdev_prn_open, gdev_prn_output_page, gdev_prn_close,
268                      cmyk_1bit_map_color_rgb, cmyk_1bit_map_cmyk_color,
269 	             gdev_bjc_get_params, gdev_bjc_put_params);
270 
271 const gx_device_bjc_printer gs_bjccmyk_device =
272 bjc_device(bjc_cmykcolor_procs, "bjccmyk",
273 	   DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
274 	   X_DPI, Y_DPI,
275 //	   0, 0, 0, 0,		/* margins */
276            (3.4 / 25.4), (7.0 / 25.4), (3.4 / 25.4), (3.0 / 25.4),
277 	   4,                   /* num components */
278 	   4,                   /* depth  */
279 	   1,                   /* max gray */
280 	   1,                   /* max color */
281 	   2,                   /* dither gray */
282 	   2,                   /* dither color */
283 	   bjc_print_page_cmyk, (INK_K|INK_C|INK_M|INK_Y));
284 
285 
286 /***************************************************************************/
287 /* --------------------------- 24 bit TrueColor -------------------------- */
288 /***************************************************************************/
289 
290 
291 
292 private const gx_device_procs bjc_truecolor_procs =
293 bjc_cmyk_param_procs(gdev_prn_open, gdev_prn_output_page, gdev_prn_close,
294                      cmyk_8bit_map_color_rgb, cmyk_8bit_map_cmyk_color,
295 	             gdev_bjc_get_params, gdev_bjc_put_params);
296 
297 const gx_device_bjc_printer gs_bjccolor_device =
298 bjc_device(bjc_truecolor_procs, "bjccolor",
299 	   DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
300 	   X_DPI, Y_DPI,
301 //	   0, 0, 0, 0,		/* margins */
302            (3.4 / 25.4), (7.0 / 25.4), (3.4 / 25.4), (3.0 / 25.4),
303 	   4,                   /* num components */
304 	   32,                  /* depth  */
305 	   255,                 /* max gray */
306 	   255,                 /* max color */
307 	   256,                 /* dither gray */
308 	   256,                 /* dither color */
309 	   bjc_print_page_color, (INK_K|INK_C|INK_M|INK_Y));
310 
311 
312 /***************************************************************************/
313 /* ---------------------------Print a page routine------------------------ */
314 /***************************************************************************/
315 
316 /*
317 private int
318 bjc_print_page(gx_device_printer * pdev, FILE * file)
319 {
320 #define ppdev ((gx_device_bjc_printer *) pdev)
321 #define prdev ((gx_device_printer *) pdev)
322 
323     uint raster = gdev_prn_raster(pdev);
324     uint bjc_raster = raster + (-raster & 3);
325     byte *row = gs_alloc_bytes(pdev->memory, bjc_raster, "bjc file buffer");
326     int y;
327     int code;
328     char alma[512];
329 
330     sprintf(alma, "\nNumC: %d, Depth: %d, Mgray: %d, Mrgb: %d\n"
331 	    "Dgray: %d, Drgb: %d", pdev->color_info.num_components,
332 	    pdev->color_info.depth,
333 	    pdev->color_info.max_gray,
334 	    pdev->color_info.max_color,
335 	    pdev->color_info.dither_grays,
336 	    pdev->color_info.dither_colors
337 	   );
338 
339     if (row == 0)
340 	return_error(gs_error_VMerror);
341 
342 
343 done:
344     gs_free_object(pdev->memory, row, "bjc file buffer");
345 
346 
347     fwrite((const char *) alma, 512, 1, file);
348     return code;
349 
350 #undef ppdev
351 }
352 */
353 
354 void
bjc_put_bjl_command(FILE * file,int bjl_command)355 bjc_put_bjl_command(FILE * file, int bjl_command)
356 {
357     BJL_command *command = BJL_command_set;
358     for( ; command->string; command++)
359 	if(command->numeric == bjl_command) break;
360     if(command->string) {
361       fwrite((const char *)"\033[K\002\000\000\037BJLSTART\012", 16, 1, file);
362       fwrite(command->string, command->length, 1, file);
363       fwrite((const char *)"\012BJLEND\012", 8, 1, file); }
364 }
365 
366 
367 /* ------ Get/put parameters ------ */
368 
369 
370 /* Functions for manipulation params strings */
371 
372 const stringParamDescription *
paramValueToParam(const stringParamDescription * params,int value)373 paramValueToParam(const stringParamDescription * params, int value)
374 {
375 
376     for (; params->p_string.data; ++params) {
377 	if (params->p_value == value) {
378 	    return params;
379 	}
380     }
381 
382     return (stringParamDescription *) NULL;
383 }
384 
385 const stringParamDescription *
paramStringToParam(const stringParamDescription * params,const char * name,uint len)386 paramStringToParam(const stringParamDescription * params,
387     		   const char * name, uint len)
388 {
389     for (; params->p_string.data; ++params) {
390         if (len == params->p_string.size)
391 	    if (!(strncmp((const char *)params->p_string.data,
392 			  name, len))) {
393 		return params;
394 	    }
395     }
396 
397     return (stringParamDescription *) NULL;
398 }
399 
400 
401 /* Get parameters.  BJC printer devices add several more parameters */
402 /* to the default set. */
403 private int
gdev_bjc_get_params(gx_device * pdev,gs_param_list * plist)404 gdev_bjc_get_params(gx_device * pdev, gs_param_list * plist)
405 {
406     const gx_device_bjc_printer * ppdev = (gx_device_bjc_printer *)pdev;
407     //    gs_param_string
408 
409     int code = gdev_prn_get_params(pdev, plist);
410 //    stringParamDescription *tmppar;
411     if (code < 0 ||
412 	(code = param_write_string(plist, "PrinterType",
413 		 &paramValueToParam(strPrinterType, ppdev->printerType)->p_string)) < 0 ||
414 	(code = param_write_string(plist, "Feeder",
415 		 &paramValueToParam(strFeeder, ppdev->feeder)->p_string)) < 0 ||
416 	(code = param_write_string(plist, "Media",
417 		 &paramValueToParam(strMedia, ppdev->mediaType)->p_string)) < 0 ||
418 	(code = param_write_string(plist, "Quality",
419 		 &paramValueToParam(strQuality, ppdev->quality)->p_string)) < 0 ||
420 	(code = param_write_string(plist, "InkColor",
421 		 &paramValueToParam(strInk, ppdev->ink)->p_string)) < 0 ||
422 
423 	(code = param_write_bool(plist, "Inverse", &ppdev->inverse)) < 0 ||
424 	(code = param_write_bool(plist, "Smooth", &ppdev->smooth)) < 0 ||
425 	(code = param_write_bool(plist, "Compress", &ppdev->compress)) < 0 ||
426 	(code = param_write_bool(plist, "LimitCheck", &ppdev->limit)) < 0 ||
427 	(code = param_write_bool(plist, "DecomposeK", &ppdev->compose)) < 0 ||
428 
429 	(code = param_write_int(plist, "PaperRed", &ppdev->paperColor.red)) < 0 ||
430 	(code = param_write_int(plist, "PaperGreen", &ppdev->paperColor.green)) < 0 ||
431 	(code = param_write_int(plist, "PaperBlue", &ppdev->paperColor.blue)) < 0 ||
432 	(code = param_write_int(plist, "Random", &ppdev->rnd)) < 0 ||
433 
434 	(code = param_write_float(plist, "Gamma", &ppdev->gamma)) < 0 ||
435 	(code = param_write_float(plist, "RedGamma", &ppdev->redGamma)) < 0 ||
436 	(code = param_write_float(plist, "GreenGamma", &ppdev->greenGamma)) < 0 ||
437 	(code = param_write_float(plist, "BlueGamma", &ppdev->blueGamma)) < 0)
438 	return code;
439     return code;
440 
441 }
442 
443 /* Put parameters. */
444 private int
gdev_bjc_put_params(gx_device * pdev,gs_param_list * plist)445 gdev_bjc_put_params(gx_device * pdev, gs_param_list * plist)
446 {
447     int code, ecode = 0;
448     const char *param_name;
449     gs_param_string tmppar;
450     uint parsize;
451     stringParamDescription *tmpstr=NULL;
452 
453 #   define ppdev ((gx_device_bjc_printer *)pdev)
454 //    int Type, Pass, Feeder, Paper, Red, Green, Blue;
455 
456 #define CHECK_PARAM_CASES(good, label)			\
457     case 1:						\
458 	break;						\
459     case 0:						\
460         if ( good ) break;				\
461     	ecode = gs_error_rangecheck; goto label;	\
462     default:						\
463 	ecode = code;					\
464 label:							\
465 	param_signal_error(plist, param_name, ecode)
466 
467 #define CHECK_str_PARAM_CASES(set, str, label)     	\
468     case 1:						\
469 	break;						\
470     case 0:						\
471         parsize = tmppar.size;                          \
472         tmpstr = paramStringToParam(str,                \
473 			 (const char *)tmppar.data,     \
474 			  parsize);                     \
475         if ( tmpstr ) { set = tmpstr->p_value; break;}	\
476     	ecode = gs_error_rangecheck; goto label;	\
477     default:						\
478 	ecode = code;					\
479 label:							\
480 	param_signal_error(plist, param_name, ecode)
481 
482     switch ( code = param_read_string(plist, (param_name = "PrinterType"),
483 				     &tmppar)) {
484 	CHECK_str_PARAM_CASES(ppdev->printerType, strPrinterType, label_Type);
485     }
486     switch (code = param_read_string(plist, (param_name = "Feeder"),
487 				  &tmppar)) {
488 	CHECK_str_PARAM_CASES(ppdev->feeder, strFeeder, label_Feeder);
489     }
490     switch (code = param_read_string(plist, (param_name = "Media"),
491 				  &tmppar)) {
492 	CHECK_str_PARAM_CASES(ppdev->mediaType, strMedia, label_Paper);
493     }
494     switch (code = param_read_string(plist, (param_name = "Quality"),
495 				  &tmppar)) {
496 	CHECK_str_PARAM_CASES(ppdev->quality, strQuality, label_Quality);
497     }
498     switch (code = param_read_string(plist, (param_name = "InkColor"),
499 				  &tmppar)) {
500 	CHECK_str_PARAM_CASES(ppdev->ink, strInk, label_Ink);
501     }
502 
503     switch (code = param_read_bool(plist, (param_name = "Inverse"),
504 				  &ppdev->inverse)) {
505 	CHECK_PARAM_CASES( ppdev->inverse == true ||
506 			   ppdev->inverse == false , label_Inverse);
507     }
508     switch (code = param_read_bool(plist, (param_name = "Compress"),
509 				  &ppdev->compress)) {
510 	CHECK_PARAM_CASES( ppdev->compress == true ||
511 			   ppdev->compress == false , label_Compress);
512     }
513     switch (code = param_read_bool(plist, (param_name = "Smooth"),
514 				  &ppdev->smooth)) {
515 	CHECK_PARAM_CASES( ppdev->smooth == true ||
516 			   ppdev->smooth == false , label_Smooth);
517     }
518 
519     switch (code = param_read_bool(plist, (param_name = "LimitCheck"),
520 				  &ppdev->limit)) {
521 	CHECK_PARAM_CASES( ppdev->limit == true ||
522 			   ppdev->limit == false , label_Limit);
523     }
524 
525     switch (code = param_read_bool(plist, (param_name = "DecomposeK"),
526 				  &ppdev->compose)) {
527 	CHECK_PARAM_CASES( ppdev->compose == true ||
528 			   ppdev->compose == false , label_Compose);
529     }
530 
531     switch (code = param_read_int(plist, (param_name = "PaperRed"),
532 				  &ppdev->paperColor.red)) {
533 	CHECK_PARAM_CASES( ppdev->paperColor.red >= 0 &&
534 			   ppdev->paperColor.red <= 255 , label_Red);
535     }
536     switch (code = param_read_int(plist, (param_name = "PaperGreen"),
537 				  &ppdev->paperColor.green)) {
538 	CHECK_PARAM_CASES(ppdev->paperColor.green >= 0 &&
539 			  ppdev->paperColor.green <= 255 , label_Green);
540     }
541     switch (code = param_read_int(plist, (param_name = "PaperBlue"),
542 				  &ppdev->paperColor.blue)) {
543 	CHECK_PARAM_CASES(ppdev->paperColor.blue >= 0 &&
544 			  ppdev->paperColor.blue <= 255  , label_Blue);
545     }
546     switch (code = param_read_int(plist, (param_name = "Random"),
547 				  &ppdev->rnd)) {
548 	CHECK_PARAM_CASES(ppdev->rnd >= 0 &&
549 			  ppdev->rnd <= 100  , label_Random);
550     }
551     switch (code = param_read_float(plist, (param_name = "Gamma"),
552 				  &ppdev->gamma)) {
553 	CHECK_PARAM_CASES(ppdev->gamma >= 0.0 &&
554 			  ppdev->gamma <= 10.0  , label_Gamma);
555     }
556     switch (code = param_read_float(plist, (param_name = "RedGamma"),
557 				  &ppdev->redGamma)) {
558 	CHECK_PARAM_CASES(ppdev->redGamma >= 0.0 &&
559 			  ppdev->redGamma <= 10.0  , label_Rgamma);
560     }
561     switch (code = param_read_float(plist, (param_name = "GreenGamma"),
562 				  &ppdev->greenGamma)) {
563 	CHECK_PARAM_CASES(ppdev->greenGamma >= 0.0 &&
564 			  ppdev->greenGamma <= 10.0  , label_Ggamma);
565     }
566     switch (code = param_read_float(plist, (param_name = "BlueGamma"),
567 				  &ppdev->blueGamma)) {
568 	CHECK_PARAM_CASES(ppdev->blueGamma >= 0.0 &&
569 			  ppdev->blueGamma <= 10.0  , label_Bgamma);
570     }
571     if (ecode < 0) return ecode;
572 
573     return gdev_prn_put_params(pdev, plist);
574 #undef ppdev
575 }
576 
577 private int
bjc_print_page_mono(gx_device_printer * pdev,FILE * file)578 bjc_print_page_mono(gx_device_printer * pdev, FILE * file)
579 {
580 #define ppdev ((gx_device_bjc_printer *) pdev)
581 #define prdev ((gx_device_printer *) pdev)
582 
583     uint raster = gdev_prn_raster(pdev);
584     uint cmplen;
585     byte *row = gs_alloc_bytes(pdev->memory, raster, "bjc mono file buffer");
586     byte *cmp = gs_alloc_bytes(pdev->memory, (raster << 1) + 1,
587 			       "bjc mono comp buffer"); /*worst case */
588     byte *outrow; /* misc variable for send a row */
589     int y;
590     int skip;    /* empty raster lines */
591     char color = (ppdev->smooth == true ? 0x12 :       /* smooted black */
592 		  ((ppdev->ink & INK_K) ? 0x11: 0x10)); /* black or color */
593     char ink   = 0x01; /* regular ink type */
594     char compress = (ppdev->compress == true ? 0x01 : 0x00); /* compression or not */
595     int x_resolution = pdev->HWResolution[0];
596     int y_resolution = pdev->HWResolution[1];
597     int length = 0/*x71*/, lm = 0/*x01*/, rm = 0/*x01*/, top = 0/*x50*/;
598     byte inkc = ppdev->ink;
599     byte mask_array[] = { 0xff, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe };
600     byte lastmask = mask_array[pdev->width % 8];
601 
602     if (row == 0 || cmp == 0)		/* can't allocate row buffer */
603 	return_error(gs_error_VMerror);
604 
605     /* Write the setup data. */
606 
607     bjc_put_set_initial (file);   /* start printing */
608     bjc_put_print_method(file, color, media_codes[ppdev->mediaType].c, ppdev->quality, 0);
609     bjc_put_media_supply(file, ppdev->feeder, media_codes[ppdev->mediaType].l);
610     bjc_put_raster_resolution(file, x_resolution, y_resolution);
611     bjc_put_page_margins(file, length, lm, rm, top);
612     bjc_put_set_compression(file, compress);
613     bjc_put_image_format(file, 0, 0, ink);   /* normal ink */
614 
615 
616     /* Write the contents of the image. */
617     skip = 0;
618     for (y = 0; y < pdev->height ; y++) {
619       gdev_prn_copy_scan_lines(pdev, y, row, raster);
620       if (bjc_invert_bytes(row, raster, ppdev->inverse, lastmask)) /* black -> K and check empty line*/
621        {  /* empty line raster */
622 	if (skip) bjc_put_raster_skip(file, skip);
623 	skip = 1;
624 	if(compress) cmplen = bjc_compress(row, raster, cmp), outrow = cmp;
625         else outrow = row, cmplen = raster;  /* compress or not */
626         if(inkc & INK_K) bjc_put_cmyk_image(file, CMYK_K, outrow, cmplen),
627 	        bjc_put_CR(file);
628         if(inkc & INK_C) bjc_put_cmyk_image(file, CMYK_C, outrow, cmplen),
629         	bjc_put_CR(file);
630         if(inkc & INK_M) bjc_put_cmyk_image(file, CMYK_M, outrow, cmplen),
631 	        bjc_put_CR(file);
632         if(inkc & INK_Y) bjc_put_cmyk_image(file, CMYK_Y, outrow, cmplen),
633 	        bjc_put_CR(file); /* use the needed ink(s) */
634        }
635       else skip++; /* +1 empty line */
636     }
637     if (skip) bjc_put_raster_skip(file, skip);
638     bjc_put_FF(file);            /* eject a page */
639     bjc_put_initialize (file);
640 
641     gs_free_object(pdev->memory, cmp, "bjc mono comp buffer");
642     gs_free_object(pdev->memory, row, "bjc mono file buffer");
643 
644     return 0;
645 
646 #undef ppdev
647 }
648 
649 private int
bjc_print_page_gray(gx_device_printer * pdev,FILE * file)650 bjc_print_page_gray(gx_device_printer * pdev, FILE * file)
651 {
652 #define ppdev ((gx_device_bjc_printer *) pdev)
653 #define prdev ((gx_device_printer *) pdev)
654 
655     uint width =   pdev->width; /* Because grayscale */
656     uint raster = (pdev->width >> 3) + ( (pdev->width % 8) ? 1:0);
657     uint cmplen;
658     byte *row = gs_alloc_bytes(pdev->memory, width, "bjc gray file buffer");
659     byte *dit = gs_alloc_bytes(pdev->memory, raster, "bjc gray dither buffer");
660     byte *cmp = gs_alloc_bytes(pdev->memory, (raster << 1) + 1,
661 			       "bjc gray comp buffer"); /*worst case */
662     byte *out; /* misc variable for send a row */
663     int y;
664     int skip;    /* empty raster lines */
665     char color = (ppdev->smooth == true ? 0x12 :       /* smooted black */
666 		  ((ppdev->ink & INK_K) ? 0x11: 0x10)); /* black or color */
667     char ink   = 0x01; /* regular ink type */
668     char compress = (ppdev->compress == true ? 0x01 : 0x00); /* compression or not */
669     int x_resolution = pdev->HWResolution[0];
670     int y_resolution = pdev->HWResolution[1];
671     int length = 0/*x71*/, lm = 0/*x01*/, rm = 0/*x01*/, top = 0/*x50*/;
672     byte inkc = ppdev->ink;
673     byte mask_array[] = { 0xff, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe };
674     byte lastmask = mask_array[pdev->width % 8];
675 
676     if (row == 0 || cmp == 0 ||
677        dit == 0 )		/* can't allocate row buffers */
678 	return_error(gs_error_VMerror);
679 
680     /* Write the setup data. */
681 
682     bjc_build_gamma_table(ppdev->gamma, CMYK_K); /* set up the gamma table */
683 
684     bjc_put_set_initial (file);   /* start printing */
685     bjc_put_print_method(file, color, media_codes[ppdev->mediaType].c, ppdev->quality, 0);
686     bjc_put_media_supply(file, ppdev->feeder, media_codes[ppdev->mediaType].l);
687     bjc_put_raster_resolution(file, x_resolution, y_resolution);
688     bjc_put_page_margins(file, length, lm, rm, top);
689     bjc_put_set_compression(file, compress);
690     bjc_put_image_format(file, 0, 0, ink);   /* normal ink */
691 
692 
693     /* Write the contents of the image. */
694     skip = 0;
695     if(FloydSteinbergInitG(pdev) == -1)
696 	        return_error(gs_error_VMerror);   /* initiate the dithering */
697 
698     for (y = 0; y < pdev->height ; y++) {
699      gdev_prn_copy_scan_lines(pdev, y, row, width);   /* image -> row */
700      FloydSteinbergDitheringG(row, dit, width, raster, ppdev->limit); /* gray */
701       if (bjc_invert_bytes(dit, raster, ppdev->inverse, lastmask)) /* black -> K and check empty line*/
702        {  /* end of empty lines */
703 	if (skip) bjc_put_raster_skip(file, skip);
704 	skip = 1;
705 
706 	  if(compress) cmplen = bjc_compress(dit, raster, cmp), out = cmp;
707           else cmplen = raster, out = dit;  /* compress or not */
708 
709 	  if(inkc & INK_K) bjc_put_cmyk_image(file, CMYK_K, out, cmplen),
710 	        bjc_put_CR(file);
711           if(inkc & INK_C) bjc_put_cmyk_image(file, CMYK_C, out, cmplen),
712         	bjc_put_CR(file);
713           if(inkc & INK_M) bjc_put_cmyk_image(file, CMYK_M, out, cmplen),
714 	        bjc_put_CR(file);
715           if(inkc & INK_Y) bjc_put_cmyk_image(file, CMYK_Y, out, cmplen),
716 	        bjc_put_CR(file); /* use the needed ink(s) */
717 
718        } else skip++; /* +1 empty line */
719     }
720     if (skip) bjc_put_raster_skip(file, skip);
721     bjc_put_FF(file);            /* eject a page */
722     bjc_put_initialize (file);
723 
724     FloydSteinbergCloseG(pdev);
725     gs_free_object(pdev->memory, dit, "bjc gray dither buffer");
726     gs_free_object(pdev->memory, cmp, "bjc gray comp buffer");
727     gs_free_object(pdev->memory, row, "bjc gray file buffer");
728 
729     return 0;
730 
731 #undef ppdev
732 }
733 
734 private int
bjc_print_page_cmyk(gx_device_printer * pdev,FILE * file)735 bjc_print_page_cmyk(gx_device_printer * pdev, FILE * file)
736 {
737 #define ppdev ((gx_device_bjc_printer *) pdev)
738 #define prdev ((gx_device_printer *) pdev)
739 
740 //    uint raster = gdev_prn_raster(pdev);
741     uint raster = bitmap_raster(pdev->width);
742     uint a_raster;                             /* a tmp variable */
743     uint cmplen;
744     byte *row = gs_alloc_bytes(pdev->memory, raster*4,
745 			       "bjc cmyk file buffer"); /* one for each component */
746     byte *cmp = gs_alloc_bytes(pdev->memory, (raster << 1) + 1,
747 			       "bjc cmyk comp buffer"); /*worst case */
748     byte *rows[4];
749     byte *outrow; /* misc variable for send a row */
750     int y;
751     int skip;    /* empty raster lines */
752     char color = 0x10; /* color */
753     char ink   = 0x01; /* regular ink type */
754     char compress = (ppdev->compress == true ? 0x01 : 0x00); /* compression or not */
755     char skip_x;
756     int x_resolution = pdev->HWResolution[0];
757     int y_resolution = pdev->HWResolution[1];
758     int length = 0/*x71*/, lm = 0/*x01*/, rm = 0/*x01*/, top = 0/*x50*/;
759     int plane;
760     byte mask_array[] = { 0xff, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe };
761     byte lastmask = mask_array[pdev->width % 8];
762     skip_t skipc;
763     byte inkc = ppdev->ink;
764     bool inverse = ppdev->inverse;
765     gx_render_plane_t render_plane;
766 
767     if (row == 0 || cmp == 0)		/* can't allocate row buffer */
768 	return_error(gs_error_VMerror);
769 
770     /* Write the setup data. */
771 
772     bjc_put_set_initial (file);   /* start printing */
773     bjc_put_print_method(file, color, media_codes[ppdev->mediaType].c, ppdev->quality, 0);
774     bjc_put_media_supply(file, ppdev->feeder, media_codes[ppdev->mediaType].l);
775     bjc_put_raster_resolution(file, x_resolution, y_resolution);
776     bjc_put_page_margins(file, length, lm, rm, top);
777     bjc_put_set_compression(file, compress);
778     bjc_put_image_format(file, 0, 0, ink);   /* normal ink */
779 
780 
781     /* Write the contents of the image. */
782     skip = 0;
783 
784     for (y = 0; y < pdev->height ; y++) {
785 
786         skip_x = 0;
787         for (plane = 0; plane < 4; plane++) {   /* print each color component */
788             gx_render_plane_init(&render_plane, (gx_device *)pdev, plane);
789             gdev_prn_get_lines(pdev, y, 1, row + raster*plane, raster,
790                                &rows[plane], &a_raster, &render_plane);
791         }
792 
793         {
794             int i;
795             byte *byteC=rows[0], *byteM=rows[1],
796                 *byteY=rows[2], *byteK=rows[3];
797             for(i=0; i<raster; i++, byteC++, byteM++, byteY++, byteK++) {
798                 if (ppdev->compose) {
799                     *byteK =  *byteC & *byteM & *byteY;
800                     *byteC &= ~(*byteK);
801                     *byteM &= ~(*byteK);
802                     *byteY &= ~(*byteK);
803                 }
804                 else {
805                     *byteC |= *byteK;
806                     *byteM |= *byteK;
807                     *byteY |= *byteK;
808                     *byteK =  0;
809                 }
810             }
811         }
812 
813         if(bjc_invert_cmyk_bytes(rows[0], rows[1], rows[2], rows[3],
814                                  raster, inverse, lastmask, &skipc)) {
815 
816             if (skip) bjc_put_raster_skip(file, skip);
817             skip = 1;
818             if(skipc.skipC && (inkc & INK_C)) {
819                 if(compress) cmplen = bjc_compress(rows[0], raster, cmp), outrow = cmp;
820                 else outrow = rows[0], cmplen = raster;  /* compress or not */
821                 bjc_put_cmyk_image(file, CMYK_C, outrow, cmplen), bjc_put_CR(file);
822             }
823             if(skipc.skipM && (inkc & INK_M)) {
824                 if(compress) cmplen = bjc_compress(rows[1], raster, cmp), outrow = cmp;
825                 else outrow = rows[1], cmplen = raster;  /* compress or not */
826                 bjc_put_cmyk_image(file, CMYK_M, outrow, cmplen), bjc_put_CR(file);
827             }
828             if(skipc.skipY && (inkc & INK_Y)) {
829                 if(compress) cmplen = bjc_compress(rows[2], raster, cmp), outrow = cmp;
830                 else outrow = rows[2], cmplen = raster;  /* compress or not */
831                 bjc_put_cmyk_image(file, CMYK_Y, outrow, cmplen), bjc_put_CR(file);
832             }
833             if(skipc.skipK && (inkc & INK_K)) {
834                 if(compress) cmplen = bjc_compress(rows[3], raster, cmp), outrow = cmp;
835                 else outrow = rows[3], cmplen = raster;  /* compress or not */
836                 bjc_put_cmyk_image(file, CMYK_K, outrow, cmplen), bjc_put_CR(file);
837             }
838         }
839         else skip++; /* +1 empty line */
840     }
841 
842     if (skip) bjc_put_raster_skip(file, skip);
843     bjc_put_FF(file);            /* eject a page */
844     bjc_put_initialize (file);
845 
846     gs_free_object(pdev->memory, cmp, "bjc cmyk comp buffer");
847     gs_free_object(pdev->memory, row, "bjc cmyk file buffer");
848 
849     return 0;
850 
851 #undef ppdev
852 }
853 
854 private int
bjc_print_page_color(gx_device_printer * pdev,FILE * file)855 bjc_print_page_color(gx_device_printer * pdev, FILE * file)
856 {
857 #define ppdev ((gx_device_bjc_printer *) pdev)
858 #define prdev ((gx_device_printer *) pdev)
859 
860 //    uint raster = gdev_prn_raster(pdev);
861     uint width =   pdev->width; /* Because grayscale */
862     uint raster = (pdev->width >> 3) + ( (pdev->width % 8) ? 1:0);
863     uint cmplen;
864     byte *row = gs_alloc_bytes(pdev->memory, width*4,
865 			       "bjc true file buffer"); /* one for each component */
866     byte *dit = gs_alloc_bytes(pdev->memory, raster*4,
867                                "bjc true dither buffer");
868     byte *cmp = gs_alloc_bytes(pdev->memory, (raster << 1) + 1,
869 			       "bjc true comp buffer"); /*worst case */
870     byte *rowC = dit;                 /*C*/
871     byte *rowM = dit + raster;        /*M*/
872     byte *rowY = dit + 2*raster;      /*Y*/
873     byte *rowK = dit + 3*raster;      /*K*/
874     byte *outrow; /* misc variable for send a row */
875     int y;
876     int skip;    /* empty raster lines */
877     char color = 0x10; /* color */
878     char ink   = 0x01; /* regular ink type */
879     char compress = (ppdev->compress == true ? 0x01 : 0x00); /* compression or not */
880     int x_resolution = pdev->HWResolution[0];
881     int y_resolution = pdev->HWResolution[1];
882     int length = 0/*x71*/, lm = 0/*x01*/, rm = 0/*x01*/, top = 0/*x50*/;
883     byte mask_array[] = { 0xff, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe };
884     byte lastmask = mask_array[pdev->width % 8];
885     skip_t skipc;
886     byte inkc = ppdev->ink;
887     float rgamma = ppdev->gamma != 1.0 ? ppdev->gamma:ppdev->redGamma;
888     float ggamma = ppdev->gamma != 1.0 ? ppdev->gamma:ppdev->greenGamma;
889     float bgamma = ppdev->gamma != 1.0 ? ppdev->gamma:ppdev->blueGamma;
890 
891     if (row == 0 || cmp == 0 || dit == 0)     /* can't allocate row buffer */
892 	return_error(gs_error_VMerror);
893 
894     bjc_build_gamma_table(rgamma, CMYK_C); /* set up the gamma table */
895     bjc_build_gamma_table(ggamma, CMYK_M); /* set up the gamma table */
896     bjc_build_gamma_table(bgamma, CMYK_Y); /* set up the gamma table */
897 
898     /* Write the setup data. */
899 
900     bjc_put_set_initial (file);   /* start printing */
901     bjc_put_print_method(file, color, media_codes[ppdev->mediaType].c, ppdev->quality, 0);
902     bjc_put_media_supply(file, ppdev->feeder, media_codes[ppdev->mediaType].l);
903     bjc_put_raster_resolution(file, x_resolution, y_resolution);
904     bjc_put_page_margins(file, length, lm, rm, top);
905     bjc_put_set_compression(file, compress);
906     bjc_put_image_format(file, 0, 0, ink);   /* normal ink */
907 
908 
909     /* Write the contents of the image. */
910     skip = 0;
911 
912     if(FloydSteinbergInitC(pdev) == -1)
913 	        return_error(gs_error_VMerror);   /* initiate the dithering */
914 
915     for (y = 0; y < pdev->height ; y++) {
916         gdev_prn_copy_scan_lines(pdev, y, row, gdev_prn_raster(pdev));
917 	/* image -> row */
918         FloydSteinbergDitheringC(row, dit, width, raster, ppdev->limit,
919                                  ppdev->compose);
920 
921         if(bjc_invert_cmyk_bytes(rowC, rowM, rowY, rowK,
922                                  raster, ~ppdev->inverse, lastmask,
923                                  &skipc)) {
924             if (skip) bjc_put_raster_skip(file, skip);
925             skip = 1;
926             if(skipc.skipC && (inkc & INK_C) ) {
927                 if(compress) cmplen = bjc_compress(rowC, raster, cmp), outrow = cmp;
928                 else outrow = rowC, cmplen = raster;  /* compress or not */
929                 bjc_put_cmyk_image(file, CMYK_C, outrow, cmplen), bjc_put_CR(file);
930             }
931             if(skipc.skipM  && (inkc & INK_M) ) {
932                 if(compress) cmplen = bjc_compress(rowM, raster, cmp), outrow = cmp;
933                 else outrow = rowM, cmplen = raster;  /* compress or not */
934                 bjc_put_cmyk_image(file, CMYK_M, outrow, cmplen), bjc_put_CR(file);
935             }
936             if(skipc.skipY  && (inkc & INK_Y) ) {
937                 if(compress) cmplen = bjc_compress(rowY, raster, cmp), outrow = cmp;
938                 else outrow = rowY, cmplen = raster;  /* compress or not */
939                 bjc_put_cmyk_image(file, CMYK_Y, outrow, cmplen), bjc_put_CR(file);
940             }
941             if(skipc.skipK  && (inkc & INK_K) ) {
942                 if(compress) cmplen = bjc_compress(rowK, raster, cmp), outrow = cmp;
943                 else outrow = rowK, cmplen = raster;  /* compress or not */
944                 bjc_put_cmyk_image(file, CMYK_K, outrow, cmplen), bjc_put_CR(file);
945             }
946         }
947         else skip++; /* +1 empty line */
948     }
949 
950     if (skip) bjc_put_raster_skip(file, skip);
951     bjc_put_FF(file);            /* eject a page */
952     bjc_put_initialize (file);
953 
954     FloydSteinbergCloseC(pdev);
955     gs_free_object(pdev->memory, cmp, "bjc true comp buffer");
956     gs_free_object(pdev->memory, dit, "bjc true dither buffer");
957     gs_free_object(pdev->memory, row, "bjc true file buffer");
958 
959     return 0;
960 
961 #undef ppdev
962 }
963