diff -rNc ghostscript-7.05.orig/src/contrib.mak ghostscript-7.05/src/contrib.mak *** ghostscript-7.05.orig/src/contrib.mak Fri Feb 22 20:45:55 2002 --- ghostscript-7.05/src/contrib.mak Fri Jul 12 22:46:38 2002 *************** *** 41,46 **** --- 41,50 ---- # bjc600 Canon Color BubbleJet BJC-600, BJC-4000 and BJC-70 # also good for Apple printers like the StyleWriter 2x00 # bjc800 Canon Color BubbleJet BJC-800 + # bjccmyk Canon Color BubbleJet BJC-210/240/250/250ex/265/1000 + # bjccolor Canon Color BubbleJet BJC-210 ... 1000 truecolor printing + # bjcgray Canon Color BubbleJet BJC-210 ... 1000 grayscale printing + # bjcmono Canon Color BubbleJet BJC-210 ... 1000 monochrome printing # ccr CalComp Raster format # cdeskjet H-P DeskJet 500C with 1 bit/pixel color # cdjcolor H-P DeskJet 500C with 24 bit/pixel color and *************** *** 317,322 **** --- 321,355 ---- $(GLOBJ)gdevdjtc.$(OBJ) : $(GLSRC)gdevdjtc.c $(PDEVH) $(malloc__h) $(gdevpcl_h) $(GLCC) $(GLO_)gdevdjtc.$(OBJ) $(C_) $(GLSRC)gdevdjtc.c + + ### ----------------- The BJC-210/240/250/250ex/265/1000 ---------------- ### + + ### + ### For questions about the driver, mailto://szaszg@hu.inter.net + ### http://bjc250gs.sourceforge.net + ### + + bjc_h=$(GLSRC)gdevbjc_.h + + bjc_=$(GLOBJ)gdevbjc_.$(OBJ) $(GLOBJ)gdevbjca.$(OBJ) + + $(GLOBJ)gdevbjc_.$(OBJ) : $(GLSRC)gdevbjc_.c $(PDEVH) $(bjc_h) + $(GLCC) $(GLO_)gdevbjc_.$(OBJ) $(C_) $(GLSRC)gdevbjc_.c + + $(GLOBJ)gdevbjca.$(OBJ) : $(GLSRC)gdevbjca.c $(PDEVH) $(bjc_h) + $(GLCC) $(GLO_)gdevbjca.$(OBJ) $(C_) $(GLSRC)gdevbjca.c + + $(DD)bjcmono.dev : $(bjc_) $(DD)page.dev + $(SETPDEV) $(DD)bjcmono $(bjc_) + + $(DD)bjcgray.dev : $(bjc_) $(DD)page.dev + $(SETPDEV) $(DD)bjcgray $(bjc_) + + $(DD)bjccmyk.dev : $(bjc_) $(DD)page.dev + $(SETPDEV) $(DD)bjccmyk $(bjc_) + + $(DD)bjccolor.dev : $(bjc_) $(DD)page.dev + $(SETPDEV) $(DD)bjccolor $(bjc_) ### -------------------- The H-P Color LaserJet 5/5M -------------------- ### diff -rNc ghostscript-7.05.orig/src/gdevbjc_.c ghostscript-7.05/src/gdevbjc_.c *** ghostscript-7.05.orig/src/gdevbjc_.c Thu Jan 1 01:00:00 1970 --- ghostscript-7.05/src/gdevbjc_.c Fri Jul 12 22:46:38 2002 *************** *** 0 **** --- 1,962 ---- + /* BJC-210/240/250/265/1000 Bubble Jet Printer driver for GhostScript + * main subroutines for GS + * + * Copyright 2000, 2001, 2002 Gergely Szász (Gergely Sza'sz) + * mailto://szaszg@hu.inter.net http://bjc250gs.sourceforge.net + * + * This program may be distributed and/or modified under the terms of + * the GNU General Public License as published by the Free Software + * Foundation (the "GPL"); either version 2 of the GPL, or (at your option) + * any later version. + * + * When distributed under the terms of the GPL, this program is distributed + * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GPL for more details. + * + * If this program is being distributed under the terms of the GPL, you + * should have received a copy of the GPL along with this program, normally + * in a plain ASCII text file named COPYING; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 + * U.S.A. + */ + + /* Copyright (C) 1989, 2000 Aladdin Enterprises. All rights reserved. + + This program may also be distributed as part of AFPL Ghostscript, under the + terms of the Aladdin Free Public License (the "License"). + + AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND. No + author or distributor accepts any responsibility for the consequences of + using it, or for whether it serves any particular purpose or works at + all, unless he or she says so in writing. Refer to the License for full + details. + + Every copy of AFPL Ghostscript must include a copy of the License, + normally in a plain ASCII text file named PUBLIC. The License grants you + the right to copy, modify and redistribute AFPL Ghostscript, but only + under certain conditions described in the License. Among other things, + the License requires that the copyright notice and this notice be + preserved on all copies. + */ + + /* BJC printers drivers */ + #include "gdevprn.h" + #include "gsparam.h" + #include "gdevbjc_.h" + + /* ------ The device descriptors ------ */ + private dev_proc_print_page(bjc_print_page); + private dev_proc_print_page(bjc_print_page_mono); + private dev_proc_print_page(bjc_print_page_gray); + private dev_proc_print_page(bjc_print_page_cmyk); + private dev_proc_print_page(bjc_print_page_color); + private dev_proc_put_params(gdev_bjc_put_params); + private dev_proc_get_params(gdev_bjc_get_params); + const stringParamDescription * + paramValueToParam(P2(const stringParamDescription *, int)); + const stringParamDescription * + paramStringToParam(P3(const stringParamDescription *, const char *, uint)); + + BJL_command BJL_command_set[] = { + { "@Cleaning=1", BJC_BJL_CLEANING, 11}, + { "@PowerOff", BJC_BJL_POWER_OFF, 9}, + { "@RollerCleaning", BJC_BJL_ROCLEANING, 15}, + { "@TestPrint=NozzleCheck", BJC_BJL_NOZZLECHK, 22}, + { "@TestPrint=A", BJC_BJL_TESTA, 12}, + { "@TestPrint=B", BJC_BJL_TESTB, 12}, + { "@TestPrint=C", BJC_BJL_TESTC, 12}, + { "@TestPrint=DemoPrint", BJC_BJL_DEMO, 20}, + + #define BJL_CMC_AP "ControlMode=Common\012AutoPower" //+28 + + { BJL_CMC_AP "On=Enable", BJC_BJL_ON_ENABLE, 37}, + { BJL_CMC_AP "On=Disable", BJC_BJL_ON_DISABLE, 38}, + { BJL_CMC_AP "Off=1", BJC_BJL_OFF_1MIN, 33}, + { BJL_CMC_AP "Off=10", BJC_BJL_OFF_10MIN, 34}, + { BJL_CMC_AP "Off=30", BJC_BJL_OFF_30MIN, 34}, + { BJL_CMC_AP "Off=60", BJC_BJL_OFF_60MIN, 34}, + { BJL_CMC_AP "Off=Disable", BJC_BJL_OFF_DISABLE, 39}, + { NULL } + }; + + + /* String parameter definitions */ + + stringParamDescription strPrinterType[] = { + { { "BJC-250", 7, false }, 0 }, + { { "BJC-250ex", 9, false }, 1 }, + { { "BJC-1000", 8, false }, 2 }, + + { { "250", 3, false }, 0 }, + { { "250ex", 5, false }, 1 }, + { { "1000", 4, false }, 2 }, + { {0} } + }; + + stringParamDescription strFeeder[] = { + { { "Manual", 6, false }, 0x11 }, + { { "Auto", 4, false }, 0x10 }, + + { { "m", 1, false }, 0x11 }, + { { "a", 1, false }, 0x10 }, + { {0} } + }; + + stringParamDescription strQuality[] = { + { { "Normal", 6, false }, 0 }, + { { "High", 4, false }, 1 }, + { { "Draft", 5, false }, 2 }, + { { "NonBleed", 8, false }, 8 }, + + { { "n", 1, false }, 0 }, + { { "h", 1, false }, 1 }, + { { "d", 1, false }, 2 }, + { { "b", 1, false }, 8 }, + { {0} } + }; + + stringParamDescription strInk[] = { + { { "Black", 5, false }, 8 }, + { { "Cyan", 4, false }, 1 }, + { { "Magenta", 7, false }, 2 }, + { { "Yellow", 6, false }, 4 }, + { { "Red", 3, false }, 6 }, + { { "Green", 5, false }, 5 }, + { { "Blue", 4, false }, 3 }, + + { { "K", 1, false }, 8 }, + { { "C", 1, false }, 1 }, + { { "M", 1, false }, 2 }, + { { "Y", 1, false }, 4 }, + { { "R", 1, false }, 6 }, + { { "G", 1, false }, 5 }, + { { "B", 1, false }, 3 }, + { { "CK", 2, false }, 9 }, + { { "MK", 2, false }, 10 }, + { { "YK", 2, false }, 12 }, + { { "RK", 2, false }, 14 }, + { { "GK", 2, false }, 13 }, + { { "BK", 2, false }, 11 }, + { { "CMY", 3, false }, 7 }, + { { "CMYK", 4, false }, 15 }, + { {0} } + }; + + private stringParamDescription strMedia[] = { + {{"PlainPaper", 10, false}, 0}, + {{"CoatedPaper", 11, false}, 1}, + {{"TransparencyFilm", 16, false}, 2}, + {{"BackprintFilm", 13, false}, 3}, + {{"T-ShirtTransfer", 15, false}, 3}, + {{"FabricSheet", 11, false}, 4}, + {{"GlossyPaper", 11, false}, 5}, + {{"GlossyPhotoPaper", 16, false}, 5}, + {{"HighGlossPaper", 14, false}, 5}, + {{"HighGlossyFilm", 14, false}, 6}, + {{"Envelope", 8, false}, 7}, + {{"OtherPaper", 10, false}, 8}, + {{"HighResolutionPaper", 19, false}, 9}, + /* { { "HighResPaper", 12, false }, 11 }, */ + {{"GlossyPhotoCard", 15, false}, 10}, + /* { { "FullBleed", 9, false }, 12 }, */ + {{"Banner", 6, false}, 11}, + + {{"Plain", 5, false}, 0}, + {{"Coated", 6, false}, 1}, + {{"Trans", 5, false}, 2}, + {{"Back", 4, false}, 3}, + {{"Shirt", 4, false}, 3}, + /* { { "Lead", 4, false }, 4 }, */ + {{"Fabric", 6, false}, 4}, + {{"Glossy", 6, false}, 5}, + {{"HGloss", 6, false}, 6}, + {{"Env", 3, false}, 7}, + {{"Oth", 3, false}, 8}, + {{"HiRes", 5, false}, 9}, + /* { { "Bleed", 5, false }, 12 }, */ + {{"Card", 4, false}, 10}, + {{"Ban", 3, false}, 11}, + + {{"p", 1, false}, 0}, + {{"c", 1, false}, 1}, + {{"t", 1, false}, 2}, + {{"b", 1, false}, 3}, + {{"s", 1, false}, 3}, + {{"f", 1, false}, 4}, + {{"g", 1, false}, 5}, + {{"F", 1, false}, 6}, + {{"e", 1, false}, 7}, + {{"o", 1, false}, 8}, + {{"h", 1, false}, 9}, + {{"C", 1, false}, 10}, + {{"B", 1, false}, 11}, + {{0}} + }; + + static media_t media_codes[] = { + {0x00, 0x00}, /* Plain paper */ + {0x10, 0x10}, /* Coated paper */ + {0x20, 0x20}, /* Transp */ + {0x30, 0x30}, /* Backprint or T-shirt */ + {0x50, 0x40}, /* Fabric */ + {0x60, 0x50}, /* Glossy (Photo) Paper */ + {0x70, 0x60}, /* High gloss film */ + {0x80, 0x00}, /* Envelope */ + {0x90, 0x10}, /* Other */ + {0xb0, 0x70}, /* Hi Res */ + {0xc0, 0x50}, /* Glossy Photo Cards */ + {0xd0, 0x00}, /* Banner */ + }; + + /***************************************************************************/ + /* ------------------------- 1 bit Monochrome ---------------------------- */ + /***************************************************************************/ + + private const gx_device_procs bjcmono_procs = + prn_color_params_procs(gdev_prn_open, gdev_prn_output_page, gdev_prn_close, + NULL, NULL, + gdev_bjc_get_params, gdev_bjc_put_params); + + const gx_device_bjc_printer gs_bjcmono_device = + bjc_device(bjcmono_procs, "bjcmono", + DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS, + X_DPI, Y_DPI, + // 0, 0, 0, 0, /* margins */ + (3.4 / 25.4), (7.0 / 25.4), (3.4 / 25.4), (3.0 / 25.4), + 1, /* num components */ + 1, /* depth */ + 1, /* max gray */ + 0, /* max color */ + 2, /* dither gray */ + 0, /* dither color */ + bjc_print_page_mono, INK_K); /* printer rutin, default ink */ + + + /***************************************************************************/ + /* -------------------------- 8 bit Grayscale ---------------------------- */ + /***************************************************************************/ + + private const gx_device_procs bjcgray_procs = + prn_color_params_procs(gdev_prn_open, gdev_prn_output_page, gdev_prn_close, + gx_default_gray_map_rgb_color, gx_default_gray_map_color_rgb, + gdev_bjc_get_params, gdev_bjc_put_params); + + const gx_device_bjc_printer gs_bjcgray_device = + bjc_device(bjcgray_procs, "bjcgray", + DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS, + X_DPI, Y_DPI, + // 0, 0, 0, 0, /* margins */ + (3.4 / 25.4), (7.0 / 25.4), (3.4 / 25.4), (3.0 / 25.4), + 1, /* num components */ + 8, /* depth */ + 255, /* max gray */ + 0, /* max color */ + 256, /* dither gray */ + 0, /* dither color */ + bjc_print_page_gray, INK_K); + + + /***************************************************************************/ + /* --------------------------- 3 bit CMYK Color -------------------------- */ + /***************************************************************************/ + + + + private const gx_device_procs bjc_cmykcolor_procs = + bjc_cmyk_param_procs(gdev_prn_open, gdev_prn_output_page, gdev_prn_close, + cmyk_1bit_map_color_rgb, cmyk_1bit_map_cmyk_color, + gdev_bjc_get_params, gdev_bjc_put_params); + + const gx_device_bjc_printer gs_bjccmyk_device = + bjc_device(bjc_cmykcolor_procs, "bjccmyk", + DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS, + X_DPI, Y_DPI, + // 0, 0, 0, 0, /* margins */ + (3.4 / 25.4), (7.0 / 25.4), (3.4 / 25.4), (3.0 / 25.4), + 4, /* num components */ + 4, /* depth */ + 1, /* max gray */ + 1, /* max color */ + 2, /* dither gray */ + 2, /* dither color */ + bjc_print_page_cmyk, (INK_K|INK_C|INK_M|INK_Y)); + + + /***************************************************************************/ + /* --------------------------- 24 bit TrueColor -------------------------- */ + /***************************************************************************/ + + + + private const gx_device_procs bjc_truecolor_procs = + bjc_cmyk_param_procs(gdev_prn_open, gdev_prn_output_page, gdev_prn_close, + cmyk_8bit_map_color_rgb, cmyk_8bit_map_cmyk_color, + gdev_bjc_get_params, gdev_bjc_put_params); + + const gx_device_bjc_printer gs_bjccolor_device = + bjc_device(bjc_truecolor_procs, "bjccolor", + DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS, + X_DPI, Y_DPI, + // 0, 0, 0, 0, /* margins */ + (3.4 / 25.4), (7.0 / 25.4), (3.4 / 25.4), (3.0 / 25.4), + 4, /* num components */ + 32, /* depth */ + 255, /* max gray */ + 255, /* max color */ + 256, /* dither gray */ + 256, /* dither color */ + bjc_print_page_color, (INK_K|INK_C|INK_M|INK_Y)); + + + /***************************************************************************/ + /* ---------------------------Print a page routine------------------------ */ + /***************************************************************************/ + + /* + private int + bjc_print_page(gx_device_printer * pdev, FILE * file) + { + #define ppdev ((gx_device_bjc_printer *) pdev) + #define prdev ((gx_device_printer *) pdev) + + uint raster = gdev_prn_raster(pdev); + uint bjc_raster = raster + (-raster & 3); + byte *row = gs_alloc_bytes(pdev->memory, bjc_raster, "bjc file buffer"); + int y; + int code; + char alma[512]; + + sprintf(alma, "\nNumC: %d, Depth: %d, Mgray: %d, Mrgb: %d\n" + "Dgray: %d, Drgb: %d", pdev->color_info.num_components, + pdev->color_info.depth, + pdev->color_info.max_gray, + pdev->color_info.max_color, + pdev->color_info.dither_grays, + pdev->color_info.dither_colors + ); + + if (row == 0) + return_error(gs_error_VMerror); + + + done: + gs_free_object(pdev->memory, row, "bjc file buffer"); + + + fwrite((const char *) alma, 512, 1, file); + return code; + + #undef ppdev + } + */ + + void + bjc_put_bjl_command(FILE * file, int bjl_command) + { + BJL_command *command = BJL_command_set; + for( ; command->string; command++) + if(command->numeric == bjl_command) break; + if(command->string) { + fwrite((const char *)"\033[K\002\000\000\037BJLSTART\012", 16, 1, file); + fwrite(command->string, command->length, 1, file); + fwrite((const char *)"\012BJLEND\012", 8, 1, file); } + } + + + /* ------ Get/put parameters ------ */ + + + /* Functions for manipulation params strings */ + + const stringParamDescription * + paramValueToParam(const stringParamDescription * params, int value) + { + + for (; params->p_string.data; ++params) { + if (params->p_value == value) { + return params; + } + } + + return (stringParamDescription *) NULL; + } + + const stringParamDescription * + paramStringToParam(const stringParamDescription * params, + const char * name, uint len) + { + for (; params->p_string.data; ++params) { + if (len == params->p_string.size) + if (!(strncmp((const char *)params->p_string.data, + name, len))) { + return params; + } + } + + return (stringParamDescription *) NULL; + } + + + /* Get parameters. BJC printer devices add several more parameters */ + /* to the default set. */ + private int + gdev_bjc_get_params(gx_device * pdev, gs_param_list * plist) + { + const gx_device_bjc_printer * ppdev = (gx_device_bjc_printer *)pdev; + // gs_param_string + + int code = gdev_prn_get_params(pdev, plist); + // stringParamDescription *tmppar; + if (code < 0 || + (code = param_write_string(plist, "PrinterType", + ¶mValueToParam(strPrinterType, ppdev->printerType)->p_string)) < 0 || + (code = param_write_string(plist, "Feeder", + ¶mValueToParam(strFeeder, ppdev->feeder)->p_string)) < 0 || + (code = param_write_string(plist, "Media", + ¶mValueToParam(strMedia, ppdev->mediaType)->p_string)) < 0 || + (code = param_write_string(plist, "Quality", + ¶mValueToParam(strQuality, ppdev->quality)->p_string)) < 0 || + (code = param_write_string(plist, "InkColor", + ¶mValueToParam(strInk, ppdev->ink)->p_string)) < 0 || + + (code = param_write_bool(plist, "Inverse", &ppdev->inverse)) < 0 || + (code = param_write_bool(plist, "Smooth", &ppdev->smooth)) < 0 || + (code = param_write_bool(plist, "Compress", &ppdev->compress)) < 0 || + (code = param_write_bool(plist, "LimitCheck", &ppdev->limit)) < 0 || + (code = param_write_bool(plist, "DecomposeK", &ppdev->compose)) < 0 || + + (code = param_write_int(plist, "PaperRed", &ppdev->paperColor.red)) < 0 || + (code = param_write_int(plist, "PaperGreen", &ppdev->paperColor.green)) < 0 || + (code = param_write_int(plist, "PaperBlue", &ppdev->paperColor.blue)) < 0 || + (code = param_write_int(plist, "Random", &ppdev->rnd)) < 0 || + + (code = param_write_float(plist, "Gamma", &ppdev->gamma)) < 0 || + (code = param_write_float(plist, "RedGamma", &ppdev->redGamma)) < 0 || + (code = param_write_float(plist, "GreenGamma", &ppdev->greenGamma)) < 0 || + (code = param_write_float(plist, "BlueGamma", &ppdev->blueGamma)) < 0) + return code; + return code; + + } + + /* Put parameters. */ + private int + gdev_bjc_put_params(gx_device * pdev, gs_param_list * plist) + { + int code, ecode = 0; + const char *param_name; + gs_param_string tmppar; + uint parsize; + stringParamDescription *tmpstr=NULL; + + # define ppdev ((gx_device_bjc_printer *)pdev) + // int Type, Pass, Feeder, Paper, Red, Green, Blue; + + #define CHECK_PARAM_CASES(good, label) \ + case 1: \ + break; \ + case 0: \ + if ( good ) break; \ + ecode = gs_error_rangecheck; goto label; \ + default: \ + ecode = code; \ + label: \ + param_signal_error(plist, param_name, ecode) + + #define CHECK_str_PARAM_CASES(set, str, label) \ + case 1: \ + break; \ + case 0: \ + parsize = tmppar.size; \ + tmpstr = paramStringToParam(str, \ + (const char *)tmppar.data, \ + parsize); \ + if ( tmpstr ) { set = tmpstr->p_value; break;} \ + ecode = gs_error_rangecheck; goto label; \ + default: \ + ecode = code; \ + label: \ + param_signal_error(plist, param_name, ecode) + + switch ( code = param_read_string(plist, (param_name = "PrinterType"), + &tmppar)) { + CHECK_str_PARAM_CASES(ppdev->printerType, strPrinterType, label_Type); + } + switch (code = param_read_string(plist, (param_name = "Feeder"), + &tmppar)) { + CHECK_str_PARAM_CASES(ppdev->feeder, strFeeder, label_Feeder); + } + switch (code = param_read_string(plist, (param_name = "Media"), + &tmppar)) { + CHECK_str_PARAM_CASES(ppdev->mediaType, strMedia, label_Paper); + } + switch (code = param_read_string(plist, (param_name = "Quality"), + &tmppar)) { + CHECK_str_PARAM_CASES(ppdev->quality, strQuality, label_Quality); + } + switch (code = param_read_string(plist, (param_name = "InkColor"), + &tmppar)) { + CHECK_str_PARAM_CASES(ppdev->ink, strInk, label_Ink); + } + + switch (code = param_read_bool(plist, (param_name = "Inverse"), + &ppdev->inverse)) { + CHECK_PARAM_CASES( ppdev->inverse == true || + ppdev->inverse == false , label_Inverse); + } + switch (code = param_read_bool(plist, (param_name = "Compress"), + &ppdev->compress)) { + CHECK_PARAM_CASES( ppdev->compress == true || + ppdev->compress == false , label_Compress); + } + switch (code = param_read_bool(plist, (param_name = "Smooth"), + &ppdev->smooth)) { + CHECK_PARAM_CASES( ppdev->smooth == true || + ppdev->smooth == false , label_Smooth); + } + + switch (code = param_read_bool(plist, (param_name = "LimitCheck"), + &ppdev->limit)) { + CHECK_PARAM_CASES( ppdev->limit == true || + ppdev->limit == false , label_Limit); + } + + switch (code = param_read_bool(plist, (param_name = "DecomposeK"), + &ppdev->compose)) { + CHECK_PARAM_CASES( ppdev->compose == true || + ppdev->compose == false , label_Compose); + } + + switch (code = param_read_int(plist, (param_name = "PaperRed"), + &ppdev->paperColor.red)) { + CHECK_PARAM_CASES( ppdev->paperColor.red >= 0 && + ppdev->paperColor.red <= 255 , label_Red); + } + switch (code = param_read_int(plist, (param_name = "PaperGreen"), + &ppdev->paperColor.green)) { + CHECK_PARAM_CASES(ppdev->paperColor.green >= 0 && + ppdev->paperColor.green <= 255 , label_Green); + } + switch (code = param_read_int(plist, (param_name = "PaperBlue"), + &ppdev->paperColor.blue)) { + CHECK_PARAM_CASES(ppdev->paperColor.blue >= 0 && + ppdev->paperColor.blue <= 255 , label_Blue); + } + switch (code = param_read_int(plist, (param_name = "Random"), + &ppdev->rnd)) { + CHECK_PARAM_CASES(ppdev->rnd >= 0 && + ppdev->rnd <= 100 , label_Random); + } + switch (code = param_read_float(plist, (param_name = "Gamma"), + &ppdev->gamma)) { + CHECK_PARAM_CASES(ppdev->gamma >= 0.0 && + ppdev->gamma <= 10.0 , label_Gamma); + } + switch (code = param_read_float(plist, (param_name = "RedGamma"), + &ppdev->redGamma)) { + CHECK_PARAM_CASES(ppdev->redGamma >= 0.0 && + ppdev->redGamma <= 10.0 , label_Rgamma); + } + switch (code = param_read_float(plist, (param_name = "GreenGamma"), + &ppdev->greenGamma)) { + CHECK_PARAM_CASES(ppdev->greenGamma >= 0.0 && + ppdev->greenGamma <= 10.0 , label_Ggamma); + } + switch (code = param_read_float(plist, (param_name = "BlueGamma"), + &ppdev->blueGamma)) { + CHECK_PARAM_CASES(ppdev->blueGamma >= 0.0 && + ppdev->blueGamma <= 10.0 , label_Bgamma); + } + if (ecode < 0) return ecode; + + return gdev_prn_put_params(pdev, plist); + #undef ppdev + } + + private int + bjc_print_page_mono(gx_device_printer * pdev, FILE * file) + { + #define ppdev ((gx_device_bjc_printer *) pdev) + #define prdev ((gx_device_printer *) pdev) + + uint raster = gdev_prn_raster(pdev); + uint cmplen; + byte *row = gs_alloc_bytes(pdev->memory, raster, "bjc mono file buffer"); + byte *cmp = gs_alloc_bytes(pdev->memory, (raster << 1) + 1, + "bjc mono comp buffer"); /*worst case */ + byte *outrow; /* misc variable for send a row */ + int y; + int skip; /* empty raster lines */ + char color = (ppdev->smooth == true ? 0x12 : /* smooted black */ + ((ppdev->ink & INK_K) ? 0x11: 0x10)); /* black or color */ + char ink = 0x01; /* regular ink type */ + char compress = (ppdev->compress == true ? 0x01 : 0x00); /* compression or not */ + int x_resolution = pdev->HWResolution[0]; + int y_resolution = pdev->HWResolution[1]; + int length = 0/*x71*/, lm = 0/*x01*/, rm = 0/*x01*/, top = 0/*x50*/; + byte inkc = ppdev->ink; + byte mask_array[] = { 0xff, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe }; + byte lastmask = mask_array[pdev->width % 8]; + + if (row == 0 || cmp == 0) /* can't allocate row buffer */ + return_error(gs_error_VMerror); + + /* Write the setup data. */ + + bjc_put_set_initial (file); /* start printing */ + bjc_put_print_method(file, color, media_codes[ppdev->mediaType].c, ppdev->quality, 0); + bjc_put_media_supply(file, ppdev->feeder, media_codes[ppdev->mediaType].l); + bjc_put_raster_resolution(file, x_resolution, y_resolution); + bjc_put_page_margins(file, length, lm, rm, top); + bjc_put_set_compression(file, compress); + bjc_put_image_format(file, 0, 0, ink); /* normal ink */ + + + /* Write the contents of the image. */ + skip = 0; + for (y = 0; y < pdev->height ; y++) { + gdev_prn_copy_scan_lines(pdev, y, row, raster); + if (bjc_invert_bytes(row, raster, ppdev->inverse, lastmask)) /* black -> K and check empty line*/ + { /* empty line raster */ + if (skip) bjc_put_raster_skip(file, skip); + skip = 1; + if(compress) cmplen = bjc_compress(row, raster, cmp), outrow = cmp; + else outrow = row, cmplen = raster; /* compress or not */ + if(inkc & INK_K) bjc_put_cmyk_image(file, CMYK_K, outrow, cmplen), + bjc_put_CR(file); + if(inkc & INK_C) bjc_put_cmyk_image(file, CMYK_C, outrow, cmplen), + bjc_put_CR(file); + if(inkc & INK_M) bjc_put_cmyk_image(file, CMYK_M, outrow, cmplen), + bjc_put_CR(file); + if(inkc & INK_Y) bjc_put_cmyk_image(file, CMYK_Y, outrow, cmplen), + bjc_put_CR(file); /* use the needed ink(s) */ + } + else skip++; /* +1 empty line */ + } + if (skip) bjc_put_raster_skip(file, skip); + bjc_put_FF(file); /* eject a page */ + bjc_put_initialize (file); + + gs_free_object(pdev->memory, cmp, "bjc mono comp buffer"); + gs_free_object(pdev->memory, row, "bjc mono file buffer"); + + return 0; + + #undef ppdev + } + + private int + bjc_print_page_gray(gx_device_printer * pdev, FILE * file) + { + #define ppdev ((gx_device_bjc_printer *) pdev) + #define prdev ((gx_device_printer *) pdev) + + uint width = pdev->width; /* Because grayscale */ + uint raster = (pdev->width >> 3) + ( (pdev->width % 8) ? 1:0); + uint cmplen; + byte *row = gs_alloc_bytes(pdev->memory, width, "bjc gray file buffer"); + byte *dit = gs_alloc_bytes(pdev->memory, raster, "bjc gray dither buffer"); + byte *cmp = gs_alloc_bytes(pdev->memory, (raster << 1) + 1, + "bjc gray comp buffer"); /*worst case */ + byte *out; /* misc variable for send a row */ + int y; + int skip; /* empty raster lines */ + char color = (ppdev->smooth == true ? 0x12 : /* smooted black */ + ((ppdev->ink & INK_K) ? 0x11: 0x10)); /* black or color */ + char ink = 0x01; /* regular ink type */ + char compress = (ppdev->compress == true ? 0x01 : 0x00); /* compression or not */ + int x_resolution = pdev->HWResolution[0]; + int y_resolution = pdev->HWResolution[1]; + int length = 0/*x71*/, lm = 0/*x01*/, rm = 0/*x01*/, top = 0/*x50*/; + byte inkc = ppdev->ink; + byte mask_array[] = { 0xff, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe }; + byte lastmask = mask_array[pdev->width % 8]; + + if (row == 0 || cmp == 0 || + dit == 0 ) /* can't allocate row buffers */ + return_error(gs_error_VMerror); + + /* Write the setup data. */ + + bjc_build_gamma_table(ppdev->gamma, CMYK_K); /* set up the gamma table */ + + bjc_put_set_initial (file); /* start printing */ + bjc_put_print_method(file, color, media_codes[ppdev->mediaType].c, ppdev->quality, 0); + bjc_put_media_supply(file, ppdev->feeder, media_codes[ppdev->mediaType].l); + bjc_put_raster_resolution(file, x_resolution, y_resolution); + bjc_put_page_margins(file, length, lm, rm, top); + bjc_put_set_compression(file, compress); + bjc_put_image_format(file, 0, 0, ink); /* normal ink */ + + + /* Write the contents of the image. */ + skip = 0; + if(FloydSteinbergInitG(pdev) == -1) + return_error(gs_error_VMerror); /* initiate the dithering */ + + for (y = 0; y < pdev->height ; y++) { + gdev_prn_copy_scan_lines(pdev, y, row, width); /* image -> row */ + FloydSteinbergDitheringG(row, dit, width, raster, ppdev->limit); /* gray */ + if (bjc_invert_bytes(dit, raster, ppdev->inverse, lastmask)) /* black -> K and check empty line*/ + { /* end of empty lines */ + if (skip) bjc_put_raster_skip(file, skip); + skip = 1; + + if(compress) cmplen = bjc_compress(dit, raster, cmp), out = cmp; + else cmplen = raster, out = dit; /* compress or not */ + + if(inkc & INK_K) bjc_put_cmyk_image(file, CMYK_K, out, cmplen), + bjc_put_CR(file); + if(inkc & INK_C) bjc_put_cmyk_image(file, CMYK_C, out, cmplen), + bjc_put_CR(file); + if(inkc & INK_M) bjc_put_cmyk_image(file, CMYK_M, out, cmplen), + bjc_put_CR(file); + if(inkc & INK_Y) bjc_put_cmyk_image(file, CMYK_Y, out, cmplen), + bjc_put_CR(file); /* use the needed ink(s) */ + + } else skip++; /* +1 empty line */ + } + if (skip) bjc_put_raster_skip(file, skip); + bjc_put_FF(file); /* eject a page */ + bjc_put_initialize (file); + + FloydSteinbergCloseG(pdev); + gs_free_object(pdev->memory, dit, "bjc gray dither buffer"); + gs_free_object(pdev->memory, cmp, "bjc gray comp buffer"); + gs_free_object(pdev->memory, row, "bjc gray file buffer"); + + return 0; + + #undef ppdev + } + + private int + bjc_print_page_cmyk(gx_device_printer * pdev, FILE * file) + { + #define ppdev ((gx_device_bjc_printer *) pdev) + #define prdev ((gx_device_printer *) pdev) + + // uint raster = gdev_prn_raster(pdev); + uint raster = bitmap_raster(pdev->width); + uint a_raster; /* a tmp variable */ + uint cmplen; + byte *row = gs_alloc_bytes(pdev->memory, raster*4, + "bjc cmyk file buffer"); /* one for each component */ + byte *cmp = gs_alloc_bytes(pdev->memory, (raster << 1) + 1, + "bjc cmyk comp buffer"); /*worst case */ + byte *rows[4]; + byte *outrow; /* misc variable for send a row */ + int y; + int skip; /* empty raster lines */ + char color = 0x10; /* color */ + char ink = 0x01; /* regular ink type */ + char compress = (ppdev->compress == true ? 0x01 : 0x00); /* compression or not */ + char skip_x; + int x_resolution = pdev->HWResolution[0]; + int y_resolution = pdev->HWResolution[1]; + int length = 0/*x71*/, lm = 0/*x01*/, rm = 0/*x01*/, top = 0/*x50*/; + int plane; + byte mask_array[] = { 0xff, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe }; + byte lastmask = mask_array[pdev->width % 8]; + skip_t skipc; + byte inkc = ppdev->ink; + bool inverse = ppdev->inverse; + gx_render_plane_t render_plane; + + if (row == 0 || cmp == 0) /* can't allocate row buffer */ + return_error(gs_error_VMerror); + + /* Write the setup data. */ + + bjc_put_set_initial (file); /* start printing */ + bjc_put_print_method(file, color, media_codes[ppdev->mediaType].c, ppdev->quality, 0); + bjc_put_media_supply(file, ppdev->feeder, media_codes[ppdev->mediaType].l); + bjc_put_raster_resolution(file, x_resolution, y_resolution); + bjc_put_page_margins(file, length, lm, rm, top); + bjc_put_set_compression(file, compress); + bjc_put_image_format(file, 0, 0, ink); /* normal ink */ + + + /* Write the contents of the image. */ + skip = 0; + + for (y = 0; y < pdev->height ; y++) { + + skip_x = 0; + for (plane = 0; plane < 4; plane++) { /* print each color component */ + gx_render_plane_init(&render_plane, (gx_device *)pdev, plane); + gdev_prn_get_lines(pdev, y, 1, row + raster*plane, raster, + &rows[plane], &a_raster, &render_plane); + } + + { + int i; + byte *byteC=rows[0], *byteM=rows[1], + *byteY=rows[2], *byteK=rows[3]; + for(i=0; icompose) { + *byteK = *byteC & *byteM & *byteY; + *byteC &= ~(*byteK); + *byteM &= ~(*byteK); + *byteY &= ~(*byteK); + } + else { + *byteC |= *byteK; + *byteM |= *byteK; + *byteY |= *byteK; + *byteK = 0; + } + } + } + + if(bjc_invert_cmyk_bytes(rows[0], rows[1], rows[2], rows[3], + raster, inverse, lastmask, &skipc)) { + + if (skip) bjc_put_raster_skip(file, skip); + skip = 1; + if(skipc.skipC && (inkc & INK_C)) { + if(compress) cmplen = bjc_compress(rows[0], raster, cmp), outrow = cmp; + else outrow = rows[0], cmplen = raster; /* compress or not */ + bjc_put_cmyk_image(file, CMYK_C, outrow, cmplen), bjc_put_CR(file); + } + if(skipc.skipM && (inkc & INK_M)) { + if(compress) cmplen = bjc_compress(rows[1], raster, cmp), outrow = cmp; + else outrow = rows[1], cmplen = raster; /* compress or not */ + bjc_put_cmyk_image(file, CMYK_M, outrow, cmplen), bjc_put_CR(file); + } + if(skipc.skipY && (inkc & INK_Y)) { + if(compress) cmplen = bjc_compress(rows[2], raster, cmp), outrow = cmp; + else outrow = rows[2], cmplen = raster; /* compress or not */ + bjc_put_cmyk_image(file, CMYK_Y, outrow, cmplen), bjc_put_CR(file); + } + if(skipc.skipK && (inkc & INK_K)) { + if(compress) cmplen = bjc_compress(rows[3], raster, cmp), outrow = cmp; + else outrow = rows[3], cmplen = raster; /* compress or not */ + bjc_put_cmyk_image(file, CMYK_K, outrow, cmplen), bjc_put_CR(file); + } + } + else skip++; /* +1 empty line */ + } + + if (skip) bjc_put_raster_skip(file, skip); + bjc_put_FF(file); /* eject a page */ + bjc_put_initialize (file); + + gs_free_object(pdev->memory, cmp, "bjc cmyk comp buffer"); + gs_free_object(pdev->memory, row, "bjc cmyk file buffer"); + + return 0; + + #undef ppdev + } + + private int + bjc_print_page_color(gx_device_printer * pdev, FILE * file) + { + #define ppdev ((gx_device_bjc_printer *) pdev) + #define prdev ((gx_device_printer *) pdev) + + // uint raster = gdev_prn_raster(pdev); + uint width = pdev->width; /* Because grayscale */ + uint raster = (pdev->width >> 3) + ( (pdev->width % 8) ? 1:0); + uint cmplen; + byte *row = gs_alloc_bytes(pdev->memory, width*4, + "bjc true file buffer"); /* one for each component */ + byte *dit = gs_alloc_bytes(pdev->memory, raster*4, + "bjc true dither buffer"); + byte *cmp = gs_alloc_bytes(pdev->memory, (raster << 1) + 1, + "bjc true comp buffer"); /*worst case */ + byte *rowC = dit; /*C*/ + byte *rowM = dit + raster; /*M*/ + byte *rowY = dit + 2*raster; /*Y*/ + byte *rowK = dit + 3*raster; /*K*/ + byte *outrow; /* misc variable for send a row */ + int y; + int skip; /* empty raster lines */ + char color = 0x10; /* color */ + char ink = 0x01; /* regular ink type */ + char compress = (ppdev->compress == true ? 0x01 : 0x00); /* compression or not */ + int x_resolution = pdev->HWResolution[0]; + int y_resolution = pdev->HWResolution[1]; + int length = 0/*x71*/, lm = 0/*x01*/, rm = 0/*x01*/, top = 0/*x50*/; + byte mask_array[] = { 0xff, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe }; + byte lastmask = mask_array[pdev->width % 8]; + skip_t skipc; + byte inkc = ppdev->ink; + float rgamma = ppdev->gamma != 1.0 ? ppdev->gamma:ppdev->redGamma; + float ggamma = ppdev->gamma != 1.0 ? ppdev->gamma:ppdev->greenGamma; + float bgamma = ppdev->gamma != 1.0 ? ppdev->gamma:ppdev->blueGamma; + + if (row == 0 || cmp == 0 || dit == 0) /* can't allocate row buffer */ + return_error(gs_error_VMerror); + + bjc_build_gamma_table(rgamma, CMYK_C); /* set up the gamma table */ + bjc_build_gamma_table(ggamma, CMYK_M); /* set up the gamma table */ + bjc_build_gamma_table(bgamma, CMYK_Y); /* set up the gamma table */ + + /* Write the setup data. */ + + bjc_put_set_initial (file); /* start printing */ + bjc_put_print_method(file, color, media_codes[ppdev->mediaType].c, ppdev->quality, 0); + bjc_put_media_supply(file, ppdev->feeder, media_codes[ppdev->mediaType].l); + bjc_put_raster_resolution(file, x_resolution, y_resolution); + bjc_put_page_margins(file, length, lm, rm, top); + bjc_put_set_compression(file, compress); + bjc_put_image_format(file, 0, 0, ink); /* normal ink */ + + + /* Write the contents of the image. */ + skip = 0; + + if(FloydSteinbergInitC(pdev) == -1) + return_error(gs_error_VMerror); /* initiate the dithering */ + + for (y = 0; y < pdev->height ; y++) { + gdev_prn_copy_scan_lines(pdev, y, row, gdev_prn_raster(pdev)); + /* image -> row */ + FloydSteinbergDitheringC(row, dit, width, raster, ppdev->limit, + ppdev->compose); + + if(bjc_invert_cmyk_bytes(rowC, rowM, rowY, rowK, + raster, ~ppdev->inverse, lastmask, + &skipc)) { + if (skip) bjc_put_raster_skip(file, skip); + skip = 1; + if(skipc.skipC && (inkc & INK_C) ) { + if(compress) cmplen = bjc_compress(rowC, raster, cmp), outrow = cmp; + else outrow = rowC, cmplen = raster; /* compress or not */ + bjc_put_cmyk_image(file, CMYK_C, outrow, cmplen), bjc_put_CR(file); + } + if(skipc.skipM && (inkc & INK_M) ) { + if(compress) cmplen = bjc_compress(rowM, raster, cmp), outrow = cmp; + else outrow = rowM, cmplen = raster; /* compress or not */ + bjc_put_cmyk_image(file, CMYK_M, outrow, cmplen), bjc_put_CR(file); + } + if(skipc.skipY && (inkc & INK_Y) ) { + if(compress) cmplen = bjc_compress(rowY, raster, cmp), outrow = cmp; + else outrow = rowY, cmplen = raster; /* compress or not */ + bjc_put_cmyk_image(file, CMYK_Y, outrow, cmplen), bjc_put_CR(file); + } + if(skipc.skipK && (inkc & INK_K) ) { + if(compress) cmplen = bjc_compress(rowK, raster, cmp), outrow = cmp; + else outrow = rowK, cmplen = raster; /* compress or not */ + bjc_put_cmyk_image(file, CMYK_K, outrow, cmplen), bjc_put_CR(file); + } + } + else skip++; /* +1 empty line */ + } + + if (skip) bjc_put_raster_skip(file, skip); + bjc_put_FF(file); /* eject a page */ + bjc_put_initialize (file); + + FloydSteinbergCloseC(pdev); + gs_free_object(pdev->memory, cmp, "bjc true comp buffer"); + gs_free_object(pdev->memory, dit, "bjc true dither buffer"); + gs_free_object(pdev->memory, row, "bjc true file buffer"); + + return 0; + + #undef ppdev + } diff -rNc ghostscript-7.05.orig/src/gdevbjc_.h ghostscript-7.05/src/gdevbjc_.h *** ghostscript-7.05.orig/src/gdevbjc_.h Thu Jan 1 01:00:00 1970 --- ghostscript-7.05/src/gdevbjc_.h Fri Jul 12 22:46:38 2002 *************** *** 0 **** --- 1,230 ---- + /* BJC-210/240/250/265/1000 Bubble Jet Printer driver for GhostScript + * header file + * + * Copyright 2000, 2001, 2002 Gergely Szász (Gergely Sza'sz) + * mailto://szaszg@hu.inter.net http://bjc250gs.sourceforge.net + * + * This program may be distributed and/or modified under the terms of + * the GNU General Public License as published by the Free Software + * Foundation (the "GPL"); either version 2 of the GPL, or (at your option) + * any later version. + * + * When distributed under the terms of the GPL, this program is distributed + * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GPL for more details. + * + * If this program is being distributed under the terms of the GPL, you + * should have received a copy of the GPL along with this program, normally + * in a plain ASCII text file named COPYING; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 + * U.S.A. + */ + + /* Copyright (C) 1989, 2000 Aladdin Enterprises. All rights reserved. + + This program may also be distributed as part of AFPL Ghostscript, under the + terms of the Aladdin Free Public License (the "License"). + + AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND. No + author or distributor accepts any responsibility for the consequences of + using it, or for whether it serves any particular purpose or works at + all, unless he or she says so in writing. Refer to the License for full + details. + + Every copy of AFPL Ghostscript must include a copy of the License, + normally in a plain ASCII text file named PUBLIC. The License grants you + the right to copy, modify and redistribute AFPL Ghostscript, but only + under certain conditions described in the License. Among other things, + the License requires that the copyright notice and this notice be + preserved on all copies. + */ + + /* BJC printer drivers definitions and utility interfaces */ + + #ifndef gdevbjc_INCLUDED + # define gdevbjc_INCLUDED + + /* Define the default X and Y resolution. */ + #define X_DPI 360 + #define Y_DPI 360 + + #define CMYK_K 'K' + #define CMYK_C 'C' + #define CMYK_M 'M' + #define CMYK_Y 'Y' + + #define INK_K 8 + #define INK_C 1 + #define INK_M 2 + #define INK_Y 4 + + typedef struct { + gs_param_string p_string; + int p_value; + } stringParamDescription; + + /* Definitions of device parameters */ + struct skip_s { + bool skipC; + bool skipM; + bool skipY; + bool skipK; + }; + + typedef struct skip_s skip_t; + + typedef struct { + unsigned char l; + unsigned char c; + } media_t; + + struct gx_device_bjc_printer_s { + gx_device_common; + gx_prn_device_common; + int printerType; /* BJC-250, BJC-250ex, BJC1000, ... */ + int feeder; /* Needed paper feeder */ + int mediaType; /* paper type */ + int quality; + int ink; + int rnd; + bool inverse; + bool compress; + bool smooth; + bool limit; /* paper color correction limit check */ + bool compose; /* color K decomposition */ + float gamma; + float redGamma; + float greenGamma; + float blueGamma; + struct { + int red; + int green; + int blue; + } paperColor; /* paper color for color correction */ + }; + + typedef struct gx_device_bjc_printer_s gx_device_bjc_printer; + + #define bjc_device_margins_body(dtype, procs, dname, w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_page)\ + std_device_full_body_type(dtype, &procs, dname, &st_device_printer,\ + (int)((long)(w10) * (xdpi) / 10),\ + (int)((long)(h10) * (ydpi) / 10),\ + xdpi, ydpi,\ + ncomp, depth, mg, mc, dg, dc,\ + -(lo) * (xdpi), -(to) * (ydpi),\ + (lm) * 72.0, (bm) * 72.0,\ + (rm) * 72.0, (tm) * 72.0\ + ),\ + prn_device_body_rest_(print_page) + + #define bjc_device_margins(procs, dname, w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_page, def_ink)\ + { bjc_device_margins_body(gx_device_bjc_printer, procs, dname,\ + w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, \ + ncomp, depth, mg, mc, dg, dc, print_page),\ + (int) 0, /* def, printer: BJC250 */ \ + (int) 0x10, /* Auto Feeder */ \ + (int) 0, /* Plain paper */ \ + (int) 0, /* Normal quality */ \ + (int) def_ink, /* Black monochrome ink */ \ + (int) 15, /* Randomness is 15% */ \ + (bool) false, /* Normal printing */ \ + (bool) true, /* Use compression */ \ + (bool) false, /* no smoothing */ \ + (bool) false, /* no limit check */ \ + (bool) true, /* yes we run decomp */ \ + (float) 1.0, /* initiaal gamma */ \ + (float) 1.0, /* initiaal gamma */ \ + (float) 1.0, /* initiaal gamma */ \ + (float) 1.0, /* initiaal gamma */ \ + { (int) 255, /* White paper */ \ + (int) 255, /* */ \ + (int) 255 } /* */ \ + }; + + + #define bjc_device(procs, dname, w10, h10, xdpi, ydpi, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_page, def_ink)\ + bjc_device_margins(procs, dname, w10, h10, xdpi, ydpi,\ + lm, tm, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_page, def_ink) + + + #define bjc_cmyk_param_procs(v_prn_open, v_prn_output_page, v_prn_close, \ + p_map_color_rgb, p_map_cmyk_color, \ + v_prn_get_params, v_prn_put_params)\ + {v_prn_open, NULL, NULL, v_prn_output_page, v_prn_close,\ + NULL, p_map_color_rgb, NULL, NULL, NULL, NULL, NULL, NULL,\ + v_prn_get_params, v_prn_put_params,\ + p_map_cmyk_color, NULL, NULL, NULL, gx_page_device_get_page_device} + + + /* There are the definitions of commands for the Canon BJC printers. */ + + #define BJC_BJL_CLEANING 0x00 // "@Cleaning=1\n" + #define BJC_BJL_POWER_OFF 0x01 // "@PowerOff\n" + #define BJC_BJL_ROCLEANING 0x02 // "@RollerCleaning\n" + #define BJC_BJL_NOZZLECHK 0x03 // "@TestPrint=NozzleCheck\n" + #define BJC_BJL_TESTA 0x04 // "@TestPrint=A\012" + #define BJC_BJL_TESTB 0x05 // "@TestPrint=B\012" + #define BJC_BJL_TESTC 0x06 // "@TestPrint=A\012" + #define BJC_BJL_DEMO 0x07 // "@TestPrint=DemoPrint\012" + + #define BJC_BJL_ON_ENABLE 0x20 // "AutoPowerOn=Enable\n" + #define BJC_BJL_ON_DISABLE 0x21 // "AutoPowerOn=Disable\n" + #define BJC_BJL_OFF_1MIN 0x22 // "AutoPowerOff=1\n" + #define BJC_BJL_OFF_10MIN 0x23 // "AutoPowerOff=10\n" + #define BJC_BJL_OFF_30MIN 0x24 // "AutoPowerOff=30\n" + #define BJC_BJL_OFF_60MIN 0x25 // "AutoPowerOff=60\n" + #define BJC_BJL_OFF_DISABLE 0x26 // "AutoPowerOff=Disable\n" + + typedef struct { + const char *string; + int numeric; + int length; } BJL_command; + + /* Put a BJL command to stream */ + + void bjc_put_bjl_command(P2(FILE * file, int bjl_command)); + + void bjc_put_LF(P1(FILE *file)); + void bjc_put_FF(P1(FILE *file)); + void bjc_put_CR(P1(FILE *file)); + void bjc_put_initialize(P1(FILE *file)); + void bjc_put_set_initial(P1(FILE *file)); + void bjc_put_set_compression(P2(FILE *file, char compression)); + void bjc_put_print_method_short(P2(FILE *file, char color)); + void bjc_put_print_method(P5(FILE *file, char color, char media, char quality, char density)); + void bjc_put_raster_resolution(P3(FILE *file, int x_resolution, int y_resolution)); + void bjc_put_raster_skip(P2(FILE *file, int skip)); + void bjc_put_page_margins(P5(FILE *file, int length, int lm, int rm, int top)); + void bjc_put_media_supply(P3(FILE *file, char supply, char type)); + void bjc_put_cmyk_image(P4(FILE *file, char component, const char *data, int count)); + void bjc_put_move_lines(P2(FILE *file, int lines)); + void bjc_put_move_lines_unit(P2(FILE *file, int unit)); + void bjc_put_extended_margins(P5(FILE *file, int length, int lm, int rm, int top)); + void bjc_put_image_format(P4(FILE *file, char depth, char format, char ink)); + void bjc_put_page_id(P2(FILE *file, int id)); + void bjc_put_continue_image(P3(FILE *file, const char *data, int count)); + void bjc_put_indexed_image(P4(FILE *file, int dot_rows, int dot_cols, int layers)); + + bool bjc_invert_bytes(P4(byte *row, uint raster, bool inverse, byte lastmask)); + bool bjc_invert_cmyk_bytes(P8(byte *rowC,byte *rowM, byte *rowY, byte *rowK, uint raster, + bool inverse, byte lastmask, skip_t *skip)); + uint bjc_compress(P3(const byte *row, uint raster, byte *compressed)); + + int FloydSteinbergInitG(P1(gx_device_printer * pdev)); + void FloydSteinbergDitheringG(P5(byte *row, byte *dithered, uint width, uint raster, bool limit_extr)); + void FloydSteinbergCloseG(P1(gx_device_printer *pdev)); + + int FloydSteinbergForwardCut(P5(int error, int *Errors, int i, byte *dithered, byte bitmask)); + int FloydSteinbergBckwardCut(P5(int error, int *Errors, int i, byte *dithered, byte bitmask)); + int FloydSteinbergInitC(P1(gx_device_printer * pdev)); + void FloydSteinbergDitheringC(P6(byte *row, byte *dithered, uint width, uint raster, + bool limit_extr, bool composeK)); + void FloydSteinbergCloseC(P1(gx_device_printer *pdev)); + + void bjc_build_gamma_table(P2(float gamma, char color)); + void bjc_rgb_to_cmy (P6(byte r, byte g, byte b, int *c, int *m, int *y)); + void bjc_rgb_to_gray(P4(byte r, byte g, byte b, int *k)); + uint bjc_rand(void); + void bjc_init_tresh(P1(int rnd)); + #endif /* gdevbjc_INCLUDED */ diff -rNc ghostscript-7.05.orig/src/gdevbjca.c ghostscript-7.05/src/gdevbjca.c *** ghostscript-7.05.orig/src/gdevbjca.c Thu Jan 1 01:00:00 1970 --- ghostscript-7.05/src/gdevbjca.c Fri Jul 12 22:46:38 2002 *************** *** 0 **** --- 1,875 ---- + /* BJC-210/240/250/265/1000 Bubble Jet Printer driver for GhostScript + * utility subroutines and dithering code + * + * Copyright 2000, 2001, 2002 Gergely Szász (Gergely Sza'sz) + * mailto://szaszg@hu.inter.net http://bjc250gs.sourceforge.net + * + * This program may be distributed and/or modified under the terms of + * the GNU General Public License as published by the Free Software + * Foundation (the "GPL"); either version 2 of the GPL, or (at your option) + * any later version. + * + * When distributed under the terms of the GPL, this program is distributed + * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GPL for more details. + * + * If this program is being distributed under the terms of the GPL, you + * should have received a copy of the GPL along with this program, normally + * in a plain ASCII text file named COPYING; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 + * U.S.A. + */ + + /* Copyright (C) 1989, 2000 Aladdin Enterprises. All rights reserved. + + This program may also be distributed as part of AFPL Ghostscript, under the + terms of the Aladdin Free Public License (the "License"). + + AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND. No + author or distributor accepts any responsibility for the consequences of + using it, or for whether it serves any particular purpose or works at + all, unless he or she says so in writing. Refer to the License for full + details. + + Every copy of AFPL Ghostscript must include a copy of the License, + normally in a plain ASCII text file named PUBLIC. The License grants you + the right to copy, modify and redistribute AFPL Ghostscript, but only + under certain conditions described in the License. Among other things, + the License requires that the copyright notice and this notice be + preserved on all copies. + */ + + /* BJC printer drivers utilities */ + #include "gdevprn.h" + #include "gdevbjc_.h" + #include + #include + + private void bjc_put_bytes(P3(FILE *file, const char *data, int count)); + private void bjc_put_hi_lo(P2(FILE *file, int value)); + private void bjc_put_lo_hi(P2(FILE *file, int value)); + private void bjc_put_command(P3(FILE *file, char command, int count)); + + /* ---------------- Utilities ---------------- */ + + private void + bjc_put_bytes(FILE *file, const char *data, int count) + { + + fwrite(data, count, 1, file); + } + + private void + bjc_put_hi_lo(FILE *file, int value) + { + fputc(((value & 0xffff) >> 8), file); + fputc(value & 0xff, file); + } + + private void + bjc_put_lo_hi(FILE *file, int value) + { + fputc(value & 0xff, file); + fputc(((value & 0xffff) >> 8), file); + } + + private void + bjc_put_command(FILE *file, char command, int count) + { char tmp[3] = { '\033', '(', ' '}; + tmp[2] = command; + fwrite( tmp, 3, 1, file); + bjc_put_lo_hi(file, count); + } + + /* ---------------- Commands ---------------- */ + + /* Line feed (^J) */ + void + bjc_put_LF(FILE *file) + { + fputc(0x0a, file); + } + + /* Form feed (^L) */ + void + bjc_put_FF(FILE *file) + { + fputc(0x0c, file); + } + + /* Carriage return (^M) */ + void + bjc_put_CR(FILE *file) + { + fputc(0x0d, file); + } + + /* Return to initial condition (ESC @) */ + void + bjc_put_initialize(FILE *file) + { + bjc_put_bytes(file, "\033@", 2); + } + + /* Set initial condition (ESC [ K ) */ + void + bjc_put_set_initial(FILE *file) + { + bjc_put_bytes(file, "\033[K\002\000\000\017", 7); + } + + /* Set data compression (ESC [ b ) */ + void + bjc_put_set_compression(FILE *file, char compression) + { + bjc_put_command(file, 'b', 1); + fputc(compression, file); + } + + /* Select print method (ESC ( c []) */ + void + bjc_put_print_method_short(FILE *file, char color) + { + bjc_put_command(file, 'c', 1); + fputc(color, file); + } + void + bjc_put_print_method(FILE *file, char color, char media, char quality, + char density) + { + bjc_put_command(file, 'c', 2 + (density != 0)); + fputc(color, file); + fputc(media | quality, file); + if (density) + fputc(density, file); + } + + /* Set raster resolution (ESC ( d []) */ + void + bjc_put_raster_resolution(FILE *file, int x_resolution, int y_resolution) + { + if (x_resolution == y_resolution) { + bjc_put_command(file, 'd', 2); + } else { + bjc_put_command(file, 'd', 4); + bjc_put_hi_lo(file, y_resolution); + } + bjc_put_hi_lo(file, x_resolution); + } + + /* Raster skip (ESC ( e ) */ + void + bjc_put_raster_skip(FILE *file, int skip) + { + bjc_put_command(file, 'e', 2); + bjc_put_hi_lo(file, skip); + } + + /* Set page margins (ESC ( g ) */ + void + bjc_put_page_margins(FILE *file, int length, int lm, int rm, int top) + { + char parms[4]; + + parms[0] = length, parms[1] = lm, parms[2] = rm, parms[3] = top; + /* count = 4; */ /* could be 1..3 */ + bjc_put_command(file, 'g', 4); + bjc_put_bytes(file, parms, 4); + } + + /* Set media supply method (ESC * l ) */ + void + bjc_put_media_supply(FILE *file, char supply, char type) + { + bjc_put_command(file, 'l', 2); + fputc(supply, file); + fputc(type << 4, file); + } + + /* Identify ink cartridge (ESC ( m ) */ /* + void + bjc_put_identify_cartridge(FILE *file, + bjc_identify_cartridge_command_t command) + { + bjc_put_command(s, 'm', 1); + spputc(s, command); + } */ + + /* CMYK raster image (ESC ( A ) */ + void + bjc_put_cmyk_image(FILE *file, char component, + const char *data, int count) + { + bjc_put_command(file, 'A', count + 1); + fputc(component, file); + bjc_put_bytes(file, data, count); + } + + /* Move by raster lines (ESC ( n ) */ + void + bjc_put_move_lines(FILE *file, int lines) + { + bjc_put_command(file, 'n', 2); + bjc_put_hi_lo(file, lines); + } + + /* Set unit for movement by raster lines (ESC ( o ) */ + void + bjc_put_move_lines_unit(FILE *file, int unit) + { + bjc_put_command(file, 'o', 2); + bjc_put_hi_lo(file, unit); + } + + /* Set extended margins (ESC ( p */ + /* ) */ + void + bjc_put_extended_margins(FILE *file, int length, int lm, int rm, int top) + { + bjc_put_command(file, 'p', 8); + bjc_put_hi_lo(file, length); + bjc_put_hi_lo(file, lm); + bjc_put_hi_lo(file, rm); + bjc_put_hi_lo(file, top); + } + + /* Set image format (ESC ( t ) */ + void + bjc_put_image_format(FILE *file, char depth, char format, char ink) + { + bjc_put_command(file, 't', 3); + fputc(depth, file); + fputc(format, file); + fputc(ink, file); + } + + /* Page ID (ESC ( q ) */ + void + bjc_put_page_id(FILE *file, int id) + { + bjc_put_command(file, 'q', 1); + fputc(id, file); + } + + /* Continue raster image (ESC ( F ) */ + void + bjc_put_continue_image(FILE *file, const char *data, int count) + { + bjc_put_command(file, 'F', count); + bjc_put_bytes(file, data, count); + } + + /* BJ indexed image (ESC ( f R */ + /* ) */ + void + bjc_put_indexed_image(FILE *file, int dot_rows, int dot_cols, int layers) + { + bjc_put_command(file, 'f', 5); + fputc('R', file); /* per spec */ + fputc(dot_rows, file); + fputc(dot_cols, file); + fputc(layers, file); + } + + + /* ------------------------------------------------------------------ */ + + /* Invert a raster line ( we need it for Black -> K ) */ + bool + bjc_invert_bytes(byte *row, uint raster, bool inverse, byte lastmask) + { bool ret=false; + + for(; raster > 1; row++, raster--) { + if(!(inverse)) *row = ~(*row); + if(*row) ret = true; + } + if(!(inverse)) *row ^= 0xff; + *row &= lastmask; + return ret; + } + + bool + bjc_invert_cmyk_bytes(byte *rowC, byte *rowM, byte *rowY, byte *rowK, + uint raster, bool inverse, byte lastmask, + skip_t *skip) + { bool ret=false; + byte tmpC, tmpM, tmpY; + + skip->skipC=false; + skip->skipM=false; + skip->skipY=false; + skip->skipK=false; + + for(; raster > 1; rowC++, rowM++, rowY++, rowK++, raster--) { + if(inverse) { + tmpC = ~(*rowC|*rowK); + tmpM = ~(*rowM|*rowK); + tmpY = ~(*rowY|*rowK); + *rowK = ~(*rowC|*rowM|*rowY|*rowK); + *rowC = tmpC; + *rowM = tmpM; + *rowY = tmpY; + } + if(*rowC) skip->skipC=true; + if(*rowM) skip->skipM=true; + if(*rowY) skip->skipY=true; + if(*rowK) skip->skipK=true; + if(*rowC|*rowM|*rowY|*rowK) ret = true; + } + return ret; + } + + /* "1D runlength compression for BJC-600 + * this code is borrowed from gdevpcl.c:gdev_pcl_mode2compress." + * I copy it from gdevcdj.c + * It is return with the compressed length. 'compressed' point to the + * compression buffer + */ + uint + bjc_compress(const byte *row, uint raster, byte *compressed) + { + const byte *end_row = row; + register const byte *exam = row; + register byte *cptr = compressed; /* output pointer into compressed bytes */ + + end_row += raster; + + while ( exam < end_row ) { + /* Search ahead in the input looking for a run */ + /* of at least 4 identical bytes. */ + const byte *compr = exam; + const byte *end_dis; + const byte *next; + register byte test, test2; + + test = *exam; + while ( exam < end_row ) { + test2 = *++exam; + if ( test == test2 ) + break; + test = test2; + } + + + /* Find out how long the run is */ + end_dis = exam - 1; + if ( exam == end_row ) { /* no run */ + next = --end_row; + } else { + + next = exam + 1; + while ( next < end_row && *next == test ) next++; + } + + + /* Now [compr..end_dis) should be encoded as dissimilar, */ + /* and [end_dis..next) should be encoded as similar. */ + /* Note that either of these ranges may be empty. */ + + + for ( ; ; ) { /* Encode up to 128 dissimilar bytes */ + uint count = end_dis - compr; /* uint for faster switch */ + switch ( count ) { /* Use memcpy only if it's worthwhile. */ + case 6: cptr[6] = compr[5]; + case 5: cptr[5] = compr[4]; + case 4: cptr[4] = compr[3]; + case 3: cptr[3] = compr[2]; + case 2: cptr[2] = compr[1]; + case 1: cptr[1] = compr[0]; + *cptr = count - 1; + cptr += count + 1; + case 0: /* all done */ + break; + default: + if ( count > 128 ) count = 128; + *cptr++ = count - 1; + memcpy(cptr, compr, count); + cptr += count, compr += count; + continue; + } + break; + } + + + { /* Encode up to 128 similar bytes. */ + /* Note that count may be <0 at end of row. */ + int count = next - end_dis; + if (next < end_row || test != 0) + while ( count > 0 ) { + + int this = (count > 128 ? 128 : count); + *cptr++ = 257 - this; + *cptr++ = (byte)test; + count -= this; + } + exam = next; + } + } + return (uint)(cptr - compressed); + } + + void bjc_rgb_to_cmy(byte r, byte g, byte b, + int *c, int *m, int *y) + { *c=255-r; + *m=255-g; + *y=255-b; + } + + void bjc_rgb_to_gray(byte r, byte g, byte b, + int *k) + { + *k = ( (int)r * 77 + (int)g * 151 + (int)b * 28) >> 8; + } + + int bjc_gamma_tableC[256]; + int bjc_gamma_tableM[256]; + int bjc_gamma_tableY[256]; + #define bjc_gamma_tableK bjc_gamma_tableC + + void bjc_build_gamma_table(float gamma, char color) + { int i; + int *table; + + switch(color) { + case CMYK_C: + table = bjc_gamma_tableC; + break; + case CMYK_M: + table = bjc_gamma_tableM; + break; + case CMYK_Y: + table = bjc_gamma_tableY; + break; + case CMYK_K: + default: + table = bjc_gamma_tableK; + break; + } + + if(gamma == 1.0) for (i = 0; i < 256; i++) table[i] = (255 - i) << 4; + else for (i = 0; i < 256; i++) table[i] = + 4080 - (int)(pow((double)i / 255.0, gamma) * 4080.0 + .5); + } + + /* -------------------------------------------------------------------------*/ + /* Subroutines and tables for randomization */ + /* -------------------------------------------------------------------------*/ + + int bjc_rand_seed[55] = { + 3627, 15177, 6104, 15555, 14210, 9940, 11987, 7070, 6147, 15691, 14536, 12896, + 8959, 14926, 9034, 13544, 13665, 3175, 10177, 14856, 16042, 4265, 13976, 10805, + 14817, 8216, 695, 8656, 9189, 15304, 1469, 9641, 1648, 16218, 12421, 5451, + 255, 11268, 16121, 11645, 1855, 5982, 9983, 1052, 5255, 15264, 6123, 3577, + 9712, 14629, 4593, 15670 + }; + int bjc_j=0, bjc_k=31; + + int bjc_treshold[1024]; + + uint bjc_rand(void) + { + uint ret=bjc_rand_seed[bjc_j] = bjc_rand_seed[bjc_j++] + + bjc_rand_seed[bjc_k++]; + if(bjc_j==55) bjc_j = 0; + if(bjc_k==55) bjc_k = 0; + return ret & 0x03ff; + } /* random numbers 0-1023 */ + + + void bjc_init_tresh(int rnd) + { + int i=(int)(time(NULL) & 0x0ff); + float delta=40.64*rnd; + for(;i>0;i--) bjc_rand(); + for(i=-512; i<512; i++) bjc_treshold[i+512] = + (int)(delta * i / 1024.0 + 2040); + } /* init treshold array ~rnd% around halfway (127*16) */ + + + /* Declarations for Floyd-Steinberg dithering. + * + * Errors are accumulated into the array fserrors[], at a resolution of + * 1/16th of a pixel count. The error at a given pixel is propagated + * to its not-yet-processed neighbors using the standard F-S fractions, + * ... (here) 7/16 + * 3/16 5/16 1/16 + * We work left-to-right on even rows, right-to-left on odd rows. + * + * We can get away with a single array (holding one row's worth of errors) + * by using it to store the current row's errors at pixel columns not yet + * processed, but the next row's errors at columns already processed. We + * need only a few extra variables to hold the errors immediately around the + * current column. (If we are lucky, those variables are in registers, but + * even if not, they're probably cheaper to access than array elements are.) + * + * The fserrors[] array has (#columns + 2) entries; the extra entry at + * each end saves us from special-casing the first and last pixels. + * Each entry is three values long, one value for each color component. + */ + + bool FloydSteinbergDirectionForward = true; + + int *FloydSteinbergErrorsC; + int *FloydSteinbergErrorsM; + int *FloydSteinbergErrorsY; + int *FloydSteinbergErrorsK; + int *FloydSteinbergErrorsG; + + int FloydSteinbergC; + int FloydSteinbergM; + int FloydSteinbergY; + int FloydSteinbergK; + int FloydSteinbergG; + + int + FloydSteinbergInitG(gx_device_printer * pdev) + { int i; + #define ppdev ((gx_device_bjc_printer *) pdev) + + FloydSteinbergErrorsG = (int *) gs_alloc_bytes(pdev->memory, + sizeof(int)*(pdev->width+3), + "bjc error buffer"); + if (FloydSteinbergErrorsG == 0) /* can't allocate error buffer */ + return -1; + FloydSteinbergDirectionForward=true; + + for (i=0; i < pdev->width+3; i++) FloydSteinbergErrorsG[i] = 0; + /* clear */ + bjc_rgb_to_gray(ppdev->paperColor.red, + ppdev->paperColor.green, + ppdev->paperColor.blue, + &FloydSteinbergG); + FloydSteinbergG = (255 - FloydSteinbergG) << 4; /* Maybe */ + bjc_init_tresh(ppdev->rnd); + return 0; + #undef ppdev + } + + void + FloydSteinbergDitheringG(byte *row, byte *dithered, uint width, + uint raster, bool limit_extr) + { + byte byteG=0, bitmask = 0x80; /* first bit */ + int i; + int error = 0, delta; + int err_corr; + int *err_vect; + + if (FloydSteinbergDirectionForward) { + /* First point */ + err_vect = FloydSteinbergErrorsG + 1; + + for( i=width; i>0; i--, row++, err_vect++) { /* i, sample, error */ + err_corr = bjc_gamma_tableK[255-(*row)] + FloydSteinbergG; + if(err_corr > 4080 && limit_extr) err_corr = 4080; + error += err_corr + *(err_vect+1); /* the error in 1/16 */ + + if(error > bjc_treshold[bjc_rand()]) { + error -= 4080; + byteG |= bitmask; + } + + *(err_vect+1) = (error + 8) >> 4; + delta = error << 1; /* 2 err */ + error += delta; /* 3/16 */ + *(err_vect-1) += (error + 8) >> 4; + error += delta; /* 5/16 */ + *err_vect += (error + 8) >> 4; + error += delta + 8; /* 7/16 */ + error >>= 4; + + if (bitmask == 0x01) { + *dithered = byteG; + bitmask = 0x80; + byteG = 0; + dithered++; + } + else if (i == 1) { + *dithered = byteG; + } + else bitmask >>= 1; + } + FloydSteinbergDirectionForward=false; + } + else { + row += width - 1; /* point to the end of the row */ + dithered += raster - 1; + bitmask = 1 << ((raster << 3 ) - width) ; + err_vect = FloydSteinbergErrorsG + width + 1; + + for( i=width; i>0; i--, row--, err_vect--) { + err_corr = bjc_gamma_tableK[255-(*row)] + FloydSteinbergG; + if(err_corr > 4080 && limit_extr) err_corr = 4080; + + error += err_corr + *(err_vect - 1); + + if(error > bjc_treshold[bjc_rand()]) { + error -= 4080; + byteG |= bitmask; + } + + *(err_vect-1) = (error + 8) >> 4; /* 1/16 */ + delta = error << 1; /* 2 err */ + error += delta; + *(err_vect+1) += (error +8) >> 4; /* 3/16 */ + error += delta; + *err_vect += (error + 8) >> 4; /* 5/16 */ + error += delta + 8; /* 7/16 */ + error >>= 4; + + if (bitmask == 0x80) { + *dithered = byteG; + bitmask = 0x01; + byteG = 0; + dithered--; + } else if(i==1) { + *dithered = byteG; + } + else bitmask <<= 1; + } + FloydSteinbergDirectionForward=true; + } + } + + void FloydSteinbergCloseG(gx_device_printer *pdev) + { + gs_free_object(pdev->memory, FloydSteinbergErrorsG, "bjc error buffer"); + } + + int + FloydSteinbergInitC(gx_device_printer * pdev) + { int i; + #define ppdev ((gx_device_bjc_printer *) pdev) + + FloydSteinbergErrorsC = (int *) gs_alloc_bytes(pdev->memory, + 3*sizeof(int)*(pdev->width+3), + "bjc CMY error buffer"); + if (FloydSteinbergErrorsC == 0 ) /* can't allocate error buffer */ + return -1; + + for (i=0; i < 3 * (pdev->width+3); i++) FloydSteinbergErrorsC[i] = 0; + + FloydSteinbergDirectionForward=true; + bjc_rgb_to_cmy(ppdev->paperColor.red, + ppdev->paperColor.green, + ppdev->paperColor.blue, + &FloydSteinbergC, + &FloydSteinbergM, + &FloydSteinbergY); + + FloydSteinbergC <<= 4; + FloydSteinbergM <<= 4; + FloydSteinbergY <<= 4; + bjc_init_tresh(ppdev->rnd); + return 0; + #undef ppdev + } + + void + FloydSteinbergDitheringC(byte *row, byte *dithered, uint width, + uint raster, bool limit_extr, bool composeK) + { byte byteC=0, byteM=0, byteY=0, byteK=0, bitmask = 0x80; /* first bit */ + int i; + int errorC = 0, errorM = 0, errorY = 0, delta; + int err_corrC, err_corrM, err_corrY; + int *err_vect; + + if (FloydSteinbergDirectionForward) { + err_vect = FloydSteinbergErrorsC + 3; /* errCMY */ + /* First point */ + + for( i=width; i>0; i--, row+=4, err_vect+=3) { /*separate components */ + + /* C + K */ + err_corrC = bjc_gamma_tableC[ (*row) + (*(row+3))] + + FloydSteinbergC; + err_corrM = bjc_gamma_tableM[(*(row+1)) + (*(row+3))] + + FloydSteinbergM; + err_corrY = bjc_gamma_tableY[(*(row+2)) + (*(row+3))] + + FloydSteinbergY; + + if(err_corrC > 4080 && limit_extr) err_corrC = 4080; + if(err_corrM > 4080 && limit_extr) err_corrM = 4080; + if(err_corrY > 4080 && limit_extr) err_corrY = 4080; + + errorC += err_corrC + (*(err_vect + 3)); /* CMYCMYCMY */ + errorM += err_corrM + (*(err_vect + 4)); /* | ^ ! */ + errorY += err_corrY + (*(err_vect + 5)); + + if(errorC > bjc_treshold[bjc_rand()]) { + errorC -= 4080; + byteC |= bitmask; + } + + if(errorM > bjc_treshold[bjc_rand()]) { + errorM -= 4080; + byteM |= bitmask; + } + + if(errorY > bjc_treshold[bjc_rand()]) { + errorY -= 4080; + byteY |= bitmask; + } + + *(err_vect+3) = (errorC + 8) >> 4; /* 1/16 */ + delta = errorC << 1; /* 2 err */ + errorC += delta; + *(err_vect-3) += (errorC + 8) >> 4; /* 3/16 */ + errorC += delta; + *err_vect += (errorC + 8) >> 4; /* 5/16 */ + errorC += delta + 8; /* 7/16 */ + errorC >>= 4; + + *(err_vect+4) = (errorM + 8) >> 4; /* 1/16 */ + delta = errorM << 1; /* 2 err */ + errorM += delta; + *(err_vect-2) += (errorM + 8) >> 4; /* 3/16 */ + errorM += delta; + *(err_vect+1) += (errorM + 8) >> 4; /* 5/16 */ + errorM += delta + 8; /* 7/16 */ + errorM >>= 4; + + *(err_vect+5) = (errorY + 8) >> 4; /* 1/16 */ + delta = errorY << 1; /* 2 err */ + errorY += delta; + *(err_vect-1) += (errorY + 8) >> 4; /* 3/16 */ + errorY += delta; + *(err_vect+2) += (errorY + 8) >> 4; /* 5/16 */ + errorY += delta + 8; /* 7/16 */ + errorY >>= 4; + + if (bitmask == 0x01) { + bitmask = 0x80; + if(composeK) { + byteK = byteC & byteM & byteY; + byteC = byteC & ~byteK; + byteM = byteM & ~byteK; + byteY = byteY & ~byteK; + } /* if no K byteK always 0 */ + *dithered = byteC; + *(dithered+ raster) = byteM; + *(dithered+2*raster) = byteY; + *(dithered+3*raster) = byteK; + byteC = byteM = byteY = byteK = 0; + dithered++; + } + else if(i == 1) { + if(composeK) { + byteK = byteC & byteM & byteY; + byteC = byteC & ~byteK; + byteM = byteM & ~byteK; + byteY = byteY & ~byteK; + } /* if no K byteK always 0 */ + *dithered = byteC; + *(dithered+ raster) = byteM; + *(dithered+2*raster) = byteY; + *(dithered+3*raster) = byteK; + } + else bitmask >>= 1; + } + FloydSteinbergDirectionForward=false; + } + else { + row += (width << 2) - 4; /* point to the end of the row */ + dithered += raster - 1; + err_vect = FloydSteinbergErrorsC + 3 * width + 3; /* errCMY */ + bitmask = 1 << ((raster << 3 ) - width) ; + + for( i=width; i>0; i--, row-=4, err_vect-=3) { + + err_corrC = bjc_gamma_tableC[ (*row) + (*(row+3))] + + FloydSteinbergC; + err_corrM = bjc_gamma_tableM[(*(row+1)) + (*(row+3))] + + FloydSteinbergM; + err_corrY = bjc_gamma_tableY[(*(row+2)) + (*(row+3))] + + FloydSteinbergY; + + if(err_corrC > 4080 && limit_extr) err_corrC = 4080; + if(err_corrM > 4080 && limit_extr) err_corrM = 4080; + if(err_corrY > 4080 && limit_extr) err_corrY = 4080; + + errorC += err_corrC + (*(err_vect - 3)); /* CMYCMYCMY */ + errorM += err_corrM + (*(err_vect - 2)); /* ! ^ | */ + errorY += err_corrY + (*(err_vect - 1)); + + if(errorC > bjc_treshold[bjc_rand()]) { + errorC -= 4080; + byteC |= bitmask; + } + + if(errorM > bjc_treshold[bjc_rand()]) { + errorM -= 4080; + byteM |= bitmask; + } + + if(errorY > bjc_treshold[bjc_rand()]) { + errorY -= 4080; + byteY |= bitmask; + } + + *(err_vect-3) = (errorC + 8) >> 4; /* 1/16 */ + delta = errorC << 1; /* 2 err */ + errorC += delta; + *(err_vect+3) += (errorC + 8) >> 4; /* 3/16 */ + errorC += delta; + *err_vect += (errorC + 8) >> 4; /* 5/16 */ + errorC += delta + 8; /* 7/16 */ + errorC >>= 4; + + *(err_vect-2) = (errorM + 8) >> 4; /* 1/16 */ + delta = errorM << 1; /* 2 err */ + errorM += delta; + *(err_vect+4) += (errorM + 8) >> 4; /* 3/16 */ + errorM += delta; + *(err_vect+1) += (errorM + 8) >> 4; /* 5/16 */ + errorM += delta + 8; /* 7/16 */ + errorM >>= 4; + + *(err_vect-1) = (errorY + 8) >> 4; /* 1/16 */ + delta = errorY << 1; /* 2 err */ + errorY += delta; + *(err_vect+5) += (errorY + 8) >> 4; /* 3/16 */ + errorY += delta; + *(err_vect+2) += (errorY + 8) >> 4; /* 5/16 */ + errorY += delta + 8; /* 7/16 */ + errorY >>= 4; + + if (bitmask == 0x80) { + bitmask = 0x01; + if(composeK) { + byteK = byteC & byteM & byteY; + byteC = byteC & ~byteK; + byteM = byteM & ~byteK; + byteY = byteY & ~byteK; + } /* if no K byteK always 0 */ + *dithered = byteC; + *(dithered+ raster) = byteM; + *(dithered+2*raster) = byteY; + *(dithered+3*raster) = byteK; + byteC = byteM = byteY = byteK = 0; + dithered--; + } + else if(i == 1) { + if(composeK) { + byteK = byteC & byteM & byteY; + byteC = byteC & ~byteK; + byteM = byteM & ~byteK; + byteY = byteY & ~byteK; + } /* if no K byteK always 0 */ + *dithered = byteC; + *(dithered+ raster) = byteM; + *(dithered+2*raster) = byteY; + *(dithered+3*raster) = byteK; + } + else bitmask <<= 1; + } + FloydSteinbergDirectionForward=true; + } + } + + void FloydSteinbergCloseC(gx_device_printer *pdev) + { + gs_free_object(pdev->memory, FloydSteinbergErrorsC, + "bjc CMY error buffer"); + } diff -rNc ghostscript-7.05.orig/src/unix-gcc.mak ghostscript-7.05/src/unix-gcc.mak *** ghostscript-7.05.orig/src/unix-gcc.mak Fri Apr 19 23:23:09 2002 --- ghostscript-7.05/src/unix-gcc.mak Fri Jul 12 22:46:38 2002 *************** *** 369,375 **** DEVICE_DEVS3=$(DD)deskjet.dev $(DD)djet500.dev $(DD)laserjet.dev $(DD)ljetplus.dev $(DD)ljet2p.dev $(DD)ljet3.dev $(DD)ljet3d.dev $(DD)ljet4.dev $(DD)ljet4d.dev $(DD)lj5mono.dev $(DD)lj5gray.dev DEVICE_DEVS4=$(DD)cdeskjet.dev $(DD)cdjcolor.dev $(DD)cdjmono.dev $(DD)cdj550.dev $(DD)pj.dev $(DD)pjxl.dev $(DD)pjxl300.dev DEVICE_DEVS5=$(DD)uniprint.dev $(DD)ijs.dev ! DEVICE_DEVS6=$(DD)bj10e.dev $(DD)bj200.dev $(DD)bjc600.dev $(DD)bjc800.dev DEVICE_DEVS7=$(DD)faxg3.dev $(DD)faxg32d.dev $(DD)faxg4.dev 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 --- 369,375 ---- DEVICE_DEVS3=$(DD)deskjet.dev $(DD)djet500.dev $(DD)laserjet.dev $(DD)ljetplus.dev $(DD)ljet2p.dev $(DD)ljet3.dev $(DD)ljet3d.dev $(DD)ljet4.dev $(DD)ljet4d.dev $(DD)lj5mono.dev $(DD)lj5gray.dev DEVICE_DEVS4=$(DD)cdeskjet.dev $(DD)cdjcolor.dev $(DD)cdjmono.dev $(DD)cdj550.dev $(DD)pj.dev $(DD)pjxl.dev $(DD)pjxl300.dev DEVICE_DEVS5=$(DD)uniprint.dev $(DD)ijs.dev ! DEVICE_DEVS6=$(DD)bj10e.dev $(DD)bj200.dev $(DD)bjc600.dev $(DD)bjc800.dev $(DD)bjcmono.dev $(DD)bjcgray.dev $(DD)bjccmyk.dev $(DD)bjccolor.dev DEVICE_DEVS7=$(DD)faxg3.dev $(DD)faxg32d.dev $(DD)faxg4.dev 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