home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1997, 2000 Aladdin Enterprises. All rights reserved.
-
- This file is part of AFPL Ghostscript.
-
- 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 Aladdin Free Public License (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.
- */
-
- /* $Id: gdevupd.c,v 1.3 2000/09/19 19:00:23 lpd Exp $ */
- /* "uniprint" -- Ugly Printer Driver by Gunther Hess (gunther@elmos.de) */
-
- /* Revision-History:
- 23-Mar-1997 - 1.43: First published version
- 24-Mar-1997 - 1.44: gs4.03 compatible version on the web
- 31-Mar-1997 - 1.53: First Version inside gs-fileset (limited)
- 28-Apr-1997 - 1.54: Version intended for public gs-release
- 4-May-1997 - 1.55: Deactivated an accidentially active Debug-Option
- 14-Jun-1997 - 1.56: Bug-Workaround for White on White Printing (gs5.0)
- 17-Jun-1997 - 1.57: More reasonable Fix for the above Bug
- ...
- 7-Jul-1997 - 1.68: NULL-Param-BUG, HR's BJC, Pwidth/-height BUG, YFlip
- 25-Jul-1997 - 1.69: Bug-Fix: incomplete Change of PHEIGHT-Treatment
- 4-Aug-1997 - 1.70: Arrgh: still incomplete Change of PHEIGHT-Treatment
- 17-AUG-1997 - 1.71: Fix of BSD-sprintf bug. (returns char * there)
- ...
- 28-Sep-1997 - 1.77: Fixed the byte<>char and casted-lvalue Problems
- ...
- 12-Mar-1998 - 1.80: Some PJL-Functions, Map-Bug-Fix (by Wonder-Wolfgang)
- 21-Oct-1998 - 1.81: Added RGB2CMY[_]K Modi (Eric Domenjoud)
- ...
- 27-Feb-2000 - 1.84: CMYKgenerate with forced K-Control [distributed]
-
- */
-
- /* Canon BJC 610 additions from (hr)
- Helmut Riegler <helmut-riegler@net4you.co.at>
-
- The BJC-4000 can be supported very easily, only by creating the right .upp
- parameter file. If you have this printer and you are willing to do this,
- contact me, I'll give you the technical details (ESC codes).
- */
-
- /* ------------------------------------------------------------------- */
- /* Compile-Time-Options */
- /* ------------------------------------------------------------------- */
-
- /**
- There are two compile-time options for this driver:
- 1. UPD_SIGNAL enables interrupt detection, that aborts printing and
- 2. UPD_MESSAGES controls the amount of messages generated by the driver
- */
-
- #ifndef UPD_SIGNAL
- #ifdef __unix__
- #define UPD_SIGNAL 1 /** Activated, if undefined, on UNIX-Systems */
- #else /* !__unix__ */
- #define UPD_SIGNAL 0 /** Inactive on others, by default */
- #endif /* ?__unix__ */
- #endif /* UPD_SIGNAL */
-
- #ifndef UPD_MESSAGES
- #define UPD_MESSAGES UPD_M_ERROR /** Error-messages only, if not defined */
- #endif /* UPD_MESSAGES */
-
- /* ------------------------------------------------------------------- */
- /* Required Header-Files */
- /* ------------------------------------------------------------------- */
-
- #ifndef hess_test_INCLUDED /* A private test-Option */
-
- #include "gdevprn.h" /** Printer-superclass header */
- #include "gsparam.h" /** For the Parameter-Handling (optional) */
-
- #include <stdlib.h> /** for rand */
- #include <limits.h> /** for INT_MIN */
- #include <ctype.h> /** for isupper */
-
- #endif /* hess_test_INCLUDED A private test-Option */
-
- #if UPD_SIGNAL
- #include <signal.h> /** Only included, if UPD_SIGNAL is active (true) */
- #endif /* UPD_SIGNAL */
-
- /* ------------------------------------------------------------------- */
- /* Device-Structure (including an additional Structure-Pointer-Type) */
- /* ------------------------------------------------------------------- */
-
- typedef struct upd_s upd_t,*upd_p; /** Type & Pointer of device-specifics */
- typedef const upd_t *upd_pc; /** Pointer to constant device-specfics */
-
- typedef struct upd_device_s { /** The driver must typedef ... */
- gx_device_common; /** common fields for all devices */
- gx_prn_device_common; /** common fields for printing-devices */
- gs_param_string upd_version; /** Source-Code Version */
- upd_p upd; /** uniprint-specific extension */
- } upd_device; /** some type usually <name>_device> */
-
- /* ------------------------------------------------------------------- */
- /* Major Driver-Functions */
- /* ------------------------------------------------------------------- */
-
- private dev_proc_print_page(upd_print_page); /** print a page (required) */
-
- private dev_proc_open_device(upd_open); /** device-initialization (opt) */
- private dev_proc_close_device(upd_close); /** device-release (opt) */
-
- private dev_proc_get_params(upd_get_params); /** export parameters (opt) */
- private dev_proc_put_params(upd_put_params); /** import parameters (opt) */
-
- /**
- A `normal' Device-Driver wil only implement one of the following pairs
- of functions for the colormapping. But "uniprint" is something special and
- it really provides all four reasonable pairs and in addition to that
- a fifth set of functions, that delivers better FS-Results with KCMY.
-
- The first pair is for the mapping into a single stored component, that
- usually represents a grayscale. But nevertheless GHOSTSCRIPT deals with
- RGB-Values, but promises to deal with R==G==B-Values when asking to map.
-
- The second pair deals with RGB-Values.
- */
-
- private dev_proc_map_rgb_color( upd_rgb_1color); /** RGB->Gray-Index */
- private dev_proc_map_color_rgb( upd_1color_rgb); /** Gray-Index->RGB */
-
- private dev_proc_map_rgb_color( upd_rgb_3color); /** RGB->RGB-Index */
- private dev_proc_map_color_rgb( upd_3color_rgb); /** RGB-Index->RGB */
-
- /**
- The third pair maps RGB-Values into four components, which one might
- expect to be KCMY-Values, but they are not: "uniprint" considers this four
- Values as White+RGB Values!
- */
-
- private dev_proc_map_rgb_color( upd_rgb_4color); /** RGB->WRGB-Index */
- private dev_proc_map_color_rgb(upd_4color_rgb); /** WRGB-Index->RGB */
-
- /**
- The fourth pair deals with KCMY-Values. The Mapping-Function
- is of a different type, due to the additional argument, but the
- inverse-Function is of the same type, and expects RGB-Values to be
- deliverd into the receiving 3-Component-Array!
- */
-
- private dev_proc_map_cmyk_color(upd_cmyk_icolor); /** KCMY->KCMY-Index */
- private dev_proc_map_color_rgb( upd_icolor_rgb); /** KCMY->RGB-Index */
-
- /**
- The difference between the icolor-pair and the kcolor-pair is the enforced
- black-generation in the forward-mapping. that is taken into account by the
- reverse-mapping too.
- */
-
- private dev_proc_map_cmyk_color(upd_cmyk_kcolor); /** adds black generation */
- private dev_proc_map_color_rgb( upd_kcolor_rgb); /** watches black-gen */
-
- /**
- "ovcolor" is CMYK with Black-Generation and Undercolor-Removal, which
- is suitable for overprinting:
- CMY' = (CMY-K')/(1-K')
- with
- K' = min(C,M,Y)
- */
-
- private dev_proc_map_rgb_color(upd_rgb_ovcolor); /** RGB->CMYK-Index */
- #define upd_ovcolor_rgb upd_icolor_rgb /** CMYK-Index->RGB */
-
- /**
- "novcolor" is CMYK with Black-Generation and Undercolor-Removal, which
- is suitable for CMY / K - Printing:
- CMY' = CMY-K'
- with
- K' = min(C,M,Y)
- */
-
- private dev_proc_map_rgb_color(upd_rgb_novcolor); /** RGB->CMYK-Index */
- #define upd_novcolor_rgb upd_icolor_rgb /** CMYK-Index->RGB */
-
- /**
- For the sake of efficiency there is that bunch of functions and they
- perform no validity checks, thus it has to be assured that they are
- only active, if there is a valid device-structure for then.
- upd_procs_map performs this task.
- */
-
- private int upd_procs_map( P1(upd_device *udev));
-
- /* ------------------------------------------------------------------- */
- /* Prototype of the Device-Structure (the only thing exported!) */
- /* ------------------------------------------------------------------- */
-
- /**
- "uniprint" needs a procedure-table of its own, since it provides several
- optional procedures. Simpler-Drivers (e.g. non-color-drivers) may use
- prn_std_procs instead of defining their own procedure-table.
- */
-
- #define upd_set_dev_proc(dev, p, proc) \
- ((dev)->std_procs.p = (dev)->orig_procs.p = (proc))
-
- private gx_device_procs upd_procs = { /** Table of procedures */
- upd_open, /** open-function, upd-special */
- gx_default_get_initial_matrix, /** retrieve matrix */
- gx_default_sync_output, /** sync display */
- gdev_prn_output_page, /** superclass-print (calls back) */
- upd_close, /** close-function, upd-special */
- gx_default_map_rgb_color, /** RGB-mapping */
- gx_default_map_color_rgb, /** reverse mapping */
- NULL, /** fill_rectangle */
- NULL, /** tile_rectangle */
- NULL, /** copy_mono */
- NULL, /** copy_color */
- NULL, /** draw_line */
- gx_default_get_bits, /** reads scanlines, e.g. for the driver */
- upd_get_params, /** Export parameters, upd-special */
- upd_put_params, /** Import parameters, upd-special */
- gx_default_map_cmyk_color /** KCMY-mapping */
- }; /** */
-
- /**
- The prototype-instance of the device-structure _must_ have the name
- "gs_uniprint_device", where "uniprint" is the external name of the driver.
- This notice is bluntly copied from drivers.txt, which a potential
- driver-author should carefully read.
-
- Just to mention: this prototype is quite similar to the one, that
- "prn_device" produces and it identifies "uniprint" as a monochrome 1Bit
- device to GHOSTSCRIPT. But during the lifetime of a driver-instance
- this might change.
-
- This is the end of the part of declarations, that are common for
- color-drivers. The next sections address "uniprint"-specific data-types
- and the reader might directly skip to the section titled
-
- upd_print_page: The main workhorse
- */
-
- upd_device far_data gs_uniprint_device = { /** */
- prn_device_body(upd_device, upd_procs, /** The Type and Procedures */
- "uniprint", /** External name of the Device */
- DEFAULT_WIDTH_10THS, /** X-Size (1/10") */
- DEFAULT_HEIGHT_10THS, /** Y-Size (1/10") */
- 72, 72, /** X,Y-DpI */
- 0.0, 0.0, 0.0, 0.0, /** L,B,R,T-Margin */
- 1, /** color_info.num_components 1/3/4 */
- 1, /** color_info.depth 1/2/4/8/16/24/32 */
- 1, /** color_info.max_gray # of distinct gray levels -1 (255/1) */
- 0, /** color_info.max_color # of distinct color levels -1 (255/1/0)*/
- 1, /** color_info.dither_grays size of gray ramp for dithering (5/2) */
- 0, /** color_info.dither_colors size of color cube ditto (5/2/0) */
- upd_print_page), /** Print-procedure */
- { NULL, 0, true }, /** Driver-Version */
- NULL /** upd-field: Initially none */
- }; /** */
-
-
- /* ------------------------------------------------------------------- */
- /* UPD-Data- and Prototypes */
- /* ------------------------------------------------------------------- */
-
- /*@ gdevupd.h < */
- /* ------------------------------------------------------------------- */
- /* External names of the UPD-Parameters */
- /* ------------------------------------------------------------------- */
-
- /** UPD-Parameters
-
- "uniprint" supports a hole bunch of external parameters. This Parameters
- fall into the following categories:
-
- 0. special-string the upd_version, readonly upd_version
- 1. choice name-indices, stored in upd->choice
- 2. boolean single bits, stored in upd->flags
- 3. integers single numbers, stored in upd->ints
- 4. integer-Arrays arrays of numbers, stored in upd->int_a
- 5. string device-commands, stored in upd->strings
- 6. string-Arrays arrayed device-commands, stored in upd->string_a
- 7. float-Arrays arrays of floats, stored in upd->float_a
-
- Currently there is no need for single floats, but they may be introduced in
- future versions. Since "uniprint" somtimes manipulates the contents of the
- array-variables it dynamically allocates storage for all this parameters.
-
- The following sections defines the names for this parameters in the order,
- they are stored within the mentioned dynamic fields of the upd-structure.
- A NULL-name means that the corresponding parameter is not externally visible.
- Besides the name, there is always a symbolic index #defined, that MUST match
- the Index-Number of the name.
- Actually
- */
-
- static const char *const upd_version = "upVersion"; /** Readonly Version */
-
- /** Names for the multiple-choice-Parameters
-
- Currently there are three Parameters, that are handled as named choices.
- For each of them, there is an array of constant strings that consists of
-
- 1. the Parameter-Name
- 2. - n-1 the available choices.
- n. A terminating NULL
- */
-
- static const char *const upd_mapper[] = { "upColorModel",
- #define MAP_GRAY 1 /** Monochrome & Grayscale Devices */
- "DeviceGray", /** Monochrome & Grayscale Devices */
- #define MAP_RGBW 2 /** RGB with White-Generation */
- "DeviceRGBW", /** RGB with White-Generation */
- #define MAP_RGB 3 /** RGB-Mapping */
- "DeviceRGB", /** RGB-Mapping */
- #define MAP_CMYK 4 /** CMYK-Mapping */
- "DeviceCMYK", /** CMYK-Mapping */
- #define MAP_CMYKGEN 5 /** CMYK-Mapping with Black-Generation */
- "DeviceCMYKgenerate", /** CMYK-Mapping with Black-Generation */
- #define MAP_RGBOV 6 /** RGB->CMYK with BG and UCR for CMYK */
- "DeviceRGB2CMYK", /** RGB->CMYK with BG and UCR for CMYK */
- #define MAP_RGBNOV 7 /** RGB->CMYK with BG and UCR for CMY + K */
- "DeviceRGB2CMY_K", /** RGB->CMYK with BG and UCR for CMY + K */
- NULL
- };
-
- static const char *const upd_render[] = { "upRendering",
- #define RND_FSCOMP 1 /** Componentwise Floyd-Steinberg */
- "ErrorDiffusion", /** Componentwise Floyd-Steinberg */
- #define RND_FSCMYK 2 /** CMYK-specialized 32Bit Floyd-Steinberg */
- "FSCMYK32", /** CMYK-specialized 32Bit Floyd-Steinberg */
- #define RND_FSCMY_K 3 /** CMY_K Rendering */
- "FSCMY_K",
- NULL
- };
-
- static const char *const upd_format[] = { "upOutputFormat",
- #define FMT_RAS 1 /** Generates SUN-Rasterfiles */
- "SunRaster", /** Generates SUN-Rasterfiles */
- #define FMT_EPSON 2 /** Generates X+Y-Weaved ESC/P-Output */
- "Epson", /** Generates X+Y-Weaved ESC/P-Output */
- #define FMT_ESCP2Y 3 /** Generates Y-Weaved ESC/P2-Output */
- "EscP2", /** Generates Y-Weaved ESC/P2-Output */
- #define FMT_ESCP2XY 4 /** Generates X+Y-Weaved ESC/P2-Output */
- "EscP2XY", /** Generates X+Y-Weaved ESC/P2-Output */
- #define FMT_RTL 5 /** Generates HP-PCL/RTL-Output */
- "Pcl", /** Generates HP-PCL/RTL-Output */
- #define FMT_CANON 6 /** Generates Output for Canon extended mode (hr) */
- "Canon", /** Generates Output for Canon extended mode (hr) */
- NULL
- };
-
- static const char *const *const upd_choice[] = {
- #define C_MAPPER 0 /** the selected Mapper */
- upd_mapper,
- #define C_RENDER 1 /** the selected Rendering */
- upd_render,
- #define C_FORMAT 2 /** the selected Choice */
- upd_format
- };
-
- /** Names for the flags (bool)
- */
-
- static const char *const upd_flags[] = { /** */
- #define B_REVDIR ((uint32) 1<<0) /** FS-Dir-Flag */
- "upFSReverseDirection", /** FS-Dir-Flag */
- #define B_FIXDIR ((uint32) 1<<1) /** Do not alter FS-direction */
- "upFSFixedDirection", /** Do not alter FS-direction */
- #define B_FSWHITE ((uint32) 1<<2) /** Process white in FS */
- "upFSProcessWhiteSpace", /** Process white in FS */
- #define B_FSZERO ((uint32) 1<<3) /** Zero FS-Initialization */
- "upFSZeroInit", /** Zero FS-Initialization */
-
- #define B_PAGEWIDTH ((uint32) 1<<4) /** Adjust Width in BOP */
- "upAdjustPageWidthCommand", /** Adjust Page-Width in BOP */
- #define B_PAGELENGTH ((uint32) 1<<5) /** Adjust Length in BOP */
- "upAdjustPageLengthCommand", /** Adjust Page-Length in BOP */
- #define B_TOPMARGIN ((uint32) 1<<6) /** Adjust Top-Margin in BOP */
- "upAdjustTopMarginCommand", /** Adjust Top-Margin in BOP */
- #define B_BOTTOMMARGIN ((uint32) 1<<7) /** Adjust Bottom-Margin in BOP */
- "upAdjustBottomMarginCommand", /** Adjust Bottom-Margin in BOP */
- #define B_RESOLUTION ((uint32) 1<<8) /** Adjust Resolution in BOP */
- "upAdjustResolutionCommand", /** Adjust Resolution in BOP */
- #define B_MEDIASIZE ((uint32) 1<<9) /** Adjust Mediasize in BOP */
- "upAdjustMediaSize", /** Adjust Mediasize in BOP */
-
- #define B_XABS ((uint32) 1<<10) /** Use Absolute X-Values */
- "upFormatXabsolute", /** Use Absolute X-Values */
- #define B_YABS ((uint32) 1<<11) /** Use Absolute Y-Values */
- "upFormatYabsolute", /** Use Absolute Y-Values */
-
- #define B_MAP ((uint32) 1<<12) /** Mapping Initialized */
- "upColorModelInitialized", /** Mapping Initialized */
- #define B_BUF ((uint32) 1<<13) /** Raster-Buffer Initialized */
- "upRasterBufferInitialized", /** Raster-Buffer Initialized */
- #define B_RENDER ((uint32) 1<<14) /** Rendering Initialized */
- "upRenderingInitialized", /** Rendering Initialized */
- #define B_FORMAT ((uint32) 1<<15) /** Formatter Initialized */
- "upOutputFormatInitialized", /** Formatter Initialized */
- #define B_ABORT ((uint32) 1<<16) /** Abort on Interrupt */
- "upOutputAborted", /** Abort on Interrupt */
- #define B_ERROR ((uint32) 1<<17) /** Severe Error detected */
- "upErrorDetected", /** Severe Error detected */
-
- #define B_OPEN ((uint32) 1<<18) /** Open-Command written */
- "upWroteData", /** Open-Command written */
-
- #define B_YFLIP ((uint32) 1<<19) /** Mirrored printing (hr) */
- "upYFlip", /** Mirrored printing (hr) */
-
- #define B_REDUCEK ((uint32) 1<<20) /** CMY->Black Reduction */
- "upFSReduceK"
-
- };
-
- /** B_OK4GO: Bits required to execute the print-loop */
-
- #define B_OK4GO (B_MAP | B_BUF | B_RENDER | B_FORMAT)
-
- /** Names for the ints
- */
-
- static const char *const upd_ints[] = {
- #define I_PWIDTH 0 /** Output-Width */
- "upOutputWidth",
- #define I_PHEIGHT 1 /** Output-Height */
- "upOutputHeight",
- #define I_OCOMP 2 /** Output-Components */
- "upOutputComponents",
- #define I_NSCNBUF 3 /** Output-Buffers */
- "upOutputBuffers",
- #define I_XSTEP 4 /** Unit-Step */
- "upOutputXStep", /* > 0 -> divide Raster-X, < 0 muliply Raster-X */
- #define I_XOFS 5 /** abs. X-Offset */
- "upOutputXOffset",
- #define I_YSTEP 6 /** Unit-Step */
- "upOutputYStep", /* > 0 -> divide Raster-Y, < 0 muliply Raster-Y */
- #define I_YOFS 7 /** abs. Y-Offset */
- "upOutputYOffset",
- #define I_PINS2WRITE 8 /** Number of Pins */
- "upOutputPins",
-
- #define I_NXPASS 9 /** X-Passes */
- "upWeaveXPasses",
- #define I_NYPASS 10 /** Y-Passes */
- "upWeaveYPasses",
- #define I_NPASS 11 /** Total # Passes */
- "upWeavePasses",
- #define I_BEG_Y 12 /** Start of normal Weaving */
- "upWeaveInitialScan",
- #define I_END_Y 13 /** End of normal Weaving */
- "upWeaveFinalScan",
- #define I_BEGSKIP 14 /** A Scan-Offset */
- "upWeaveYOffset"
- };
-
- /** Names for the Integer-Arrays
- */
-
- static const char *const upd_int_a[] = { /** */
- #define IA_COLOR_INFO 0 /** external color_info */
- "upColorInfo", /** external color_info */
-
- #define IA_COMPBITS 1 /** Bits stored per Component */
- "upComponentBits", /** Bits stored per Component */
- #define IA_COMPSHIFT 2 /** Shift for the stored Bits */
- "upComponentShift", /** Shift for the stored Bits */
- #define IA_COMPORDER 3 /** Order of Output-Components */
- "upOutputComponentOrder", /** Order of Output-Components */
-
- #define IA_STD_DY 4 /** Standard-Weave Feeds */
- "upWeaveYFeeds", /** Standard-Weave Feeds */
- #define IA_STD_IX 5 /** Standard-Weave X-Passes */
- "upWeaveXStarts", /** Standard-Weave X-Start */
- #define IA_BEG_DY 6 /** Initial-Weave Feeds */
- "upWeaveInitialYFeeds", /** Initial-Weave Feeds */
- #define IA_BEG_IX 7 /** Initial-Weave X-Start */
- "upWeaveInitialXStarts", /** Initial-Weave X-Start */
- #define IA_BEGBOT 8 /** Initial-Weave #Pins */
- "upWeaveInitialPins", /** Initial-Weave #Pins */
- #define IA_END_DY 9 /** Final-Weave Feeds */
- "upWeaveFinalYFeeds", /** Final-Weave Feeds */
- #define IA_END_IX 10 /** Final-Weave X-Start */
- "upWeaveFinalXStarts", /** Final-Weave X-Start */
- #define IA_ENDTOP 11 /** Final-Weave #Pins */
- "upWeaveFinalPins" /** Final-Weave #Pins */
- };
-
- /** Names of the String-Parameters
- */
-
- static const char *const upd_strings[] = { /** */
- #define S_MODEL 0 /** Name of the Printer-Model */
- "upModel", /** Name of the Printer-Model */
- #define S_OPEN 1 /** Printer-Begin-Job */
- "upBeginJobCommand", /** Printer-Begin-Job */
- #define S_CLOSE 2 /** Printer-End-Job */
- "upEndJobCommand", /** Printer-End-Job */
- #define S_BEGIN 3 /** Printer-Begin-Page */
- "upBeginPageCommand", /** Printer-Begin-Page */
- #define S_END 4 /** Printer-End-Page */
- "upEndPageCommand", /** Printer-End-Page */
- #define S_ABORT 5 /** Printer-Abort-Command */
- "upAbortCommand", /** Printer-Abort-Command */
-
- #define S_XMOVE 6 /** X-Positioning-Command */
- "upXMoveCommand", /** X-Positioning-Command */
- #define S_XSTEP 7 /** X-Step Command (1<I_XSTEP) */
- "upXStepCommand", /** X-Step Command (1<I_XSTEP) */
- #define S_SETLF 8 /** Set-Linefeed-Command */
- "upSetLineFeedCommand", /** Set-Linefeed-Command */
- #define S_YMOVE 9 /** Y-Positioning-Command */
- "upYMoveCommand", /** Y-Positioning-Command */
- #define S_YSTEP 10 /** Y-Step Command (1<I_YSTEP) */
- "upYStepCommand" /** Y-Step Command (1<I_YSTEP) */
- }; /** */
-
- /** Names for the String-Arrays
- */
-
- static const char *const upd_string_a[] = { /** */
- #define SA_SETCOMP 0 /** Select Components */
- "upSelectComponentCommands", /** Select Components */
- #define SA_WRITECOMP 1 /** Write Component Comands */
- "upWriteComponentCommands" /** Write Component Commands */
- }; /** */
-
- /** Names for the float-Arrays
- */
- static const char *const upd_float_a[] = { /** */
- #define FA_WXFER 0 /** White-Transfer */
- "upWhiteTransfer", /** White-Transfer */
- #define FA_RXFER 1 /** Red-Transfer */
- "upRedTransfer", /** Red-Transfer */
- #define FA_GXFER 2 /** Green-Transfer */
- "upGreenTransfer", /** Green-Transfer */
- #define FA_BXFER 3 /** Blue-Transfer */
- "upBlueTransfer", /** Blue-Transfer */
- #define FA_KXFER 4 /** Black-Transfer */
- "upBlackTransfer", /** Black-Transfer */
- #define FA_CXFER 5 /** Cyan-Transfer */
- "upCyanTransfer", /** Cyan-Transfer */
- #define FA_MXFER 6 /** Magenta-Transfer */
- "upMagentaTransfer", /** Magenta-Transfer */
- #define FA_YXFER 7 /** Yellow-Transfer */
- "upYellowTransfer", /** Yellow-Transfer */
- #define FA_MARGINS 8 /** private Margins */
- "upMargins", /** private Margins */
- #define FA_MAP 9 /** Color-Map */
- "upColorMap" /** Color-Map */
- }; /** */
-
- /* ------------------------------------------------------------------- */
- /* UPD-specific datatypes */
- /* ------------------------------------------------------------------- */
-
- /**
- int32 and uint32 are 32Bit-Integer-Types used in the
- Floyd-Steinberg Algorithm and instead of gx_color_index. The
- 8-Byte long's on some 64Bit-Machines are apparently useless,
- since gdevprn.c does (currently) support only 32-Bit Rasterdata.
- */
-
- #if arch_log2_sizeof_int < 2 /* int is too small */
- typedef long int32;
- #define INT32_MIN LONG_MIN
- #define INT32_MAX LONG_MAX
- typedef unsigned long uint32;
- #define UINT32_MAX ULONG_MAX
- #else /* int is sufficient */
- typedef int int32;
- #define INT32_MIN INT_MIN
- #define INT32_MAX INT_MAX
- typedef unsigned int uint32;
- #define UINT32_MAX UINT_MAX
- #endif /* use int or long ? */
-
- /**
- "updcmap" is used by the color-mapping functions of the driver.
- there are four cmaps in the "uniprint"-structure, one for each component.
- To be exact, it's not "4" but rather "UPD_CMAP_MAX", which is a synonym.
- */
-
- typedef struct updcmap_s { /** */
- gx_color_value *code; /** Values related to codes */
- uint32 bitmsk; /** Mask, right justified */
- int bitshf; /** Shift to right-justify */
- int xfer; /** Index to the Xfer-Array */
- int bits; /** # of Bits */
- int comp; /** Output-Number */
- bool rise; /* Rising/Falling Curve */
- } updcmap_t, *updcmap_p; /** */
- typedef const updcmap_t *updcmap_pc;
-
-
- /**
- "updcomp" holds similar informations, but is used for the rendering
- */
-
- typedef struct updcomp_s { /* Parameters for Floyd-Steinberg */
- int32 offset; /* Offset added to scaled values */
- int32 scale; /* Scale for the raw values */
- int32 threshold; /* Val must be larger than this to fire */
- int32 spotsize; /* subtracted from Val when fired */
- uint32 bitmsk; /* Mask */
- int bitshf; /* shift */
- int bits; /* # of Bits */
- int cmap; /* Index for the Parameter-name */
- } updcomp_t, *updcomp_p; /* Parameters for Floyd-Steinberg */
-
- /** updscan is the Element of the scan-buffer. */
-
- typedef struct updscan_s { /* Single Scanline (1 Bit/Pixel) */
- byte *bytes; /* Buffer used w. 32-Bit Words */
- int *xbegin; /* 1st Pixel set (or nbytes<<3 if none) */
- int *xend; /* last Pixel set (or -1, if none) */
- } updscan_t, *updscan_p; /* Single Scanline (1 Bit/Pixel) */
-
-
- /** Main upd-Structure ***/
-
- #define UPD_CMAP_MAX 4 /** Number of Colormaps provided */
- #define UPD_VALPTR_MAX 32 /** Number of valbuf-Pointers */
-
- #define upd_proc_pxlget(name) uint32 name(P1(upd_p upd))
- #define upd_proc_render(name) int name(P1(upd_p upd))
- #define upd_proc_writer(name) int name(P2(upd_p upd,FILE *out))
-
- struct upd_s { /* All upd-specific data */
-
- int *choice; /** Named-Choices */
- int *ints; /** Integers */
- gs_param_int_array *int_a; /** Integer-Arrays */
- gs_param_string *strings; /** Strings */
- gs_param_string_array *string_a; /** String-Arrays */
- gs_param_float_array *float_a; /** Float-Arrays */
-
- updcmap_t cmap[UPD_CMAP_MAX]; /** Mapping-Data */
-
- byte *gsbuf; /* Storage for GS-Rasterdata */
- byte *gsscan; /* Begin of GS-Rasterdata */
-
- byte *pxlptr; /* Source for pxlget */
- upd_proc_pxlget( (*pxlget)); /* The Pixel-Reader */
- upd_proc_render( (*render)); /* Actual Rendering */
- upd_proc_writer( (*writer));
-
- updscan_p *scnbuf; /* Output-Values */
- int32 *valbuf; /* Floyd-Steinberg-Buffer */
- void *valptr[UPD_VALPTR_MAX];
-
- byte *outbuf; /* Output-Buffer */
- upd_proc_render( (*start_render)); /* Setup for rendering */
- upd_proc_writer( (*start_writer)); /* Setup for writilg */
-
- uint32 flags; /** Some flags */
- int pdwidth; /** pdev-width upon open */
- int pdheight; /** pdev-height upon open */
-
- uint ngsbuf; /* Size of gsbuf */
- int gswidth; /* Width in GS-Pixels */
- int gsheight; /* Height in GS-Pixels */
-
- int rwidth; /* Rendering-Width */
-
- int pwidth; /* Printing-Width */
- int pheight; /* # scanlines printed */
-
- int ncomp; /* # Components in gsbuf */
- int nmap; /* # Entries in color-map */
-
- uint nvalbuf; /* Size of valbuf */
- int nscnbuf; /* Number of entries in scnbuf. */
-
- int ocomp; /* # Components written */
- int nbytes; /* Size of scnbuf[][].words */
- int nlimits; /* Size of scnbuf[][].xbegin/end */
- int scnmsk; /* Size of scanbuf - 1 */
- uint noutbuf; /* Size of the Output-Buffer */
-
- int ixpass; /* Current X-pass (0 ... nxpass-1) */
- int ipass; /* Current pass (0 ... npass-1) */
- int icomp; /* Selected Component */
- int lf; /* Selected Line-Space */
-
- int xprinter; /* Actual X-Position */
-
- int yscan; /* Top-Scan (page-vari) */
- int yprinter; /* Actual Y-Position (page-vari) */
- int yscnbuf; /* Y not yet buffered */
- }; /* All upd-specific data */
-
-
- /* ------------------------------------------------------------------- */
- /* Various Message-Levels */
- /* ------------------------------------------------------------------- */
-
- /**
- UPD_MESSAGES, Is collection of Bits, that controls Messages
- */
-
- #define UPD_M_NONE 0x0000 /** No Messages at all */
- #define UPD_M_ERROR 0x0001 /** Errors */
- #define UPD_M_WARNING 0x0002 /** Warnings */
- #define UPD_M_TOPCALLS 0x0004 /** Log Calls to main Functions */
- #define UPD_M_MAPCALLS 0x0008 /** Log Color-Mapping-Calls */
- #define UPD_M_SETUP 0x0010 /** Log Setup-Activity */
- #define UPD_M_FSBUF 0x0020 /** Error-Summary for valbuf */
-
-
- /* ------------------------------------------------------------------- */
- /* The UPD-Routines */
- /* ------------------------------------------------------------------- */
-
- /**
- Besides the main routines required for the color-mapping, that were
- declared near the beginning, there are some auxillary functions.
- Most prominent are "upd_open_map" and "upd_close_map", which
- do the proper actions when opening and closing the device.
- */
-
- private int upd_open_map( P1(upd_device *udev));
- private int upd_close_map(P1(upd_device *udev));
-
- /**
- But "upd_truncate" and "upd_expand" are also mentionable. They are
- the actual workhorses for the component-oriented mapping. When mapping
- the 16Bit Component-Values to the indices, some truncation takes place
- and this is what "upd_truncate" does, in the most general manner i can
- think of and with O(log(n)) in time. "upd_expand" is required for the
- reverse mapping-functions and is a constant-time `algorithm'.
- */
- private uint32 upd_truncate(P3(upd_pc,int,gx_color_value));
- private gx_color_value upd_expand( P3(upd_pc,int,uint32));
-
- /**
- The next group of internal functions adresses the rendering. Besides
- the main-functions "upd_open_render" and "upd_close_render", there
- are groups of up to 3 Functions, for each algorithm available with
- UPD. Two routines are invoked during open and close and the third
- is called for each scanline. Actually a fourth function is provided,
- that is invoked at the beginning of each page to be printed, but the
- current algorithms do not need it.
- */
- private void upd_open_render( P1(upd_device *udev));
- private void upd_close_render( P1(upd_device *udev));
-
- private void upd_open_fscomp( P1(upd_device *udev));
- private int upd_fscomp( P1(upd_p upd));
- private void upd_close_fscomp( P1(upd_device *udev));
-
- private void upd_open_fscmyk( P1(upd_device *udev));
- private int upd_fscmyk( P1(upd_p upd));
-
- private void upd_open_fscmy_k( P1(upd_device *udev));
- private int upd_fscmy_k( P1(upd_p upd));
-
- /**
- I hope that the formatting stuff can be kept simple and thus most
- of the work is done inside the general open and close-functions.
- During open, there is a call to a format-specific open-function, but
- this is only for checking and determining the amount of of bytes required
- for the output-buffer (and limit-values in the scan-buffer).
- */
- private int upd_open_writer( P1(upd_device *udev));
- private void upd_close_writer( P1(upd_device *udev));
- #if UPD_SIGNAL
- private void upd_signal_handler(P1(int sig));
- #endif
-
- /**
- The first format are the uncompressed! SUN-Rasterfiles. The primary intention
- of this format is testing, but it might turn out to be useful for other
- purposes, even if the amount of generated data is huge. On the other hand
- it is a violation of UPD's rules: the start-routine computes the Begin-Page
- sequence (the Rasterfile header) since it would be a nuisance to provide
- this code within each (test-)personalization in PostScript.
- */
- private int upd_open_rascomp( P1(upd_device *udev));
- private int upd_start_rascomp( P2(upd_p upd, FILE *out));
- private int upd_rascomp( P2(upd_p upd, FILE *out));
-
- /**
- The second format is ESC/P, the format introduced with the first Epson
- impact printers. This format is used by a lot of other printers too.
- It is also uncompressed. This formatter supports X- and Y-Weaving,
- which makes it the most sophisticated one inside this driver.
- */
-
- private void upd_limits( P2(upd_p upd, bool check));
- private int upd_open_wrtescp( P1(upd_device *udev));
- private int upd_wrtescp( P2(upd_p upd, FILE *out));
-
- /**
- The third format is ESC/P2, the format use by the newer Epson-Printers.
- It allows runlength-Compression similar to the RTL/PCL-Family of Printers.
- This formatter does not allow for X-Weaving.
-
- The fourth writer is a ESC/P2-Writer, that supports X-Weaving
- */
- private int upd_rle(P3(byte *out,const byte *in,int nbytes));
- private int upd_open_wrtescp2( P1(upd_device *udev));
- private int upd_wrtescp2( P2(upd_p upd, FILE *out));
- private int upd_wrtescp2x( P2(upd_p upd, FILE *out));
-
- /**
- The fifth writer is a HP-RTL/PCL-Writer
- */
-
- private int upd_open_wrtrtl( P1(upd_device *udev));
- private int upd_wrtrtl( P2(upd_p upd, FILE *out));
-
- /**
- The sixth writer is for Canon Extended Mode (currently BJC610) (hr)
- */
-
- private int upd_open_wrtcanon( P1(upd_device *udev));
- private int upd_wrtcanon( P2(upd_p upd, FILE *out));
-
- /**
- Generalized Pixel Get & Read
- */
- private uint32 upd_pxlfwd(P1(upd_p upd));
- private uint32 upd_pxlrev(P1(upd_p upd));
- #define upd_pxlget(UPD) (*UPD->pxlget)(UPD)
-
-
- /* ------------------------------------------------------------------- */
- /* Macros to deal with the Parameter-Memory */
- /* ------------------------------------------------------------------- */
-
- /**
- Usually the creation of copies of external parameters is not necessary,
- at least with gs-versions > 4.03. But uniprint writes to the parameters
- in some cases or creates some by itself, thus to get a unified interface
- all parameter-data are copied and thus it is legal to manipulate them.
-
- Here are several Macros, named "UPD_MM_*" to deal with that.
- */
-
- /** UPD_MM_GET_ARRAY allocates & initializes an array of values */
- #define UPD_MM_GET_ARRAY(Which,Nelts) \
- Which = NULL; \
- if(0 < (Nelts)) { \
- byte *tmp = gs_malloc(Nelts,sizeof(Which[0]),"uniprint/params");\
- if(tmp) { \
- memset(tmp,0,(Nelts)*sizeof(Which[0])); \
- Which = (void *) tmp; \
- } else { \
- return_error(gs_error_VMerror); \
- } \
- }
-
- /** UPD_MM_DEL_ARRAY frees an array of values */
- #define UPD_MM_DEL_ARRAY(Which,Nelts,Delete) \
- if(Which && 0 < (Nelts)) { \
- uint ii; \
- for(ii = 0; (Nelts) > ii; ++ii) Delete(Which[ii]); \
- gs_free((byte *)Which,Nelts,sizeof(Which[0]),"uniprint/params");\
- } \
- Which = 0
-
- /** UPD_MM_DEL_VALUE deletes a value, does nothing */
- #define UPD_MM_DEL_VALUE(Which) /* */
-
- /** UPD_MM_DEL_PARAM deletes a single gs-array-parameter */
- #define UPD_MM_DEL_PARAM(Which) { \
- if(Which.data && Which.size) \
- gs_free((byte *)Which.data,Which.size,sizeof(Which.data[0]),\
- "uniprint/params"); \
- }
-
- /** UPD_MM_DEL_APARAM deletes a nested gs-array-parameter */
- #define UPD_MM_DEL_APARAM(Which) { \
- if(Which.data && Which.size) { \
- uint iii; \
- for(iii = 0; iii < Which.size; ++iii) \
- UPD_MM_DEL_PARAM(Which.data[iii]); \
- gs_free((byte *)Which.data,Which.size,sizeof(Which.data[0]),\
- "uniprint/params"); \
- } \
- }
-
- /** UPD_MM_CPY_ARRAY creates a new copy of an array of values */
- #define UPD_MM_CPY_ARRAY(To,From,Nelts,Copy) \
- UPD_MM_GET_ARRAY(To,Nelts); \
- if(To && From) { \
- uint ii; \
- for(ii = 0; (Nelts) > ii; ++ii) Copy(To[ii],From[ii]);\
- }
-
- /** UPD_MM_CPY_VALUE Copies a simple Value */
- #define UPD_MM_CPY_VALUE(To,From) To = From
-
- /** UPD_MM_CPY_PARAM Creates a copy of a gs-parameter */
- #define UPD_MM_CPY_PARAM(To,From) \
- if(From.data && From.size) { \
- UPD_MM_GET_ARRAY(To.data,From.size); \
- if(To.data) { \
- To.size = From.size; \
- memcpy((byte *)To.data,From.data,To.size*sizeof(To.data[0]));\
- } \
- }
-
- /** UPD_MM_CPY_APARAM Creates a copy of a nested gs-parameter */
- #define UPD_MM_CPY_APARAM(To,From) \
- if(From.data && From.size) { \
- UPD_MM_GET_ARRAY(To.data,From.size); \
- if(To.data) { \
- gs_param_string *tmp2 = (gs_param_string *) To.data; \
- uint iii; \
- To.size = From.size; \
- for(iii = 0; To.size > iii; ++iii) \
- UPD_MM_CPY_PARAM(tmp2[iii],From.data[iii]); \
- } \
- }
-
- /* ------------------------------------------------------------------- */
- /* UPD-Initialized-Data */
- /* ------------------------------------------------------------------- */
-
- /** Version-String */
-
- static const char rcsid[] = "$Revision: 1.3 $";
-
- /** Default-Transfer-curve */
-
- static const float upd_data_xfer[2] = { 0.0, 1.0 };
-
- /*@ > */
-
-
- /* ------------------------------------------------------------------- */
- /* upd_signal_handler: Catch interrupts */
- /* ------------------------------------------------------------------- */
-
- #if UPD_SIGNAL
- static upd_p sigupd = NULL;
- private void
- upd_signal_handler(int sig)
- {
- if(sigupd) sigupd->flags |= B_ABORT;
- }
- #endif
-
-
- /* ------------------------------------------------------------------- */
- /* upd_print_page: The main workhorse */
- /* ------------------------------------------------------------------- */
-
- /**
- Function: upd_print_page
-
- This is the top-level printing routine. It works through this
- steps:
-
- 1. Once for each generated file, the "device-open-sequence" is written.
- 2. The "page-begin-sequence" is written.
-
- 3. The data are generated and written:
- 3.1: Data are converted into a "printer-family"-specific format.
- This step includes the halftoning, if selected.
- 3.2: Data are written with a printer-specific function.
- There is not much code-compression inside theese functions,
- since i observed to improvments in print-speed. Other
- drivers do a better job in this.
-
- 4. The "page-end-sequence" is written.
- 5. If a one-page-per-file mode is selected, the "device-close-sequence"
- is added to the output. For multi-page files, this writing is
- performed in "upd_close", the drivers close-function.
-
- The routine is quite short, since all the allocation and checking
- occur in upd_open and upd_putparams. The only test, that upd_print_page
- does, is the verification wether the device is in a sane state. This
- must be done here, since during the initialisation, the device is
- usually opened several times, before obtaining a valid state.
- */
-
- private int
- upd_print_page(gx_device_printer *pdev, FILE *out)
- {
- upd_device *const udev = (upd_device *) pdev;
- const upd_p upd = udev->upd;
- const int *const ints = upd ? upd->ints : NULL;
- int error,need,yfill;
-
- #if UPD_SIGNAL /* variables required for signal-handling only */
- void (*oldint )(P1(int)) = NULL;
- void (*oldterm)(P1(int)) = NULL;
- upd_p oldupd = sigupd;
- #endif /* variables required for signal-handling only */
-
- /*
- * Refuse to work, if not explicitly enabled during open
- * (some/lot of allocated memory is required)
- */
- if(!upd || B_OK4GO != (upd->flags & (B_OK4GO | B_ERROR))) {
- #if UPD_MESSAGES & (UPD_M_ERROR | UPD_M_TOPCALLS)
- fprintf(stderr,"CALL-REJECTED upd_print_page(0x%05lx,0x%05lx)\n",
- (long) udev,(long) out);
- #endif
- return gs_error_undefined;
- }
-
- #if UPD_MESSAGES & UPD_M_TOPCALLS
- fprintf(stderr,"CALL: upd_print_page(0x%05lx,0x%05lx)\n",
- (long) udev,(long) out);
- #endif
-
- #if UPD_SIGNAL /* Setup of signal-handling */
- sigupd = upd;
- oldint = signal(SIGINT, upd_signal_handler);
- oldterm = signal(SIGTERM,upd_signal_handler);
- #endif /* Setup of signal-handling */
-
- /*
- * If the OutputFile was just opened, transfer the Open-Sequence to it.
- */
- if(!(upd->flags & B_OPEN)) {
-
- if(0 < upd->strings[S_OPEN].size)
- fwrite(upd->strings[S_OPEN].data,1,upd->strings[S_OPEN].size,out);
- upd->flags |= B_OPEN;
- }
- /*
- * Always write the the Page-begin-sequence
- */
- if(0 < upd->strings[S_BEGIN].size)
- fwrite(upd->strings[S_BEGIN].data,1,upd->strings[S_BEGIN].size,out);
- /*
- * Establish page-variables
- */
-
- /* Positions */
- upd->xprinter = 0;
- upd->yscan = 0; /* Position we are processing */
- upd->yprinter = 0; /* Actual Printer-Positions */
- upd->yscnbuf = 0; /* Next free scnbuf-Line */
-
- /* Rendering & Writing Setup, if available */
- if(upd->start_render) (*upd->start_render)(upd);
- if(upd->start_writer) (*upd->start_writer)(upd,out);
-
- /* How many scanlines do we need ? */
- need = ints[I_NYPASS] * ints[I_PINS2WRITE];
- if(0 >= need) need = 1;
-
- /* The Weave-counters */
- upd->ipass = 0;
- upd->ixpass = 0;
- upd->icomp = -1; /* Enforces initial selection */
- upd->lf = -1; /* Enforces initial selection */
- /*
- * Main Loop
- */
- while(upd->pheight > upd->yscan) { /* Main-Loop */
-
- /*
- * Load as much data into the scan-buffer as possible
- * (this is done in scan-sequence, the printing not necessarily.)
- */
- if(ints[I_BEGSKIP] > upd->yscan) yfill = 0;
- else yfill = upd->yscan - ints[I_BEGSKIP];
-
- for(yfill += upd->nscnbuf; upd->yscnbuf < yfill; upd->yscnbuf++) {
-
- if(upd->gsheight > upd->yscnbuf) {
-
- if(0 > (*dev_proc(udev,get_bits))((gx_device *) udev,
- upd->yscnbuf,upd->gsbuf,&upd->gsscan)) {
- #if UPD_MESSAGES & UPD_M_WARNING
- fprintf(stderr,"get_bits aborted with error, yscnbuf = %4d\n",
- upd->yscnbuf);
- #endif
- break;
- }
- } else {
-
- memset(upd->gsscan = upd->gsbuf,0,upd->ngsbuf);
-
- }
-
- if(0 > (*upd->render)(upd)) {
- #if UPD_MESSAGES & UPD_M_WARNING
- fprintf(stderr,"Rendering aborted with error, yscnbuf = %4d\n",
- upd->yscnbuf);
- #endif
- break;
- }
-
- }
- /*
- * Did the buffering loop take an error exit ?
- */
- if((upd->yscnbuf ^ yfill) & upd->scnmsk) break;
- /*
- * Print as much as possible
- */
- while((upd->yscan - ints[I_BEGSKIP] + need) < upd->yscnbuf) {
-
- /* first write the scan(s) */
- (*upd->writer)(upd,out);
-
- /* Check for termination */
- if(upd->yscan >= upd->pheight) break;
- if(upd->flags & B_ABORT ) {
- #if UPD_MESSAGES & UPD_M_WARNING
- fprintf(stderr,"Printing aborted upon interrupt, yscan = %4d\n",
- upd->yscan);
- #endif
- break;
- }
- }
- /*
- * Did the print-Loop take an error exit ?
- */
- if((upd->yscan - ints[I_BEGSKIP] + need) < upd->yscnbuf) break;
- } /* Main-Loop */
-
- /*
- * If we aborted for some reason, use the dedicated sequence
- */
-
- if((upd->pheight > upd->yscan) &&
- (0 < upd->strings[S_ABORT].size)) { /* Only This! */
- fwrite(upd->strings[S_ABORT].data,1,upd->strings[S_ABORT].size,out);
-
- upd->flags &= ~B_OPEN; /* Inhibit Close-Sequence ! */
- /*
- * If there is no special sequence, or we came to normal end,
- * write the normal sequence, if any
- */
-
- } else if(0 < upd->strings[S_END].size) {
- fwrite(upd->strings[S_END].data,1,upd->strings[S_END].size,out);
- }
- /*
- * If necessary, write the close-sequence
- */
- if((NULL != udev->fname ) && strchr(udev->fname,'%')) {
-
- if(0 < upd->strings[S_CLOSE].size)
- fwrite(upd->strings[S_CLOSE].data,1,upd->strings[S_CLOSE].size,out);
-
- upd->flags &= ~B_OPEN;
- }
-
- /*
- * clean up, and return status
- */
-
- fflush(out); /* just to prepare for ferror */
-
- if(upd->pheight > upd->yscan) error = gs_error_interrupt;
- else if(ferror(out)) error = gs_error_ioerror;
- else error = 0;
-
- #if UPD_MESSAGES & UPD_M_TOPCALLS
- fprintf(stderr,"RETURN: %d = upd_print_page(0x%05lx,0x%05lx)\n",
- error,(long) udev,(long)out);
- #endif
-
- #if UPD_SIGNAL /* Restore Interrupt-state */
- sigupd = oldupd;
- (void) signal(SIGINT ,oldint);
- (void) signal(SIGTERM,oldterm);
- #endif /* Restore Interrupt-state */
-
- return error;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_open: Initialize everything for printing */
- /* ------------------------------------------------------------------- */
- /**
- "upd_open" is -through the specified table of procedures- called instead
- of the normal open-procedures for printer-devices, that performs quite
- a complex job. Thus it is necessary to call this `superclass-open´
- here.
-
- Besides that, this routine does quite a complex job too, in initializes
- everything required to print a page. This might be time-consuming, the
- alternative would be "upd_print_page", but i often print 100 pages or
- more, but i never experienced more than 5-6 open-calls.
- */
-
- private int
- upd_open(gx_device *pdev)
- {
- upd_device *const udev = (upd_device *) pdev;
- const upd_p upd = udev->upd;
- int error;
-
- #if UPD_MESSAGES & UPD_M_TOPCALLS
- fprintf(stderr,"CALL: upd_open(0x%05lx)\n",(long) pdev);
- #endif
-
- /** enforce the UPD-Margins */
-
- if((NULL != upd) &&
- (NULL != upd->float_a[FA_MARGINS].data) &&
- (4 == upd->float_a[FA_MARGINS].size) ) {
- static float m[4];
- m[1] = upd->float_a[FA_MARGINS].data[1] / 72.0;
- m[3] = upd->float_a[FA_MARGINS].data[3] / 72.0;
- if(B_YFLIP & upd->flags) {
- m[0] = upd->float_a[FA_MARGINS].data[2] / 72.0;
- m[2] = upd->float_a[FA_MARGINS].data[0] / 72.0;
- } else {
- m[0] = upd->float_a[FA_MARGINS].data[0] / 72.0;
- m[2] = upd->float_a[FA_MARGINS].data[2] / 72.0;
- }
- gx_device_set_margins((gx_device *) udev, m, true);
- }
-
- /** call the super-class open **/
- error = gdev_prn_open(pdev);
-
- /** invoke the subroutines, if an upd is present. */
-
- if(upd) {
-
- upd->flags &= ~B_OK4GO;
-
- /**
- The following initializations are run, even in case of an error in
- the super-class open, just to bring our upd into a sane state.
- */
- if(0 > error) upd->flags |= B_ERROR;
-
- if(gs_error_VMerror == upd_open_map(udev)) error = gs_error_VMerror;
-
- /**
- The following piece of code is here for demonstration-purposes:
- It determines the size of the printed image and allocates the
- buffer for the raw raster-data
- */
- upd->gswidth = udev->width -
- (dev_l_margin(udev)+dev_r_margin(udev))*udev->x_pixels_per_inch;
-
- upd->gsheight = udev->height -
- (dev_t_margin(udev)+dev_b_margin(udev))*udev->y_pixels_per_inch;
-
- upd->ngsbuf = 0; /* Ensure sane values */
- upd->gsbuf = NULL; /* Ensure sane values */
-
- if(B_MAP & upd->flags) { /* Only if prerequisites were met */
- uint want = gx_device_raster(pdev,true);
- upd->gsbuf = gs_malloc(want,1,"upd/gsbuf");
-
- if(upd->gsbuf) {
- upd->ngsbuf = want;
- upd->flags |= B_BUF; /* Signal Success */
- } else {
- error = gs_error_VMerror; /* Signal Error */
- upd->flags |= B_ERROR;
- }
-
- } /* Only if prerequisites were met */
-
- upd_open_render(udev); /* First subloop in printing */
-
- if(gs_error_VMerror == upd_open_writer(udev)) error = gs_error_VMerror;
-
- udev->upd->pdwidth = udev->width;
- udev->upd->pdheight = udev->height;
-
- #if UPD_MESSAGES & UPD_M_SETUP
- if((upd->flags & (B_OK4GO | B_ERROR)) == B_OK4GO) {
- int i,j,l,ln,lv;
- fprintf(stderr,"\nupd->flags = 0x%05lx\n",(unsigned long)upd->flags);
- fprintf(stderr, "upd->pdwidth = %5d\n",upd->pdwidth);
- fprintf(stderr, "upd->pdheight = %5d\n",upd->pdheight);
- fprintf(stderr, "upd->ngsbuf = %5u\n",upd->ngsbuf);
- fprintf(stderr, "upd->gswidth = %5d\n",upd->gswidth);
- fprintf(stderr, "upd->gsheight = %5d\n",upd->gsheight);
- fprintf(stderr, "upd->rwidth = %5d\n",upd->rwidth);
- fprintf(stderr, "upd->pwidth = %5d\n",upd->pwidth);
- fprintf(stderr, "upd->pheight = %5d\n",upd->pheight);
- fprintf(stderr, "upd->nvalbuf = %5u\n",upd->nvalbuf);
- fprintf(stderr, "upd->nscnbuf = %5d\n",upd->nscnbuf);
- fprintf(stderr, "upd->ncomp = %5d\n",upd->ncomp);
- fprintf(stderr, "upd->ocomp = %5d\n",upd->ocomp);
- fprintf(stderr, "upd->nbytes = %5d\n",upd->nbytes);
- fprintf(stderr, "upd->nlimits = %5d\n",upd->nlimits);
- fprintf(stderr, "upd->scnmsk = %5d\n",upd->scnmsk);
- fprintf(stderr, "upd->noutbuf = %5u\n",upd->noutbuf);
- fprintf(stderr, "upd->ixpass = %5d\n",upd->ixpass);
- fprintf(stderr, "upd->ipass = %5d\n",upd->ipass);
- fprintf(stderr, "upd->icomp = %5d\n",upd->icomp);
- fprintf(stderr, "upd->lf = %5d\n",upd->lf);
- fprintf(stderr, "upd->xprinter = %5d\n",upd->xprinter);
- fprintf(stderr, "upd->yscan = %5d\n",upd->yscan);
- fprintf(stderr, "upd->yprinter = %5d\n",upd->yprinter);
- fprintf(stderr, "upd->yscnbuf = %5d\n",upd->yscnbuf);
-
- ln = 13;
- lv = 5;
- for(i = 0; countof(upd_choice) > i; ++i) {
- if(!upd_choice[i]) continue;
- l = strlen(upd_choice[i][0]);
- if(ln < l) ln = l;
- for(j = 1; upd_choice[i][j]; ++j) {
- l = strlen(upd_choice[i][j]);
- if(lv < l) lv = l;
- }
- }
-
- for(i = 0; countof(upd_flags) > i; ++i) {
- if(upd_flags[i]) {
- l = strlen(upd_flags[i]);
- if(ln < l) ln = l;
- }
- }
-
- for(i = 0; countof(upd_ints) > i; ++i) {
- if(upd_ints[i]) {
- l = strlen(upd_ints[i]);
- if(ln < l) ln = l;
- }
- }
-
- for(i = 0; countof(upd_int_a) > i; ++i) {
- if(upd_int_a[i]) {
- l = strlen(upd_int_a[i]);
- if(ln < l) ln = l;
- }
- }
-
- for(i = 0; countof(upd_strings) > i; ++i) {
- if(upd_strings[i]) {
- l = strlen(upd_strings[i]);
- if(ln < l) ln = l;
- }
- }
-
- for(i = 0; countof(upd_string_a) > i; ++i) {
- if(upd_string_a[i]) {
- l = strlen(upd_string_a[i]);
- if(ln < l) ln = l;
- }
- }
-
- for(i = 0; countof(upd_float_a) > i; ++i) {
- if(upd_float_a[i]) {
- l = strlen(upd_float_a[i]);
- if(ln < l) ln = l;
- }
- }
-
- for(i = 0; countof(upd_choice) > i; ++i) {
- if(upd_choice[i]) {
- fprintf(stderr,"%*s = %-*s (%2d)\n",ln,upd_choice[i][0],
- lv,upd_choice[i][upd->choice[i]],upd->choice[i]);
- } else {
- fprintf(stderr,"%*s[%2d] = %2d\n",ln-4,"upd_choice",i,
- upd->choice[i]);
- }
- }
-
- for(i = 0; countof(upd_flags) > i; ++i) {
- if(upd_flags[i]) {
- fprintf(stderr,"%*s = %s\n",ln,upd_flags[i],
- ((uint32) 1 << i) & upd->flags ? "true" : "false");
- } else {
- fprintf(stderr,"%*s[%2d] = %s\n",ln-4,"upd_flags",i,
- ((uint32) 1 << i) & upd->flags ? "true" : "false");
-
- }
- }
-
- for(i = 0; countof(upd_ints) > i; ++i) {
- if(upd_ints[i]) {
- fprintf(stderr,"%*s = %5d\n",ln,upd_ints[i],upd->ints[i]);
- } else {
- fprintf(stderr,"%*s[%2d] = %5d\n",ln-4,"upd_ints",i,upd->ints[i]);
- }
- }
-
- }
-
-
- fprintf(stderr,"\n%sready to print\n\n",
- B_OK4GO != (upd->flags & (B_OK4GO | B_ERROR)) ?
- "NOT " : "");
- #endif
-
- }
-
- #if UPD_MESSAGES & UPD_M_TOPCALLS
- fprintf(stderr,"RETURN: %d = upd_open(0x%05lx)\n",
- error,(long) pdev);
- #endif
-
- return error;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_close: Release everything allocated in upd_open */
- /* ------------------------------------------------------------------- */
-
- private int
- upd_close(gx_device *pdev)
- {
- upd_device *const udev = (upd_device *) pdev;
- const upd_p upd = udev->upd;
- int error = 0;
- int code;
-
- #if UPD_MESSAGES & UPD_M_TOPCALLS
- fprintf(stderr,"CALL: upd_close(0x%05lx)\n",(long)pdev);
- #endif
-
- /** If necessary, write the close-sequence **/
-
- if( upd && (( B_OPEN | B_OK4GO) ==
- ((B_OPEN | B_OK4GO | B_ERROR) & upd->flags))) {
-
- if(udev->file && upd->strings && 0 < upd->strings[S_CLOSE].size)
- fwrite(upd->strings[S_CLOSE].data,1,
- upd->strings[S_CLOSE].size,udev->file);
-
- upd->flags &= ~B_OPEN;
- }
-
- /** Then release the open-allocated memory */
- if(upd) {
-
- upd_close_writer(udev);
-
- if(upd->gsbuf)
- gs_free(upd->gsbuf,upd->ngsbuf,1,"uniprint/gsbuf");
- upd->gsbuf = NULL;
- upd->ngsbuf = 0;
- upd->flags &= ~B_BUF;
-
- upd_close_render(udev);
- upd_close_map(udev);
-
- UPD_MM_DEL_ARRAY(upd->choice, countof(upd_choice), UPD_MM_DEL_VALUE);
- UPD_MM_DEL_ARRAY(upd->ints, countof(upd_ints), UPD_MM_DEL_VALUE);
- UPD_MM_DEL_ARRAY(upd->int_a, countof(upd_int_a), UPD_MM_DEL_PARAM);
- UPD_MM_DEL_ARRAY(upd->strings, countof(upd_strings), UPD_MM_DEL_PARAM);
- UPD_MM_DEL_ARRAY(upd->string_a,countof(upd_string_a),UPD_MM_DEL_APARAM);
- UPD_MM_DEL_ARRAY(upd->float_a, countof(upd_float_a), UPD_MM_DEL_PARAM);
-
- gs_free(upd,sizeof(upd[0]),1,"uniprint");
-
- udev->upd = NULL;
- }
-
- /** Then call the superclass close **/
- code = gdev_prn_close(pdev);
- error = error > code ? code : error;
-
-
- #if UPD_MESSAGES & UPD_M_TOPCALLS
- fprintf(stderr,"RETURN: %d = upd_close(0x%05lx)\n",
- error,(long) pdev);
- #endif
-
- return error;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_get_params: Export Parameters to the Interpreter */
- /* ------------------------------------------------------------------- */
-
- #if UPD_MESSAGES & UPD_M_TOPCALLS
- #define UPD_EXIT_GET(Err,Dev,List) \
- if(0 > Err) { \
- fprintf(stderr,"RETURN-%d: %d upd_get_params(0x%05lx,0x%05lx)\n", \
- __LINE__,Err,(long) Dev,(long) List); \
- return_error(Err); \
- }
- #else
- #define UPD_EXIT_GET(Err,Dev,List) if(0 > Err) return_error(Err);
- #endif
-
- private int
- upd_get_params(gx_device *pdev, gs_param_list *plist)
- {
- upd_device *const udev = (upd_device *) pdev;
- const upd_p upd = udev->upd;
- int error,i;
-
- #if UPD_MESSAGES & UPD_M_TOPCALLS
- fprintf(stderr,"CALL: upd_get_params(0x%05lx,0x%05lx)\n",
- (long) udev,(long) plist);
- #endif
-
- /** Call the SuperClass-get_params at the beginning */
- error = gdev_prn_get_params((gx_device *)udev,plist);
- UPD_EXIT_GET(error,udev,plist);
-
- /** Export the version */
- if(upd_version) { /* Version-Export enabled */
- udev->upd_version.data = (const byte *) rcsid;
- udev->upd_version.size = strlen(rcsid);
- udev->upd_version.persistent = true;
- error = param_write_string(plist,upd_version,&udev->upd_version);
- UPD_EXIT_GET(error,udev,plist);
- } /* Version-Export enabled */
-
- /** Export the Named choices */
- for(i = 0; i < countof(upd_choice); ++i) {
- if(!upd_choice[i]) continue; /* Choice-Export disabled */
- if(upd && upd->choice && upd->choice[i]) {
- gs_param_string name;
- name.data = (const byte *) upd_choice[i][upd->choice[i]];
- name.size = strlen((const char *) name.data);
- name.persistent = true;
- error = param_write_name(plist,upd_choice[i][0],&name);
- } else {
- error = param_write_null(plist,upd_choice[i][0]);
- }
- UPD_EXIT_GET(error,udev,plist);
- }
-
- /** Export the flags (bool) */
- for(i = 0; i < countof(upd_flags); ++i) {
- if(!upd_flags[i]) continue; /* Flag-Export disabled */
- if(upd) {
- bool value = upd->flags & ((uint32) 1 << i);
- error = param_write_bool(plist,upd_flags[i],&value);
- } else {
- error = param_write_null(plist,upd_flags[i]);
- }
- UPD_EXIT_GET(error,udev,plist);
- }
-
- /** Export the ints */
- for(i = 0; i < countof(upd_ints); ++i) {
- if(!upd_ints[i]) continue; /* int-Export disabled */
- if(upd && upd->ints && upd->ints[i]) {
- int value = upd->ints[i];
- error = param_write_int( plist,upd_ints[i],&value);
- } else {
- error = param_write_null(plist,upd_ints[i]);
- }
- UPD_EXIT_GET(error,udev,plist);
- }
-
- /** Export the int-arrays */
- for(i = 0; i < countof(upd_int_a); ++i) {
- if(!upd_int_a[i]) continue; /* int-Array-Export disabled */
- if(upd && upd->int_a && upd->int_a[i].size) {
- error = param_write_int_array( plist,upd_int_a[i],(upd->int_a+i));
- } else {
- error = param_write_null(plist,upd_int_a[i]);
- }
- UPD_EXIT_GET(error,udev,plist);
- }
-
- /** Export the strings */
- for(i = 0; i < countof(upd_strings); ++i) {
- if(!upd_strings[i]) continue; /* String-Export disabled */
- if(upd && upd->strings && upd->strings[i].size) {
- error = param_write_string( plist,upd_strings[i],(upd->strings+i));
- } else {
- error = param_write_null(plist,upd_strings[i]);
- }
- UPD_EXIT_GET(error,udev,plist);
- }
-
- /** Export the string-Arrays */
- for(i = 0; i < countof(upd_string_a); ++i) {
- if(!upd_string_a[i]) continue; /* String-Array-Export disabled */
- if(upd && upd->string_a && upd->string_a[i].size) {
- error =
- param_write_string_array( plist,upd_string_a[i],(upd->string_a+i));
- } else {
- error = param_write_null(plist,upd_string_a[i]);
- }
- UPD_EXIT_GET(error,udev,plist);
- }
-
- /** Export the float-Arrays */
- for(i = 0; i < countof(upd_float_a); ++i) {
- if(!upd_float_a[i]) continue; /* Float-Array-Export disabled */
- if(upd && upd->float_a && upd->float_a[i].size) {
- error =
- param_write_float_array( plist,upd_float_a[i],(upd->float_a+i));
- } else {
- error = param_write_null(plist,upd_float_a[i]);
- }
- UPD_EXIT_GET(error,udev,plist);
- }
-
- #if UPD_MESSAGES & UPD_M_TOPCALLS
- fprintf(stderr,"RETURN: %d = upd_get_params(0x%05lx,0x%05lx)\n",
- error,(long) udev,(long) plist);
- #endif
-
- return error;
- }
-
- #undef UPD_EXIT_GET
-
- /* ------------------------------------------------------------------- */
- /* upd_put_params: Load Parameters into the device-structure */
- /* ------------------------------------------------------------------- */
-
- private int
- upd_put_params(gx_device *pdev, gs_param_list *plist)
- {
- upd_device *const udev = (upd_device *) pdev;
- upd_p upd = udev->upd;
- int error = 0, code,i;
-
- float MarginsHWResolution[2],Margins[2];
- gx_device_color_info color_info;
- uint32 flags = 0;
- int *choice = NULL;
- int *ints = NULL;
- gs_param_int_array *int_a = NULL;
- gs_param_string *strings = NULL;
- gs_param_string_array *string_a = NULL;
- gs_param_float_array *float_a = NULL, mfa;
-
- /**
- Error is used for two purposes: either it holds a negative error
- code or it is used as a bitfield, that tells, which parameters
- were actually loaded. If any of the important parameters changed
- upd_put_params closes the device, since the real parameter-evaluation
- is carried out by upd_open.
- */
-
- #define UPD_PUT_FLAGS 0x0002
- #define UPD_PUT_CHOICE 0x0004
- #define UPD_PUT_INTS 0x0008
- #define UPD_PUT_INT_A 0x0010
- #define UPD_PUT_STRINGS 0x0020
- #define UPD_PUT_STRING_A 0x0040
- #define UPD_PUT_FLOAT_A 0x0080
- #define UPD_PUT_CHANGEDSIZE 0x0100
-
- #if UPD_MESSAGES & UPD_M_TOPCALLS
- fprintf(stderr,"CALL: upd_put_params(0x%05lx,0x%05lx)\n",
- (long)udev,(long)plist);
- #endif
-
-
- /**
- I consider the following part of upd_put_params a bad-nasty-hack-hack
- and i am uncertain, wether it really works in the intended way. I provide it
- just for the case someone is performing nasty-parameter-changes on the
- active device, especially switching the OutputFile. If this happens in
- a situation, where data were written to the file, but the termination
- sequence is required, the driver does it now. (If you want to know, why
- i am writing bad-nasty-hack-hack, visit http://www.zark.com )
- */
- if(upd && (B_OPEN & udev->upd->flags) && (NULL != udev->file)) {
-
- gs_param_string fname = { NULL, 0, false };
-
- code = param_read_string(plist,"OutputFile",&fname);
- if((1 != code) && (0 != code)) {
- code = param_read_null(plist,"OutputFile");
- if(0 == code) {
- fname.data = (const byte *) "";
- fname.size = 0;
- }
- }
-
- if((0 == code) &&
- strncmp((const char *)fname.data,udev->fname,fname.size)) {
- if(upd->strings && 0 < udev->upd->strings[S_CLOSE].size)
- fwrite(upd->strings[S_CLOSE].data,1,
- upd->strings[S_CLOSE].size,udev->file);
-
- upd->flags &= ~B_OPEN;
- }
- }
- /* Done with the bad-nasty-hack-hack */
-
- /**
- The next thing "upd_put_params" does, is a little strange too. It imports
- a readonly-parameter, the version-string. I do not know wether it is still
- required, but some versions of GHOSTSCRIPT disliked it very much, if an
- existing parameter was not touched by the put-operation.
-
- On the other hand it is the right time to show the basic-outline of the
- parameter-importing flow. Basically the proper "param_read"-procedure
- is called. If it indicated, that the parameter was present, but of the
- wrong type, a read for the null-type is attempted, which is by convention
- somehow an reset to default. This sequence is applied to all the parameters
- and in case of the array-parameters, a succesful null-read is marked by
- setting data and size to 0.
- */
- #if UPD_MESSAGES & UPD_M_SETUP
- #define UPD_PARAM_READ(Param_read,Name,Object) \
- code = Param_read(plist,Name,&Object); \
- if(0 > code) { \
- code = param_read_null(plist,Name); \
- if(0 == code) memset(&Object,0,sizeof(Object));\
- } \
- if(!code) fprintf(stderr, \
- "upd_put_params: retrieved parameter \"%s\"\n",\
- Name); \
- if(0 > code) { \
- param_signal_error(plist,Name,code); \
- if(error > code) error = code; \
- }
- #else
- #define UPD_PARAM_READ(Param_read,Name,Object) \
- code = Param_read(plist,Name,&Object); \
- if(0 > code) { \
- code = param_read_null(plist,Name); \
- if(0 == code) memset(&Object,0,sizeof(Object));\
- } \
- if(0 > code) { \
- param_signal_error(plist,Name,code); \
- if(error > code) error = code; \
- }
- #endif
-
- UPD_PARAM_READ(param_read_string,upd_version,udev->upd_version)
-
-
- /**
- upd_put_params begins it's normal work by creating a copy, of
- the data, that it might change, except for color_info that might
- be changed in the device-structure, all manipulations are carried
- out on this copies.
- */
- MarginsHWResolution[0] = udev->MarginsHWResolution[0];
- MarginsHWResolution[1] = udev->MarginsHWResolution[1];
- Margins[0] = udev->Margins[0];
- Margins[1] = udev->Margins[1];
-
- color_info = udev->color_info;
- if(upd) {
- flags = upd->flags;
- UPD_MM_CPY_ARRAY(choice, upd->choice, countof(upd_choice),
- UPD_MM_CPY_VALUE);
- UPD_MM_CPY_ARRAY(ints, upd->ints, countof(upd_ints),
- UPD_MM_CPY_VALUE);
- UPD_MM_CPY_ARRAY(int_a, upd->int_a, countof(upd_int_a),
- UPD_MM_CPY_PARAM);
- UPD_MM_CPY_ARRAY(strings, upd->strings, countof(upd_strings),
- UPD_MM_CPY_PARAM);
- UPD_MM_CPY_ARRAY(string_a,upd->string_a,countof(upd_string_a),
- UPD_MM_CPY_APARAM);
- UPD_MM_CPY_ARRAY(float_a, upd->float_a, countof(upd_float_a),
- UPD_MM_CPY_PARAM);
- } else {
- flags = 0;
- UPD_MM_GET_ARRAY(choice, countof(upd_choice));
- UPD_MM_GET_ARRAY(ints, countof(upd_ints));
- UPD_MM_GET_ARRAY(int_a, countof(upd_int_a));
- UPD_MM_GET_ARRAY(strings, countof(upd_strings));
- UPD_MM_GET_ARRAY(string_a,countof(upd_string_a));
- UPD_MM_GET_ARRAY(float_a, countof(upd_float_a));
- }
-
- /** Import the Multiple-Choices */
- for(i = 0; countof(upd_choice) > i; ++i) {
- gs_param_string value = { NULL, 0, false};
- if(!upd_choice[i][0]) continue;
- UPD_PARAM_READ(param_read_name,upd_choice[i][0],value);
- if(0 == code) {
- if(0 <= error) error |= UPD_PUT_CHOICE;
- choice[i] = 0;
- if(0 < value.size) {
- int j;
- for(j = 1; upd_choice[i][j]; ++j) {
- if((strlen(upd_choice[i][j]) == value.size) &&
- (0 == strncmp(upd_choice[i][j],
- (char *) value.data,value.size))) {
- choice[i] = j;
- break;
- }
- }
- }
- }
- }
-
- /** Import the Boolean Values */
- for(i = 0; countof(upd_flags) > i; ++i) {
- uint32 bit = (uint32) 1 << i;
- bool flag = flags & bit ? true : false;
- if(!upd_flags[i]) continue;
- UPD_PARAM_READ(param_read_bool,upd_flags[i],flag);
- if(0 == code) {
- if(0 <= error) error |= UPD_PUT_FLAGS;
- if(flag) flags |= bit;
- else flags &= ~bit;
- }
- }
-
- /** Import the Integer Values */
- for(i = 0; countof(upd_ints) > i; ++i) {
- int value = ints[i];
- if(!upd_ints[i]) continue;
- UPD_PARAM_READ(param_read_int,upd_ints[i],value);
- if(0 == code) {
- if(0 <= error) error |= UPD_PUT_INTS;
- ints[i] = value;
- }
- }
-
- /** Import the Integer Arrays */
- for(i = 0; countof(upd_int_a) > i; ++i) {
- gs_param_int_array value = int_a[i];
- if(!upd_int_a[i]) continue;
- UPD_PARAM_READ(param_read_int_array,upd_int_a[i],value);
- if(0 == code) {
- if(0 <= error) error |= UPD_PUT_INT_A;
- UPD_MM_DEL_PARAM(int_a[i]);
- if(!value.size) {
- value.data = NULL;
- int_a[i] = value;
- } else {
- UPD_MM_CPY_PARAM(int_a[i],value);
- }
- }
- }
-
- /** Import the Strings */
- for(i = 0; countof(upd_strings) > i; ++i) {
- gs_param_string value = strings[i];
- if(!upd_strings[i]) continue;
- UPD_PARAM_READ(param_read_string,upd_strings[i],value);
- if(0 == code) {
- if(0 <= error) error |= UPD_PUT_STRINGS;
- UPD_MM_DEL_PARAM(strings[i]);
- if(!value.size) {
- value.data = NULL;
- strings[i] = value;
- } else {
- UPD_MM_CPY_PARAM(strings[i],value);
- }
- }
- }
-
- /** Import the String Arrays */
- for(i = 0; countof(upd_string_a) > i; ++i) {
- gs_param_string_array value = string_a[i];
- if(!upd_string_a[i]) continue;
- UPD_PARAM_READ(param_read_string_array,upd_string_a[i],value);
- if(0 == code) {
- if(0 <= error) error |= UPD_PUT_STRING_A;
- UPD_MM_DEL_APARAM(string_a[i]);
- if(!value.size) {
- value.data = NULL;
- string_a[i] = value;
- } else {
- UPD_MM_CPY_APARAM(string_a[i],value);
- }
- }
- }
-
- /** Import the Float Arrays */
- for(i = 0; countof(upd_float_a) > i; ++i) {
- gs_param_float_array value = float_a[i];
- if(!upd_float_a[i]) continue;
- UPD_PARAM_READ(param_read_float_array,upd_float_a[i],value);
- if(0 == code) {
- if(0 <= error) error |= UPD_PUT_FLOAT_A;
- UPD_MM_DEL_PARAM(float_a[i]);
- if(!value.size) {
- value.data = NULL;
- float_a[i] = value;
- } else {
- UPD_MM_CPY_PARAM(float_a[i],value);
- }
- }
- }
-
- /**
- Prior to the call to the superclass-put_params, the memory-layout and
- the color-model needs adjustment. This is performed here, if any parameters
- were set.
- In addition to that, Resolution & Margin-Parameters are tested & adjusted.
- */
- if(0 < error) {
-
- int *ip,*ip2,ncomp,nbits;
-
- if(6 > int_a[IA_COLOR_INFO].size) {
- UPD_MM_DEL_PARAM(int_a[IA_COLOR_INFO]);
- UPD_MM_GET_ARRAY(int_a[IA_COLOR_INFO].data,6);
- int_a[IA_COLOR_INFO].size = 6;
- }
- ip = (int *) int_a[IA_COLOR_INFO].data;
-
- if(0 == ip[0]) { /* Try to obtain num_components */
- switch(choice[C_MAPPER]) {
- case MAP_GRAY: ip[0] = 1; break;
- case MAP_RGBW: ip[0] = 3; break;
- case MAP_RGB: ip[0] = 3; break;
- case MAP_CMYK: ip[0] = 4; break;
- case MAP_CMYKGEN: ip[0] = 4; break;
- case MAP_RGBOV: ip[0] = 3; break;
- case MAP_RGBNOV: ip[0] = 3; break;
- default: ip[0] = color_info.num_components; break;
- }
- } /* Try to obtain num_components */
-
- switch(choice[C_MAPPER]) {
- case MAP_GRAY: ncomp = 1; break;
- case MAP_RGBW: ncomp = 4; break;
- case MAP_RGB: ncomp = 3; break;
- case MAP_CMYK: ncomp = 4; break;
- case MAP_CMYKGEN: ncomp = 4; break;
- case MAP_RGBOV: ncomp = 4; break;
- case MAP_RGBNOV: ncomp = 4; break;
- default: ncomp = ip[0]; break;
- }
- if(UPD_CMAP_MAX < ncomp) ncomp = UPD_CMAP_MAX;
-
- if(ncomp > int_a[IA_COMPBITS].size) { /* Default ComponentBits */
- UPD_MM_GET_ARRAY(ip2,ncomp);
- nbits = 32 / ncomp;
- if(8 < nbits) nbits = 8;
- for(i = 0; i < ncomp; ++i) ip2[i] = nbits;
- UPD_MM_DEL_PARAM(int_a[IA_COMPBITS]);
- int_a[IA_COMPBITS].data = ip2;
- int_a[IA_COMPBITS].size = ncomp;
- } /* Default ComponentBits */
-
- if(ncomp > int_a[IA_COMPSHIFT].size) { /* Default ComponentShift */
- nbits = 0;
- for(i = 0; i < ncomp; ++i) nbits += int_a[IA_COMPBITS].data[i];
- UPD_MM_GET_ARRAY(ip2,ncomp);
- for(i = 0; i < ncomp; ++i) {
- ip2[i] = nbits - int_a[IA_COMPBITS].data[i];
- nbits -= int_a[IA_COMPBITS].data[i];
- }
- UPD_MM_DEL_PARAM(int_a[IA_COMPSHIFT]);
- int_a[IA_COMPSHIFT].data = ip2;
- int_a[IA_COMPSHIFT].size = ncomp;
- } /* Default ComponentShift */
-
- if(0 == ip[1]) { /* Try to compute the depth */
- nbits = 0;
- for(i = 0; i < ncomp; ++i) {
- if(nbits < (int_a[IA_COMPBITS].data[i] +
- int_a[IA_COMPSHIFT].data[i]))
- nbits = int_a[IA_COMPBITS].data[i] +
- int_a[IA_COMPSHIFT].data[i];
- }
- if( 1 >= nbits) nbits = 1;
- else if( 2 >= nbits) nbits = 2;
- else if( 4 >= nbits) nbits = 4;
- else if( 8 >= nbits) nbits = 8;
- else if(16 >= nbits) nbits = 16;
- else if(24 >= nbits) nbits = 24;
- else nbits = 32;
-
- ip[1] = nbits;
-
- } /* Try to compute the depth */
-
- if(0 == ip[2]) { /* Number of Gray-Levels */
- nbits = 0;
- for(i = 0; i < ncomp; ++i) if(nbits < int_a[IA_COMPBITS].data[i])
- nbits = int_a[IA_COMPBITS].data[i];
- if(nbits > 8) nbits = 8;
- ip[2] = (1 << nbits) - 1;
- } /* Number of Gray-Levels */
-
- if(0 == ip[3] && 1 < ip[0]) { /* Number of Colors */
- nbits = 0;
- for(i = 0; i < ip[0]; ++i) nbits += int_a[IA_COMPBITS].data[i];
- if(nbits > 8) nbits = 8;
- ip[3] = (1 << nbits) - 1;
- } /* Number of Colors */
-
- if(0 == ip[4]) { /* Gray-Ramp */
- nbits = 0;
- for(i = 0; i < ncomp; ++i) if(nbits < int_a[IA_COMPBITS].data[i])
- nbits = int_a[IA_COMPBITS].data[i];
- if(2 < nbits) ip[4] = 5;
- else ip[4] = 2;
- } /* Gray-Ramp */
-
- if(0 == ip[5] && 1 < ip[0]) { /* Color-Ramp */
- nbits = 0;
- for(i = 0; i < ncomp; ++i) if(nbits < int_a[IA_COMPBITS].data[i])
- nbits = int_a[IA_COMPBITS].data[i];
- if(2 < nbits) ip[5] = 5;
- else ip[5] = 2;
- } /* Color-Ramp */
-
- udev->color_info.num_components = ip[0];
- udev->color_info.depth = ip[1];
- udev->color_info.max_gray = (gx_color_value) ip[2];
- udev->color_info.max_color = (gx_color_value) ip[3];
- udev->color_info.dither_grays = (gx_color_value) ip[4];
- udev->color_info.dither_colors = (gx_color_value) ip[5];
-
- /*
- * Now we're dealing with the Resolution- & Margin-Stuff
- * (This is close to be a bad-nasty-hack-hack)
- */
- if((0 == param_read_float_array(plist,"HWResolution",&mfa)) &&
- (2 == mfa.size) && (0 != mfa.data)) {
- udev->MarginsHWResolution[0] = mfa.data[0];
- udev->MarginsHWResolution[1] = mfa.data[1];
- } else {
- udev->MarginsHWResolution[0] = udev->HWResolution[0];
- udev->MarginsHWResolution[1] = udev->HWResolution[1];
- }
-
- if((0 == param_read_float_array(plist,".HWMargins",&mfa)) &&
- (4 == mfa.size) && (0 != mfa.data)) {
- udev->Margins[0] = -mfa.data[0] * udev->MarginsHWResolution[0] / 72.0;
- udev->Margins[1] = -mfa.data[3] * udev->MarginsHWResolution[1] / 72.0;
- }
- } /* Change the color-Info */
-
- /* Call the superclass-put_params now */
- code = gdev_prn_put_params((gx_device *)udev,plist);
- if(0 > code) error = code;
-
- /**
- If the superclass-"put_params" went o.k. too, then the new parameters are
- transferred into the device-structure. In the case of "uniprint", this may
-
- 1. Close the device, which might fail.
- 2. Allocate new memory for the upd-specific structure, that might fail too.
-
- */
- /* *HGS* recognize a changed device geometry */
- if( udev->upd && /* HGS */
- ((udev->width != udev->upd->pdwidth) || /* HGS */
- (udev->height != udev->upd->pdheight) )) /* HGS */
- error |= UPD_PUT_CHANGEDSIZE; /* HGS */
-
- if(0 < error && udev->is_open) {
- code = gs_closedevice((gx_device *)udev);
- if(0 > code) error = code;
- }
-
- if(0 < error) { /* Actually something loaded without error */
-
- if(!(upd = udev->upd)) {
- UPD_MM_GET_ARRAY(udev->upd,1);
- upd = udev->upd;
- } else {
- UPD_MM_DEL_ARRAY(upd->choice, countof(upd_choice), UPD_MM_DEL_VALUE);
- UPD_MM_DEL_ARRAY(upd->ints, countof(upd_ints), UPD_MM_DEL_VALUE);
- UPD_MM_DEL_ARRAY(upd->int_a, countof(upd_int_a), UPD_MM_DEL_PARAM);
- UPD_MM_DEL_ARRAY(upd->strings, countof(upd_strings), UPD_MM_DEL_PARAM);
- UPD_MM_DEL_ARRAY(upd->string_a,countof(upd_string_a),UPD_MM_DEL_APARAM);
- UPD_MM_DEL_ARRAY(upd->float_a, countof(upd_float_a), UPD_MM_DEL_PARAM);
- }
-
- upd->choice = choice;
- upd->flags = flags;
- upd->ints = ints;
- upd->int_a = int_a;
- upd->strings = strings;
- upd->string_a = string_a;
- upd->float_a = float_a;
-
- if(0 < error) error = 0;
-
- } else {
-
- udev->Margins[0] = Margins[0];
- udev->Margins[1] = Margins[1];
- udev->MarginsHWResolution[0] = MarginsHWResolution[0];
- udev->MarginsHWResolution[1] = MarginsHWResolution[1];
-
- udev->color_info = color_info;
- UPD_MM_DEL_ARRAY(choice, countof(upd_choice), UPD_MM_DEL_VALUE);
- UPD_MM_DEL_ARRAY(ints, countof(upd_ints), UPD_MM_DEL_VALUE);
- UPD_MM_DEL_ARRAY(int_a, countof(upd_int_a), UPD_MM_DEL_PARAM);
- UPD_MM_DEL_ARRAY(strings, countof(upd_strings), UPD_MM_DEL_PARAM);
- UPD_MM_DEL_ARRAY(string_a,countof(upd_string_a),UPD_MM_DEL_APARAM);
- UPD_MM_DEL_ARRAY(float_a, countof(upd_float_a), UPD_MM_DEL_PARAM);
-
- }
-
- /*
- * upd_put_params keeps the Procedures upd to date
- */
-
- upd_procs_map(udev);
-
-
- #if UPD_MESSAGES & UPD_M_TOPCALLS
- fprintf(stderr,"RETURN: %d = upd_put_params(0x%05lx,0x%05lx)\n",
- error,(long) udev, (long) plist);
- #endif
-
- return error;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_cmyk_icolor: KCMY->KCMY-Index Mapping */
- /* ------------------------------------------------------------------- */
- /**
- The next Routines, that follow, are the color-mapping routines.
- GHOSTSCRIPT talks about "gx_color_values" and the driver has
- to merge the 1, 3 or four values into up to 32 Bits, that means
- it is necessary to do some truncation and shifting. For the truncation
- "uniprint" uses the internal function "upd_truncate" and "upd_expand"
- reverses this in the reverse-mapping procedures.
- */
-
- private gx_color_index
- upd_cmyk_icolor(gx_device *pdev,
- gx_color_value c, gx_color_value m, gx_color_value y,gx_color_value k)
- {
- const upd_p upd = ((upd_device *)pdev)->upd;
- gx_color_index rv;
-
- /**
- All 4-Component-Modi have to deal with the Problem, that a value
- with all bits set can be produced, which is treated as an error-return
- from the mapping-functions. But with RGBW or KCMY, there is a neat
- trick: Grayscale are transferred as RGB/CMY=0 and holding Data only
- in the W- or K-Component.
- */
-
- if((c == m) && (m == y)) {
-
- rv = upd_truncate(upd,0,c > k ? c : k);
-
- } else {
-
- rv = upd_truncate(upd,0,k) | upd_truncate(upd,1,c)
- | upd_truncate(upd,2,m) | upd_truncate(upd,3,y);
-
-
- /* It might still become a "gx_no_color_value" due to truncation, thus: */
-
- if(rv == gx_no_color_index) rv ^= 1;
- }
-
-
- #if UPD_MESSAGES & UPD_M_MAPCALLS
- fprintf(stderr,
- "cmyk_icolor: (%5.1f,%5.1f,%5.1f,%5.1f) : (%5.1f,%5.1f,%5.1f,%5.1f) : 0x%0*lx\n",
- 255.0 * (double) c / (double) gx_max_color_value,
- 255.0 * (double) m / (double) gx_max_color_value,
- 255.0 * (double) y / (double) gx_max_color_value,
- 255.0 * (double) k / (double) gx_max_color_value,
- 255.0 * (double) ((rv >> upd->cmap[1].bitshf) & upd->cmap[1].bitmsk)
- / (double) upd->cmap[1].bitmsk,
- 255.0 * (double) ((rv >> upd->cmap[2].bitshf) & upd->cmap[2].bitmsk)
- / (double) upd->cmap[2].bitmsk,
- 255.0 * (double) ((rv >> upd->cmap[3].bitshf) & upd->cmap[3].bitmsk)
- / (double) upd->cmap[3].bitmsk,
- 255.0 * (double) ((rv >> upd->cmap[0].bitshf) & upd->cmap[0].bitmsk)
- / (double) upd->cmap[0].bitmsk,
- (pdev->color_info.depth + 3)>>2,rv);
- #endif
-
- return rv;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_icolor_rgb: Stored KCMY back to a RGB */
- /* ------------------------------------------------------------------- */
-
- private int
- upd_icolor_rgb(gx_device *pdev, gx_color_index color, gx_color_value prgb[3])
- {
- const upd_p upd = ((upd_device *)pdev)->upd;
- gx_color_value c,m,y,k;
-
- /*
- * Expand to the Component-Values
- */
- k = upd_expand(upd,0,color);
- c = upd_expand(upd,1,color);
- m = upd_expand(upd,2,color);
- y = upd_expand(upd,3,color);
-
- /*
- * Then Invert and subtract K from the colors
- */
- prgb[0] = gx_max_color_value - c;
- if(prgb[0] > k) prgb[0] -= k;
- else prgb[0] = 0;
-
- prgb[1] = gx_max_color_value - m;
- if(prgb[1] > k) prgb[1] -= k;
- else prgb[1] = 0;
-
- prgb[2] = gx_max_color_value - y;
- if(prgb[2] > k) prgb[2] -= k;
- else prgb[2] = 0;
-
-
- #if UPD_MESSAGES & UPD_M_MAPCALLS
- fprintf(stderr,
- "icolor_rgb: 0x%0*lx -> (%5.1f,%5.1f,%5.1f,%5.1f) -> (%5.1f,%5.1f,%5.1f,%5.1f) -> (%5.1f,%5.1f,%5.1f)\n",
- (pdev->color_info.depth + 3)>>2,color,
- 255.0 * (double) ((color >> upd->cmap[1].bitshf) & upd->cmap[1].bitmsk)
- / (double) upd->cmap[1].bitmsk,
- 255.0 * (double) ((color >> upd->cmap[2].bitshf) & upd->cmap[2].bitmsk)
- / (double) upd->cmap[2].bitmsk,
- 255.0 * (double) ((color >> upd->cmap[3].bitshf) & upd->cmap[3].bitmsk)
- / (double) upd->cmap[3].bitmsk,
- 255.0 * (double) ((color >> upd->cmap[0].bitshf) & upd->cmap[0].bitmsk)
- / (double) upd->cmap[0].bitmsk,
- 255.0 * (double) c / (double) gx_max_color_value,
- 255.0 * (double) m / (double) gx_max_color_value,
- 255.0 * (double) y / (double) gx_max_color_value,
- 255.0 * (double) k / (double) gx_max_color_value,
- 255.0 * (double) prgb[0] / (double) gx_max_color_value,
- 255.0 * (double) prgb[1] / (double) gx_max_color_value,
- 255.0 * (double) prgb[2] / (double) gx_max_color_value);
- #endif
-
- return 0;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_rgb_1color: Grayscale-RGB->Grayscale-index-Mapping */
- /* ------------------------------------------------------------------- */
-
- private gx_color_index
- upd_rgb_1color(gx_device *pdev,
- gx_color_value r, gx_color_value g, gx_color_value b)
- {
- const upd_p upd = ((upd_device *)pdev)->upd;
- gx_color_index rv;
-
- rv = upd_truncate(upd,0,r);
-
- #if UPD_MESSAGES & UPD_M_MAPCALLS
- fprintf(stderr,
- "rgb_1color: (%5.1f,%5.1f,%5.1f) : (%5.1f) : 0x%0*lx\n",
- 255.0 * (double) r / (double) gx_max_color_value,
- 255.0 * (double) g / (double) gx_max_color_value,
- 255.0 * (double) b / (double) gx_max_color_value,
- 255.0 * (double) ((rv >> upd->cmap[0].bitshf) & upd->cmap[0].bitmsk)
- / (double) upd->cmap[0].bitmsk,
- (pdev->color_info.depth + 3)>>2,rv);
- #endif
-
- return rv;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_1color_rgb: reversal of the above */
- /* ------------------------------------------------------------------- */
-
- private int
- upd_1color_rgb(gx_device *pdev, gx_color_index color, gx_color_value prgb[3])
- {
- const upd_p upd = ((upd_device *)pdev)->upd;
- /*
- * Actual task: expand to full range of gx_color_value
- */
- prgb[0] = upd_expand(upd,0,color);
-
- prgb[2] = prgb[1] = prgb[0];
-
- #if UPD_MESSAGES & UPD_M_MAPCALLS
- fprintf(stderr,"1color_rgb: 0x%0*lx -> %5.1f -> (%5.1f,%5.1f,%5.1f)\n",
- (pdev->color_info.depth + 3)>>2,color,
- 255.0 * (double) ((color >> upd->cmap[0].bitshf) & upd->cmap[0].bitmsk)
- / (double) upd->cmap[0].bitmsk,
- 255.0 * (double) prgb[0] / (double) gx_max_color_value,
- 255.0 * (double) prgb[1] / (double) gx_max_color_value,
- 255.0 * (double) prgb[2] / (double) gx_max_color_value);
- #endif
-
- return 0;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_rgb_3color: component-wise RGB->RGB-Mapping */
- /* ------------------------------------------------------------------- */
-
- private gx_color_index
- upd_rgb_3color(gx_device *pdev,
- gx_color_value r, gx_color_value g, gx_color_value b)
- {
- const upd_p upd = ((upd_device *)pdev)->upd;
- gx_color_index rv;
-
- rv = upd_truncate(upd,0,r) | upd_truncate(upd,1,g) | upd_truncate(upd,2,b);
- if(rv == gx_no_color_index) rv ^= 1;
-
- #if UPD_MESSAGES & UPD_M_MAPCALLS
- fprintf(stderr,
- "rgb_3color: (%5.1f,%5.1f,%5.1f) : (%5.1f,%5.1f,%5.1f) : 0x%0*lx\n",
- 255.0 * (double) r / (double) gx_max_color_value,
- 255.0 * (double) g / (double) gx_max_color_value,
- 255.0 * (double) b / (double) gx_max_color_value,
- 255.0 * (double) ((rv >> upd->cmap[0].bitshf) & upd->cmap[0].bitmsk)
- / (double) upd->cmap[0].bitmsk,
- 255.0 * (double) ((rv >> upd->cmap[1].bitshf) & upd->cmap[1].bitmsk)
- / (double) upd->cmap[1].bitmsk,
- 255.0 * (double) ((rv >> upd->cmap[2].bitshf) & upd->cmap[2].bitmsk)
- / (double) upd->cmap[2].bitmsk,
- (pdev->color_info.depth + 3)>>2,rv);
- #endif
-
- return rv;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_3color_rgb: reversal of the above */
- /* ------------------------------------------------------------------- */
-
- private int
- upd_3color_rgb(gx_device *pdev, gx_color_index color, gx_color_value prgb[3])
- {
- const upd_p upd = ((upd_device *)pdev)->upd;
-
- prgb[0] = upd_expand(upd,0,color);
- prgb[1] = upd_expand(upd,1,color);
- prgb[2] = upd_expand(upd,2,color);
-
- #if UPD_MESSAGES & UPD_M_MAPCALLS
- fprintf(stderr,
- "3color_rgb: 0x%0*lx -> (%5.1f,%5.1f,%5.1f) -> (%5.1f,%5.1f,%5.1f)\n",
- (pdev->color_info.depth + 3)>>2,color,
- 255.0 * (double) ((color >> upd->cmap[0].bitshf) & upd->cmap[0].bitmsk)
- / (double) upd->cmap[0].bitmsk,
- 255.0 * (double) ((color >> upd->cmap[1].bitshf) & upd->cmap[1].bitmsk)
- / (double) upd->cmap[1].bitmsk,
- 255.0 * (double) ((color >> upd->cmap[2].bitshf) & upd->cmap[2].bitmsk)
- / (double) upd->cmap[2].bitmsk,
-
- 255.0 * (double) prgb[0] / (double) gx_max_color_value,
- 255.0 * (double) prgb[1] / (double) gx_max_color_value,
- 255.0 * (double) prgb[2] / (double) gx_max_color_value);
- #endif
-
- return 0;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_rgb_4color: Create an WRGB-Index from RGB */
- /* ------------------------------------------------------------------- */
-
- private gx_color_index
- upd_rgb_4color(gx_device *pdev,
- gx_color_value r, gx_color_value g, gx_color_value b)
- {
- const upd_p upd = ((upd_device *)pdev)->upd;
- gx_color_index rv;
-
- if((r == g) && (g == b)) {
-
- rv = upd_truncate(upd,0,r);
-
- } else {
-
- gx_color_value w = g < r ? g : r; w = w < b ? w : b; /* Minimum */
-
- rv = upd_truncate(upd,0,w) | upd_truncate(upd,1,r) |
- upd_truncate(upd,2,g) | upd_truncate(upd,3,b);
-
- /* It might still become a "gx_no_color_value" due to truncation, thus: */
-
- if(rv == gx_no_color_index) rv ^= 1;
- }
-
- #if UPD_MESSAGES & UPD_M_MAPCALLS
- fprintf(stderr,
- "rgb_4color: (%5.1f,%5.1f,%5.1f) : (%5.1f,%5.1f,%5.1f,%5.1f) : 0x%0*lx\n",
- 255.0 * (double) r / (double) gx_max_color_value,
- 255.0 * (double) g / (double) gx_max_color_value,
- 255.0 * (double) b / (double) gx_max_color_value,
- 255.0 * (double) ((rv >> upd->cmap[1].bitshf) & upd->cmap[1].bitmsk)
- / (double) upd->cmap[1].bitmsk,
- 255.0 * (double) ((rv >> upd->cmap[2].bitshf) & upd->cmap[2].bitmsk)
- / (double) upd->cmap[2].bitmsk,
- 255.0 * (double) ((rv >> upd->cmap[3].bitshf) & upd->cmap[3].bitmsk)
- / (double) upd->cmap[3].bitmsk,
- 255.0 * (double) ((rv >> upd->cmap[0].bitshf) & upd->cmap[0].bitmsk)
- / (double) upd->cmap[0].bitmsk,
- (pdev->color_info.depth + 3)>>2,rv);
- #endif
-
- return rv;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_4color_rgb: Stored WRGB-Index back to a RGB */
- /* ------------------------------------------------------------------- */
-
- private int
- upd_4color_rgb(gx_device *pdev, gx_color_index color, gx_color_value prgb[3])
- {
- const upd_p upd = ((upd_device *)pdev)->upd;
-
- /*
- * Expand to the Component-Values
- */
- prgb[0] = upd_expand(upd,1,color);
- prgb[1] = upd_expand(upd,2,color);
- prgb[2] = upd_expand(upd,3,color);
-
- /* Revert our Grayscale-Trick: */
- if(!(prgb[0] || prgb[1] || prgb[2]))
- prgb[0] = prgb[1] = prgb[2] = upd_expand(upd,0,color);
-
-
- #if UPD_MESSAGES & UPD_M_MAPCALLS
- fprintf(stderr,
- "4color_rgb: 0x%0*lx -> (%5.1f,%5.1f,%5.1f,%5.1f) -> (%5.1f,%5.1f,%5.1f)\n",
- (pdev->color_info.depth + 3)>>2,color,
- 255.0 * (double) ((color >> upd->cmap[1].bitshf) & upd->cmap[1].bitmsk)
- / (double) upd->cmap[1].bitmsk,
- 255.0 * (double) ((color >> upd->cmap[2].bitshf) & upd->cmap[2].bitmsk)
- / (double) upd->cmap[2].bitmsk,
- 255.0 * (double) ((color >> upd->cmap[3].bitshf) & upd->cmap[3].bitmsk)
- / (double) upd->cmap[3].bitmsk,
- 255.0 * (double) ((color >> upd->cmap[0].bitshf) & upd->cmap[0].bitmsk)
- / (double) upd->cmap[0].bitmsk,
- 255.0 * (double) prgb[0] / (double) gx_max_color_value,
- 255.0 * (double) prgb[1] / (double) gx_max_color_value,
- 255.0 * (double) prgb[2] / (double) gx_max_color_value);
- #endif
-
- return 0;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_cmyk_kcolor: KCMY->KCMY-Index Mapping with Black Generation */
- /* ------------------------------------------------------------------- */
-
- private gx_color_index
- upd_cmyk_kcolor(gx_device *pdev,
- gx_color_value c, gx_color_value m, gx_color_value y,gx_color_value k)
- {
- const upd_p upd = ((upd_device *)pdev)->upd;
- gx_color_index rv;
- gx_color_value black;
-
- if((c == m) && (m == y)) {
-
- black = c > k ? c : k;
- rv = upd_truncate(upd,0,black);
-
- } else {
-
- if(k && !(c | m | y)) {
- black = k;
- } else {
- black = c < m ? c : m;
- black = black < y ? black : y;
- }
-
- rv = upd_truncate(upd,0,black) | upd_truncate(upd,1,c)
- | upd_truncate(upd,2,m) | upd_truncate(upd,3,y);
-
- /* It might still become a "gx_no_color_value" due to truncation, thus: */
-
- if(rv == gx_no_color_index) rv ^= 1;
- }
-
-
- #if UPD_MESSAGES & UPD_M_MAPCALLS
- fprintf(stderr,
- "cmyk_kcolor: (%5.1f,%5.1f,%5.1f,%5.1f) : (%5.1f,%5.1f,%5.1f,%5.1f) : 0x%0*lx\n",
- 255.0 * (double) c / (double) gx_max_color_value,
- 255.0 * (double) m / (double) gx_max_color_value,
- 255.0 * (double) y / (double) gx_max_color_value,
- 255.0 * (double) k / (double) gx_max_color_value,
- 255.0 * (double) ((rv >> upd->cmap[1].bitshf) & upd->cmap[1].bitmsk)
- / (double) upd->cmap[1].bitmsk,
- 255.0 * (double) ((rv >> upd->cmap[2].bitshf) & upd->cmap[2].bitmsk)
- / (double) upd->cmap[2].bitmsk,
- 255.0 * (double) ((rv >> upd->cmap[3].bitshf) & upd->cmap[3].bitmsk)
- / (double) upd->cmap[3].bitmsk,
- 255.0 * (double) ((rv >> upd->cmap[0].bitshf) & upd->cmap[0].bitmsk)
- / (double) upd->cmap[0].bitmsk,
- (pdev->color_info.depth + 3)>>2,rv);
- #endif
-
- return rv;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_kcolor_rgb: Stored CMY+generated K back to a RGB */
- /* ------------------------------------------------------------------- */
-
- private int
- upd_kcolor_rgb(gx_device *pdev, gx_color_index color, gx_color_value prgb[3])
- {
- const upd_p upd = ((upd_device *)pdev)->upd;
- gx_color_value c,m,y,k;
-
- /*
- * Expand to the Component-Values
- */
- k = upd_expand(upd,0,color);
- c = upd_expand(upd,1,color);
- m = upd_expand(upd,2,color);
- y = upd_expand(upd,3,color);
-
- /*
- * Check for plain Gray-Values
- */
- if(!(c | m | y )) {
-
- prgb[2] = prgb[1] = prgb[0] = gx_max_color_value - k;
-
- } else {
- prgb[0] = gx_max_color_value - c;
- prgb[1] = gx_max_color_value - m;
- prgb[2] = gx_max_color_value - y;
- }
-
- #if UPD_MESSAGES & UPD_M_MAPCALLS
- fprintf(stderr,
- "kcolor_rgb: 0x%0*lx -> (%5.1f,%5.1f,%5.1f,%5.1f) -> (%5.1f,%5.1f,%5.1f,%5.1f) -> (%5.1f,%5.1f,%5.1f)\n",
- (pdev->color_info.depth + 3)>>2,color,
- 255.0 * (double) ((color >> upd->cmap[1].bitshf) & upd->cmap[1].bitmsk)
- / (double) upd->cmap[1].bitmsk,
- 255.0 * (double) ((color >> upd->cmap[2].bitshf) & upd->cmap[2].bitmsk)
- / (double) upd->cmap[2].bitmsk,
- 255.0 * (double) ((color >> upd->cmap[3].bitshf) & upd->cmap[3].bitmsk)
- / (double) upd->cmap[3].bitmsk,
- 255.0 * (double) ((color >> upd->cmap[0].bitshf) & upd->cmap[0].bitmsk)
- / (double) upd->cmap[0].bitmsk,
- 255.0 * (double) c / (double) gx_max_color_value,
- 255.0 * (double) m / (double) gx_max_color_value,
- 255.0 * (double) y / (double) gx_max_color_value,
- 255.0 * (double) k / (double) gx_max_color_value,
- 255.0 * (double) prgb[0] / (double) gx_max_color_value,
- 255.0 * (double) prgb[1] / (double) gx_max_color_value,
- 255.0 * (double) prgb[2] / (double) gx_max_color_value);
- #endif
-
- return 0;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_rgb_ovcolor: Create an KCMY-Index from RGB */
- /* ------------------------------------------------------------------- */
-
- private gx_color_index
- upd_rgb_ovcolor(gx_device *pdev,
- gx_color_value r, gx_color_value g, gx_color_value b)
- {
- const upd_p upd = ((upd_device *)pdev)->upd;
- gx_color_index rv;
- gx_color_value c,m,y,black;
-
- if((r == g) && (g == b)) {
-
- black = gx_max_color_value - r;
- rv = upd_truncate(upd,0,black);
- c = m = y = 0;
-
- } else {
-
- c = gx_max_color_value - r;
- m = gx_max_color_value - g;
- y = gx_max_color_value - b;
-
- black = c < m ? c : m;
- black = black < y ? black : y;
-
- if(black != gx_max_color_value) {
- float tmp,d;
-
- d = gx_max_color_value - black;
-
- tmp = (float) (c-black) / d;
- if( 0.0 > tmp) tmp = 0.0;
- else if( 1.0 < tmp) tmp = 1.0;
- c = tmp * gx_max_color_value + 0.499;
-
- tmp = (float) (m-black) / d;
- if( 0.0 > tmp) tmp = 0.0;
- else if( 1.0 < tmp) tmp = 1.0;
- m = tmp * gx_max_color_value + 0.499;
-
- tmp = (float) (y-black) / d;
- if( 0.0 > tmp) tmp = 0.0;
- else if( 1.0 < tmp) tmp = 1.0;
- y = tmp * gx_max_color_value + 0.499;
-
- } else {
-
- c = m = y = gx_max_color_value;
-
- }
-
- rv = upd_truncate(upd,0,black) | upd_truncate(upd,1,c) |
- upd_truncate(upd,2,m) | upd_truncate(upd,3,y);
-
- /* It might still become a "gx_no_color_value" due to truncation, thus: */
-
- if(rv == gx_no_color_index) rv ^= 1;
- }
-
- #if UPD_MESSAGES & UPD_M_MAPCALLS
- fprintf(stderr,
- "rgb_ovcolor: (%5.1f,%5.1f,%5.1f) : (%5.1f,%5.1f,%5.1f,%5.1f) : 0x%0*lx\n",
- 255.0 * (double) r / (double) gx_max_color_value,
- 255.0 * (double) g / (double) gx_max_color_value,
- 255.0 * (double) b / (double) gx_max_color_value,
- 255.0 * (double) ((rv >> upd->cmap[1].bitshf) & upd->cmap[1].bitmsk)
- / (double) upd->cmap[1].bitmsk,
- 255.0 * (double) ((rv >> upd->cmap[2].bitshf) & upd->cmap[2].bitmsk)
- / (double) upd->cmap[2].bitmsk,
- 255.0 * (double) ((rv >> upd->cmap[3].bitshf) & upd->cmap[3].bitmsk)
- / (double) upd->cmap[3].bitmsk,
- 255.0 * (double) ((rv >> upd->cmap[0].bitshf) & upd->cmap[0].bitmsk)
- / (double) upd->cmap[0].bitmsk,
- (pdev->color_info.depth + 3)>>2,rv);
- #endif
-
- return rv;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_rgb_novcolor: Create an KCMY-Index from RGB */
- /* ------------------------------------------------------------------- */
-
- private gx_color_index
- upd_rgb_novcolor(gx_device *pdev,
- gx_color_value r, gx_color_value g, gx_color_value b)
- {
- const upd_p upd = ((upd_device *)pdev)->upd;
- gx_color_index rv;
- gx_color_value c,m,y,black;
-
- if((r == g) && (g == b)) {
-
- black = gx_max_color_value - r;
- rv = upd_truncate(upd,0,black);
- c = m = y = 0;
-
- } else {
-
- c = gx_max_color_value - r;
- m = gx_max_color_value - g;
- y = gx_max_color_value - b;
-
- black = c < m ? c : m;
- black = black < y ? black : y;
- c = c - black;
- m = m - black;
- y = y - black;
-
- rv = upd_truncate(upd,0,black) | upd_truncate(upd,1,c) |
- upd_truncate(upd,2,m) | upd_truncate(upd,3,y);
-
- /* It might still become a "gx_no_color_value" due to truncation, thus: */
-
- if(rv == gx_no_color_index) rv ^= 1;
- }
-
- #if UPD_MESSAGES & UPD_M_MAPCALLS
- fprintf(stderr,
- "rgb_ovcolor: (%5.1f,%5.1f,%5.1f) : (%5.1f,%5.1f,%5.1f,%5.1f) : 0x%0*lx\n",
- 255.0 * (double) r / (double) gx_max_color_value,
- 255.0 * (double) g / (double) gx_max_color_value,
- 255.0 * (double) b / (double) gx_max_color_value,
- 255.0 * (double) ((rv >> upd->cmap[1].bitshf) & upd->cmap[1].bitmsk)
- / (double) upd->cmap[1].bitmsk,
- 255.0 * (double) ((rv >> upd->cmap[2].bitshf) & upd->cmap[2].bitmsk)
- / (double) upd->cmap[2].bitmsk,
- 255.0 * (double) ((rv >> upd->cmap[3].bitshf) & upd->cmap[3].bitmsk)
- / (double) upd->cmap[3].bitmsk,
- 255.0 * (double) ((rv >> upd->cmap[0].bitshf) & upd->cmap[0].bitmsk)
- / (double) upd->cmap[0].bitmsk,
- (pdev->color_info.depth + 3)>>2,rv);
- #endif
-
- return rv;
- }
-
- /* ------------------------------------------------------------------- */
- /* NOTE: Beyond this point only "uniprint"-special-items. */
- /* ------------------------------------------------------------------- */
-
- /* ------------------------------------------------------------------- */
- /* Return the gx_color_value for a given component */
- /* ------------------------------------------------------------------- */
-
- private gx_color_value
- upd_expand(upd_pc upd,int i,uint32 ci)
- {
- const updcmap_pc cmap = upd->cmap + i; /* Writing-Shortcut */
-
- ci = (ci >> cmap->bitshf) & cmap->bitmsk; /* Extract the component */
- if(!cmap->rise) ci = cmap->bitmsk - ci; /* Invert, if necessary */
- /* no Truncation/Expansion on full range */
- if(gx_color_value_bits > cmap->bits) return cmap->code[ci];
- else return (gx_color_value) ci;
- }
- /* That's simple, isn't it? */
-
- /* ------------------------------------------------------------------- */
- /* Truncate a gx_color_value to the desired number of bits. */
- /* ------------------------------------------------------------------- */
-
- private uint32
- upd_truncate(upd_pc upd,int i,gx_color_value v) {
- const updcmap_pc cmap = upd->cmap + i;
- int32 s; /* step size */
- gx_color_value *p; /* value-pointer */
-
- if(0 == cmap->bits) { /* trivial case */
-
- v = 0;
-
- } else if(gx_color_value_bits > cmap->bits) { /* really truncate ? */
-
- p = cmap->code + ((cmap->bitmsk + 1) >> 1);
- s = ((cmap->bitmsk + 1) >> 2);
- /*
- * Perform search in monotonic code-array
- */
- while(s > 0) {
- if(v > *p) { /* we're below */
- p += s;
- } else if(v < p[-1]) { /* we're ahead for sure */
- p -= s;
- } else {
- /* years ago, i knew what this was good for */
- if((v-p[-1]) < (p[0]-v)) p -= 1;
- break;
- }
- s >>= 1;
- }
- if((v-p[-1]) < (p[0]-v)) p -= 1;
- v = p - cmap->code;
- }
-
- if(!cmap->rise) v = cmap->bitmsk - v; /* Again reverse, if necessary */
-
- return ((uint32) v) << cmap->bitshf;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_open_map: install the color-mapping */
- /* ------------------------------------------------------------------- */
-
- private int
- upd_open_map(upd_device *udev)
- {
- const upd_p upd = udev->upd;
- int imap;
-
- /** _always_ initialize crucial Values! */
- for(imap = 0; UPD_CMAP_MAX > imap; ++imap) upd->cmap[imap].code = NULL;
- upd->ncomp = 0;
-
- /** There should not be an error yet */
- if(B_ERROR & upd->flags) imap = 0;
-
- /** Establish the xfer-Indices */
- if(imap) {
- for(imap = 0; UPD_CMAP_MAX > imap; ++imap) {
- upd->cmap[imap].xfer = -1;
- upd->cmap[imap].bits = 0;
- }
- switch(upd->choice[C_MAPPER]) {
- case MAP_GRAY:
- upd->cmap[0].xfer = FA_WXFER;
- break;
- case MAP_RGBW:
- upd->cmap[0].xfer = FA_WXFER;
- upd->cmap[1].xfer = FA_RXFER;
- upd->cmap[2].xfer = FA_GXFER;
- upd->cmap[3].xfer = FA_BXFER;
- break;
- case MAP_RGB:
- upd->cmap[0].xfer = FA_RXFER;
- upd->cmap[1].xfer = FA_GXFER;
- upd->cmap[2].xfer = FA_BXFER;
- break;
- case MAP_CMYK:
- upd->cmap[0].xfer = FA_KXFER;
- upd->cmap[1].xfer = FA_CXFER;
- upd->cmap[2].xfer = FA_MXFER;
- upd->cmap[3].xfer = FA_YXFER;
- break;
- case MAP_CMYKGEN:
- upd->cmap[0].xfer = FA_KXFER;
- upd->cmap[1].xfer = FA_CXFER;
- upd->cmap[2].xfer = FA_MXFER;
- upd->cmap[3].xfer = FA_YXFER;
- break;
- case MAP_RGBOV:
- upd->cmap[0].xfer = FA_KXFER;
- upd->cmap[1].xfer = FA_CXFER;
- upd->cmap[2].xfer = FA_MXFER;
- upd->cmap[3].xfer = FA_YXFER;
- break;
- case MAP_RGBNOV:
- upd->cmap[0].xfer = FA_KXFER;
- upd->cmap[1].xfer = FA_CXFER;
- upd->cmap[2].xfer = FA_MXFER;
- upd->cmap[3].xfer = FA_YXFER;
- break;
- default:
- #if UPD_MESSAGES & UPD_M_WARNING
- if(upd_choice[C_MAPPER][0])
- fprintf(stderr,
- "upd_open_map: unsupported %s=%d\n",
- upd_choice[C_MAPPER][0],upd->choice[C_MAPPER]);
- else
- fprintf(stderr,
- "upd_open_map: unsupported choce[%d]=%d\n",
- C_MAPPER,upd->choice[C_MAPPER]);
- #endif
- imap = 0;
- break;
- }
- }
-
-
- /** The bit number sould be positive & fit into the storage */
-
- if(imap) { /* Check number of Bits & Shifts */
-
- #if UPD_MESSAGES & UPD_M_WARNING
- uint32 used = 0,bitmsk;
- #endif
- bool success = true;
-
- for(imap = 0; UPD_CMAP_MAX > imap; ++imap) {
- if(0 > upd->cmap[imap].xfer) continue;
-
- if((0 > upd->int_a[IA_COMPBITS].data[imap]) ||
- (gx_color_value_bits < upd->int_a[IA_COMPBITS].data[imap]) ||
- (0 > upd->int_a[IA_COMPSHIFT].data[imap]) ||
- (upd->int_a[IA_COMPBITS].data[imap] >
- (udev->color_info.depth - upd->int_a[IA_COMPSHIFT].data[imap]))) {
- #if UPD_MESSAGES & UPD_M_WARNING
- fprintf(stderr,
- "upd_open_map: %d Bits << %d is illegal for %d. Component\n",
- upd->int_a[IA_COMPBITS].data[imap],
- upd->int_a[IA_COMPSHIFT].data[imap],imap+1);
- #endif
-
- success = false;
-
-
- } else {
-
- int n;
- const float *now;
- float last;
-
- if((NULL == upd->float_a[upd->cmap[imap].xfer].data) ||
- (2 > upd->float_a[upd->cmap[imap].xfer].size) ) {
- float *fp;
- UPD_MM_DEL_PARAM(upd->float_a[upd->cmap[imap].xfer]);
- UPD_MM_GET_ARRAY(fp,2);
- fp[0] = 0.0;
- fp[1] = 1.0;
- upd->float_a[upd->cmap[imap].xfer].data = fp;
- upd->float_a[upd->cmap[imap].xfer].size = 2;
- }
- n = upd->float_a[upd->cmap[imap].xfer].size-1;
- now = upd->float_a[upd->cmap[imap].xfer].data;
- last = now[n];
-
- if( *now < last) { /* Rising */
- last = *now++;
- while(n--) {
- if(last >= *now) break;
- last = *now++;
- }
- } else if(*now > last) { /* Falling */
- last = *now++;
- while(n--) {
- if(last <= *now) break;
- last = *now++;
- }
- } /* Monotony-check */
-
- if(0 <= n) {
- #if UPD_MESSAGES & UPD_M_WARNING
- fprintf(stderr,
- "upd_open_map: %d. Component has non monoton Xfer\n",imap+1);
- #endif
- success = false;
-
- } else {
-
- #if UPD_MESSAGES & UPD_M_WARNING
-
- bitmsk = ((uint32) 1 << upd->int_a[IA_COMPBITS].data[imap]) -1;
- bitmsk <<= upd->int_a[IA_COMPSHIFT].data[imap];
-
- if(used & bitmsk) fprintf(stderr,
- "upd_open_map: %d. Component overlaps with others\n",imap+1);
-
- used |= bitmsk;
- #endif
- }
- }
- }
-
- if(!success) imap = 0;
-
- } /* Check number of Bits */
-
- /** Do the allocation */
-
- if(imap) {
-
- for(imap = 0; UPD_CMAP_MAX > imap; ++imap) {
- if(0 > upd->cmap[imap].xfer) continue;
-
- upd->cmap[imap].bits = upd->int_a[IA_COMPBITS].data[imap];
- upd->cmap[imap].bitshf = upd->int_a[IA_COMPSHIFT].data[imap];
- upd->cmap[imap].bitmsk = 1;
- upd->cmap[imap].bitmsk <<= upd->cmap[imap].bits;
- upd->cmap[imap].bitmsk -= 1;
- upd->cmap[imap].rise =
- upd->float_a[upd->cmap[imap].xfer].data[0] <
- upd->float_a[upd->cmap[imap].xfer].data[
- upd->float_a[upd->cmap[imap].xfer].size-1] ?
- true : false;
- upd->cmap[imap].code = gs_malloc(upd->cmap[imap].bitmsk+1,
- sizeof(upd->cmap[imap].code[0]),"upd/code");
- if(!upd->cmap[imap].code) break;
- }
-
- if(UPD_CMAP_MAX > imap) {
-
- imap = 0;
-
- #if UPD_MESSAGES & UPD_M_ERROR
- fprintf(stderr,"upd_open_map: could not allocate code-arrays\n");
- # endif
-
- }
- }
-
- /** then fill the code-arrays */
-
- if(imap) {
- /*
- * Try making things easier: (than with stcolor)
- * normalize values to 0.0/1.0-Range
- * X-Axis: Color-Values (implied)
- * Y-Values: Indices (given)
- */
-
- for(imap = 0; UPD_CMAP_MAX > imap; ++imap) {
-
- const updcmap_p cmap = upd->cmap + imap;
- uint32 ly,iy;
- float ystep,xstep,fx,fy;
-
- /* Variables & Macro for Range-Normalization */
- double offset,scale;
- #define XFVAL(I) ((upd->float_a[cmap->xfer].data[I]-offset)*scale)
-
- if(0 > cmap->xfer) continue;
-
- cmap->code[cmap->bitmsk] = gx_max_color_value;
-
- if(!cmap->bits) continue;
-
- offset = upd->float_a[cmap->xfer].data[0];
- if( 0.0 > offset) offset = 0.0;
- else if(1.0 < offset) offset = 1.0;
-
- scale = upd->float_a[cmap->xfer].data[upd->float_a[cmap->xfer].size-1];
- if( 0.0 > scale ) scale = 0.0;
- else if(1.0 < scale ) scale = 1.0;
-
- if(scale != offset) scale = 1.0 / (scale - offset);
- else scale = 0.0;
-
- /* interpolate */
- ystep = (float) 1.0 / (float) cmap->bitmsk;
- xstep = (float) 1.0 / (float)(upd->float_a[cmap->xfer].size - 1);
-
- iy = 0;
- for(ly = 0; ly <= cmap->bitmsk; ++ly) {
-
- fy = ystep * ly; /* Target-Value */
-
- while(((iy+2) < upd->float_a[cmap->xfer].size) &&
- (fy > XFVAL(iy+1))) ++iy;
-
- fx = iy + (fy - XFVAL(iy))/(XFVAL(iy+1) - XFVAL(iy));
-
- fx *= xstep * gx_max_color_value;
-
- fx = fx < 0.0 ? 0.0 :
- (fx > gx_max_color_value ? gx_max_color_value : fx);
-
- cmap->code[ly] = fx;
- if((fx - cmap->code[ly]) >= 0.5) cmap->code[ly] += 1;
- }
-
- #undef XFVAL
-
- }
- }
-
- /** If we're ok, massage upd->ncomp */
-
- if(imap) {
- switch(upd->choice[C_MAPPER]) {
- case MAP_GRAY:
- if(1 > imap) imap = 0;
- upd->ncomp = 1;
- break;
- case MAP_RGBW: /* RGB->RGBW */
- if(4 > imap) imap = 0;
- upd->ncomp = 4;
- break;
- case MAP_RGB: /* Plain RGB */
- if(3 > imap) imap = 0;
- upd->ncomp = 3;
- break;
- case MAP_CMYK: /* Plain KCMY */
- if(4 > imap) imap = 0;
- upd->ncomp = 4;
- break;
- case MAP_CMYKGEN: /* KCMY with black-generation */
- if(4 > imap) imap = 0;
- upd->ncomp = 4;
- break;
- case MAP_RGBOV: /* RGB->KCMY with black-generation */
- if(4 > imap) imap = 0;
- upd->ncomp = 4;
- break;
- case MAP_RGBNOV: /* RGB->KCMY with black-generation */
- if(4 > imap) imap = 0;
- upd->ncomp = 4;
- break;
-
- default:
- imap = 0;
- #if UPD_MESSAGES & UPD_M_WARNING
- fprintf(stderr,
- "upd_open: Mapping %d unknown\n",upd->choice[C_MAPPER]);
- #endif
-
- break;
- }
- }
-
-
- /** If unsuccesful, install the default routines */
-
- if(!imap) {
- upd_close_map(udev);
- } else {
- upd->flags |= B_MAP;
- upd_procs_map(udev);
- }
-
- return imap ? 1 : -1;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_procs_map: (de-) install the color-mapping-procedures */
- /* ------------------------------------------------------------------- */
-
- private int
- upd_procs_map(upd_device *udev)
- {
- int imap;
-
- if( udev->upd &&
- (udev->upd->flags & B_MAP)) imap = udev->upd->choice[C_MAPPER];
- else imap = 0;
-
- switch(imap) {
- case MAP_GRAY: /* Grayscale -> Grayscale */
- set_dev_proc(udev,map_rgb_color, upd_rgb_1color);
- set_dev_proc(udev,map_cmyk_color,gx_default_map_cmyk_color);
- set_dev_proc(udev,map_color_rgb, upd_1color_rgb);
- break;
- case MAP_RGBW: /* RGB->RGBW */
- set_dev_proc(udev,map_rgb_color, upd_rgb_4color);
- set_dev_proc(udev,map_cmyk_color,gx_default_map_cmyk_color);
- set_dev_proc(udev,map_color_rgb, upd_4color_rgb);
- break;
- case MAP_RGB: /* Plain RGB */
- set_dev_proc(udev,map_rgb_color, upd_rgb_3color);
- set_dev_proc(udev,map_cmyk_color,gx_default_map_cmyk_color);
- set_dev_proc(udev,map_color_rgb, upd_3color_rgb);
- break;
- case MAP_CMYK: /* Plain KCMY */
- set_dev_proc(udev,map_rgb_color, gx_default_map_rgb_color);
- set_dev_proc(udev,map_cmyk_color,upd_cmyk_icolor);
- set_dev_proc(udev,map_color_rgb, upd_icolor_rgb);
- break;
- case MAP_CMYKGEN: /* KCMY with black-generation */
- set_dev_proc(udev,map_rgb_color, gx_default_map_rgb_color);
- set_dev_proc(udev,map_cmyk_color,upd_cmyk_kcolor);
- set_dev_proc(udev,map_color_rgb, upd_kcolor_rgb);
- break;
- case MAP_RGBOV: /* RGB -> KCMY with BG and UCR for CMYK-Output */
- set_dev_proc(udev,map_rgb_color, upd_rgb_ovcolor);
- set_dev_proc(udev,map_cmyk_color,gx_default_map_cmyk_color);
- set_dev_proc(udev,map_color_rgb, upd_ovcolor_rgb);
- break;
- case MAP_RGBNOV: /* RGB -> KCMY with BG and UCR for CMY+K-Output */
- set_dev_proc(udev,map_rgb_color, upd_rgb_novcolor);
- set_dev_proc(udev,map_cmyk_color,gx_default_map_cmyk_color);
- set_dev_proc(udev,map_color_rgb, upd_novcolor_rgb);
- break;
-
- default:
- set_dev_proc(udev,map_rgb_color, gx_default_map_rgb_color);
- set_dev_proc(udev,map_cmyk_color,gx_default_map_cmyk_color);
- set_dev_proc(udev,map_color_rgb, gx_default_map_color_rgb);
- break;
- }
- return 0;
-
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_close_map: remove color mapping */
- /* ------------------------------------------------------------------- */
-
- private int
- upd_close_map(upd_device *udev)
- {
- const upd_p upd = udev->upd;
- int imap;
-
- if(upd) {
-
- for(imap = 0; UPD_CMAP_MAX > imap; ++imap) {
-
- if(upd->cmap[imap].code)
- gs_free(upd->cmap[imap].code,sizeof(upd->cmap[imap].code[0]),
- upd->cmap[imap].bitmsk+1,"upd/code");
- upd->cmap[imap].code = NULL;
-
- upd->cmap[imap].bitmsk = 0;
- upd->cmap[imap].bitshf = 0;
- upd->cmap[imap].bits = 0;
- upd->cmap[imap].rise = false;
- }
- upd->flags &= ~B_MAP;
- }
-
- upd_procs_map(udev);
-
- return 0;
- }
-
- /* ------------------------------------------------------------------- */
- /* Functions for the rendering of data */
- /* ------------------------------------------------------------------- */
-
- /**
- Inside the main-upd-type are a "valbuf" and some unidentified
- pointers. This stuff is used in conjunction with the rendering,
- which is the process of converting gx_color_indices into something
- suitable for the device.
-
- */
-
- /* ------------------------------------------------------------------- */
- /* upd_open_render: Initialize rendering */
- /* ------------------------------------------------------------------- */
-
- private void
- upd_open_render(upd_device *udev)
- {
- const upd_p upd = udev->upd;
- int icomp;
-
- /** Reset everything related to rendering */
- upd->flags &= ~B_RENDER;
- upd->valbuf = NULL;
- upd->nvalbuf = 0;
- upd->render = NULL;
- upd->start_render = NULL;
- for(icomp = 0; UPD_VALPTR_MAX > icomp; ++icomp) upd->valptr[icomp] = NULL;
-
- if( (B_BUF | B_MAP) ==
- ((B_BUF | B_MAP | B_ERROR) & upd->flags)) {
-
- /** Establish the renderingwidth in upd */
- upd->rwidth = upd->gswidth;
- if((0 < upd->ints[I_PWIDTH]) &&
- (upd->gswidth > upd->ints[I_PWIDTH]) )
- upd->rwidth = upd->ints[I_PWIDTH];
-
- /** Call the Render-specific Open-Function */
- switch(upd->choice[C_RENDER]) {
- case RND_FSCOMP:
- upd_open_fscomp(udev);
- break;
- case RND_FSCMYK:
- upd_open_fscmyk(udev);
- break;
- case RND_FSCMY_K:
- upd_open_fscmy_k(udev);
- break;
- default:
- #if UPD_MESSAGES & UPD_M_WARNING
- fprintf(stderr,"upd_open_render: Unknown rendering type %d\n",
- upd->choice[C_RENDER]);
- #endif
- break;
- }
- }
-
- if(B_RENDER != ((B_ERROR | B_RENDER) & upd->flags))
- upd_close_render(udev);
-
- return;
- }
-
-
- /* ------------------------------------------------------------------- */
- /* upd_close_render: Deinitialize rendering */
- /* ------------------------------------------------------------------- */
-
- private void
- upd_close_render(upd_device *udev)
- {
- const upd_p upd = udev->upd;
-
- if(upd) {
- int icomp;
-
- if((upd->render == upd_fscomp) ||
- (upd->render == upd_fscmyk) ) upd_close_fscomp(udev);
-
- if((0 < upd->nvalbuf) && upd->valbuf)
- gs_free(upd->valbuf,upd->nvalbuf,sizeof(upd->valbuf[0]),"upd/valbuf");
- upd->valbuf = NULL;
- upd->nvalbuf = 0;
-
- upd->flags &= ~B_RENDER;
- upd->render = NULL;
- upd->start_render = NULL;
- for(icomp = 0; UPD_VALPTR_MAX > icomp; ++icomp) upd->valptr[icomp] = NULL;
-
- }
- return;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_open_fscomp: Initialize Component-Floyd-Steinberg */
- /* ------------------------------------------------------------------- */
- #if UPD_MESSAGES & UPD_M_FSBUF
- static int32 fs_emin[UPD_VALPTR_MAX],fs_emax[UPD_VALPTR_MAX];
- #endif
- private void
- upd_open_fscomp(upd_device *udev)
- {
- const upd_p upd = udev->upd;
- int icomp,order[UPD_CMAP_MAX];
-
- #if UPD_MESSAGES & UPD_M_FSBUF
- for(icomp = 0; UPD_VALPTR_MAX < icomp; ++icomp)
- fs_emin[icomp] = fs_emax[icomp] = 0;
- #endif
-
- icomp = upd->ncomp;
-
- if((0 >= icomp) ||
- (UPD_VALPTR_MAX < icomp) ||
- (UPD_CMAP_MAX < icomp) ) icomp = 0;
-
- /**
- This Version of the FS-algorithm works on the mapped components, but
- the printing-order might be different from the order dictated by the
- mapping-routines. The optional COMPORDER-Array is used for that. The
- initial test checks it's integrity.
- */
- if(icomp) {
- if(upd->ncomp <= upd->int_a[IA_COMPORDER].size) { /* Reordering */
- bool success = true;
- for(icomp = 0; upd->ncomp > icomp; ++icomp) {
- order[icomp] = upd->int_a[IA_COMPORDER].data[icomp];
- if((0 > order[icomp]) ||
- (UPD_CMAP_MAX <= order[icomp]) ) {
- success = false;
- #if UPD_MESSAGES & UPD_M_WARNING
- fprintf(stderr,
- "upd_open_fscomp: %d is illegal component-index\n",
- order[icomp]);
- #endif
- }
- }
- if(!success) icomp = 0;
- } else { /* Default-Ordering */
- for(icomp = 0; UPD_CMAP_MAX > icomp; ++icomp) order[icomp] = icomp;
- } /* Ordering defined */
- }
-
- /**
- If anything was ok. up to now, memory get's allocated.
- */
- if(icomp) {
-
- for(icomp = 0; upd->ncomp > icomp; ++icomp) {
- upd->valptr[icomp] = gs_malloc(1,sizeof(updcomp_t),"upd/fscomp");
- if(NULL == upd->valptr[icomp]) {
- #if UPD_MESSAGES & UPD_M_ERROR
- fprintf(stderr,
- "upd_open_fscomp: could not allocate %d. updcomp\n",
- icomp);
- #endif
- icomp = 0;
- break;
- }
- }
- }
-
- if(icomp) {
- uint need;
-
- need = (2 + upd->rwidth) * upd->ncomp;
- upd->valbuf = gs_malloc(need,sizeof(upd->valbuf[0]),"upd/valbuf");
-
- if(upd->valbuf) {
- upd->nvalbuf = need;
- memset(upd->valbuf,0,need*sizeof(upd->valbuf[0]));
- } else {
- #if UPD_MESSAGES & UPD_M_ERROR
- fprintf(stderr,
- "upd_open_fscomp: could not allocate %u words for valbuf\n",need);
- #endif
- icomp = 0;
- }
- }
-
- /* Still happy? then compute component-values */
-
- if(icomp) {
- for(icomp = 0; upd->ncomp > icomp; ++icomp) {
-
- const updcomp_p comp = upd->valptr[icomp];
- const int32 nsteps = upd->cmap[order[icomp]].bitmsk;
- float ymin,ymax;
- int32 highmod,highval;
- int i;
-
- comp->threshold = nsteps;
- comp->spotsize = nsteps;
- comp->offset = 0;
- comp->scale = 1;
- comp->cmap = order[icomp];
- upd->cmap[comp->cmap].comp = icomp;
- comp->bits = upd->cmap[comp->cmap].bits;
- comp->bitshf = upd->cmap[comp->cmap].bitshf;
- comp->bitmsk = upd->cmap[comp->cmap].bitmsk;
-
- if(!nsteps) continue; /* A 0-Bit component is legal! */
-
- if(upd->cmap[comp->cmap].rise) {
- ymin = upd->float_a[upd->cmap[comp->cmap].xfer].data[0];
- ymax = upd->float_a[upd->cmap[comp->cmap].xfer].data[
- upd->float_a[upd->cmap[comp->cmap].xfer].size-1];
- } else {
- ymax = upd->float_a[upd->cmap[comp->cmap].xfer].data[0];
- ymin = upd->float_a[upd->cmap[comp->cmap].xfer].data[
- upd->float_a[upd->cmap[comp->cmap].xfer].size-1];
- }
-
- if(0.0 > ymin) {
- ymin = 0.0;
- if(0.0 > ymax) ymax = 1.0 / (float) (nsteps+1);
- }
- if(1.0 < ymax) ymax = 1.0;
-
- comp->spotsize = ((int32) 1 << 28) - 1;
-
- for(i = 0; i < 32; ++i) { /* Attempt Ideal */
-
- highval = (ymax-ymin) * (double) comp->spotsize + 0.5;
-
- if(!(highmod = highval % nsteps)) break; /* Gotcha */
-
- highval += nsteps - highmod;
- comp->spotsize = (double) highval / (ymax-ymin) + 0.5;
-
- if(!(comp->spotsize % 2)) comp->spotsize++;
-
- } /* Attempt Ideal */
-
- comp->offset = ymin * (double) comp->spotsize + (double) 0.5;
- comp->scale = highval / nsteps;
- comp->threshold = comp->spotsize / 2;
-
- #if UPD_MESSAGES & UPD_M_SETUP
- fprintf(stderr,
- "Values for %d. Component after %d iterations\n",comp->cmap+1,i);
- fprintf(stderr,
- "steps: %10ld, Bits: %d\n",(long) comp->bitmsk,comp->bits);
- fprintf(stderr,
- "xfer: %10d Points, %s\n",
- upd->float_a[upd->cmap[comp->cmap].xfer].size,
- upd->cmap[comp->cmap].rise ? "rising" : "falling");
- fprintf(stderr,
- "offset: %10d 0x%08x\n",comp->offset,comp->offset);
- fprintf(stderr,
- "scale: %10d 0x%08x\n",comp->scale,comp->scale);
- fprintf(stderr,
- "threshold: %10d 0x%08x\n",comp->threshold,comp->threshold);
- fprintf(stderr,
- "spotsize: %10d 0x%08x\n",comp->spotsize,comp->spotsize);
- #endif
- }
- }
- /**
- Optional Random Initialization of the value-Buffer
- */
- if(icomp && !(B_FSZERO & upd->flags)) {
- for(icomp = 0; icomp < upd->ncomp; ++icomp) {
- const updcomp_p comp = upd->valptr[icomp];
- int i;
- int32 lv = INT32_MAX, hv = INT32_MIN, v;
- float scale;
- for(i = icomp; i < upd->nvalbuf; i += upd->ncomp) {
- v = rand();
- if(lv > v) lv = v;
- if(hv < v) hv = v;
- upd->valbuf[i] = v;
- }
- scale = (float) comp->threshold / (float) (hv - lv);
- lv += comp->threshold / (2*scale);
- for(i = icomp; i < upd->nvalbuf; i += upd->ncomp)
- upd->valbuf[i] = scale * (upd->valbuf[i] - lv);
- }
- }
-
- /**
- The render-Routine acts as an indicator, which render-close is to use!
- */
- upd->render = upd_fscomp;
-
- if(icomp) upd->flags |= B_RENDER;
- else upd->flags &= ~B_RENDER;
-
- return;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_close_fscomp: Deinitialize Component-Floyd-Steinberg */
- /* ------------------------------------------------------------------- */
-
- private void
- upd_close_fscomp(upd_device *udev)
- {
- const upd_p upd = udev->upd;
- int icomp;
-
- #if UPD_MESSAGES & UPD_M_FSBUF
- if(upd && (upd->flags & B_RENDER)) {
-
- for(icomp = 0; icomp < upd->ncomp; ++icomp) {
- updcomp_p comp = upd->valptr[icomp];
- if(!comp) continue;
- if(!comp->spotsize) continue;
- fprintf(stderr,"%d. Component: %6.3f <= error <= %6.3f\n",
- icomp+1,
- (double) fs_emin[icomp] / (double) comp->spotsize,
- (double) fs_emax[icomp] / (double) comp->spotsize);
- }
-
- }
- #endif
-
- for(icomp = 0; UPD_VALPTR_MAX > icomp; ++icomp) {
- if(!upd->valptr[icomp]) continue;
- gs_free(upd->valptr[icomp],1,sizeof(updcomp_t),"upd/fscomp");
- upd->valptr[icomp] = NULL;
- }
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_fscomp: Apply Floyd-Steinberg to each component */
- /* ------------------------------------------------------------------- */
-
- /**
- With UPD_M_FSBUF Max/Min-Values for the Errors are computed
- */
- #if UPD_MESSAGES & UPD_M_FSBUF
- #define FS_M_ROWERR(I) \
- if(fs_emin[I] > rowerr[I]) fs_emin[I] = rowerr[I]; \
- if(fs_emax[I] < rowerr[I]) fs_emax[I] = rowerr[I];
- #else
- #define FS_M_ROWERR(I) ;
- #endif
- /**
- FS_GOAL computes the desired Pixel-Value
- */
- #define FS_GOAL(Raw,I) \
- pixel[I] = (int32)(Raw) * comp[I]->scale + comp[I]->offset \
- + rowerr[I] + colerr[I] - ((colerr[I]+4)>>3); \
- if( pixel[I] < 0) pixel[I] = 0; \
- else if( pixel[I] > comp[I]->spotsize) pixel[I] = comp[I]->spotsize;
-
- /*
- * Distribute the error: prev now next
- * X 7/16 Y
- * 3/16 5/16 1/16 Y+1
- */
- #define FS_DIST(I) \
- if(!first) rowerr[I-dir] += ((3*pixel[I]+8)>>4); /* 3/16 */ \
- rowerr[I ] = ((5*pixel[I] )>>4) /* 5/16 */ \
- + (( colerr[I]+4)>>3); /* 1/16 (rest) */ \
- colerr[I ] = pixel[I] /* 8/16 (neu) */ \
- - ((5*pixel[I] )>>4) \
- - ((3*pixel[I]+8)>>4);
- /**
- S_FSTEP adjusts the Indices (rowerr, bit and iword)
- */
- #define S_FSTEP \
- rowerr += dir; \
- first = false; \
- if(0 > dir) { /* Reverse */ \
- if(!(bit <<= 1)) { bit = 0x01; ibyte--; }\
- } else { /* Forward */ \
- if(!(bit >>= 1)) { bit = 0x80; ibyte++; }\
- } /* Inc/Dec Bit */
-
- private int
- upd_fscomp(upd_p upd)
- {
- const updscan_p scan = upd->scnbuf[upd->yscnbuf & upd->scnmsk];
- const updcomp_p *comp = (updcomp_p *) upd->valptr;
- int32 *const pixel = upd->valbuf;
- int32 *const colerr = pixel + upd->ncomp;
- int32 *rowerr = colerr + upd->ncomp;
- int pwidth = upd->rwidth;
- int dir,ibyte;
- int iblack,bblack,pxlset;
- uint32 ci;
- byte bit;
- bool first = true;
- /*
- * Erase the component-Data
- */
- switch(upd->ncomp) {
- case 4: memset(scan[3].bytes,0,upd->nbytes);
- case 3: memset(scan[2].bytes,0,upd->nbytes);
- memset(scan[1].bytes,0,upd->nbytes);
- default: memset(scan[0].bytes,0,upd->nbytes);
- }
- /*
- * determine the direction
- */
- if(upd->flags & B_REVDIR) { /* This one reverse */
-
- if(upd->flags & B_YFLIP) {
- dir = upd->ncomp;
- bit = 0x80;
- ibyte = 0;
- } else {
- dir = -upd->ncomp;
- rowerr += upd->ncomp * (pwidth-1);
- bit = 0x80 >> ((pwidth-1) & 7);
- ibyte = (pwidth-1) >> 3;
- }
-
- if(!(upd->flags & B_FSWHITE)) {
- upd_pxlfwd(upd);
- while((0 < pwidth) && !upd_pxlget(upd)) pwidth--;
- }
-
- upd_pxlrev(upd);
-
- } else { /* This one forward */
-
- if(upd->flags & B_YFLIP) {
- dir = -upd->ncomp;
- rowerr += upd->ncomp * (pwidth-1);
- bit = 0x80 >> ((pwidth-1) & 7);
- ibyte = (pwidth-1) >> 3;
- } else {
- dir = upd->ncomp;
- bit = 0x80;
- ibyte = 0;
- }
-
- if(!(upd->flags & B_FSWHITE)) {
- upd_pxlrev(upd);
- while((0 < pwidth) && !upd_pxlget(upd)) pwidth--;
- }
-
- upd_pxlfwd(upd);
-
- } /* reverse or forward */
- /*
- * Toggle Direction, if not fixed
- */
- if(!(upd->flags & B_FIXDIR)) upd->flags ^= B_REVDIR;
- /*
- * Skip over leading white-space
- */
- if(!(upd->flags & B_FSWHITE)) {
- upd_proc_pxlget((*fun)) = upd->pxlget;
- byte *ptr = upd->pxlptr;
- while((0 < pwidth) && !upd_pxlget(upd)) {
- pwidth--;
- fun = upd->pxlget;
- ptr = upd->pxlptr;
- S_FSTEP
- }
- upd->pxlget = fun;
- upd->pxlptr = ptr;
- }
- /*
- * Set iblack, if black-reduction is active
- */
- iblack = -1;
- bblack = 0;
- if((4 == upd->ncomp) && (B_REDUCEK & upd->flags)) {
- iblack = upd->cmap[0].comp;
- bblack = 1<<iblack;
- }
- /*
- * Process all Pixels
- */
- first = true;
- while(0 < pwidth--) {
- /*
- * Execute FS-Algorithm for each active component
- */
- pxlset = 0;
- ci = upd_pxlget(upd);
- switch(upd->ncomp) {
- case 4: FS_M_ROWERR(3)
- FS_GOAL(comp[3]->bitmsk & (ci >> comp[3]->bitshf),3)
- if(pixel[3] > comp[3]->threshold) { /* "Fire" */
- pixel[3] -= comp[3]->spotsize;
- scan[3].bytes[ibyte] |= bit;
- pxlset |= 8;
- } /* "Fire" */
- FS_DIST(3)
-
- case 3: FS_M_ROWERR(2)
- FS_GOAL(comp[2]->bitmsk & (ci >> comp[2]->bitshf),2)
- if(pixel[2] > comp[2]->threshold) { /* "Fire" */
- pixel[2] -= comp[2]->spotsize;
- scan[2].bytes[ibyte] |= bit;
- pxlset |= 4;
- } /* "Fire" */
- FS_DIST(2)
-
- FS_M_ROWERR(1)
- FS_GOAL(comp[1]->bitmsk & (ci >> comp[1]->bitshf),1)
- if(pixel[1] > comp[1]->threshold) { /* "Fire" */
- pixel[1] -= comp[1]->spotsize;
- scan[1].bytes[ibyte] |= bit;
- pxlset |= 2;
- } /* "Fire" */
- FS_DIST(1)
-
- default: FS_M_ROWERR(0)
- FS_GOAL(comp[0]->bitmsk & (ci >> comp[0]->bitshf),0)
- if(pixel[0] > comp[0]->threshold) { /* "Fire" */
- pixel[0] -= comp[0]->spotsize;
- scan[0].bytes[ibyte] |= bit;
- pxlset |= 1;
- } /* "Fire" */
- FS_DIST(0)
- }
- /*
- * Black-Reduction
- */
- if(bblack) {
- if(pxlset & bblack) pxlset |= 15;
- switch(pxlset) {
- case 0:
- case 1:
- case 2:
- case 4:
- case 8:
- case 3:
- case 5:
- case 9:
- case 6:
- case 10:
- case 12:
- break;
- default:
- scan[0].bytes[ibyte] &= ~bit;
- scan[1].bytes[ibyte] &= ~bit;
- scan[2].bytes[ibyte] &= ~bit;
- scan[3].bytes[ibyte] &= ~bit;
- scan[iblack].bytes[ibyte] |= bit;
- break;
- }
- }
- /*
- * Adjust rowerr, bit & iword, depending on direction
- */
- S_FSTEP
- }
- /*
- * Finally call the limits-Routine
- */
- if(0 < upd->nlimits) upd_limits(upd,true);
- return 0;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_open_fscmyk: Initialize Component-Floyd-Steinberg */
- /* ------------------------------------------------------------------- */
-
- private void
- upd_open_fscmyk(upd_device *udev)
- {
- const upd_p upd = udev->upd;
-
- upd_open_fscomp(udev);
-
- if((B_RENDER & upd->flags) &&
- (4 == upd->ncomp) &&
- (8 <= upd->cmap[0].bits) && (24 == upd->cmap[0].bitshf) &&
- (8 <= upd->cmap[1].bits) && (16 == upd->cmap[1].bitshf) &&
- (8 <= upd->cmap[2].bits) && ( 8 == upd->cmap[2].bitshf) &&
- (8 <= upd->cmap[3].bits) && ( 0 == upd->cmap[3].bitshf) ) {
- upd->render = upd_fscmyk;
- } else {
- upd->flags &= ~B_RENDER;
- }
-
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_fscmyk: 32 Bit, K-CMY-Order Dithering */
- /* ------------------------------------------------------------------- */
-
- private int
- upd_fscmyk(upd_p upd)
- {
- const updscan_p scan = upd->scnbuf[upd->yscnbuf & upd->scnmsk];
- int32 *const pixel = upd->valbuf;
- const updcomp_p *comp = (updcomp_p *) upd->valptr;
- int32 *const colerr = pixel + 4;
- int32 *rowerr = colerr + 4;
- int32 pwidth = upd->rwidth;
- int dir,ibyte;
- byte bit,*data;
- bool first = false;
- /*
- * Erase the component-Data
- */
- memset(scan[0].bytes,0,upd->nbytes);
- memset(scan[1].bytes,0,upd->nbytes);
- memset(scan[2].bytes,0,upd->nbytes);
- memset(scan[3].bytes,0,upd->nbytes);
-
- /*
- * determine the direction
- */
- if(upd->flags & B_REVDIR) { /* This one reverse */
-
- if(!(upd->flags & B_FSWHITE)) {
- data = upd->gsscan;
- while(0 < pwidth && !*(uint32 *)data) pwidth--, data += 4;
- if(0 >= pwidth) {
- if(0 < upd->nlimits) upd_limits(upd,false);
- return 0;
- }
- }
-
- data = upd->gsscan + 4 * (upd->rwidth-1);
-
- } else { /* This one forward */
-
- if(!(upd->flags & B_FSWHITE)) {
- data = upd->gsscan + 4 * (upd->rwidth-1);
- while(0 < pwidth && !*(uint32 *)data) pwidth--, data -= 4;
- if(0 >= pwidth) {
- if(0 < upd->nlimits) upd_limits(upd,false);
- return 0;
- }
- }
-
- data = upd->gsscan;
-
- } /* reverse or forward */
- /*
- * Bits depend on FLIP & Direction
- */
- if(!(B_REVDIR & upd->flags) == !(B_YFLIP & upd->flags)) {
- dir = 4;
- bit = 0x80;
- ibyte = 0;
- } else {
- dir = -4;
- rowerr += 4 * (upd->rwidth-1);
- bit = 0x80 >> ((upd->rwidth-1) & 7);
- ibyte = (upd->rwidth-1) >> 3;
- }
-
- /*
- * Toggle Direction, if not fixed
- */
- if(!(upd->flags & B_FIXDIR)) upd->flags ^= B_REVDIR;
- /*
- * Skip over leading white-space
- */
- if(!(upd->flags & B_FSWHITE)) {
- while(0 < pwidth && !*((uint32 *)data)) {
- pwidth--;
- if(B_YFLIP & upd->flags) data -= dir;
- else data += dir;
- S_FSTEP
- }
- }
- /*
- * Process all Pixels
- */
- first = true;
- while(0 < pwidth--) {
- /*
- * Compute the Black-Value first
- */
- FS_M_ROWERR(upd->cmap[0].comp) FS_GOAL(data[0],upd->cmap[0].comp);
-
- /*
- * Decide wether this is a color value
- */
- if(data[1] || data[2] || data[3]) {
-
- FS_M_ROWERR(upd->cmap[1].comp) FS_GOAL(data[1],upd->cmap[1].comp)
- FS_M_ROWERR(upd->cmap[2].comp) FS_GOAL(data[2],upd->cmap[2].comp)
- FS_M_ROWERR(upd->cmap[3].comp) FS_GOAL(data[3],upd->cmap[3].comp)
- /*
- * if black fires, then all other components fire logically too
- */
- if(pixel[upd->cmap[0].comp] > comp[upd->cmap[0].comp]->threshold) {
-
- pixel[0] -= comp[0]->spotsize;
- pixel[1] -= comp[1]->spotsize;
- pixel[2] -= comp[2]->spotsize;
- pixel[3] -= comp[3]->spotsize;
- scan[upd->cmap[0].comp].bytes[ibyte] |= bit;
-
- /*
- * if black is below threshold, only components with larger data-values
- * are allowed to fire
- */
- } else { /* Restricted firing */
-
- if(( data[0] < data[1]) &&
- (pixel[upd->cmap[1].comp] >
- comp[upd->cmap[1].comp]->threshold)) { /* "Fire" */
- pixel[upd->cmap[1].comp] -= comp[upd->cmap[1].comp]->spotsize;
- scan[upd->cmap[1].comp].bytes[ibyte] |= bit;
- } /* "Fire" */
-
- if(( data[0] < data[2]) &&
- (pixel[upd->cmap[2].comp] >
- comp[upd->cmap[2].comp]->threshold)) { /* "Fire" */
- pixel[upd->cmap[2].comp] -= comp[upd->cmap[2].comp]->spotsize;
- scan[upd->cmap[2].comp].bytes[ibyte] |= bit;
- } /* "Fire" */
-
- if(( data[0] < data[3]) &&
- (pixel[upd->cmap[3].comp] >
- comp[upd->cmap[3].comp]->threshold)) { /* "Fire" */
- pixel[upd->cmap[3].comp] -= comp[upd->cmap[3].comp]->spotsize;
- scan[upd->cmap[3].comp].bytes[ibyte] |= bit;
- } /* "Fire" */
-
- } /* Fire-Mode */
-
- /*
- * Handle Color-Errors
- */
- FS_DIST(upd->cmap[3].comp)
- FS_DIST(upd->cmap[2].comp)
- FS_DIST(upd->cmap[1].comp)
-
- } else if(pixel[upd->cmap[0].comp] > comp[upd->cmap[0].comp]->threshold) {
- scan[upd->cmap[0].comp].bytes[ibyte] |= bit;
- pixel[upd->cmap[0].comp] -= comp[upd->cmap[0].comp]->spotsize;
- }
-
- FS_DIST(upd->cmap[0].comp)
- /*
- * Adjust bit & iword, depending on direction
- */
- S_FSTEP
- if(upd->flags & B_YFLIP) data -= dir;
- else data += dir;
- }
- /*
- * Finally call the limits-Routine
- */
- if(0 < upd->nlimits) upd_limits(upd,true);
- return 0;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_open_fscmy_k: Initialize for CMY_K Printing */
- /* ------------------------------------------------------------------- */
-
- private void
- upd_open_fscmy_k(upd_device *udev)
- {
- const upd_p upd = udev->upd;
-
- upd_open_fscomp(udev);
-
- if((B_RENDER & upd->flags) &&
- (4 == upd->ncomp)) {
- upd->render = upd_fscmy_k;
- } else {
- upd->flags &= ~B_RENDER;
- }
-
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_fscmy_k: CMY_K rendering */
- /* ------------------------------------------------------------------- */
-
- private int
- upd_fscmy_k(upd_p upd)
- {
- const updscan_p scan = upd->scnbuf[upd->yscnbuf & upd->scnmsk];
- const updcomp_p *comp = (updcomp_p *) upd->valptr;
- int32 *const pixel = upd->valbuf;
- int32 *const colerr = pixel + upd->ncomp;
- int32 *rowerr = colerr + upd->ncomp;
- int pwidth = upd->rwidth;
- int dir,ibyte;
- uint32 ci;
- byte bit;
- bool first = true;
- /*
- * Erase the component-Data
- */
- memset(scan[3].bytes,0,upd->nbytes);
- memset(scan[2].bytes,0,upd->nbytes);
- memset(scan[1].bytes,0,upd->nbytes);
- memset(scan[0].bytes,0,upd->nbytes);
- /*
- * determine the direction
- */
- if(upd->flags & B_REVDIR) { /* This one reverse */
-
- if(upd->flags & B_YFLIP) {
- dir = 4;
- bit = 0x80;
- ibyte = 0;
- } else {
- dir = -4;
- rowerr += 4 * (pwidth-1);
- bit = 0x80 >> ((pwidth-1) & 7);
- ibyte = (pwidth-1) >> 3;
- }
-
- if(!(upd->flags & B_FSWHITE)) {
- upd_pxlfwd(upd);
- while((0 < pwidth) && !upd_pxlget(upd)) pwidth--;
- }
-
- upd_pxlrev(upd);
-
- } else { /* This one forward */
-
- if(upd->flags & B_YFLIP) {
- dir = -4;
- rowerr += 4 * (pwidth-1);
- bit = 0x80 >> ((pwidth-1) & 7);
- ibyte = (pwidth-1) >> 3;
- } else {
- dir = 4;
- bit = 0x80;
- ibyte = 0;
- }
-
- if(!(upd->flags & B_FSWHITE)) {
- upd_pxlrev(upd);
- while((0 < pwidth) && !upd_pxlget(upd)) pwidth--;
- }
-
- upd_pxlfwd(upd);
-
- } /* reverse or forward */
- /*
- * Toggle Direction, if not fixed
- */
- if(!(upd->flags & B_FIXDIR)) upd->flags ^= B_REVDIR;
- /*
- * Skip over leading white-space
- */
- if(!(upd->flags & B_FSWHITE)) {
- upd_proc_pxlget((*fun)) = upd->pxlget;
- byte *ptr = upd->pxlptr;
- while((0 < pwidth) && !upd_pxlget(upd)) {
- pwidth--;
- fun = upd->pxlget;
- ptr = upd->pxlptr;
- S_FSTEP
- }
- upd->pxlget = fun;
- upd->pxlptr = ptr;
- }
- /*
- * Process all Pixels
- */
- first = true;
- while(0 < pwidth--) {
-
- /* get the Pixel-Value */
-
- ci = upd_pxlget(upd);
-
- /* process all components */
-
- FS_M_ROWERR(0) FS_GOAL(comp[0]->bitmsk & (ci >> comp[0]->bitshf),0)
- FS_M_ROWERR(1) FS_GOAL(comp[1]->bitmsk & (ci >> comp[1]->bitshf),1)
- FS_M_ROWERR(2) FS_GOAL(comp[2]->bitmsk & (ci >> comp[2]->bitshf),2)
- FS_M_ROWERR(3) FS_GOAL(comp[3]->bitmsk & (ci >> comp[3]->bitshf),3)
-
- if(pixel[0] > comp[0]->threshold) { /* Black fires */
-
- pixel[0] -= comp[0]->spotsize;
- scan[0].bytes[ibyte] |= bit;
-
- } else { /* Colors may fire */
-
- if((pixel[1] <= comp[1]->threshold) ||
- (pixel[2] <= comp[2]->threshold) ||
- (pixel[3] <= comp[3]->threshold) ) { /* Really a Color */
-
- if(pixel[1] > comp[1]->threshold) {
- pixel[1] -= comp[1]->spotsize;
- scan[1].bytes[ibyte] |= bit;
- }
-
- if(pixel[2] > comp[2]->threshold) {
- pixel[2] -= comp[2]->spotsize;
- scan[2].bytes[ibyte] |= bit;
- }
-
- if(pixel[3] > comp[3]->threshold) {
- pixel[3] -= comp[3]->spotsize;
- scan[3].bytes[ibyte] |= bit;
- }
-
- } else {
- pixel[1] -= comp[1]->spotsize;
- pixel[2] -= comp[2]->spotsize;
- pixel[3] -= comp[3]->spotsize;
- scan[0].bytes[ibyte] |= bit;
- }
- }
-
- FS_DIST(0)
- FS_DIST(1)
- FS_DIST(2)
- FS_DIST(3)
-
- /*
- * Adjust rowerr, bit & iword, depending on direction
- */
- S_FSTEP
- }
- /*
- * Finally call the limits-Routine
- */
- if(0 < upd->nlimits) upd_limits(upd,true);
- return 0;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_open_writer: Initialize rendering */
- /* ------------------------------------------------------------------- */
-
- private int
- upd_open_writer(upd_device *udev)
- {
- const upd_p upd = udev->upd;
- bool success = true;
-
-
- /** Reset the crucial values */
- upd->start_writer = NULL;
- upd->writer = NULL;
- upd->scnbuf = NULL;
- upd->nscnbuf = 0;
- upd->nbytes = 0;
- upd->nlimits = 0;
- upd->outbuf = NULL;
- upd->noutbuf = 0;
-
- /** Rendering should be succesfully initialized */
- if(B_RENDER != ((B_RENDER | B_ERROR) & upd->flags))
- success = false;
-
- /** Create number of components */
- upd->ocomp = upd->ncomp;
- if(0 < upd->ints[I_OCOMP]) upd->ocomp = upd->ints[I_OCOMP];
-
- /** Massage some Parameters */
- if(success) {
-
- /* Make sure, that Pass & Pin-Numbers are at least 1 */
- if(1 > upd->ints[I_NYPASS]) upd->ints[I_NYPASS] = 1;
- if(1 > upd->ints[I_NXPASS]) upd->ints[I_NXPASS] = 1;
- if(1 > upd->ints[I_PINS2WRITE]) upd->ints[I_PINS2WRITE] = 1;
-
- if((upd->ints[I_NXPASS] * upd->ints[I_NYPASS]) > upd->ints[I_NPASS])
- upd->ints[I_NPASS] = upd->ints[I_NXPASS] * upd->ints[I_NYPASS];
-
- /* Create Default noWeave-Feeds */
-
- if(upd->ints[I_NPASS] > upd->int_a[IA_STD_DY].size) {
- int ix,iy,*ip;
- UPD_MM_DEL_PARAM(upd->int_a[IA_STD_DY]);
- UPD_MM_GET_ARRAY(ip,upd->ints[I_NPASS]);
- upd->int_a[IA_STD_DY].data = ip;
- upd->int_a[IA_STD_DY].size = upd->ints[I_NPASS];
-
- for(iy = 1; iy < upd->ints[I_NYPASS]; ++iy) {
- for(ix = 1; ix < upd->ints[I_NXPASS]; ++ix) *ip++ = 0;
- *ip++ = 1;
- }
- for(ix = 1; ix < upd->ints[I_NXPASS]; ++ix) *ip++ = 0;
- *ip = upd->ints[I_NYPASS] * upd->ints[I_PINS2WRITE]
- - upd->ints[I_NYPASS] + 1;
-
- upd->ints[I_BEG_Y] = 0;
- upd->ints[I_END_Y] = upd->ints[I_PHEIGHT] ?
- upd->ints[I_PHEIGHT] : upd->gsheight;
- }
-
- /* Adjust BEG_Y */
- if(0 >= upd->ints[I_BEG_Y]) {
- if(0 < upd->int_a[IA_BEG_DY].size) {
- int i,sum = 0;
- for(i = 0; i < upd->int_a[IA_BEG_DY].size; ++i)
- sum += upd->int_a[IA_BEG_DY].data[i];
- upd->ints[I_BEG_Y] = sum;
- } else {
- upd->ints[I_BEG_Y] = 0;
- }
- }
-
- /* Adjust END_Y */
- /* Arrgh, I knew, why I refused to provide defaults for crucial */
- /* parameters in uniprint. But o.k. it's nice for size-changing */
- /* PostScript-Code. Nevertheless, it's still not perfect. */
-
- if(0 >= upd->int_a[IA_ENDTOP].size ||
- 0 >= upd->int_a[IA_END_DY].size ) upd->ints[I_END_Y] =
- upd->ints[I_PHEIGHT] ? upd->ints[I_PHEIGHT] : upd->gsheight;
-
- if(0 >= upd->ints[I_END_Y]) upd->ints[I_END_Y] = upd->ints[I_PHEIGHT] ?
- upd->ints[I_PHEIGHT] : upd->gsheight;
-
-
- /* Create Default X-Passes */
-
- if(0 >= upd->int_a[IA_STD_IX].size) {
- int ix,i,*ip;
- UPD_MM_DEL_PARAM(upd->int_a[IA_STD_IX]);
- UPD_MM_GET_ARRAY(ip,upd->int_a[IA_STD_DY].size);
- upd->int_a[IA_STD_IX].data = ip;
- upd->int_a[IA_STD_IX].size = upd->int_a[IA_STD_DY].size;
-
- for(i = 0, ix = 0; i < upd->int_a[IA_STD_IX].size; ++i) {
- *ip++ = ix++;
- if(ix == upd->ints[I_NXPASS]) ix = 0;
- }
- }
-
- if((0 >= upd->int_a[IA_BEG_IX].size) &&
- (0 < upd->int_a[IA_BEG_DY].size) ) {
- int ix,i,*ip;
- UPD_MM_DEL_PARAM(upd->int_a[IA_BEG_IX]);
- UPD_MM_GET_ARRAY(ip,upd->int_a[IA_BEG_DY].size);
- upd->int_a[IA_BEG_IX].data = ip;
- upd->int_a[IA_BEG_IX].size = upd->int_a[IA_BEG_DY].size;
-
- for(i = 0, ix = 0; i < upd->int_a[IA_BEG_IX].size; ++i) {
- *ip++ = ix++;
- if(ix == upd->ints[I_NXPASS]) ix = 0;
- }
- }
-
- if((0 >= upd->int_a[IA_END_IX].size) &&
- (0 < upd->int_a[IA_END_DY].size) ) {
- int ix,i,*ip;
- UPD_MM_DEL_PARAM(upd->int_a[IA_END_IX]);
- UPD_MM_GET_ARRAY(ip,upd->int_a[IA_END_DY].size);
- upd->int_a[IA_END_IX].data = ip;
- upd->int_a[IA_END_IX].size = upd->int_a[IA_END_DY].size;
-
- for(i = 0, ix = 0; i < upd->int_a[IA_END_IX].size; ++i) {
- *ip++ = ix++;
- if(ix == upd->ints[I_NXPASS]) ix = 0;
- }
- }
- }
-
- if(upd->ints[I_NPASS] > upd->int_a[IA_STD_DY].size) {
- #if UPD_MESSAGES & UPD_M_WARNING
- fprintf(stderr,
- "upd_open_writer: Only %d instead of %d normal Feeds\n",
- (int) upd->int_a[IA_STD_DY].size,upd->ints[I_NPASS]);
- #endif
- success = false;
-
- } else if(upd->int_a[IA_STD_IX].size < upd->int_a[IA_STD_DY].size) {
- #if UPD_MESSAGES & UPD_M_WARNING
- fprintf(stderr,
- "upd_open_writer: Only %d instead of %d normal Xstarts\n",
- (int) upd->int_a[IA_STD_IX].size,
- (int) upd->int_a[IA_STD_DY].size);
- #endif
- success = false;
- }
-
- /** The sum of Values in STD_DY should equal NYPASS * PINS2WRITE (diagnostic) */
-
- #if UPD_MESSAGES & UPD_M_WARNING
- if(success) {
- int i,sum = 0;
- for(i = 0; upd->ints[I_NPASS] > i; ++i)
- sum += upd->int_a[IA_STD_DY].data[i];
- if((upd->ints[I_NYPASS]*upd->ints[I_PINS2WRITE]) != sum)
- fprintf(stderr,
- "upd_open_writer: Sum of normal Feeds is %d rather than %d\n",
- sum,upd->ints[I_NYPASS]*upd->ints[I_PINS2WRITE]);
- }
- #endif
-
- if(upd->int_a[IA_BEG_IX].size < upd->int_a[IA_BEG_DY].size) {
- #if UPD_MESSAGES & UPD_M_WARNING
- fprintf(stderr,
- "upd_open_writer: Only %d instead of %d initial Xstarts\n",
- (int) upd->int_a[IA_BEG_IX].size,
- (int) upd->int_a[IA_BEG_DY].size);
- #endif
- success = false;
- }
-
- if(upd->int_a[IA_BEGBOT].size < upd->int_a[IA_BEG_DY].size) {
- #if UPD_MESSAGES & UPD_M_WARNING
- fprintf(stderr,
- "upd_open_writer: Only %d instead of %d initial Pins\n",
- (int) upd->int_a[IA_BEGBOT].size,
- (int) upd->int_a[IA_BEG_DY].size);
- #endif
- success = false;
-
- } else {
-
- int i;
- for(i = 0; i < upd->int_a[IA_BEG_DY].size; ++i)
- if((upd->int_a[IA_BEGBOT].data[i] > upd->ints[I_PINS2WRITE]) ||
- (upd->int_a[IA_BEGBOT].data[i] < 0 ) ) break;
-
- if(i < upd->int_a[IA_BEG_DY].size) {
- #if UPD_MESSAGES & UPD_M_WARNING
- fprintf(stderr,
- "upd_open_writer: Only %d is invalid initial Pins\n",
- upd->int_a[IA_BEGBOT].data[i]);
- #endif
- success = false;
- }
- }
-
-
- /** The sum of Values in BEG_DY should equal BEG_Y */
-
- #if UPD_MESSAGES & UPD_M_WARNING
- if(success) {
- int i,sum = 0;
- for(i = 0; upd->int_a[IA_BEG_DY].size > i; ++i)
- sum += upd->int_a[IA_BEG_DY].data[i];
- if(upd->ints[I_BEG_Y] != sum)
- fprintf(stderr,
- "upd_open_writer: Sum of initial Feeds is %d rather than %d\n",
- sum,upd->ints[I_BEG_Y]);
- }
- #endif
-
- if(upd->int_a[IA_END_IX].size < upd->int_a[IA_END_DY].size) {
- #if UPD_MESSAGES & UPD_M_WARNING
- fprintf(stderr,
- "upd_open_writer: Only %d instead of %d final Xstarts\n",
- (int) upd->int_a[IA_END_IX].size,
- (int) upd->int_a[IA_END_DY].size);
- #endif
- success = false;
- }
-
- if(upd->int_a[IA_ENDTOP].size < upd->int_a[IA_END_DY].size) {
- #if UPD_MESSAGES & UPD_M_WARNING
- fprintf(stderr,
- "upd_open_writer: Only %d instead of %d Final Pins\n",
- (int) upd->int_a[IA_ENDTOP].size,
- (int) upd->int_a[IA_END_DY].size);
- #endif
- success = false;
-
- } else {
-
- int i;
- for(i = 0; i < upd->int_a[IA_END_DY].size; ++i)
- if((upd->int_a[IA_ENDTOP].data[i] > upd->ints[I_PINS2WRITE]) ||
- (upd->int_a[IA_ENDTOP].data[i] < 0 ) ) break;
-
- if(i < upd->int_a[IA_END_DY].size) {
- #if UPD_MESSAGES & UPD_M_WARNING
- fprintf(stderr,
- "upd_open_writer: Only %d is invalid initial Pins\n",
- upd->int_a[IA_ENDTOP].data[i]);
- #endif
- success = false;
- }
- }
-
- /** SA_SETCOMP must be valid, if present */
- if((0 < upd->string_a[SA_SETCOMP].size) &&
- (upd->ocomp > upd->string_a[SA_SETCOMP].size)) {
- #if UPD_MESSAGES & UPD_M_WARNING
- fprintf(stderr,
- "upd_open_writer: Only %d SETCOMP-Commands (%d required)\n",
- (int) upd->string_a[SA_SETCOMP].size,upd->ocomp);
- #endif
- success = false;
- }
-
- /** Determine required number of scan-Buffers */
-
- if(success) { /* Compute nscnbuf */
- int32 want,use;
-
- want = upd->ints[I_NYPASS];
- want *= upd->ints[I_PINS2WRITE];
-
- if(upd->ints[I_NSCNBUF] > want) want = upd->ints[I_NSCNBUF];
-
- if(1 > want) want = 1;
-
- for(use = 1; 0 < use; use <<= 1) if(use > want) break;
-
- if(use <= INT_MAX) upd->nscnbuf = upd->ints[I_NSCNBUF] = use;
- else success = false;
-
- } /* Compute nscnbuf */
-
- /** Determine number of words in scan-buffers */
-
- if(success) { /* Compute pwidth, scnmsk, nbytes, pheight */
-
- if(0 < upd->ints[I_PWIDTH]) upd->pwidth = upd->ints[I_PWIDTH];
- else upd->pwidth = upd->gswidth;
-
- upd->nbytes = (upd->pwidth+CHAR_BIT*sizeof(upd->scnbuf[0]->bytes[0]) - 1)
- / (CHAR_BIT*sizeof(upd->scnbuf[0]->bytes[0]));
-
- upd->scnmsk = upd->nscnbuf - 1;
-
- if(0 < upd->ints[I_PHEIGHT]) upd->pheight = upd->ints[I_PHEIGHT];
- else upd->pheight = upd->gsheight;
-
- } /* Compute pwidth, scnmsk, nbytes */
-
- /** Call the writer-specific open-function */
-
- if(success) { /* Determine sizes */
- switch(upd->choice[C_FORMAT]) {
- case FMT_RAS:
- if(0 > upd_open_rascomp(udev)) success = false;
- break;
- case FMT_EPSON:
- if(0 > upd_open_wrtescp(udev)) success = false;
- break;
- case FMT_ESCP2Y:
- case FMT_ESCP2XY:
- if(0 > upd_open_wrtescp2(udev)) success = false;
- break;
- case FMT_RTL:
- if(0 > upd_open_wrtrtl(udev)) success = false;
- break;
- case FMT_CANON: /* (hr) */
- if(0 > upd_open_wrtcanon(udev)) success = false;
- break;
- default:
- success = false;
- #if UPD_MESSAGES & UPD_M_WARNING
- fprintf(stderr,"upd_open_writer: Unknown writer-type %d\n",
- upd->choice[C_FORMAT]);
- #endif
- break;
- }
- } /* Determine sizes*/
-
- /** Allocate the Outputbuffer */
- if(success && (0 < upd->noutbuf)) { /* Allocate outbuf */
- upd->outbuf = gs_malloc(upd->noutbuf,sizeof(upd->outbuf[0]),"upd/outbuf");
- if(!upd->outbuf) success = false;
- } /* Allocate outbuf */
-
- /** Allocate the desired scan-buffer-pointers */
- if(success) {
- upd->scnbuf = gs_malloc(upd->nscnbuf,sizeof(upd->scnbuf[0]),"upd/scnbuf");
- if(NULL == upd->scnbuf) {
- success = false;
- } else {
- int ibuf;
- for(ibuf = 0; ibuf < upd->nscnbuf; ++ibuf) {
- if(success) upd->scnbuf[ibuf] =
- gs_malloc(upd->ocomp,sizeof(upd->scnbuf[0][0]),"upd/scnbuf[]");
- else upd->scnbuf[ibuf] = NULL;
-
- if(!upd->scnbuf[ibuf]) {
- success = false;
- } else {
- int icomp;
- for(icomp = 0; icomp < upd->ocomp; ++icomp) {
- if(success) upd->scnbuf[ibuf][icomp].bytes =
- gs_malloc(upd->nbytes,sizeof(upd->scnbuf[0][0].bytes[0]),
- "upd/bytes");
- else upd->scnbuf[ibuf][icomp].bytes = NULL;
- if(!upd->scnbuf[ibuf][icomp].bytes) success = false;
-
- if(0 < upd->nlimits) {
-
- upd->scnbuf[ibuf][icomp].xbegin = gs_malloc(upd->nlimits,
- sizeof(upd->scnbuf[0][0].xbegin[0]),"upd/xbegin");
- if(!upd->scnbuf[ibuf][icomp].xbegin) success = false;
-
- upd->scnbuf[ibuf][icomp].xend = gs_malloc(upd->nlimits,
- sizeof(upd->scnbuf[0][0].xend[0]),"upd/xend");
- if(!upd->scnbuf[ibuf][icomp].xbegin) success = false;
-
- } else {
-
- upd->scnbuf[ibuf][icomp].xbegin = NULL;
- upd->scnbuf[ibuf][icomp].xend = NULL;
-
- }
- }
- }
- }
- }
- }
-
- if(success) upd->flags |= B_FORMAT;
- else upd_close_writer(udev);
-
- return success ? 1 : -1;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_close_writer: Deinitialize rendering */
- /* ------------------------------------------------------------------- */
-
- private void
- upd_close_writer(upd_device *udev)
- {
- const upd_p upd = udev->upd;
-
- if(upd) {
- int ibuf,icomp;
-
- if((0 < upd->noutbuf) && upd->outbuf)
- gs_free(upd->outbuf,upd->noutbuf,sizeof(upd->outbuf[0]),"upd/outbuf");
- upd->noutbuf = 0;
- upd->outbuf = NULL;
-
- if((0 < upd->nscnbuf) && upd->scnbuf) {
- for(ibuf = 0; upd->nscnbuf > ibuf; ++ibuf) {
-
- if(!upd->scnbuf[ibuf]) continue;
-
- for(icomp = 0; icomp < upd->ocomp; ++icomp) {
-
- if((0 < upd->nbytes) && upd->scnbuf[ibuf][icomp].bytes)
- gs_free(upd->scnbuf[ibuf][icomp].bytes,upd->nbytes,
- sizeof(upd->scnbuf[ibuf][icomp].words[0]),"upd/bytes");
- upd->scnbuf[ibuf][icomp].bytes = NULL;
-
- if((0 < upd->nlimits) && upd->scnbuf[ibuf][icomp].xbegin)
- gs_free(upd->scnbuf[ibuf][icomp].xbegin,upd->nlimits,
- sizeof(upd->scnbuf[ibuf][icomp].xbegin[0]),"upd/xbegin");
- upd->scnbuf[ibuf][icomp].xbegin = NULL;
-
- if((0 < upd->nlimits) && upd->scnbuf[ibuf][icomp].xend)
- gs_free(upd->scnbuf[ibuf][icomp].xend,upd->nlimits,
- sizeof(upd->scnbuf[ibuf][icomp].xend[0]),"upd/xend");
- upd->scnbuf[ibuf][icomp].xend = NULL;
- }
-
- if(icomp)
- gs_free(upd->scnbuf[ibuf],upd->ocomp,sizeof(upd->scnbuf[0][0]),
- "upd/scnbuf[]");
- upd->scnbuf[ibuf] = NULL;
-
- }
- gs_free(upd->scnbuf,upd->nscnbuf,sizeof(upd->scnbuf[0]),"upd/scnbuf");
- }
-
-
- upd->flags &= ~B_FORMAT;
- }
- }
-
-
- /* ------------------------------------------------------------------- */
- /* upd_limits: Establish passwise limits, after rendering */
- /* ------------------------------------------------------------------- */
-
- private void
- upd_limits(upd_p upd, bool check)
- {
- updscan_p scans = upd->scnbuf[upd->yscnbuf & upd->scnmsk], scan;
- int xs,x,xe,icomp,pass;
- byte *bytes,bit;
-
- for(icomp = 0; icomp < upd->ocomp; ++icomp) {
- scan = scans + icomp;
- for(pass = 0; pass < upd->nlimits; ++pass) {
- scan->xbegin[pass] = upd->pwidth;
- scan->xend[ pass] = -1;
- }
- }
-
- if(check) { /* Really check */
- for(icomp = 0; icomp < upd->ocomp; ++icomp) { /* Check Components */
- scan = scans + icomp;
- bytes = scan->bytes;
-
- for(xs = 0; xs < upd->nbytes && !bytes[xs]; ++xs);
-
- if(xs < upd->nbytes) { /* Has Data */
- for(xe = upd->nbytes; xs < xe && !bytes[xe-1]; --xe);
-
- for(pass = 0; pass < upd->nlimits; ++pass) { /* limit (pass) loop */
-
- x = ((xs<<3)/upd->nlimits)*upd->nlimits + pass;
- while((x >> 3) < xs) x += upd->nlimits;
-
- bit = 0x80 >> (x & 7);
- while(x < scan->xbegin[pass]) {
- if(bytes[x>>3] & bit) scan->xbegin[pass] = x;
- x += upd->nlimits;
- bit = 0x80 >> (x & 7);
- }
-
- x = (((xe<<3)|7)/upd->nlimits)*upd->nlimits + pass;
-
- while((x >> 3) < xe) x += upd->nlimits;
- while((x >> 3) > xe) x -= upd->nlimits;
-
- bit = 0x80 >> (xs & 7);
- while(x > scan->xend[pass]) {
- if(bytes[x>>3] & bit) scan->xend[pass] = x;
- x -= upd->nlimits;
- bit = 0x80 >> (x & 7);
- }
-
- } /* limit (pass) loop */
-
- } /* Has Data */
-
- } /* Check Components */
-
- } /* Really check */
-
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_open_rascomp: ncomp * 1Bit Raster-Writer */
- /* ------------------------------------------------------------------- */
-
- private int
- upd_open_rascomp(upd_device *udev)
- {
- const upd_p upd = udev->upd;
- int32 noutbuf;
- int error = 0;
-
- noutbuf = upd->pwidth;
-
- if(1 < upd->ncomp) noutbuf *= 8; /* ??? upd->ocomp */
-
- noutbuf = ((noutbuf+15)>>4)<<1;
-
- if(INT_MAX >= noutbuf) {
- upd->noutbuf = noutbuf;
- upd->start_writer = upd_start_rascomp;
- upd->writer = upd_rascomp;
- } else {
- error = -1;
- }
-
- return error;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_start_rascomp: write appropiate raster-header */
- /* ------------------------------------------------------------------- */
- #if arch_is_big_endian
- #define put32(I32,Out) \
- fwrite(&I32,1,4,Out)
- #else
- #define put32(I32,Out) \
- putc(((I32)>>24)&255,Out),\
- putc(((I32)>>16)&255,Out),\
- putc(((I32)>> 8)&255,Out),\
- putc( (I32) &255,Out)
- #endif
-
- private int
- upd_start_rascomp(upd_p upd, FILE *out) {
-
- /** if no begin-sequence externally set */
- if(0 == upd->strings[S_BEGIN].size) {
- int32 val;
-
- /** ras_magic */
- val = 0x59a66a95;
- put32(val,out);
-
- /** ras_width */
- val = upd->pwidth;
- put32(val,out);
-
- /** ras_height */
- val = upd->pheight;
- put32(val,out);
-
- /** ras_depth */
- if(1 < upd->ncomp) val = 8; /* ??? upd->ocomp */
- else val = 1;
- put32(val,out);
-
- /** ras_length */
- val *= upd->pwidth;
- val = ((val+15)>>4)<<1;
- val *= upd->pheight;
- put32(val,out);
-
- /** ras_type */
- val = 1;
- put32(val,out);
-
- /** ras_maptype */
- val = 1;
- put32(val,out);
-
- /** ras_maplength */
- val = 3 * (1 << upd->ncomp); /* ??? upd->ocomp */
- put32(val,out);
-
- /** R,G,B-Map */
- if(1 == upd->ncomp) { /* ??? upd->ocomp */
- const updcomp_p comp = upd->valptr[0];
-
- if(upd->cmap[comp->cmap].rise) {
- putc((char) 0x00,out); putc((char) 0xff,out);
- putc((char) 0x00,out); putc((char) 0xff,out);
- putc((char) 0x00,out); putc((char) 0xff,out);
- } else {
- putc((char) 0xff,out); putc((char) 0x00,out);
- putc((char) 0xff,out); putc((char) 0x00,out);
- putc((char) 0xff,out); putc((char) 0x00,out);
- }
-
- } else if(3 == upd->ncomp) { /* ??? upd->ocomp */
- int rgb;
-
- for( rgb = 0; rgb < 3; ++rgb) {
- int entry;
- for(entry = 0; entry < 8; ++entry) {
- byte xval = upd->cmap[rgb].rise ? 0x00 : 0xff;
- if(entry & (1<<upd->cmap[rgb].comp)) xval ^= 0xff;
- putc(xval,out);
- }
- }
- } else { /* we have 4 components */
- int rgb;
-
- for(rgb = 16; 0 <= rgb; rgb -= 8) {
- int entry;
- for(entry = 0; entry < 16; ++entry) {
- uint32 rgbval = 0;
-
- if(entry & (1<<upd->cmap[0].comp)) {
-
- rgbval = 0xffffff;
-
- } else {
-
- if(entry & (1<<upd->cmap[1].comp)) rgbval |= 0xff0000;
- if(entry & (1<<upd->cmap[2].comp)) rgbval |= 0x00ff00;
- if(entry & (1<<upd->cmap[3].comp)) rgbval |= 0x0000ff;
- }
-
- if(!upd->cmap[1].rise) rgbval ^= 0xff0000;
- if(!upd->cmap[2].rise) rgbval ^= 0x00ff00;
- if(!upd->cmap[3].rise) rgbval ^= 0x0000ff;
-
- if(!(upd->choice[C_MAPPER] == MAP_RGBW)) rgbval ^= 0xffffff;
-
- putc((rgbval>>rgb)&255,out);
- }
- }
- }
- }
- memset(upd->outbuf,0,upd->noutbuf);
-
- return 0;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_rascomp: assemble & write a scanline */
- /* ------------------------------------------------------------------- */
- private int
- upd_rascomp(upd_p upd, FILE *out) {
- updscan_p scan = upd->scnbuf[upd->yscan & upd->scnmsk];
- uint bits = upd->pwidth;
-
- if(1 == upd->ncomp) { /* ??? upd->ocomp */
- uint nbytes;
-
- nbytes = (bits+7)>>3;
- memcpy(upd->outbuf,scan->bytes,nbytes);
- if((bits &= 7)) upd->outbuf[nbytes-1] &= ((byte) 0xff) << (8-bits);
-
- } else {
-
- byte *buf = upd->outbuf, bit = 0x80;
- int ibyte = 0;
-
- while(0 < bits--) {
- byte val = 0;
- switch(upd->ncomp) { /* ??? upd->ocomp */
- case 4: if(scan[3].bytes[ibyte] & bit) val |= 8;
- case 3: if(scan[2].bytes[ibyte] & bit) val |= 4;
- if(scan[1].bytes[ibyte] & bit) val |= 2;
- case 1: if(scan[0].bytes[ibyte] & bit) val |= 1;
- }
- *buf++ = val;
- if(!(bit >>= 1)) {
- bit = 0x80;
- ibyte += 1;
- }
- }
- }
-
- fwrite(upd->outbuf,1,upd->noutbuf,out);
- upd->yscan += 1;
-
- return 0;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_open_wrtescp: ESC/P Writer intended for ESC * m commands */
- /* ------------------------------------------------------------------- */
-
- private int
- upd_open_wrtescp(upd_device *udev)
- {
- const upd_p upd = udev->upd;
- int error = 0;
-
- /** Adjust the PageLength, If Requested */
- if((B_PAGELENGTH & upd->flags) &&
- (0 < upd->strings[S_BEGIN].size)) { /* BOP-Checker */
- int i,state = 0,value = 0;
- byte *bp = (byte *) upd->strings[S_BEGIN].data;
- for(i = 0; i < upd->strings[S_BEGIN].size; ++i) {
- switch(state) {
- case 0:
- if(0x1b == bp[i]) state = 1;
- break;
- case 1:
- if('C' == bp[i]) state = 2;
- else state = 0;
- break;
- case 2:
- if(bp[i]) {
- value = 0.5 + udev->height * (float) bp[i]
- / udev->y_pixels_per_inch;
- if( 0 >= value) bp[i] = 1;
- else if(128 > value) bp[i] = value;
- else bp[i] = 127;
- state = 0;
- } else {
- state = 3;
- }
- break;
- case 3:
- value = 0.5 + udev->height / udev->y_pixels_per_inch;
- if( 0 >= value) bp[i] = 1;
- else if( 22 > value) bp[i] = value;
- else bp[i] = 22;
- state = 0;
- break;
- }
- }
- } /* BOP-Checker */
-
-
- /** Either SETLF or YMOVE must be set */
- if((0 == upd->strings[S_SETLF].size) &&
- (0 == upd->strings[S_YMOVE].size) ) {
- #if UPD_MESSAGES & UPD_M_WARNING
- fprintf(stderr,
- "ESC/P-Open: Either SETLF- or YMOVE-Command must be present\n");
- #endif
- error = -1;
- }
-
- /** X-Positioning must be set too */
- if(((1 < upd->ints[I_XSTEP] ) &&
- (0 == upd->strings[S_XSTEP].size) ) ||
- ((1 < upd->ints[I_NXPASS] ) &&
- (0 == upd->strings[S_XMOVE].size) &&
- (0 == upd->strings[S_XSTEP].size) ) ) {
- #if UPD_MESSAGES & UPD_M_WARNING
- fprintf(stderr,
- "ESC/P-Open: Missing XSTEP- and/or XMOVE-Command\n");
- #endif
- error = -1;
- }
-
- /** SA_WRITECOMP must be valid */
- if(upd->ncomp > upd->string_a[SA_WRITECOMP].size) { /* ??? upd->ocomp */
- #if UPD_MESSAGES & UPD_M_WARNING
- fprintf(stderr,
- "ESC/P-Open: WRITECOMP-Commands must be given\n");
- #endif
- error = -1;
- }
-
- /**
- If all this is correct, it's time to coumput the size of the output-buffer.
- It must hold:
- 1. Y-Positioning
- 2. X-Positioning
- 3. Component-Selection
- 4. The Raster-Command
- 5. The Data
- */
- if(0 <= error) {
- int32 i,noutbuf,need;
-
- if(0 < upd->strings[S_YMOVE].size) {
- noutbuf = upd->strings[S_YMOVE].size + 2;
- } else {
- int nmax = upd->pheight;
- if( 1 < upd->ints[I_YSTEP]) nmax /= upd->ints[I_YSTEP];
- else if(-1 > upd->ints[I_YSTEP]) nmax *= -upd->ints[I_YSTEP];
- noutbuf = 2 * upd->strings[S_SETLF].size + 2;
- noutbuf += nmax/255 + 1;
- }
-
- if(1 < upd->ints[I_YSTEP])
- noutbuf += (upd->ints[I_YSTEP]-1) * upd->strings[S_YSTEP].size;
-
- noutbuf += upd->strings[S_XMOVE].size + 2;
-
- if(1 < upd->ints[I_XSTEP])
- noutbuf += (upd->ints[I_XSTEP]-1) * upd->strings[S_XSTEP].size;
-
- if(0 < upd->string_a[SA_SETCOMP].size) {
- need = 0;
- for(i = 0; i < upd->ocomp; ++i)
- if(need < upd->string_a[SA_SETCOMP].data[i].size)
- need = upd->string_a[SA_SETCOMP].data[i].size;
- noutbuf += need;
- }
-
- need = 0;
- for(i = 0; i < upd->ocomp; ++i)
- if(need < upd->string_a[SA_WRITECOMP].data[i].size)
- need = upd->string_a[SA_WRITECOMP].data[i].size;
- noutbuf += need + 2;
-
- noutbuf += ((upd->ints[I_PINS2WRITE] + 7) / 8)
- * ((upd->pwidth + upd->ints[I_NXPASS] - 1)/upd->ints[I_NXPASS]);
-
- if((0 < noutbuf) && (noutbuf <= INT_MAX)) {
- upd->noutbuf = noutbuf;
- upd->writer = upd_wrtescp;
- upd->nlimits = upd->ints[I_NXPASS];
- error = 1;
- } else {
- error = -1;
- #if UPD_MESSAGES & UPD_M_WARNING
- fprintf(stderr,
- "ESC/P-Open: %ld is unreasonable size of Outputbuffer\n",
- (long) noutbuf);
- #endif
- }
- }
-
- return error;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_wrtescp: Write a pass */
- /* ------------------------------------------------------------------- */
-
- private int
- upd_wrtescp(upd_p upd, FILE *out)
- {
- int pinbot,pin,pintop,xbegin,x,xend,icomp,ybegin,yend,y,ioutbuf,n,ixpass;
- byte *obytes,bit;
- updscan_p scan;
-
- /** Determine the number of pins to write */
-
- if(upd->yscan < upd->ints[I_BEG_Y]) {
- ixpass = upd->int_a[IA_BEG_IX].data[upd->ipass];
- pintop = 0;
- pinbot = upd->int_a[IA_BEGBOT].data[upd->ipass];
- } else if(upd->yscan >= upd->ints[I_END_Y]) {
- ixpass = upd->int_a[IA_END_IX].data[upd->ipass];
- pinbot = upd->ints[I_PINS2WRITE];
- pintop = pinbot - upd->int_a[IA_ENDTOP].data[upd->ipass];
- } else {
- ixpass = upd->int_a[IA_STD_IX].data[upd->ipass];
- pintop = 0;
- pinbot = upd->ints[I_PINS2WRITE];
- }
-
- ybegin = pintop * upd->ints[I_NYPASS] + upd->yscan - upd->ints[I_BEGSKIP];
- yend = pinbot * upd->ints[I_NYPASS] + upd->yscan - upd->ints[I_BEGSKIP];
-
- /** Determine Width of this scan */
-
- xbegin = upd->pwidth;
- xend = -1;
-
- for(y = ybegin; y < yend; y += upd->ints[I_NYPASS]) { /* Pin-testloop */
-
- if(0 > y) continue; /* Inserted Scanlines */
-
- scan = upd->scnbuf[y & upd->scnmsk];
-
- for(icomp = 0; icomp < upd->ocomp; ++icomp) { /* Compwise test */
- if(xbegin > scan[icomp].xbegin[ixpass])
- xbegin = scan[icomp].xbegin[ixpass];
- if(xend < scan[icomp].xend[ ixpass])
- xend = scan[icomp].xend[ ixpass];
- } /* Compwise test */
-
- } /* Pin-testloop */
-
- if(xbegin <= xend) { /* Some data to write */
-
- ioutbuf = 0;
-
- if(0 == upd->strings[S_XMOVE].size) xbegin = ixpass;
-
- /*
- * Adjust the Printers Y-Position
- */
- if(upd->yscan != upd->yprinter) { /* Adjust Y-Position */
- if(B_YABS & upd->flags) y = upd->yscan + upd->ints[I_YOFS];
- else y = upd->yscan - upd->yprinter;
-
- if( 1 < upd->ints[I_YSTEP]) {
- n = y / upd->ints[I_YSTEP]; /* Major-Steps */
- y -= n * upd->ints[I_YSTEP]; /* Minor-Steps */
- } else if(-1 > upd->ints[I_YSTEP]) {
- n = y * -upd->ints[I_YSTEP]; /* May this work? */
- y = 0;
- } else {
- n = y;
- y = 0;
- }
-
- if(n) { /* Coarse Positioning */
- if(0 < upd->strings[S_YMOVE].size) {
-
- memcpy(upd->outbuf+ioutbuf,
- upd->strings[S_YMOVE].data,
- upd->strings[S_YMOVE].size);
- ioutbuf += upd->strings[S_YMOVE].size;
-
- upd->outbuf[ioutbuf++] = n & 0xff;
- upd->outbuf[ioutbuf++] = (n>>8) & 0xff;
-
- } else {
-
- while(n) {
- int n2do = n > 255 ? 255 : n;
- if(upd->lf != n2do) {
- memcpy(upd->outbuf+ioutbuf,
- upd->strings[S_SETLF].data,
- upd->strings[S_SETLF].size);
- ioutbuf += upd->strings[S_SETLF].size;
- upd->outbuf[ioutbuf++] = n2do;
- upd->lf = n2do;
- }
- upd->outbuf[ioutbuf++] = '\n';
- n -= n2do;
- }
- }
- } /* Coarse Positioning */
-
- if(0 < upd->strings[S_YSTEP].size) {
- while(y--) {
- memcpy(upd->outbuf+ioutbuf,
- upd->strings[S_YSTEP].data,
- upd->strings[S_YSTEP].size);
- ioutbuf += upd->strings[S_YSTEP].size;
- }
- }
-
- upd->yprinter = upd->yscan;
- } /* Adjust Y-Position */
-
- /*
- * Now write the required components
- */
- for(icomp = 0; icomp < upd->ocomp; ++icomp) { /* Component-Print */
- /*
- * First check, wether this Component needs printing
- */
- for(y = ybegin; y < yend; y += upd->ints[I_NYPASS]) { /* Comp-Test */
- if(0 > y) continue;
- scan = upd->scnbuf[y & upd->scnmsk]+icomp;
- if(0 <= scan->xend[ixpass]) break;
- } /* Comp-Test */
- if(y >= yend) continue; /* Component not required */
- /*
- * Select the Component
- */
- if((0 < upd->string_a[SA_SETCOMP].size) &&
- (upd->icomp != icomp ) ) { /* Selection enabled */
- upd->icomp = icomp;
- if(0 < upd->string_a[SA_SETCOMP].data[icomp].size) {
- memcpy(upd->outbuf+ioutbuf,
- upd->string_a[SA_SETCOMP].data[icomp].data,
- upd->string_a[SA_SETCOMP].data[icomp].size);
- ioutbuf += upd->string_a[SA_SETCOMP].data[icomp].size;
- }
- } /* Selection enabled */
- /*
- * Establish the X-Position
- */
- if(xbegin != upd->xprinter) {
-
- if(0 == upd->strings[S_XMOVE].size) {
-
- upd->outbuf[ioutbuf++] = '\r';
- upd->xprinter = 0;
- n = 0;
- x = ixpass;
-
- } else {
-
- if(B_XABS & upd->flags) n = x = xbegin + upd->ints[I_XOFS];
- else n = x = xbegin - upd->xprinter;
-
- if( 1 < upd->ints[I_XSTEP]) {
- if(0 > n) {
- n -= upd->ints[I_XSTEP];
- x -= n;
- }
- if(n) n /= upd->ints[I_XSTEP]; /* Major-Steps */
- if(x) x %= upd->ints[I_XSTEP]; /* Minor-Steps */
-
- } else if(-1 > upd->ints[I_XSTEP]) {
- n *= -upd->ints[I_XSTEP]; /* May this work? */
- x = 0;
- }
-
- if(n) { /* Adjust X-Position */
-
- memcpy(upd->outbuf+ioutbuf,
- upd->strings[S_XMOVE].data,
- upd->strings[S_XMOVE].size);
- ioutbuf += upd->strings[S_XMOVE].size;
-
- upd->outbuf[ioutbuf++] = n & 0xff;
- upd->outbuf[ioutbuf++] = (n>>8) & 0xff;
-
- } /* Adjust X-Position */
-
- }
-
- if(x && 0 < upd->strings[S_XSTEP].size) { /* Fine-Adjust X */
- while(x--) {
- memcpy(upd->outbuf+ioutbuf,
- upd->strings[S_XSTEP].data,
- upd->strings[S_XSTEP].size);
- ioutbuf += upd->strings[S_XSTEP].size;
- }
- } /* Fine-Adjust X */
- }
- upd->xprinter = xend+1;
- /*
- * Send the Write-Command
- */
- if(0 < upd->string_a[SA_WRITECOMP].data[icomp].size) {
- memcpy(upd->outbuf+ioutbuf,
- upd->string_a[SA_WRITECOMP].data[icomp].data,
- upd->string_a[SA_WRITECOMP].data[icomp].size);
- ioutbuf += upd->string_a[SA_WRITECOMP].data[icomp].size;
- }
- n = (xend - xbegin) / upd->ints[I_NXPASS] + 1;;
- upd->outbuf[ioutbuf++] = n & 255;
- upd->outbuf[ioutbuf++] = (n>>8) & 255;
- /*
- * Clear the data-Part
- */
- obytes = upd->outbuf+ioutbuf;
- n *= (upd->ints[I_PINS2WRITE]+7)>>3;
- memset(obytes,0,n);
- ioutbuf += n;
- /*
- * Set the Pixels
- */
- for(x = xbegin; x <= xend; x += upd->ints[I_NXPASS]) {
-
- bit = 0x80 >> (pintop & 7);
- obytes += pintop>>3;
-
- for(pin = pintop, y = ybegin; pin < pinbot;
- pin++, y += upd->ints[I_NYPASS]) {
- if(0 <= y) {
- scan = upd->scnbuf[y & upd->scnmsk]+icomp;
- if(scan->bytes[x>>3] & (0x80 >> (x & 7))) *obytes |= bit;
- }
- if(!(bit >>= 1)) { obytes++; bit = 0x80; }
- }
-
- obytes += (upd->ints[I_PINS2WRITE]-pinbot+7)>>3;
- }
- /*
- * Send this Component to the Printer
- */
- fwrite(upd->outbuf,1,ioutbuf,out);
- ioutbuf = 0;
- } /* Component-Print */
- } /* Some data to write */
-
- /** Advance counters in upd, change modi */
-
- if(upd->yscan < upd->ints[I_BEG_Y]) {
- upd->yscan += upd->int_a[IA_BEG_DY].data[upd->ipass++];
- if( upd->ints[I_BEG_Y] <= upd->yscan) upd->ipass = 0;
- else if(upd->int_a[IA_BEG_DY].size <= upd->ipass) upd->ipass = 0;
- } else if(upd->yscan >= upd->ints[I_END_Y]) {
- upd->yscan += upd->int_a[IA_END_DY].data[upd->ipass++];
- if(upd->int_a[IA_END_DY].size <= upd->ipass) upd->ipass = 0;
- } else {
- upd->yscan += upd->int_a[IA_STD_DY].data[upd->ipass++];
- if(upd->int_a[IA_STD_DY].size <= upd->ipass) upd->ipass = 0;
- if(upd->yscan >= upd->ints[I_END_Y]) upd->ipass = 0;
- }
-
- return 0;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_open_wrtescp2: ESC/P2 Writer intended for ESC . 1 commands */
- /* ------------------------------------------------------------------- */
-
- private int
- upd_open_wrtescp2(upd_device *udev)
- {
- const upd_p upd = udev->upd;
- int error = 0;
- float pixels_per_inch = 360.0;
-
- /** Analyze (and optionally adjust) the BOP-Sequence */
- if(0 < upd->strings[S_BEGIN].size) { /* BOP-Checker */
- int i,state = 0,value = 0;
- byte *bp = (byte *) upd->strings[S_BEGIN].data;
- for(i = 0; i < upd->strings[S_BEGIN].size; ++i) {
- switch(state) {
- case 0:
- if(0x1b == bp[i]) state = 1;
- break;
- case 1:
- if('(' == bp[i]) state = 2;
- else state = 0;
- break;
- case 2:
- switch(bp[i]) {
- case 'U': state = 3; break; /* Printer-Resolution */
- case 'C': state = 6; break; /* Page-Length */
- case 'c': state = 10; break; /* Top/Bottom Margin */
- default: state = 0; break;
- }
- break;
- case 3:
- if(1 == bp[i]) state = 4;
- else state = 0;
- break;
- case 4:
- if(0 == bp[i]) state = 5;
- else state = 0;
- break;
- case 5:
- pixels_per_inch = 3600.0 / (float) bp[i];
- state = 0;
- break;
- case 6:
- if(2 == bp[i]) state = 7;
- else state = 0;
- break;
- case 7:
- if(0 == bp[i]) state = 8;
- else state = 0;
- break;
- case 8:
- if(B_PAGELENGTH & upd->flags) {
- value = 0.5 + udev->height
- * pixels_per_inch / udev->y_pixels_per_inch;
- bp[i] = value & 0xff;
- }
- state = 9;
- break;
- case 9:
- if(B_PAGELENGTH & upd->flags) {
- bp[i] = (value>>8) & 0xff;
- }
- state = 0;
- break;
- case 10:
- if(4 == bp[i]) state = 11;
- else state = 0;
- break;
- case 11:
- if(0 == bp[i]) state = 12;
- else state = 0;
- break;
- case 12:
- if(B_TOPMARGIN & upd->flags) {
- value = dev_t_margin(udev) * pixels_per_inch;
- bp[i] = value & 0xff;
- }
- state = 13;
- break;
- case 13:
- if(B_TOPMARGIN & upd->flags) {
- bp[i] = (value>>8) & 0xff;
- }
- state = 14;
- break;
- case 14:
- if(B_BOTTOMMARGIN & upd->flags) {
- value = 0.5 + udev->height
- * pixels_per_inch / udev->y_pixels_per_inch
- - dev_b_margin(udev) * pixels_per_inch;
- bp[i] = value & 0xff;
- }
- state = 15;
- break;
- case 15:
- if(B_BOTTOMMARGIN & upd->flags) {
- bp[i] = (value>>8) & 0xff;
- }
- state = 0;
- break;
- }
- }
- } /* BOP-Checker */
-
- /** Create Y-Move-Command, if not given */
- if(0 == upd->strings[S_YMOVE].size) {
- byte *bp;
- UPD_MM_DEL_PARAM(upd->strings[S_YMOVE]);
- UPD_MM_GET_ARRAY(bp,5);
- upd->strings[S_YMOVE].data = bp;
- upd->strings[S_YMOVE].size = 5;
- *bp++ = 0x1b; /* ESC */
- *bp++ = '(';
- *bp++ = upd->flags & B_YABS ? 'V' : 'v';
- *bp++ = 2;
- *bp++ = 0;
- }
-
- /** X-Positioning must be set too, sometimes */
- if((1 < upd->ints[I_XSTEP]) && (0 == upd->strings[S_XSTEP].size)) {
-
- #if UPD_MESSAGES & UPD_M_WARNING
- fprintf(stderr,
- "ESC/P2-Open: XSTEP-Command required for XSTEP=%d\n",
- upd->ints[I_XSTEP]);
- #endif
- error = -1;
-
- } else if((1 < upd->ints[I_NXPASS] ) &&
- (0 == upd->strings[S_XMOVE].size) &&
- (0 == upd->strings[S_XSTEP].size) ) {
- byte *bp;
- int ratio;
-
- ratio = (udev->y_pixels_per_inch + .5) / udev->x_pixels_per_inch;
-
- if(0 == upd->ints[I_XSTEP]) { /* Adjust scale-factor too! */
- if(ratio > 1) upd->ints[I_XSTEP] = -ratio;
- } else { /* Adjust scale-factor too! */
- ratio = -upd->ints[I_XSTEP];
- }
-
- if(2 == upd->ints[I_NXPASS]) { /* Use a relative Step */
-
- UPD_MM_DEL_PARAM(upd->strings[S_XSTEP]);
- UPD_MM_GET_ARRAY(bp,4);
- upd->strings[S_XSTEP].size = 4;
- upd->strings[S_XSTEP].data = bp;
- *bp++ = 0x1b;
- *bp++ = '\\';
- *bp++ = ratio & 0xff;
- *bp++ = (ratio>>8) & 0xff;
-
- } else { /* Use relative or absolute Move */
-
- UPD_MM_DEL_PARAM(upd->strings[S_XMOVE]);
- UPD_MM_GET_ARRAY(bp,2);
- upd->strings[S_XMOVE].size = 2;
- upd->strings[S_XMOVE].data = bp;
- *bp++ = 0x1b;
- *bp++ = upd->flags & B_XABS ? '$' : '\\';
-
- }
- }
-
- /** If there is neither a writecomp nor a setcomp-command, generate both */
- if((0 == upd->string_a[SA_WRITECOMP].size) &&
- (0 == upd->string_a[SA_SETCOMP].size ) ) { /* Default-commands */
- byte *bp;
- gs_param_string *ap;
- int i;
-
- if(4 == upd->ocomp) { /* Establish Component-Selection */
- UPD_MM_DEL_APARAM(upd->string_a[SA_SETCOMP]);
- UPD_MM_GET_ARRAY(ap,4);
- upd->string_a[SA_SETCOMP].data = ap;
- upd->string_a[SA_SETCOMP].size = 4;
- for(i = 0; i < 4; ++i) {
- UPD_MM_GET_ARRAY(bp,3);
- ap[i].size = 3;
- ap[i].data = bp;
- *bp++ = 0x1b;
- *bp++ = 'r';
- switch(((updcomp_p)upd->valptr[i])->cmap) { /* use COMPORDER! */
- case 0: *bp++ = 0; break; /* Black */
- case 1: *bp++ = 2; break; /* Cyan */
- case 2: *bp++ = 1; break; /* Magenta */
- case 3: *bp++ = 4; break; /* Yellow */
- } /* use COMPORDER! */
- }
- } /* Establish Component-Selection */
-
- UPD_MM_DEL_APARAM(upd->string_a[SA_WRITECOMP]);
- UPD_MM_GET_ARRAY(ap,upd->ocomp);
- upd->string_a[SA_WRITECOMP].data = ap;
- upd->string_a[SA_WRITECOMP].size = upd->ncomp;
- for(i = 0; i < upd->ocomp; ++i) {
- UPD_MM_GET_ARRAY(bp,6);
- ap[i].size = 6;
- ap[i].data = bp;
- *bp++ = 0x1b;
- *bp++ = '.';
- *bp++ = 1; /* RLE */
- *bp++ = 3600.0 * upd->ints[I_NYPASS] / udev->y_pixels_per_inch + 0.5;
- *bp++ = 3600.0 * upd->ints[I_NXPASS] / udev->x_pixels_per_inch + 0.5;
- *bp++ = upd->ints[I_PINS2WRITE];
- }
- } /* Default-commands */
-
- /** SA_WRITECOMP must be valid */
- if(upd->ocomp > upd->string_a[SA_WRITECOMP].size) {
- #if UPD_MESSAGES & UPD_M_WARNING
- fprintf(stderr,
- "ESC/P2-Open: WRITECOMP-Commands must be given\n");
- #endif
- error = -1;
- }
-
- /** Check Validity of X-Pass */
- switch(upd->choice[C_FORMAT]) {
- case FMT_ESCP2Y:
- if(1 < upd->ints[I_NXPASS]) {
- #if UPD_MESSAGES & UPD_M_WARNING
- fprintf(stderr,
- "ESC/P2-Open: FMT_ESCP2Y cannot handle multiple X-Passes\n");
- #endif
- error = -1;
- } else {
- upd->writer = upd_wrtescp2;
- }
- break;
- case FMT_ESCP2XY:
- upd->writer = upd_wrtescp2x;
- upd->nlimits = upd->ints[I_NXPASS];
- #if UPD_MESSAGES & UPD_M_WARNING
- if(1 == upd->ints[I_NXPASS])
- fprintf(stderr,
- "ESC/P2-Open: FMT_ESCP2XY should not be used with 1X-Pass\n");
- #endif
- break;
- default:
- #if UPD_MESSAGES & UPD_M_WARNING
- fprintf(stderr,
- "ESC/P2-Open: %d is not a ESC/P2-Format\n",
- upd->choice[C_FORMAT]);
- #endif
- error = - 1;
- break;
- }
-
-
- /**
- If all this is correct, it's time to compute the size of the output-buffer.
- It must hold:
- 1. Y-Positioning
- 2. X-Positioning
- 3. Component-Selection
- 4. The Raster-Command
- 5. The Data
- */
- if(0 <= error) {
- int32 i,noutbuf,need;
-
- if(0 < upd->strings[S_YMOVE].size) {
- noutbuf = upd->strings[S_YMOVE].size + 2;
- } else {
- int nmax = upd->pheight;
- if( 1 < upd->ints[I_YSTEP]) nmax /= upd->ints[I_YSTEP];
- else if(-1 > upd->ints[I_YSTEP]) nmax *= -upd->ints[I_YSTEP];
- noutbuf = 2 * upd->strings[S_SETLF].size + 2;
- noutbuf += nmax/255 + 1;
- }
-
- if(1 < upd->ints[I_YSTEP])
- noutbuf += (upd->ints[I_YSTEP]-1) * upd->strings[S_YSTEP].size;
-
- if(0 == upd->strings[S_XMOVE].size) {
- noutbuf += 1; /* The CR */
- noutbuf += (upd->ints[I_NXPASS]-1) * upd->strings[S_XSTEP].size;
- } else {
- noutbuf += upd->strings[S_XMOVE].size + 2;
-
- if(1 < upd->ints[I_XSTEP])
- noutbuf += (upd->ints[I_XSTEP]-1) * upd->strings[S_XSTEP].size;
- }
-
- if(0 < upd->string_a[SA_SETCOMP].size) {
- need = 0;
- for(i = 0; i < upd->ocomp; ++i)
- if(need < upd->string_a[SA_SETCOMP].data[i].size)
- need = upd->string_a[SA_SETCOMP].data[i].size;
- noutbuf += need;
- }
-
- need = 0;
- for(i = 0; i < upd->ocomp; ++i)
- if(need < upd->string_a[SA_WRITECOMP].data[i].size)
- need = upd->string_a[SA_WRITECOMP].data[i].size;
- noutbuf += need + 2;
-
- noutbuf += 2*upd->nbytes + (upd->nbytes + 127) / 128;
-
- upd->noutbuf = noutbuf;
- error = 1;
-
- }
-
- return error;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_wrtescp2: Write a pass */
- /* ------------------------------------------------------------------- */
-
- private int
- upd_wrtescp2(upd_p upd, FILE *out)
- {
- int pinbot,pin,pintop,xbegin,x,xend,icomp,ybegin,yend,y,ioutbuf,n;
- byte *obytes;
- updscan_p scan;
-
- /** Determine the number of pins to write */
-
- if(upd->yscan < upd->ints[I_BEG_Y]) {
- pintop = 0;
- pinbot = upd->int_a[IA_BEGBOT].data[upd->ipass];
- } else if(upd->yscan >= upd->ints[I_END_Y]) {
- pinbot = upd->ints[I_PINS2WRITE];
- pintop = pinbot - upd->int_a[IA_ENDTOP].data[upd->ipass];
- } else {
- pintop = 0;
- pinbot = upd->ints[I_PINS2WRITE];
- }
-
- ybegin = pintop * upd->ints[I_NYPASS] + upd->yscan - upd->ints[I_BEGSKIP];
- yend = pinbot * upd->ints[I_NYPASS] + upd->yscan - upd->ints[I_BEGSKIP];
-
- /** Determine Width of this scan */
-
- xbegin = upd->nbytes;
- xend = -1;
-
- for(y = ybegin; y < yend; y += upd->ints[I_NYPASS]) { /* Pin-testloop */
-
- if(0 > y) continue; /* Inserted Scanlines */
-
- scan = upd->scnbuf[y & upd->scnmsk];
-
- for(icomp = 0; icomp < upd->ocomp; ++icomp) { /* Compwise test */
- obytes = scan[icomp].bytes;
-
- for(x = 0; x < xbegin && !obytes[x]; x++);
- if(x < xbegin) xbegin = x;
-
- if(x < upd->nbytes) {
- for(x = upd->nbytes-1; x > xend && !obytes[x]; x--);
- if(x > xend) xend = x;
- }
- } /* Compwise test */
-
- } /* Pin-testloop */
-
- if(xbegin <= xend) { /* Some data to write */
-
- ioutbuf = 0;
-
- if(0 == upd->strings[S_XMOVE].size) xbegin = 0;
-
- /*
- * Adjust the Printers Y-Position
- */
- if(upd->yscan != upd->yprinter) { /* Adjust Y-Position */
- if(B_YABS & upd->flags) y = upd->yscan + upd->ints[I_YOFS];
- else y = upd->yscan - upd->yprinter;
-
- if( 1 < upd->ints[I_YSTEP]) {
- n = y / upd->ints[I_YSTEP]; /* Major-Steps */
- y -= n * upd->ints[I_YSTEP]; /* Minor-Steps */
- } else if(-1 > upd->ints[I_YSTEP]) {
- n = y * -upd->ints[I_YSTEP]; /* May this work? */
- y = 0;
- } else {
- n = y;
- y = 0;
- }
-
- if(n) { /* Coarse Positioning */
- memcpy(upd->outbuf+ioutbuf,
- upd->strings[S_YMOVE].data,upd->strings[S_YMOVE].size);
- ioutbuf += upd->strings[S_YMOVE].size;
-
- upd->outbuf[ioutbuf++] = n & 0xff;
- upd->outbuf[ioutbuf++] = (n>>8) & 0xff;
-
- } /* Coarse Positioning */
-
- if(0 < upd->strings[S_YSTEP].size) {
- while(y--) {
- memcpy(upd->outbuf+ioutbuf,
- upd->strings[S_YSTEP].data,
- upd->strings[S_YSTEP].size);
- ioutbuf += upd->strings[S_YSTEP].size;
- }
- }
-
- upd->yprinter = upd->yscan;
- } /* Adjust Y-Position */
- /*
- * Now write the required components
- */
- for(icomp = 0; icomp < upd->ocomp; ++icomp) { /* Component-Print */
- /*
- * First check, wether this Component needs printing
- */
- for(y = ybegin; y < yend; y += upd->ints[I_NYPASS]) { /* Comp-Test */
- if(0 > y) continue;
- obytes = upd->scnbuf[y & upd->scnmsk][icomp].bytes;
- for(x = xbegin; x <= xend && !obytes[x]; ++x);
- if( x <= xend) break;
- } /* Comp-Test */
- if(y >= yend) continue; /* Component not required */
- /*
- * Select the Component
- */
- if((0 < upd->string_a[SA_SETCOMP].size) &&
- (upd->icomp != icomp ) ) { /* Selection enabled */
- upd->icomp = icomp;
- if(0 < upd->string_a[SA_SETCOMP].data[icomp].size) {
- memcpy(upd->outbuf+ioutbuf,
- upd->string_a[SA_SETCOMP].data[icomp].data,
- upd->string_a[SA_SETCOMP].data[icomp].size);
- ioutbuf += upd->string_a[SA_SETCOMP].data[icomp].size;
- }
- } /* Selection enabled */
- /*
- * Establish the X-Position
- */
- if(xbegin != upd->xprinter) {
-
- if(0 == upd->strings[S_XMOVE].size) {
-
- upd->outbuf[ioutbuf++] = '\r';
- upd->xprinter = 0;
- n = 0;
- x = 0;
-
- } else {
-
- if(B_XABS & upd->flags) n = x = xbegin + upd->ints[I_XOFS];
- else n = x = xbegin - upd->xprinter;
-
- if( 1 < upd->ints[I_XSTEP]) {
- if(0 > n) {
- n -= upd->ints[I_XSTEP];
- x -= n;
- }
- if(n) n /= upd->ints[I_XSTEP]; /* Major-Steps */
- if(x) x %= upd->ints[I_XSTEP]; /* Minor-Steps */
-
- } else if(-1 > upd->ints[I_XSTEP]) {
- n *= -upd->ints[I_XSTEP]; /* May this work? */
- x = 0;
- }
-
- if(n) { /* Adjust X-Position */
-
- memcpy(upd->outbuf+ioutbuf,
- upd->strings[S_XMOVE].data,
- upd->strings[S_XMOVE].size);
- ioutbuf += upd->strings[S_XMOVE].size;
-
- upd->outbuf[ioutbuf++] = n & 0xff;
- upd->outbuf[ioutbuf++] = (n>>8) & 0xff;
-
- } /* Adjust X-Position */
-
- }
-
- if(x && 0 < upd->strings[S_XSTEP].size) { /* Fine-Adjust X */
- while(x--) {
- memcpy(upd->outbuf+ioutbuf,
- upd->strings[S_XSTEP].data,
- upd->strings[S_XSTEP].size);
- ioutbuf += upd->strings[S_XSTEP].size;
- }
- } /* Fine-Adjust X */
- }
- upd->xprinter = xend+1;
-
- /*
- * Send the Write-Command
- */
- if(0 < upd->string_a[SA_WRITECOMP].data[icomp].size) {
- memcpy(upd->outbuf+ioutbuf,
- upd->string_a[SA_WRITECOMP].data[icomp].data,
- upd->string_a[SA_WRITECOMP].data[icomp].size);
- ioutbuf += upd->string_a[SA_WRITECOMP].data[icomp].size;
- }
- n = xend + 1 - xbegin;
- upd->outbuf[ioutbuf++] = (n<<3) & 255;
- upd->outbuf[ioutbuf++] = (n>>5) & 255;
- /*
- * Set the Pixels
- */
- for(pin = 0; pin < pintop; ++pin) {
- ioutbuf += upd_rle(upd->outbuf+ioutbuf,NULL,n);
- fwrite(upd->outbuf,1,ioutbuf,out);
- ioutbuf = 0;
- }
-
- for(y = ybegin; 0 > y; y += upd->ints[I_NYPASS]) {
- ioutbuf += upd_rle(upd->outbuf+ioutbuf,NULL,n);
- fwrite(upd->outbuf,1,ioutbuf,out);
- ioutbuf = 0;
- }
-
- for(; y < yend; y += upd->ints[I_NYPASS]) {
- ioutbuf += upd_rle(upd->outbuf+ioutbuf,
- upd->scnbuf[y & upd->scnmsk][icomp].bytes+xbegin,n);
- fwrite(upd->outbuf,1,ioutbuf,out);
- ioutbuf = 0;
- }
-
- for(pin = pinbot; pin < upd->ints[I_PINS2WRITE]; ++pin) {
- ioutbuf += upd_rle(upd->outbuf+ioutbuf,NULL,n);
- fwrite(upd->outbuf,1,ioutbuf,out);
- ioutbuf = 0;
- }
- } /* Component-Print */
- } /* Some data to write */
-
- /** Advance counters in upd, change modi */
- if(upd->yscan < upd->ints[I_BEG_Y]) {
- upd->yscan += upd->int_a[IA_BEG_DY].data[upd->ipass++];
- if( upd->ints[I_BEG_Y] <= upd->yscan) upd->ipass = 0;
- else if(upd->int_a[IA_BEG_DY].size <= upd->ipass) upd->ipass = 0;
- } else if(upd->yscan >= upd->ints[I_END_Y]) {
- upd->yscan += upd->int_a[IA_END_DY].data[upd->ipass++];
- if(upd->int_a[IA_END_DY].size <= upd->ipass) upd->ipass = 0;
- } else {
- upd->yscan += upd->int_a[IA_STD_DY].data[upd->ipass++];
- if(upd->int_a[IA_STD_DY].size <= upd->ipass) upd->ipass = 0;
- if(upd->yscan >= upd->ints[I_END_Y]) upd->ipass = 0;
- }
-
- return 0;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_wrtescp2x: Write an ESC/P2-pass with X-Weaving */
- /* ------------------------------------------------------------------- */
-
- private int
- upd_wrtescp2x(upd_p upd, FILE *out)
- {
- int pinbot,pin,pintop,xbegin,x,xend,icomp,ybegin,yend,y,ioutbuf,n,ixpass;
- byte *obytes,bit;
- updscan_p scan;
-
- /** Determine the number of pins to write */
-
- if(upd->yscan < upd->ints[I_BEG_Y]) {
- ixpass = upd->int_a[IA_BEG_IX].data[upd->ipass];
- pintop = 0;
- pinbot = upd->int_a[IA_BEGBOT].data[upd->ipass];
- } else if(upd->yscan >= upd->ints[I_END_Y]) {
- ixpass = upd->int_a[IA_END_IX].data[upd->ipass];
- pinbot = upd->ints[I_PINS2WRITE];
- pintop = pinbot - upd->int_a[IA_ENDTOP].data[upd->ipass];
- } else {
- ixpass = upd->int_a[IA_STD_IX].data[upd->ipass];
- pintop = 0;
- pinbot = upd->ints[I_PINS2WRITE];
- }
-
- ybegin = pintop * upd->ints[I_NYPASS] + upd->yscan - upd->ints[I_BEGSKIP];
- yend = pinbot * upd->ints[I_NYPASS] + upd->yscan - upd->ints[I_BEGSKIP];
-
- /** Determine Width of this scan */
-
- xbegin = upd->pwidth;
- xend = -1;
-
- for(y = ybegin; y < yend; y += upd->ints[I_NYPASS]) { /* Pin-testloop */
-
- if(0 > y) continue; /* Inserted Scanlines */
-
- scan = upd->scnbuf[y & upd->scnmsk];
-
- for(icomp = 0; icomp < upd->ocomp; ++icomp) { /* Compwise test */
- if(xbegin > scan[icomp].xbegin[ixpass])
- xbegin = scan[icomp].xbegin[ixpass];
- if(xend < scan[icomp].xend[ ixpass])
- xend = scan[icomp].xend[ ixpass];
- } /* Compwise test */
-
- } /* Pin-testloop */
-
- if(xbegin <= xend) { /* Some data to write */
-
- ioutbuf = upd->nbytes;
-
- if(0 == upd->strings[S_XMOVE].size) xbegin = ixpass;
-
- /*
- * Adjust the Printers Y-Position
- */
- if(upd->yscan != upd->yprinter) { /* Adjust Y-Position */
- if(B_YABS & upd->flags) y = upd->yscan + upd->ints[I_YOFS];
- else y = upd->yscan - upd->yprinter;
-
- if( 1 < upd->ints[I_YSTEP]) {
- n = y / upd->ints[I_YSTEP]; /* Major-Steps */
- y -= n * upd->ints[I_YSTEP]; /* Minor-Steps */
- } else if(-1 > upd->ints[I_YSTEP]) {
- n = y * -upd->ints[I_YSTEP]; /* May this work? */
- y = 0;
- } else {
- n = y;
- y = 0;
- }
-
- if(n) { /* Coarse Positioning */
- memcpy(upd->outbuf+ioutbuf,
- upd->strings[S_YMOVE].data,upd->strings[S_YMOVE].size);
- ioutbuf += upd->strings[S_YMOVE].size;
-
- upd->outbuf[ioutbuf++] = n & 0xff;
- upd->outbuf[ioutbuf++] = (n>>8) & 0xff;
-
- } /* Coarse Positioning */
-
- if(0 < upd->strings[S_YSTEP].size) {
- while(y--) {
- memcpy(upd->outbuf+ioutbuf,
- upd->strings[S_YSTEP].data,
- upd->strings[S_YSTEP].size);
- ioutbuf += upd->strings[S_YSTEP].size;
- }
- }
-
- upd->yprinter = upd->yscan;
- } /* Adjust Y-Position */
-
- /*
- * Now write the required components
- */
- for(icomp = 0; icomp < upd->ocomp; ++icomp) { /* Component-Print */
- /*
- * First check, wether this Component needs printing
- */
- for(y = ybegin; y < yend; y += upd->ints[I_NYPASS]) { /* Comp-Test */
- if(0 > y) continue;
- scan = upd->scnbuf[y & upd->scnmsk]+icomp;
- if(0 <= scan->xend[ixpass]) break;
- } /* Comp-Test */
- if(y >= yend) continue; /* Component not required */
- /*
- * Select the Component
- */
- if((0 < upd->string_a[SA_SETCOMP].size) &&
- (upd->icomp != icomp ) ) { /* Selection enabled */
- upd->icomp = icomp;
- if(0 < upd->string_a[SA_SETCOMP].data[icomp].size) {
- memcpy(upd->outbuf+ioutbuf,
- upd->string_a[SA_SETCOMP].data[icomp].data,
- upd->string_a[SA_SETCOMP].data[icomp].size);
- ioutbuf += upd->string_a[SA_SETCOMP].data[icomp].size;
- }
- } /* Selection enabled */
- /*
- * Establish the X-Position
- */
- if(xbegin != upd->xprinter) {
-
- if(0 == upd->strings[S_XMOVE].size) {
-
- upd->outbuf[ioutbuf++] = '\r';
- upd->xprinter = 0;
- n = 0;
- x = ixpass;
-
- } else {
-
- if(B_XABS & upd->flags) n = x = xbegin + upd->ints[I_XOFS];
- else n = x = xbegin - upd->xprinter;
-
- if( 1 < upd->ints[I_XSTEP]) {
- if(0 > n) {
- n -= upd->ints[I_XSTEP];
- x -= n;
- }
- if(n) n /= upd->ints[I_XSTEP]; /* Major-Steps */
- if(x) x %= upd->ints[I_XSTEP]; /* Minor-Steps */
-
- } else if(-1 > upd->ints[I_XSTEP]) {
- n *= -upd->ints[I_XSTEP]; /* May this work? */
- x = 0;
- }
-
- if(n) { /* Adjust X-Position */
-
- memcpy(upd->outbuf+ioutbuf,
- upd->strings[S_XMOVE].data,
- upd->strings[S_XMOVE].size);
- ioutbuf += upd->strings[S_XMOVE].size;
-
- upd->outbuf[ioutbuf++] = n & 0xff;
- upd->outbuf[ioutbuf++] = (n>>8) & 0xff;
-
- } /* Adjust X-Position */
-
- }
-
- if(x && 0 < upd->strings[S_XSTEP].size) { /* Fine-Adjust X */
- while(x--) {
- memcpy(upd->outbuf+ioutbuf,
- upd->strings[S_XSTEP].data,
- upd->strings[S_XSTEP].size);
- ioutbuf += upd->strings[S_XSTEP].size;
- }
- } /* Fine-Adjust X */
- }
- upd->xprinter = xend+1;
-
- /*
- * Send the Write-Command
- */
- if(0 < upd->string_a[SA_WRITECOMP].data[icomp].size) {
- memcpy(upd->outbuf+ioutbuf,
- upd->string_a[SA_WRITECOMP].data[icomp].data,
- upd->string_a[SA_WRITECOMP].data[icomp].size);
- ioutbuf += upd->string_a[SA_WRITECOMP].data[icomp].size;
- }
- n = ((xend - xbegin) / upd->ints[I_NXPASS] + 8) & ~7;
- upd->outbuf[ioutbuf++] = n & 255;
- upd->outbuf[ioutbuf++] = (n>>8) & 255;
- n >>= 3;
- /*
- * Set the Pixels
- */
- for(pin = 0; pin < pintop; ++pin) {
- ioutbuf += upd_rle(upd->outbuf+ioutbuf,NULL,n);
- fwrite(upd->outbuf+upd->nbytes,1,ioutbuf-upd->nbytes,out);
- ioutbuf = upd->nbytes;
- }
-
- for(y = ybegin; 0 > y; y += upd->ints[I_NYPASS]) {
- ioutbuf += upd_rle(upd->outbuf+ioutbuf,NULL,n);
- fwrite(upd->outbuf+upd->nbytes,1,ioutbuf-upd->nbytes,out);
- ioutbuf = upd->nbytes;
- }
-
- for(; y < yend; y += upd->ints[I_NYPASS]) {
- byte * ibytes = upd->scnbuf[y & upd->scnmsk][icomp].bytes;
- obytes = upd->outbuf;
- memset(obytes,0,upd->nbytes);
- bit = 0x80;
- for(x = xbegin; x <= xend; x += upd->ints[I_NXPASS]) {
- if(ibytes[x>>3] & (0x80 >> (x & 7))) *obytes |= bit;
- if(!(bit >>= 1)) { obytes++; bit = 0x80; }
- }
- ioutbuf += upd_rle(upd->outbuf+ioutbuf,upd->outbuf,n);
- fwrite(upd->outbuf+upd->nbytes,1,ioutbuf-upd->nbytes,out);
- ioutbuf = upd->nbytes;
- }
-
- for(pin = pinbot; pin < upd->ints[I_PINS2WRITE]; ++pin) {
- ioutbuf += upd_rle(upd->outbuf+ioutbuf,NULL,n);
- fwrite(upd->outbuf+upd->nbytes,1,ioutbuf-upd->nbytes,out);
- ioutbuf = upd->nbytes;
- }
- } /* Component-Print */
- } /* Some data to write */
-
- /** Advance counters in upd, change modi */
-
- if(upd->yscan < upd->ints[I_BEG_Y]) {
- upd->yscan += upd->int_a[IA_BEG_DY].data[upd->ipass++];
- if( upd->ints[I_BEG_Y] <= upd->yscan) upd->ipass = 0;
- else if(upd->int_a[IA_BEG_DY].size <= upd->ipass) upd->ipass = 0;
- } else if(upd->yscan >= upd->ints[I_END_Y]) {
- upd->yscan += upd->int_a[IA_END_DY].data[upd->ipass++];
- if(upd->int_a[IA_END_DY].size <= upd->ipass) upd->ipass = 0;
- } else {
- upd->yscan += upd->int_a[IA_STD_DY].data[upd->ipass++];
- if(upd->int_a[IA_STD_DY].size <= upd->ipass) upd->ipass = 0;
- if(upd->yscan >= upd->ints[I_END_Y]) upd->ipass = 0;
- }
-
- return 0;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_rle: The Runlength-Compressor */
- /* ------------------------------------------------------------------- */
-
- private int
- upd_rle(byte *out,const byte *in,int nbytes)
- {
-
- int used = 0;
- int crun,cdata;
- byte run;
-
- if(in != NULL) { /* Data present */
-
- crun = 1;
-
- while(nbytes > 0) { /* something to compress */
-
- run = in[0];
-
- while((nbytes > crun) && (run == in[crun])) if(++crun == 128) break;
-
- if((crun > 2) || (crun == nbytes)) { /* use this run */
-
- *out++ = (257 - crun) & 0xff; *out++ = run; used += 2;
-
- nbytes -= crun; in += crun;
- crun = 1;
-
- } else { /* ignore this run */
-
- for(cdata = crun; (nbytes > cdata) && (crun < 4);) {
- if(run == in[cdata]) crun += 1;
- else run = in[cdata], crun = 1;
- if(++cdata == 128) break;
- }
-
- if(crun < 3) crun = 0; /* ignore trailing run */
- else cdata -= crun;
-
- *out++ = cdata-1; used++;
- memcpy(out,in,cdata); used += cdata; out += cdata;
-
- nbytes -= cdata; in += cdata;
-
- } /* use/ignore run */
-
- } /* something to compress */
-
- } else { /* Empty scans to fill bands */
-
- while(nbytes > 0) {
- crun = nbytes > 128 ? 128 : nbytes;
- nbytes -= crun;
- *out++ = (257 - crun) & 0xff;
- *out++ = 0;
- used += 2;
- }
- } /* Data present or empty */
- return used;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_open_wrtrtl: Basic HP-RTL Writer */
- /* ------------------------------------------------------------------- */
-
- private int
- upd_open_wrtrtl(upd_device *udev)
- {
- const upd_p upd = udev->upd;
- int error = 0;
-
- /** Adjust the Raster-Width */
-
- if(0 < upd->strings[S_BEGIN].size) { /* BOP-Checker */
-
- int i,j,state = 0;
- char cv[24];
- byte *bp;
- uint ncv,nbp;
-
- j = -1;
- for(i = 0; i < upd->strings[S_BEGIN].size; ++i) {
- const int c = upd->strings[S_BEGIN].data[i];
-
- switch(state) {
- case 0:
- if( c == 0x1b) state = 1; /* ESC */
- break;
-
- case 1:
- if( c == 0x2a) state = 2; /* ESC * */
- else if( c == 0x25) state = 5; /* ESC % */
- else state = 0;
- break;
-
- case 2:
- j = i; /* This character is not part of the replaced text */
- if( c == 0x72) state = 3; /* ESC * r */
- else if( c == 0x74) state = 4; /* ESC * t */
- else state = 0;
- break;
-
- case 3:
-
- if( (B_PAGEWIDTH & upd->flags) &&
- ((c == 0x73) || (c == 0x53)) ) { /* esc * r # S */
-
- sprintf(cv,"%d",upd->pwidth);
- ncv = strlen(cv);
-
- nbp = (j+1) + ncv + (upd->strings[S_BEGIN].size-i);
- UPD_MM_GET_ARRAY(bp,nbp);
-
- if(0 <= j) memcpy(bp,upd->strings[S_BEGIN].data,j+1);
- memcpy(bp+j+1, cv,ncv);
- memcpy(bp+j+1+ncv,upd->strings[S_BEGIN].data+i,
- upd->strings[S_BEGIN].size-i);
- i = j+1+ncv;
- UPD_MM_DEL_PARAM(upd->strings[S_BEGIN]);
- upd->strings[S_BEGIN].data = bp;
- upd->strings[S_BEGIN].size = nbp;
-
- } else if((B_PAGELENGTH & upd->flags) &&
- ((c == 0x74) || (c == 0x54)) ) { /* esc * r # T */
-
- sprintf(cv,"%d",upd->pheight);
- ncv = strlen(cv);
-
- nbp = (j+1) + ncv + (upd->strings[S_BEGIN].size-i);
- UPD_MM_GET_ARRAY(bp,nbp);
-
- if(0 <= j) memcpy(bp,upd->strings[S_BEGIN].data,j+1);
- memcpy(bp+j+1, cv,ncv);
- memcpy(bp+j+1+ncv,upd->strings[S_BEGIN].data+i,
- upd->strings[S_BEGIN].size-i);
- i = j+1+ncv;
- UPD_MM_DEL_PARAM(upd->strings[S_BEGIN]);
- upd->strings[S_BEGIN].data = bp;
- upd->strings[S_BEGIN].size = nbp;
-
- }
-
- if( (0x40 < c) && (c < 0x5b)) state = 0; /* Term. cmd. */
- else if(!((0x2f < c) && (c < 0x3a))) j = i; /* Non-Number */
-
- break;
-
- case 4: /* esc * t */
-
- if( (B_RESOLUTION & upd->flags) &&
- ((c == 0x72) || (c == 0x52)) ) { /* esc * t # R */
-
- sprintf(cv,"%d",(int)
- ((udev->y_pixels_per_inch < udev->x_pixels_per_inch ?
- udev->x_pixels_per_inch : udev->y_pixels_per_inch)
- +0.5));
- ncv = strlen(cv);
-
- nbp = (j+1) + ncv + (upd->strings[S_BEGIN].size-i);
- UPD_MM_GET_ARRAY(bp,nbp);
-
- if(0 <= j) memcpy(bp,upd->strings[S_BEGIN].data,j+1);
- memcpy(bp+j+1, cv,ncv);
- memcpy(bp+j+1+ncv,upd->strings[S_BEGIN].data+i,
- upd->strings[S_BEGIN].size-i);
- i = j+1+ncv;
- UPD_MM_DEL_PARAM(upd->strings[S_BEGIN]);
- upd->strings[S_BEGIN].data = bp;
- upd->strings[S_BEGIN].size = nbp;
-
- }
-
- if( (0x40 < c) && (c < 0x5b)) state = 0; /* Term. cmd. */
- else if(!((0x2f < c) && (c < 0x3a))) j = i; /* Non-Number */
-
- break;
-
- case 5: /* ESC % - 1 2 3 4 5 X */
- if( c == 0x2d) state = 6; /* ESC % - */
- else state = 0;
- break;
-
- case 6: /* ESC % - 1 2 3 4 5 X */
- if( c == 0x31) state = 7; /* ESC % - 1 */
- else state = 0;
- break;
-
- case 7: /* ESC % - 1 2 3 4 5 X */
- if( c == 0x32) state = 8; /* ESC % - 1 2 */
- else state = 0;
- break;
-
- case 8: /* ESC % - 1 2 3 4 5 X */
- if( c == 0x33) state = 9; /* ESC % - 1 2 3 */
- else state = 0;
- break;
-
- case 9: /* ESC % - 1 2 3 4 5 X */
- if( c == 0x34) state = 10; /* ESC % - 1 2 3 4 */
- else state = 0;
- break;
-
- case 10: /* ESC % - 1 2 3 4 5 X */
- if( c == 0x35) state = 11; /* ESC % - 1 2 3 4 5 */
- else state = 0;
- break;
-
- case 11: /* ESC % - 1 2 3 4 5 X */
- if( c == 0x58) state = 12; /* ESC % - 1 2 3 4 5 X */
- else state = 0;
- break;
-
- case 12: /* PJL-BOL: @ P J L ws */
- if( c == 0x40) state = 13; /* @ */
- else state = 0;
- break;
-
- case 13: /* PJL-BOL @ P J L ws */
- if( c == 0x50) state = 14; /* @ P */
- else state = 0;
- break;
-
- case 14: /* PJL-BOL @ P J L ws */
- if( c == 0x4a) state = 15; /* @ P J */
- else state = 0;
- break;
-
- case 15: /* PJL-BOL @ P J L ws */
- if( c == 0x4c) state = 16; /* @ P J L */
- else state = 0;
- break;
-
- case 16: /* PJL-BOL @ P J L ws */
- if((c == 0x20) || (c == 0x09)) state = 19; /* @ P J L ws */
- else if( c == 0x0d ) state = 17;
- else if( c == 0x0a ) state = 12;
- else state = 0; /* PJL-Error */
- break;
-
- case 17: /* PJL-EOL */
- if( c == 0x0a) state = 12; /* Next PJL-Command */
- else state = 0; /* PJL-Error */
- break;
-
- case 18: /* PJL-Eatup: Expect Newline */
- if( c == 0x0a) state = 12;
- break;
-
- case 19: /* Begin of PJL-Command */
- if( (c == 0x53) || (c == 0x73)) state = 20; /* S E T*/
- else if( c == 0x0a ) state = 12; /* BOL */
- else if( c == 0x0d ) state = 17;
- break;
-
- case 20: /* PJL-Set: S E T */
- if( (c == 0x45) || (c == 0x65)) state = 21; /* S E */
- else if( c == 0x0a ) state = 12; /* BOL */
- else state = 18;
- break;
-
- case 21: /* PJL-Set: S E T */
- if( (c == 0x54) || (c == 0x74)) state = 22; /* S E T */
- else if( c == 0x0a ) state = 12; /* BOL */
- else state = 18;
- break;
-
- case 22: /* PJL-Set: S E T ws */
- if( (c == 0x20) || (c == 0x09)) state = 23; /* S E T ws */
- else if( c == 0x0a ) state = 12; /* BOL */
- else state = 18;
- break;
-
- case 23: /* PJL-Set: S E T ws */
- if( (c == 0x50) || (c == 0x70)) state = 24; /* set paper... */
- else if((c == 0x52) || (c == 0x72)) state = 41; /* set resolution */
- else if( c == 0x0a ) state = 12; /* BOL */
- else state = 18;
- break;
-
- case 24: /* PJL-Set: set paper... */
- if( (c == 0x41) || (c == 0x61)) state = 25; /* set pa */
- else if( c == 0x0a ) state = 12; /* BOL */
- else state = 18;
- break;
-
- case 25: /* PJL-Set: set paper... */
- if( (c == 0x50) || (c == 0x70)) state = 26; /* set pap */
- else if( c == 0x0a ) state = 12; /* BOL */
- else state = 18;
- break;
-
- case 26: /* PJL-Set: set paper... */
- if( (c == 0x45) || (c == 0x65)) state = 27; /* set pape */
- else if( c == 0x0a ) state = 12; /* BOL */
- else state = 18;
- break;
-
- case 27: /* PJL-Set: set paper... */
- if( (c == 0x52) || (c == 0x72)) state = 28; /* set paper */
- else if( c == 0x0a ) state = 12; /* BOL */
- else state = 18;
- break;
-
- case 28: /* PJL-Set: set paper? */
- if( (c == 0x4c) || (c == 0x6c)) state = 29; /* set paperlength */
- else if((c == 0x57) || (c == 0x77)) state = 36; /* set paperwidth */
- else if( c == 0x0a ) state = 12; /* BOL */
- else state = 18;
- break;
-
- case 29: /* PJL: set paperlength */
- if( (c == 0x45) || (c == 0x65)) state = 30; /* set paperle */
- else if( c == 0x0a ) state = 12; /* BOL */
- else state = 18;
- break;
-
- case 30: /* PJL: set paperlength */
- if( (c == 0x4e) || (c == 0x6e)) state = 31; /* set paperlen */
- else if( c == 0x0a ) state = 12; /* BOL */
- else state = 18;
- break;
-
- case 31: /* PJL: set paperlength */
- if( (c == 0x47) || (c == 0x67)) state = 32; /* set paperleng */
- else if( c == 0x0a ) state = 12; /* BOL */
- else state = 18;
- break;
-
- case 32: /* PJL: set paperlength */
- if( (c == 0x54) || (c == 0x74)) state = 33; /* set paperlengt */
- else if( c == 0x0a ) state = 12; /* BOL */
- else state = 18;
- break;
-
- case 33: /* PJL: set paperlength */
- if( (c == 0x48) || (c == 0x68)) state = 34; /* set paperlength */
- else if( c == 0x0a ) state = 12; /* BOL */
- else state = 18;
- break;
-
- case 34: /* PJL: set paperlength */
- if( c == 0x3d ) state = 35; /* set paperlength */
- else if( c == 0x0a ) state = 12; /* BOL */
- else if((c != 0x20) && (c != 0x09)) state = 18;
- break;
-
- case 35: /* PJL: set paperlength */
- if(c == 0x30) { /* Replace this Zero */
-
- sprintf(cv,"%d",(int)
- (720.0 * udev->height / udev->y_pixels_per_inch));
- ncv = strlen(cv);
-
- nbp = upd->strings[S_BEGIN].size + ncv - 1;
- UPD_MM_GET_ARRAY(bp,nbp);
-
- if(0 < i) memcpy(bp,upd->strings[S_BEGIN].data,i);
- memcpy(bp+i,cv,ncv);
- if(upd->strings[S_BEGIN].size > (i+1))
- memcpy(bp+i+ncv,upd->strings[S_BEGIN].data+i+1,
- upd->strings[S_BEGIN].size-i-1);
-
- i += ncv - 1;
- UPD_MM_DEL_PARAM(upd->strings[S_BEGIN]);
- upd->strings[S_BEGIN].data = bp;
- upd->strings[S_BEGIN].size = nbp;
-
- } else if( c == 0x0a ) state = 12;
- else if((c != 0x20) && (c != 0x09) && (c != 0x3d)) state = 18;
-
- break;
-
- case 36: /* PJL: set paperwidth */
- if( (c == 0x49) || (c == 0x69)) state = 37; /* set paperwi */
- else if( c == 0x0a ) state = 12; /* BOL */
- else state = 18;
- break;
-
- case 37: /* PJL: set paperwidth */
- if( (c == 0x44) || (c == 0x64)) state = 38; /* set paperwid */
- else if( c == 0x0a ) state = 12; /* BOL */
- else state = 18;
- break;
-
- case 38: /* PJL: set paperwidth */
- if( (c == 0x54) || (c == 0x74)) state = 39; /* set paperwidt */
- else if( c == 0x0a ) state = 12; /* BOL */
- else state = 18;
- break;
-
- case 39: /* PJL: set paperwidth */
- if( (c == 0x48) || (c == 0x68)) state = 40; /* set paperwidth */
- else if( c == 0x0a ) state = 12; /* BOL */
- else state = 18;
- break;
-
- case 40: /* PJL: set paperwidth */
- if(c == 0x30) { /* Replace this Zero */
-
- sprintf(cv,"%d",(int)
- (720.0 * udev->width / udev->x_pixels_per_inch));
- ncv = strlen(cv);
-
- nbp = upd->strings[S_BEGIN].size + ncv - 1;
- UPD_MM_GET_ARRAY(bp,nbp);
-
- if(0 < i) memcpy(bp,upd->strings[S_BEGIN].data,i);
- memcpy(bp+i,cv,ncv);
- if(upd->strings[S_BEGIN].size > (i+1))
- memcpy(bp+i+ncv,upd->strings[S_BEGIN].data+i+1,
- upd->strings[S_BEGIN].size-i-1);
-
- i += ncv - 1;
- UPD_MM_DEL_PARAM(upd->strings[S_BEGIN]);
- upd->strings[S_BEGIN].data = bp;
- upd->strings[S_BEGIN].size = nbp;
-
- } else if( c == 0x0a ) state = 12;
- else if((c != 0x20) && (c != 0x09) && (c != 0x3d)) state = 18;
-
- break;
-
- case 41: /* PJL: set resolution */
- if( (c == 0x45) || (c == 0x65)) state = 42; /* set re */
- else if( c == 0x0a ) state = 12; /* BOL */
- else state = 18;
- break;
-
- case 42: /* PJL: set resolution */
- if( (c == 0x53) || (c == 0x73)) state = 43; /* set res */
- else if( c == 0x0a ) state = 12; /* BOL */
- else state = 18;
- break;
-
- case 43: /* PJL: set resolution */
- if( (c == 0x4f) || (c == 0x6f)) state = 44; /* set reso */
- else if( c == 0x0a ) state = 12; /* BOL */
- else state = 18;
- break;
-
- case 44: /* PJL: set resolution */
- if( (c == 0x4c) || (c == 0x6c)) state = 45; /* set resol */
- else if( c == 0x0a ) state = 12; /* BOL */
- else state = 18;
- break;
-
- case 45: /* PJL: set resolution */
- if( (c == 0x55) || (c == 0x75)) state = 46; /* set resolu */
- else if( c == 0x0a ) state = 12; /* BOL */
- else state = 18;
- break;
-
- case 46: /* PJL: set resolution */
- if( (c == 0x54) || (c == 0x74)) state = 47; /* set resolut */
- else if( c == 0x0a ) state = 12; /* BOL */
- else state = 18;
- break;
-
- case 47: /* PJL: set resolution */
- if( (c == 0x49) || (c == 0x69)) state = 48; /* set resoluti */
- else if( c == 0x0a ) state = 12; /* BOL */
- else state = 18;
- break;
-
- case 48: /* PJL: set resolution */
- if( (c == 0x4f) || (c == 0x6f)) state = 49; /* set resolutio */
- else if( c == 0x0a ) state = 12; /* BOL */
- else state = 18;
- break;
-
- case 49: /* PJL: set resolution */
- if( (c == 0x4e) || (c == 0x6e)) state = 50; /* set resolution */
- else if( c == 0x0a ) state = 12; /* BOL */
- else state = 18;
- break;
-
- case 50: /* PJL: set resolution */
- if(c == 0x30) { /* Replace this Zero */
-
- sprintf(cv,"%d",(int)
- ((udev->y_pixels_per_inch < udev->x_pixels_per_inch ?
- udev->x_pixels_per_inch : udev->y_pixels_per_inch)
- +0.5));
- ncv = strlen(cv);
-
- nbp = upd->strings[S_BEGIN].size + ncv - 1;
- UPD_MM_GET_ARRAY(bp,nbp);
-
- if(0 < i) memcpy(bp,upd->strings[S_BEGIN].data,i);
- memcpy(bp+i,cv,ncv);
- if(upd->strings[S_BEGIN].size > (i+1))
- memcpy(bp+i+ncv,upd->strings[S_BEGIN].data+i+1,
- upd->strings[S_BEGIN].size-i-1);
-
- i += ncv - 1;
- UPD_MM_DEL_PARAM(upd->strings[S_BEGIN]);
- upd->strings[S_BEGIN].data = bp;
- upd->strings[S_BEGIN].size = nbp;
-
- } else if( c == 0x0a ) state = 12;
- else if((c != 0x20) && (c != 0x09) && (c != 0x3d)) state = 18;
-
- break;
-
- default:
- #if UPD_MESSAGES & UPD_M_ERROR
- fprintf(stderr,"UNIPRINT-Coding error, wrrtl, state = %d\n",state);
- #endif
- state = 0;
- break;
- }
- }
- } /* BOP-Checker */
-
- /** SA_WRITECOMP must be valid */
- if(upd->ocomp > upd->string_a[SA_WRITECOMP].size) {
- #if UPD_MESSAGES & UPD_M_WARNING
- fprintf(stderr,
- "PCL-Open: WRITECOMP-Commands must be given\n");
- #endif
- error = -1;
- }
-
- /**
- If all this is correct, it's time to compute the size of the output-buffer.
- It must hold:
- 1. Y-Positioning
- 2. Component-Data
- */
- if(0 <= error) {
- int32 ny,noutbuf;
- char tmp[16];
-
- if(0 < upd->strings[S_YMOVE].size) {
- sprintf(tmp,"%d",upd->pheight);
- ny = upd->strings[S_YMOVE].size + strlen(tmp);
- } else {
- ny = 1 + upd->string_a[SA_WRITECOMP].data[upd->ocomp-1].size;
- ny *= upd->pheight;
- }
-
- noutbuf = upd->nbytes + (upd->nbytes + 127) / 128;
-
- if(ny > noutbuf) noutbuf = ny;
- noutbuf += 16;
-
- if((0 < noutbuf) && (noutbuf <= INT_MAX)) {
- upd->noutbuf = noutbuf;
- upd->writer = upd_wrtrtl;
- error = 1;
- } else {
- error = -1;
- #if UPD_MESSAGES & UPD_M_WARNING
- fprintf(stderr,
- "PCL-Open: %ld is unreasonable size of Outputbuffer\n",
- (long) noutbuf);
- #endif
- }
- }
-
- return error;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_wrtrtl: Write a pass */
- /* ------------------------------------------------------------------- */
-
- private int
- upd_wrtrtl(upd_p upd, FILE *out)
- {
- const updscan_p scan = upd->scnbuf[upd->yscan & upd->scnmsk];
-
- int x,xend,icomp,ioutbuf;
- byte *data;
-
- /** Determine Width of this scan */
-
- xend = -1;
- for(icomp = 0; icomp < upd->ocomp; ++icomp) {
-
- data = scan[icomp].bytes;
-
- for(x = upd->nbytes-1; 0 <= x; --x) if(data[x]) break;
- if(x > xend) xend = x;
- }
-
- if(0 <= xend) { /* Some data to write */
-
- ioutbuf = 0;
- xend += 1;
- /*
- * Adjust the Printers Y-Position
- */
- if(upd->yscan != upd->yprinter) { /* Adjust Y-Position */
- if(1 < upd->strings[S_YMOVE].size) {
- sprintf((char *)upd->outbuf+ioutbuf,
- (char *) upd->strings[S_YMOVE].data,upd->yscan - upd->yprinter);
- ioutbuf += strlen((char *)upd->outbuf+ioutbuf);
- } else {
- while(upd->yscan > upd->yprinter) {
- for(icomp = 0; icomp < upd->ocomp; ++icomp) {
- sprintf((char *)upd->outbuf+ioutbuf,
- (char *) upd->string_a[SA_WRITECOMP].data[icomp].data,0);
- ioutbuf += strlen((char *)upd->outbuf+ioutbuf);
- }
- fwrite(upd->outbuf,1,ioutbuf,out);
- ioutbuf = 0;
- upd->yprinter += 1;
- }
- }
- upd->yprinter = upd->yscan;
- fwrite(upd->outbuf,1,ioutbuf,out);
- ioutbuf = 0;
- } /* Adjust Y-Position */
- /*
- * Now write the all! components
- */
- for(icomp = 0; icomp < upd->ocomp; ++icomp) { /* Component-Print */
- data = scan[icomp].bytes;
- for(x = 0; x <= xend; ++x) if(data[x]) break;
- if(x <= xend) {
- ioutbuf = upd_rle(upd->outbuf,scan[icomp].bytes,xend);
- fprintf(out,
- (char *)upd->string_a[SA_WRITECOMP].data[icomp].data,ioutbuf);
- fwrite(upd->outbuf,1,ioutbuf,out);
- } else {
- fprintf(out,
- (char *)upd->string_a[SA_WRITECOMP].data[icomp].data,0);
- }
- }
-
- upd->yprinter += 1;
-
- } /* Some data to write */
-
- /** Advance scan by one */
-
- upd->yscan += 1;
-
- return 0;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_open_wrtcanon: Basic Canon Extended Mode Writer (hr) */
- /* ------------------------------------------------------------------- */
-
- private int
- upd_open_wrtcanon(upd_device *udev)
- {
- const upd_p upd = udev->upd;
- int error = 0;
-
- /* max length of one printer line */
- upd->noutbuf = upd->nbytes + (upd->nbytes + 127) / 128;
- upd->writer = upd_wrtcanon;
- error = 1;
-
- return error;
- }
-
- /* ------------------------------------------------------------------- */
- /* upd_wrtcanon: Write a pass (hr) */
- /* ------------------------------------------------------------------- */
-
- #define LOW(b) ((b)&0xFF)
- #define HIGH(b) ((b)>>8)
- #define ESC 0x1B
- #define CR 0x0D
-
- private int
- upd_wrtcanon(upd_p upd, FILE *out)
- {
- const updscan_p scan = upd->scnbuf[upd->yscan & upd->scnmsk];
-
- int x, xend, icomp, ioutbuf, step, ioutbuf1;
- byte *data;
-
-
- /* Check length of the printable date */
- xend = -1;
- for(icomp = 0; icomp < upd->ocomp; ++icomp) {
- data = scan[icomp].bytes;
-
- for(x = upd->nbytes-1; 0 <= x; --x) if(data[x]) break;
-
- if(x > xend) xend = x;
- }
-
- /* If some date to print */
- if(0 <= xend) { /* Some data to write */
- ioutbuf = 0;
- xend += 1;
-
- /* Perform vertical tab */
- if(upd->yscan != upd->yprinter) {
- step = upd->yscan - upd->yprinter;
-
- fputc(ESC, out);
- fputc('(', out);
- fputc('e', out);
- fputc(2, out);
- fputc(0, out);
- fputc(HIGH(step), out);
- fputc(LOW(step), out);
-
- upd->yprinter = upd->yscan;
- }
-
- for(icomp = 0; icomp < upd->ocomp; ++icomp) {
-
- /* Are there date to print for the selected color component */
- data = scan[icomp].bytes;
- for(x = 0; x <= xend; ++x) if(data[x]) break;
-
- /* Compressing of the scan line */
- if(x <= xend) {
- ioutbuf = upd_rle(upd->outbuf, scan[icomp].bytes, xend);
- } else {
- ioutbuf = 0;
- }
-
- ioutbuf1 = ioutbuf + 1;
-
- /* prints the scan line */
- fputc(ESC, out);
- fputc('(', out);
- fputc('A', out);
- fputc(LOW(ioutbuf1), out);
- fputc(HIGH(ioutbuf1), out);
- switch(upd->ocomp) {
- case 1: fputc('K',out); break;
- case 3:
- case 4: fputc("YMCK"[icomp],out); break;
- /*
- * Please Note:
- * the validity of the NCOMP-setting should be checked
- * in the put_params-routine, thus the default-case is
- * just a matter of coding-style.
- */
- default: fputc('K',out); break;
- }
-
- fwrite(upd->outbuf, 1, ioutbuf, out);
-
- fputc(CR, out);
- }
-
- /* Printer advances one raster line */
- fputc(ESC, out);
- fputc('(', out);
- fputc('e', out);
- fputc(2, out);
- fputc(0, out);
- fputc(HIGH(1), out);
- fputc(LOW(1), out);
-
- upd->yprinter += 1;
-
- }
-
- /* Advance scan by one */
- upd->yscan += 1;
-
- return 0;
- }
-
- /* ------------------------------------------------------------------- */
- /* All the Pixel-Get Routines */
- /* ------------------------------------------------------------------- */
-
- /* That bunch of Pixel-Get Routines */
-
- private upd_proc_pxlget(upd_pxlgetnix); /* A Dummy */
-
- private upd_proc_pxlget(upd_pxlget1f1); /* 1 Bit Forward */
- private upd_proc_pxlget(upd_pxlget1f2);
- private upd_proc_pxlget(upd_pxlget1f3);
- private upd_proc_pxlget(upd_pxlget1f4);
- private upd_proc_pxlget(upd_pxlget1f5);
- private upd_proc_pxlget(upd_pxlget1f6);
- private upd_proc_pxlget(upd_pxlget1f7);
- private upd_proc_pxlget(upd_pxlget1f8);
-
- private upd_proc_pxlget(upd_pxlget1r1); /* 1 Bit Reverse */
- private upd_proc_pxlget(upd_pxlget1r2);
- private upd_proc_pxlget(upd_pxlget1r3);
- private upd_proc_pxlget(upd_pxlget1r4);
- private upd_proc_pxlget(upd_pxlget1r5);
- private upd_proc_pxlget(upd_pxlget1r6);
- private upd_proc_pxlget(upd_pxlget1r7);
- private upd_proc_pxlget(upd_pxlget1r8);
-
- private upd_proc_pxlget(upd_pxlget2f1); /* 2 Bit Forward */
- private upd_proc_pxlget(upd_pxlget2f2);
- private upd_proc_pxlget(upd_pxlget2f3);
- private upd_proc_pxlget(upd_pxlget2f4);
-
- private upd_proc_pxlget(upd_pxlget2r1); /* 2 Bit Reverse */
- private upd_proc_pxlget(upd_pxlget2r2);
- private upd_proc_pxlget(upd_pxlget2r3);
- private upd_proc_pxlget(upd_pxlget2r4);
-
- private upd_proc_pxlget(upd_pxlget4f1); /* 4 Bit Forward */
- private upd_proc_pxlget(upd_pxlget4f2);
-
- private upd_proc_pxlget(upd_pxlget4r1); /* 4 Bit Reverse */
- private upd_proc_pxlget(upd_pxlget4r2);
-
- private upd_proc_pxlget(upd_pxlget8f); /* 8 Bit Forward */
- private upd_proc_pxlget(upd_pxlget8r); /* 8 Bit Reverse */
-
- private upd_proc_pxlget(upd_pxlget16f); /* 16 Bit Forward */
- private upd_proc_pxlget(upd_pxlget16r); /* 16Bit Reverse */
-
- private upd_proc_pxlget(upd_pxlget24f); /* 24 Bit Forward */
- private upd_proc_pxlget(upd_pxlget24r); /* 24 Bit Reverse */
-
- private upd_proc_pxlget(upd_pxlget32f); /* 32 Bit Forward */
- private upd_proc_pxlget(upd_pxlget32r); /* 32 Bit Reverse */
-
- /* Initialize Forward-Run */
-
- private uint32
- upd_pxlfwd(upd_p upd)
- {
- if(!(upd->pxlptr = upd->gsscan)) {
-
- upd->pxlget = upd_pxlgetnix;
-
- } else {
- switch(upd->int_a[IA_COLOR_INFO].data[1]) {
- case 1: upd->pxlget = upd_pxlget1f1; break;
- case 2: upd->pxlget = upd_pxlget2f1; break;
- case 4: upd->pxlget = upd_pxlget4f1; break;
- case 8: upd->pxlget = upd_pxlget8f; break;
- case 16: upd->pxlget = upd_pxlget16f; break;
- case 24: upd->pxlget = upd_pxlget24f; break;
- case 32: upd->pxlget = upd_pxlget32f; break;
- default:
- #if UPD_MESSAGES & UPD_M_ERROR
- fprintf(stderr,"upd_pxlfwd: unsupported depth (%d)\n",
- upd->int_a[IA_COLOR_INFO].data[1]);
- #endif
- upd->pxlget = upd_pxlgetnix;
- break;
- }
- }
- return (uint32) 0;
- }
-
- /* 1 Bit Forward */
-
- private uint32
- upd_pxlget1f1(upd_p upd)
- {
- upd->pxlget = upd_pxlget1f2;
- return *upd->pxlptr & 0x80 ? (uint32) 1 : (uint32) 0;
- }
-
- private uint32
- upd_pxlget1f2(upd_p upd)
- {
- upd->pxlget = upd_pxlget1f3;
- return *upd->pxlptr & 0x40 ? (uint32) 1 : (uint32) 0;
- }
-
- private uint32
- upd_pxlget1f3(upd_p upd)
- {
- upd->pxlget = upd_pxlget1f4;
- return *upd->pxlptr & 0x20 ? (uint32) 1 : (uint32) 0;
- }
-
- private uint32
- upd_pxlget1f4(upd_p upd)
- {
- upd->pxlget = upd_pxlget1f5;
- return *upd->pxlptr & 0x10 ? (uint32) 1 : (uint32) 0;
- }
-
- private uint32
- upd_pxlget1f5(upd_p upd)
- {
- upd->pxlget = upd_pxlget1f6;
- return *upd->pxlptr & 0x08 ? (uint32) 1 : (uint32) 0;
- }
-
- private uint32
- upd_pxlget1f6(upd_p upd)
- {
- upd->pxlget = upd_pxlget1f7;
- return *upd->pxlptr & 0x04 ? (uint32) 1 : (uint32) 0;
- }
-
- private uint32
- upd_pxlget1f7(upd_p upd)
- {
- upd->pxlget = upd_pxlget1f8;
- return *upd->pxlptr & 0x02 ? (uint32) 1 : (uint32) 0;
- }
-
- private uint32
- upd_pxlget1f8(upd_p upd)
- {
- upd->pxlget = upd_pxlget1f1;
- return *upd->pxlptr++ & 0x01 ? (uint32) 1 : (uint32) 0;
- }
-
- /* 2 Bit Forward */
-
- private uint32
- upd_pxlget2f1(upd_p upd)
- {
- upd->pxlget = upd_pxlget2f2;
- return ((uint32) (*upd->pxlptr ) & (uint32) 0xC0) >> 6;
- }
-
- private uint32
- upd_pxlget2f2(upd_p upd)
- {
- upd->pxlget = upd_pxlget2f3;
- return ((uint32) (*upd->pxlptr ) & (uint32) 0x30) >> 4;
- }
-
- private uint32
- upd_pxlget2f3(upd_p upd)
- {
- upd->pxlget = upd_pxlget2f4;
- return ((uint32) (*upd->pxlptr ) & (uint32) 0x0C) >> 2;
- }
-
- private uint32
- upd_pxlget2f4(upd_p upd)
- {
- upd->pxlget = upd_pxlget2f1;
- return (uint32) (*upd->pxlptr++) & (uint32) 0x03;
- }
-
-
- /* 4 Bit Forward */
- private uint32
- upd_pxlget4f1(upd_p upd)
- {
- upd->pxlget = upd_pxlget4f2;
- return ((uint32) (*upd->pxlptr ) & (uint32) 0xF0) >> 4;
- }
-
- private uint32
- upd_pxlget4f2(upd_p upd)
- {
- upd->pxlget = upd_pxlget4f1;
- return (uint32) (*upd->pxlptr++) & (uint32) 0x0F;
- }
-
-
- /* 8 Bit Forward */
- private uint32
- upd_pxlget8f(upd_p upd)
- {
- return (uint32) (*upd->pxlptr++);
- }
-
-
- /* 16 Bit Forward */
- private uint32
- upd_pxlget16f(upd_p upd)
- {
- uint32 ci = (uint32) (*upd->pxlptr++) << 8;
- ci |= *upd->pxlptr++;
- return ci;
- }
-
- /* 24 Bit Forward */
- private uint32
- upd_pxlget24f(upd_p upd)
- {
- uint32 ci = (uint32) (*upd->pxlptr++) << 16;
- ci |= (uint32) (*upd->pxlptr++) << 8;
- ci |= *upd->pxlptr++;
- return ci;
- }
-
- /* 32 Bit Forward */
- private uint32
- upd_pxlget32f(upd_p upd)
- {
- uint32 ci = (uint32) (*upd->pxlptr++) << 24;
- ci |= (uint32) (*upd->pxlptr++) << 16;
- ci |= (uint32) (*upd->pxlptr++) << 8;
- ci |= *upd->pxlptr++;
- return ci;
- }
-
-
- /* Dummy-Routine */
-
- private uint32
- upd_pxlgetnix(upd_p upd)
- {
- return (uint32) 0;
- }
-
- /* Initialize Reverse-Run */
-
- private uint32
- upd_pxlrev(upd_p upd)
- {
- const uint width = upd->pwidth < upd->gswidth ? upd->pwidth : upd->gswidth;
-
- if(!(upd->pxlptr = upd->gsscan)) {
-
- upd->pxlget = upd_pxlgetnix;
-
- } else {
- uint32 ofs = (uint32) upd->int_a[IA_COLOR_INFO].data[1] * (width-1);
-
- upd->pxlptr += ofs>>3;
-
- ofs &= 7;
-
- switch(upd->int_a[IA_COLOR_INFO].data[1]) {
- case 1: switch(ofs) {
- case 0: upd->pxlget = upd_pxlget1r1; break;
- case 1: upd->pxlget = upd_pxlget1r2; break;
- case 2: upd->pxlget = upd_pxlget1r3; break;
- case 3: upd->pxlget = upd_pxlget1r4; break;
- case 4: upd->pxlget = upd_pxlget1r5; break;
- case 5: upd->pxlget = upd_pxlget1r6; break;
- case 6: upd->pxlget = upd_pxlget1r7; break;
- case 7: upd->pxlget = upd_pxlget1r8; break;
- } break;
- case 2: switch(ofs) {
- case 0: upd->pxlget = upd_pxlget2r1; break;
- case 2: upd->pxlget = upd_pxlget2r2; break;
- case 4: upd->pxlget = upd_pxlget2r3; break;
- case 6: upd->pxlget = upd_pxlget2r4; break;
- } break;
- case 4: switch(ofs) {
- case 0: upd->pxlget = upd_pxlget4r1; break;
- case 4: upd->pxlget = upd_pxlget4r2; break;
- } break;
- case 8: upd->pxlget = upd_pxlget8r; break;
- case 16:
- upd->pxlget = upd_pxlget16r;
- upd->pxlptr += 1;
- break;
- case 24:
- upd->pxlget = upd_pxlget24r;
- upd->pxlptr += 2;
- break;
- case 32:
- upd->pxlget = upd_pxlget32r;
- upd->pxlptr += 3;
- break;
- default:
- #if UPD_MESSAGES & UPD_M_ERROR
- fprintf(stderr,"upd_pxlrev: unsupported depth (%d)\n",
- upd->int_a[IA_COLOR_INFO].data[1]);
- #endif
- upd->pxlget = upd_pxlgetnix;
- break;
- }
- }
- return (uint32) 0;
- }
-
- /* 1 Bit Reverse */
-
- private uint32
- upd_pxlget1r1(upd_p upd)
- {
- upd->pxlget = upd_pxlget1r8;
- return *upd->pxlptr-- & 0x80 ? (uint32) 1 : (uint32) 0;
- }
-
- private uint32
- upd_pxlget1r2(upd_p upd)
- {
- upd->pxlget = upd_pxlget1r1;
- return *upd->pxlptr & 0x40 ? (uint32) 1 : (uint32) 0;
- }
-
- private uint32
- upd_pxlget1r3(upd_p upd)
- {
- upd->pxlget = upd_pxlget1r2;
- return *upd->pxlptr & 0x20 ? (uint32) 1 : (uint32) 0;
- }
-
- private uint32
- upd_pxlget1r4(upd_p upd)
- {
- upd->pxlget = upd_pxlget1r3;
- return *upd->pxlptr & 0x10 ? (uint32) 1 : (uint32) 0;
- }
-
- private uint32
- upd_pxlget1r5(upd_p upd)
- {
- upd->pxlget = upd_pxlget1r4;
- return *upd->pxlptr & 0x08 ? (uint32) 1 : (uint32) 0;
- }
-
- private uint32
- upd_pxlget1r6(upd_p upd)
- {
- upd->pxlget = upd_pxlget1r5;
- return *upd->pxlptr & 0x04 ? (uint32) 1 : (uint32) 0;
- }
-
- private uint32
- upd_pxlget1r7(upd_p upd)
- {
- upd->pxlget = upd_pxlget1r6;
- return *upd->pxlptr & 0x02 ? (uint32) 1 : (uint32) 0;
- }
-
- private uint32
- upd_pxlget1r8(upd_p upd)
- {
- upd->pxlget = upd_pxlget1r7;
- return *upd->pxlptr & 0x01 ? (uint32) 1 : (uint32) 0;
- }
-
- /* 2 Bit Reverse */
-
- private uint32
- upd_pxlget2r1(upd_p upd)
- {
- upd->pxlget = upd_pxlget2r4;
- return ((uint32) (*upd->pxlptr--) & (uint32) 0xC0) >> 6;
- }
-
- private uint32
- upd_pxlget2r2(upd_p upd)
- {
- upd->pxlget = upd_pxlget2r1;
- return ((uint32) (*upd->pxlptr ) & (uint32) 0x30) >> 4;
- }
-
- private uint32
- upd_pxlget2r3(upd_p upd)
- {
- upd->pxlget = upd_pxlget2r2;
- return ((uint32) (*upd->pxlptr ) & (uint32) 0x0C) >> 2;
- }
-
- private uint32
- upd_pxlget2r4(upd_p upd)
- {
- upd->pxlget = upd_pxlget2r3;
- return (uint32) (*upd->pxlptr ) & (uint32) 0x03;
- }
-
- /* 4 Bit Reverse */
-
- private uint32
- upd_pxlget4r1(upd_p upd)
- {
- upd->pxlget = upd_pxlget4r2;
- return ((uint32) (*upd->pxlptr--) & (uint32) 0xF0) >> 4;
- }
-
- private uint32
- upd_pxlget4r2(upd_p upd)
- {
- upd->pxlget = upd_pxlget4r1;
- return (uint32) (*upd->pxlptr ) & (uint32) 0x0F;
- }
-
-
- /* 8 Bit Reverse */
- private uint32
- upd_pxlget8r(upd_p upd)
- {
- return (uint32) (*upd->pxlptr--);
- }
-
-
- /* 16 Bit Reverse */
- private uint32
- upd_pxlget16r(upd_p upd)
- {
- uint32 ci = *upd->pxlptr--;
- ci |= (uint32) (*upd->pxlptr--) << 8;
- return ci;
- }
-
- /* 24 Bit Reverse */
- private uint32
- upd_pxlget24r(upd_p upd)
- {
- uint32 ci = *upd->pxlptr--;
- ci |= (uint32) (*upd->pxlptr--) << 8;
- ci |= (uint32) (*upd->pxlptr--) << 16;
- return ci;
- }
-
- /* 32 Bit Reverse */
- private uint32
- upd_pxlget32r(upd_p upd)
- {
- uint32 ci = *upd->pxlptr--;
- ci |= (uint32) (*upd->pxlptr--) << 8;
- ci |= (uint32) (*upd->pxlptr--) << 16;
- ci |= (uint32) (*upd->pxlptr--) << 24;
- return ci;
- }
-