17dd7cddfSDavid du Colombier /* Copyright (C) 1995, 1996 Aladdin Enterprises. All rights reserved.
27dd7cddfSDavid du Colombier
3*593dc095SDavid du Colombier This software is provided AS-IS with no warranty, either express or
4*593dc095SDavid du Colombier implied.
57dd7cddfSDavid du Colombier
6*593dc095SDavid du Colombier This software is distributed under license and may not be copied,
7*593dc095SDavid du Colombier modified or distributed except as expressly authorized under the terms
8*593dc095SDavid du Colombier of the license contained in the file LICENSE in this distribution.
93ff48bf5SDavid du Colombier
10*593dc095SDavid du Colombier For more information about licensing, please refer to
11*593dc095SDavid du Colombier http://www.ghostscript.com/licensing/. For information on
12*593dc095SDavid du Colombier commercial licensing, go to http://www.artifex.com/licensing/ or
13*593dc095SDavid du Colombier contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14*593dc095SDavid du Colombier San Rafael, CA 94903, U.S.A., +1(415)492-9861.
157dd7cddfSDavid du Colombier */
167dd7cddfSDavid du Colombier
17*593dc095SDavid du Colombier /* $Id: gdevstc.c,v 1.11 2004/11/22 19:25:57 giles Exp $*/
187dd7cddfSDavid du Colombier /* Epson Stylus-Color Printer-Driver */
197dd7cddfSDavid du Colombier
207dd7cddfSDavid du Colombier /***
217dd7cddfSDavid du Colombier *** This file was "copied" from gdevcdj.c (ghostscript-3.12), which was
227dd7cddfSDavid du Colombier *** contributed by:
237dd7cddfSDavid du Colombier *** George Cameron - g.cameron@biomed.abdn.ac.ukis
247dd7cddfSDavid du Colombier *** Koert Zeilstra - koert@zen.cais.com
257dd7cddfSDavid du Colombier *** Eckhard Rueggeberg - eckhard@ts.go.dlr.de
267dd7cddfSDavid du Colombier ***
277dd7cddfSDavid du Colombier *** Some of the ESC/P2-code was drawn from gdevescp.c, contributed by
287dd7cddfSDavid du Colombier *** Richard Brown - rab@eos.ncsu.edu
297dd7cddfSDavid du Colombier ***
307dd7cddfSDavid du Colombier *** The POSIX-Interrupt-Code is from (Compile-Time-Option -DSTC_SIGNAL)
317dd7cddfSDavid du Colombier *** Frederic Loyer - loyer@ensta.fr
327dd7cddfSDavid du Colombier ***
337dd7cddfSDavid du Colombier *** And several improvements are based on discussions with
347dd7cddfSDavid du Colombier *** Brian Converse - BCONVERSE@ids.net
357dd7cddfSDavid du Colombier *** Bill Davidson - bdavidson@ra.isisnet.com
367dd7cddfSDavid du Colombier *** Gero Guenther - gero@cs.tu-berlin.de
377dd7cddfSDavid du Colombier *** Jason Patterson - jason@reflections.com.au
387dd7cddfSDavid du Colombier *** ? Rueschstroer - rue@ibe.med.uni-muenchen.de
397dd7cddfSDavid du Colombier *** Steven Singer - S.Singer@ph.surrey.ac.uk
407dd7cddfSDavid du Colombier ***
417dd7cddfSDavid du Colombier *** And the remaining little rest, mainly the bugs, were written by me:
427dd7cddfSDavid du Colombier *** Gunther Hess - gunther@elmos.de
437dd7cddfSDavid du Colombier ***
447dd7cddfSDavid du Colombier *** P.S.: there is some documentation, see devices.doc
457dd7cddfSDavid du Colombier ***
467dd7cddfSDavid du Colombier *** Revision-History:
477dd7cddfSDavid du Colombier *** 16-DEC-1994 1.1 - initial Version (GS-Dithering & Plain-Write)
487dd7cddfSDavid du Colombier ...
497dd7cddfSDavid du Colombier *** 30-JAN-1995 1.11 - FS-Improvements, u/sWeave, 1/4/24-Bits
507dd7cddfSDavid du Colombier *** 5-MAR-1995 1.12 - L. Peter Deutsch - updated put_params routine
517dd7cddfSDavid du Colombier (first distributed version with gs3.33)
527dd7cddfSDavid du Colombier *** 26-APR-1995 1.13 - merged Peters fixes with algorithmic changes:
537dd7cddfSDavid du Colombier Changed 24Bit-Mode, added 32Bit-Mode (moves colors)
547dd7cddfSDavid du Colombier [Arrgh: much better than 1.12, but patch was lost]
557dd7cddfSDavid du Colombier *** 5-JUN-1995 1.14 - Added Color-Correction & Transfer-Curves
567dd7cddfSDavid du Colombier (Several Beta-Testers, but not distributed)
577dd7cddfSDavid du Colombier ...
587dd7cddfSDavid du Colombier *** 24-JUL-1995 1.16 - Made dithering-Algorithms external-functions.
597dd7cddfSDavid du Colombier (Mailed for Beta-Distribution)
607dd7cddfSDavid du Colombier *** 10-AUG-1995 1.17 - Several Bug-Fixes and some new features:
617dd7cddfSDavid du Colombier CMYK10-Coding added
627dd7cddfSDavid du Colombier Readonly Parameters added
637dd7cddfSDavid du Colombier "Algorithms", "BitsPerComponent", "Version"
647dd7cddfSDavid du Colombier Parameters Flag0-4, Model, OutputCode
657dd7cddfSDavid du Colombier (mailed for distribution)
667dd7cddfSDavid du Colombier *** 14-SEP-1995 1.18 Fixes Bugs with Borland C (gs3.47)
677dd7cddfSDavid du Colombier *** 23-SEP-1995 1.19 - reorganized printcode + bug-fixing
687dd7cddfSDavid du Colombier *** 24-SEP-1995 1.20 - Little Cleanup for the release
697dd7cddfSDavid du Colombier *** 25-SEP-1995 1.21 - Readonly-Parameters added to put_params.
707dd7cddfSDavid du Colombier *** 31-Dec-1995 1.22 - Sanitary Engineering on the code
717dd7cddfSDavid du Colombier *** 16-Jan-1996 1.23 - Added String escp_Release
727dd7cddfSDavid du Colombier *** 8-May-1996 1.90 - Reintroduced Deltarow & Fixed MEMORY-BUG!
737dd7cddfSDavid du Colombier ***/
747dd7cddfSDavid du Colombier
757dd7cddfSDavid du Colombier #include "gdevstc.h"
767dd7cddfSDavid du Colombier #ifdef STC_SIGNAL
777dd7cddfSDavid du Colombier # include <signal.h>
787dd7cddfSDavid du Colombier #endif /* STC_SIGNAL */
797dd7cddfSDavid du Colombier /***
807dd7cddfSDavid du Colombier *** Mode-Table - the various algorithms
817dd7cddfSDavid du Colombier *** (The intention is, that this source can live alone)
827dd7cddfSDavid du Colombier ***/
837dd7cddfSDavid du Colombier
847dd7cddfSDavid du Colombier private stc_proc_dither(stc_gscmyk); /* resides in this file */
857dd7cddfSDavid du Colombier private stc_proc_dither(stc_hscmyk); /* resides in this file */
867dd7cddfSDavid du Colombier
877dd7cddfSDavid du Colombier #include <stdlib.h> /* for rand, used in stc_hscmyk */
887dd7cddfSDavid du Colombier
897dd7cddfSDavid du Colombier private const stc_dither_t stc_dither[] = {
907dd7cddfSDavid du Colombier {"gscmyk", stc_gscmyk, DeviceCMYK|STC_BYTE|STC_DIRECT,0,{0.0,1.0}},
917dd7cddfSDavid du Colombier {"hscmyk", stc_hscmyk,
927dd7cddfSDavid du Colombier DeviceCMYK|STC_LONG|STC_CMYK10|STC_DIRECT|1*STC_SCAN,1+2*4,
937dd7cddfSDavid du Colombier {0.0, 1023.0}},
947dd7cddfSDavid du Colombier STC_MODI
957dd7cddfSDavid du Colombier { NULL , NULL , 0, 0,{0.0,0.0}}
967dd7cddfSDavid du Colombier };
977dd7cddfSDavid du Colombier
987dd7cddfSDavid du Colombier /***
997dd7cddfSDavid du Colombier *** forward-declarations of routines
1007dd7cddfSDavid du Colombier ***/
1017dd7cddfSDavid du Colombier
1027dd7cddfSDavid du Colombier /* Primary Device functions
1037dd7cddfSDavid du Colombier * (I've the idea to rename the driver to stc)
1047dd7cddfSDavid du Colombier */
1057dd7cddfSDavid du Colombier private dev_proc_print_page(stc_print_page);
1067dd7cddfSDavid du Colombier private dev_proc_open_device(stc_open);
1077dd7cddfSDavid du Colombier private dev_proc_close_device(stc_close);
1087dd7cddfSDavid du Colombier private dev_proc_get_params(stc_get_params);
1097dd7cddfSDavid du Colombier private dev_proc_put_params(stc_put_params);
1107dd7cddfSDavid du Colombier
1117dd7cddfSDavid du Colombier /*
1127dd7cddfSDavid du Colombier * Color-Mapping-functions.
1137dd7cddfSDavid du Colombier */
1147dd7cddfSDavid du Colombier
1157dd7cddfSDavid du Colombier /* routines for monochrome monochrome modi */
1167dd7cddfSDavid du Colombier private dev_proc_map_rgb_color(stc_map_gray_color);
1177dd7cddfSDavid du Colombier private dev_proc_map_color_rgb(stc_map_color_gray);
1187dd7cddfSDavid du Colombier
1197dd7cddfSDavid du Colombier /* routines for RGB-Modi */
1207dd7cddfSDavid du Colombier private dev_proc_map_rgb_color(stc_map_rgb_color);
1217dd7cddfSDavid du Colombier private dev_proc_map_color_rgb(stc_map_color_rgb);
1227dd7cddfSDavid du Colombier
1237dd7cddfSDavid du Colombier /* routines for general CMYK-Modi */
1247dd7cddfSDavid du Colombier private dev_proc_map_cmyk_color(stc_map_cmyk_color);
1257dd7cddfSDavid du Colombier private dev_proc_map_color_rgb(stc_map_color_cmyk);
1267dd7cddfSDavid du Colombier
1277dd7cddfSDavid du Colombier /* routines for 10Bit/Component CMYK */
1287dd7cddfSDavid du Colombier private dev_proc_map_cmyk_color(stc_map_cmyk10_color);
1297dd7cddfSDavid du Colombier private dev_proc_map_color_rgb(stc_map_color_cmyk10);
1307dd7cddfSDavid du Colombier
1317dd7cddfSDavid du Colombier /***
1327dd7cddfSDavid du Colombier *** Table of Device-Procedures
1337dd7cddfSDavid du Colombier ***/
1347dd7cddfSDavid du Colombier private gx_device_procs stcolor_procs = {
1357dd7cddfSDavid du Colombier stc_open,
1367dd7cddfSDavid du Colombier gx_default_get_initial_matrix,
1377dd7cddfSDavid du Colombier gx_default_sync_output,
1387dd7cddfSDavid du Colombier gdev_prn_output_page,
1397dd7cddfSDavid du Colombier stc_close,
1407dd7cddfSDavid du Colombier NULL,
1417dd7cddfSDavid du Colombier stc_map_color_cmyk,
1427dd7cddfSDavid du Colombier NULL, /* fill_rectangle */
1437dd7cddfSDavid du Colombier NULL, /* tile_rectangle */
1447dd7cddfSDavid du Colombier NULL, /* copy_mono */
1457dd7cddfSDavid du Colombier NULL, /* copy_color */
1467dd7cddfSDavid du Colombier NULL, /* draw_line */
1477dd7cddfSDavid du Colombier gx_default_get_bits,
1487dd7cddfSDavid du Colombier stc_get_params,
1497dd7cddfSDavid du Colombier stc_put_params,
1507dd7cddfSDavid du Colombier stc_map_cmyk_color
1517dd7cddfSDavid du Colombier };
1527dd7cddfSDavid du Colombier
1537dd7cddfSDavid du Colombier /***
1547dd7cddfSDavid du Colombier *** A local dummy-array for extvals
1557dd7cddfSDavid du Colombier ***/
1567dd7cddfSDavid du Colombier
1577dd7cddfSDavid du Colombier private float defext[] = { 0.0, 1.0 };
1587dd7cddfSDavid du Colombier
1597dd7cddfSDavid du Colombier /***
1607dd7cddfSDavid du Colombier *** Main device-control structure
1617dd7cddfSDavid du Colombier ***/
1627dd7cddfSDavid du Colombier stcolor_device far_data gs_stcolor_device = {
1637dd7cddfSDavid du Colombier prn_device_body(stcolor_device, stcolor_procs, "stcolor",
1647dd7cddfSDavid du Colombier DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
1657dd7cddfSDavid du Colombier X_DPI, Y_DPI,
1667dd7cddfSDavid du Colombier STC_L_MARGIN,STC_B_MARGIN,STC_R_MARGIN,STC_T_MARGIN,
1677dd7cddfSDavid du Colombier 4, 4, 1, 1, 2, 2, /* default: cmyk-direct */
1687dd7cddfSDavid du Colombier stc_print_page),
1697dd7cddfSDavid du Colombier {STCNWEAVE, /* stcflags: noWeave/bidirectional */
1707dd7cddfSDavid du Colombier 1, /* stcbits: matches the default */
1717dd7cddfSDavid du Colombier stc_dither, /* stcdither: first algorithm */
1727dd7cddfSDavid du Colombier NULL, /* stcam: NULL -> not used */
1737dd7cddfSDavid du Colombier { NULL, NULL, NULL, NULL}, /* extcode: none defined yet */
1747dd7cddfSDavid du Colombier { 0, 0, 0, 0}, /* sizcode: 0, since no extcode yet */
1757dd7cddfSDavid du Colombier { NULL, NULL, NULL, NULL}, /* stccode: computed by put_params */
1767dd7cddfSDavid du Colombier {defext,defext,defext,defext},/* extvals: default */
1777dd7cddfSDavid du Colombier { 2, 2, 2, 2}, /* sizvals: default countof(defext) */
1787dd7cddfSDavid du Colombier { NULL, NULL, NULL, NULL}, /* stcvals: computed by put_params */
1797dd7cddfSDavid du Colombier { 0, 0, 0}, /* white-run */
1807dd7cddfSDavid du Colombier { 0, 0, 0}, /* white-end */
1817dd7cddfSDavid du Colombier {NULL,0,false}, /* algorithm-table */
1827dd7cddfSDavid du Colombier {NULL,0,false}, /* initialization-String (BOP) */
1837dd7cddfSDavid du Colombier {NULL,0,false}, /* release-String (EOP) */
1847dd7cddfSDavid du Colombier 0,0,0,0, /* New escp-stuff */
1857dd7cddfSDavid du Colombier 1} /* itemsize used by algorithm */
1867dd7cddfSDavid du Colombier };
1877dd7cddfSDavid du Colombier /***
1887dd7cddfSDavid du Colombier *** Test for white scan-lines
1897dd7cddfSDavid du Colombier ***/
190*593dc095SDavid du Colombier private bool stc_iswhite(stcolor_device *, int, byte *);
1917dd7cddfSDavid du Colombier
1927dd7cddfSDavid du Colombier /***
1937dd7cddfSDavid du Colombier *** Functions used for conversion inside the print-loop
1947dd7cddfSDavid du Colombier ***/
1957dd7cddfSDavid du Colombier #define stc_proc_iconvert(Name) \
196*593dc095SDavid du Colombier byte * Name(stcolor_device *sd,byte *ext_data,int prt_pixels,byte *alg_line)
1977dd7cddfSDavid du Colombier
1987dd7cddfSDavid du Colombier private stc_proc_iconvert(stc_any_depth); /* general input-conversion */
1997dd7cddfSDavid du Colombier private stc_proc_iconvert(stc_rgb24_long); /* 24Bit RGB -> long's */
2007dd7cddfSDavid du Colombier
2017dd7cddfSDavid du Colombier private stc_proc_iconvert(stc_cmyk32_long); /* 32Bit CMYK -> long's */
2027dd7cddfSDavid du Colombier private stc_proc_iconvert(stc_any_direct); /* use ext_data as input */
2037dd7cddfSDavid du Colombier
2047dd7cddfSDavid du Colombier private stc_proc_iconvert(stc_cmyk10_byte); /* CMYK10->vals-> any type */
2057dd7cddfSDavid du Colombier private stc_proc_iconvert(stc_cmyk10_long); /* CMYK10->vals-> any type */
2067dd7cddfSDavid du Colombier private stc_proc_iconvert(stc_cmyk10_float); /* CMYK10->vals-> any type */
2077dd7cddfSDavid du Colombier private stc_proc_iconvert(stc_cmyk10_dbyte); /* CMYK10 direct bytes */
2087dd7cddfSDavid du Colombier private stc_proc_iconvert(stc_cmyk10_dlong); /* CMYK10 direct longs */
2097dd7cddfSDavid du Colombier
2107dd7cddfSDavid du Colombier /***
2117dd7cddfSDavid du Colombier *** Print-functions
2127dd7cddfSDavid du Colombier ***/
213*593dc095SDavid du Colombier private void stc_print_weave(stcolor_device *sd,FILE *prn_stream);
214*593dc095SDavid du Colombier private void stc_print_bands(stcolor_device *sd,FILE *prn_stream);
215*593dc095SDavid du Colombier private void stc_print_delta(stcolor_device *sd,FILE *prn_stream);
216*593dc095SDavid du Colombier private int stc_print_setup(stcolor_device *sd);
2177dd7cddfSDavid du Colombier
2187dd7cddfSDavid du Colombier /***
2197dd7cddfSDavid du Colombier *** compute the ESC/P2 specific values
2207dd7cddfSDavid du Colombier ***/
2217dd7cddfSDavid du Colombier
2227dd7cddfSDavid du Colombier private int
stc_print_setup(stcolor_device * sd)2237dd7cddfSDavid du Colombier stc_print_setup(stcolor_device *sd)
2247dd7cddfSDavid du Colombier {
2257dd7cddfSDavid du Colombier
2267dd7cddfSDavid du Colombier /*
2277dd7cddfSDavid du Colombier * Compute the resolution-parameters
2287dd7cddfSDavid du Colombier */
229*593dc095SDavid du Colombier sd->stc.escp_u = (int)(3600.0 / sd->y_pixels_per_inch); /* y-units */
230*593dc095SDavid du Colombier sd->stc.escp_h = (int)(3600.0 / sd->x_pixels_per_inch); /* x-units */
2317dd7cddfSDavid du Colombier sd->stc.escp_v = sd->stc.flags & (STCUWEAVE | STCNWEAVE) ?
2327dd7cddfSDavid du Colombier sd->stc.escp_u : 40;
2337dd7cddfSDavid du Colombier /*
2347dd7cddfSDavid du Colombier * Initialize color
2357dd7cddfSDavid du Colombier */
2367dd7cddfSDavid du Colombier sd->stc.escp_c = 0; /* preselect-black */
2377dd7cddfSDavid du Colombier
2387dd7cddfSDavid du Colombier /*
2397dd7cddfSDavid du Colombier * Band-Width
2407dd7cddfSDavid du Colombier */
2417dd7cddfSDavid du Colombier if((sd->stc.flags & STCBAND) == 0) {
2427dd7cddfSDavid du Colombier if(sd->stc.escp_v != sd->stc.escp_u) sd->stc.escp_m = 15;
2437dd7cddfSDavid du Colombier else if(STCSTCII == (sd->stc.flags & STCMODEL)) sd->stc.escp_m = 1;
2447dd7cddfSDavid du Colombier else if( sd->stc.flags & STCUWEAVE) sd->stc.escp_m = 1;
2457dd7cddfSDavid du Colombier else if((sd->stc.escp_v == sd->stc.escp_u) &&
2467dd7cddfSDavid du Colombier (sd->stc.escp_u == 5)) sd->stc.escp_m = 1;
2477dd7cddfSDavid du Colombier else sd->stc.escp_m = 1;
2487dd7cddfSDavid du Colombier }
2497dd7cddfSDavid du Colombier
2507dd7cddfSDavid du Colombier /*
2517dd7cddfSDavid du Colombier * Page-Dimensions
2527dd7cddfSDavid du Colombier */
2537dd7cddfSDavid du Colombier if((sd->stc.flags & STCWIDTH ) == 0)
254*593dc095SDavid du Colombier sd->stc.escp_width = (int)(sd->width -
255*593dc095SDavid du Colombier (dev_l_margin(sd)+dev_r_margin(sd))*sd->x_pixels_per_inch);
2567dd7cddfSDavid du Colombier
2577dd7cddfSDavid du Colombier if((sd->stc.flags & STCHEIGHT) == 0)
2587dd7cddfSDavid du Colombier sd->stc.escp_height = sd->height;
2597dd7cddfSDavid du Colombier
2607dd7cddfSDavid du Colombier if((sd->stc.flags & STCTOP) == 0)
261*593dc095SDavid du Colombier sd->stc.escp_top = (int)(dev_t_margin(sd)*sd->y_pixels_per_inch);
2627dd7cddfSDavid du Colombier
2637dd7cddfSDavid du Colombier if((sd->stc.flags & STCBOTTOM) == 0)
264*593dc095SDavid du Colombier sd->stc.escp_bottom = (int)(sd->height -
265*593dc095SDavid du Colombier dev_b_margin(sd)*sd->y_pixels_per_inch);
2667dd7cddfSDavid du Colombier
2677dd7cddfSDavid du Colombier if((sd->stc.flags & STCINIT) == 0) { /* No Initialization-String defined */
2687dd7cddfSDavid du Colombier int need = 8 /* Reset, Graphics-Mode 1 */
2697dd7cddfSDavid du Colombier + 6 /* MicroWeave */
2707dd7cddfSDavid du Colombier + 6 /* Select Units */
2717dd7cddfSDavid du Colombier + 7 /* Set Page-Length */
2727dd7cddfSDavid du Colombier + 9 /* Set Margins */
2737dd7cddfSDavid du Colombier + 3; /* Select Unidirectionality */
2747dd7cddfSDavid du Colombier byte *bp = (byte *) (sd->stc.escp_init.data);
2757dd7cddfSDavid du Colombier
2767dd7cddfSDavid du Colombier if(need != sd->stc.escp_init.size) { /* Reallocate */
2777dd7cddfSDavid du Colombier
278*593dc095SDavid du Colombier if(NULL != (bp = gs_malloc(sd->memory, need,1,"stcolor/init"))) { /* Replace */
2797dd7cddfSDavid du Colombier if(0 != sd->stc.escp_init.size)
280*593dc095SDavid du Colombier gs_free(sd->memory, (byte *)sd->stc.escp_init.data,sd->stc.escp_init.size,1,
2817dd7cddfSDavid du Colombier "stcolor/init");
2827dd7cddfSDavid du Colombier sd->stc.escp_init.data = bp;
2837dd7cddfSDavid du Colombier sd->stc.escp_init.size = need;
2847dd7cddfSDavid du Colombier sd->stc.escp_init.persistent = false;
2857dd7cddfSDavid du Colombier } else { /* Replace */
2867dd7cddfSDavid du Colombier return_error(gs_error_VMerror);
2877dd7cddfSDavid du Colombier }
2887dd7cddfSDavid du Colombier }
2897dd7cddfSDavid du Colombier
2907dd7cddfSDavid du Colombier if(need != 39) return_error(gs_error_unregistered);
2917dd7cddfSDavid du Colombier
2927dd7cddfSDavid du Colombier memcpy(bp,
2937dd7cddfSDavid du Colombier /* 1 1 11 1 11 1 1 1 2 22 2 2 22 2 22 3 3 3333 3 33*/
2947dd7cddfSDavid du Colombier /* 0 1 2 34 5 6 7 8 90 1 23 4 56 7 8 9 0 12 3 4 56 7 89 0 1 2345 6 78*/
2957dd7cddfSDavid du Colombier "\033@\033(G\001\0\1\033(i\1\0w\033(U\001\000u\033(C\2\000hh\033(c\4\000ttbb\033U",
2967dd7cddfSDavid du Colombier need);
2977dd7cddfSDavid du Colombier
2987dd7cddfSDavid du Colombier
2997dd7cddfSDavid du Colombier if((sd->stc.flags & STCUWEAVE) != 0) bp[13] = '\1';
3007dd7cddfSDavid du Colombier else bp[13] = '\0';
3017dd7cddfSDavid du Colombier
3027dd7cddfSDavid du Colombier bp[19] = sd->stc.escp_u;
3037dd7cddfSDavid du Colombier
3047dd7cddfSDavid du Colombier bp[25] = sd->stc.escp_height & 0xff;
3057dd7cddfSDavid du Colombier bp[26] = (sd->stc.escp_height>>8) & 0xff;
3067dd7cddfSDavid du Colombier
3077dd7cddfSDavid du Colombier bp[32] = sd->stc.escp_top & 0xff;
3087dd7cddfSDavid du Colombier bp[33] = (sd->stc.escp_top>>8) & 0xff;
3097dd7cddfSDavid du Colombier bp[34] = sd->stc.escp_bottom & 0xff;
3107dd7cddfSDavid du Colombier bp[35] = (sd->stc.escp_bottom>>8) & 0xff;
3117dd7cddfSDavid du Colombier
3127dd7cddfSDavid du Colombier if(sd->stc.flags & STCUNIDIR) bp[38] = 1;
3137dd7cddfSDavid du Colombier else bp[38] = 0;
3147dd7cddfSDavid du Colombier
3157dd7cddfSDavid du Colombier } /* No Initialization-String defined */
3167dd7cddfSDavid du Colombier
3177dd7cddfSDavid du Colombier if((sd->stc.flags & STCRELEASE) == 0) { /* No Release-String defined */
3187dd7cddfSDavid du Colombier int need = 3; /* ESC @ \f */
3197dd7cddfSDavid du Colombier byte *bp = (byte *) (sd->stc.escp_release.data);
3207dd7cddfSDavid du Colombier
3217dd7cddfSDavid du Colombier if(need != sd->stc.escp_release.size) { /* Reallocate */
3227dd7cddfSDavid du Colombier
323*593dc095SDavid du Colombier if(NULL != (bp = gs_malloc(sd->memory, need,1,"stcolor/release"))) { /* Replace */
3247dd7cddfSDavid du Colombier if(0 != sd->stc.escp_release.size)
325*593dc095SDavid du Colombier gs_free(sd->memory, (byte *)sd->stc.escp_release.data,sd->stc.escp_release.size,1,
3267dd7cddfSDavid du Colombier "stcolor/release");
3277dd7cddfSDavid du Colombier sd->stc.escp_release.data = bp;
3287dd7cddfSDavid du Colombier sd->stc.escp_release.size = need;
3297dd7cddfSDavid du Colombier sd->stc.escp_release.persistent = false;
3307dd7cddfSDavid du Colombier } else { /* Replace */
3317dd7cddfSDavid du Colombier return_error(gs_error_VMerror);
3327dd7cddfSDavid du Colombier }
3337dd7cddfSDavid du Colombier }
3347dd7cddfSDavid du Colombier
3357dd7cddfSDavid du Colombier if(need != 3) return_error(gs_error_unregistered);
3367dd7cddfSDavid du Colombier
3377dd7cddfSDavid du Colombier memcpy(bp,"\033@\f",need);
3387dd7cddfSDavid du Colombier
3397dd7cddfSDavid du Colombier } /* No Release-String defined */
3407dd7cddfSDavid du Colombier
3417dd7cddfSDavid du Colombier return 0;
3427dd7cddfSDavid du Colombier }
3437dd7cddfSDavid du Colombier
3447dd7cddfSDavid du Colombier /***
3457dd7cddfSDavid du Colombier *** stc_print_page: here we go to do the nasty work
3467dd7cddfSDavid du Colombier ***/
3477dd7cddfSDavid du Colombier
3487dd7cddfSDavid du Colombier private int
stc_print_page(gx_device_printer * pdev,FILE * prn_stream)3497dd7cddfSDavid du Colombier stc_print_page(gx_device_printer * pdev, FILE * prn_stream)
3507dd7cddfSDavid du Colombier {
3517dd7cddfSDavid du Colombier stcolor_device *sd = (stcolor_device *) pdev;
3527dd7cddfSDavid du Colombier long flags = sd == NULL ? 0 : sd->stc.flags;
3537dd7cddfSDavid du Colombier
3547dd7cddfSDavid du Colombier int npass; /* # of print-passes (softweave) */
3557dd7cddfSDavid du Colombier
3567dd7cddfSDavid du Colombier int ext_size; /* size of a ghostscript-scanline */
3577dd7cddfSDavid du Colombier byte *ext_line; /* dyn: for this scanline */
3587dd7cddfSDavid du Colombier
3597dd7cddfSDavid du Colombier int alg_size; /* size of a scanline for the dithering-algorithm */
3607dd7cddfSDavid du Colombier byte *alg_line; /* dyn: 1 scanline for the dithering-algorithm */
3617dd7cddfSDavid du Colombier int buf_size; /* size of the private-buffer for dither-function */
3627dd7cddfSDavid du Colombier byte *buf; /* dyn: the private buffer */
3637dd7cddfSDavid du Colombier
3647dd7cddfSDavid du Colombier int prt_pixels; /* Number of pixels printed */
3657dd7cddfSDavid du Colombier byte *col_line; /* A Line with a byte per pixel */
3667dd7cddfSDavid du Colombier
3677dd7cddfSDavid du Colombier #define OK4GO ((flags & STCOK4GO) != 0)
3687dd7cddfSDavid du Colombier #define SORRY ( flags &= ~STCOK4GO)
3697dd7cddfSDavid du Colombier
3707dd7cddfSDavid du Colombier if(0 > (npass = stc_print_setup(sd))) return_error(npass);
3717dd7cddfSDavid du Colombier
3727dd7cddfSDavid du Colombier npass = sd->stc.escp_v / sd->stc.escp_u;
3737dd7cddfSDavid du Colombier
3747dd7cddfSDavid du Colombier /***
3757dd7cddfSDavid du Colombier *** Allocate dynamic memory
3767dd7cddfSDavid du Colombier ***/
3777dd7cddfSDavid du Colombier
3787dd7cddfSDavid du Colombier ext_size = gdev_prn_raster(sd);
379*593dc095SDavid du Colombier ext_line = gs_malloc(sd->memory, ext_size,1,"stc_print_page/ext_line");
3807dd7cddfSDavid du Colombier if(ext_line == NULL) SORRY;
3817dd7cddfSDavid du Colombier
3827dd7cddfSDavid du Colombier prt_pixels = sd->stc.escp_width;
3837dd7cddfSDavid du Colombier sd->stc.prt_size = (prt_pixels+7)/8;
3847dd7cddfSDavid du Colombier prt_pixels = sd->stc.prt_size * 8;
3857dd7cddfSDavid du Colombier
386*593dc095SDavid du Colombier sd->stc.prt_scans = (int)(sd->height -
387*593dc095SDavid du Colombier (dev_t_margin(sd)+dev_b_margin(sd))*sd->y_pixels_per_inch);
3887dd7cddfSDavid du Colombier
389*593dc095SDavid du Colombier col_line = gs_malloc(sd->memory, prt_pixels,1,"stc_print_page/col_line");
3907dd7cddfSDavid du Colombier if(col_line == NULL) SORRY;
3917dd7cddfSDavid du Colombier
3927dd7cddfSDavid du Colombier alg_size = prt_pixels;
3937dd7cddfSDavid du Colombier alg_size *= sd->color_info.num_components;
3947dd7cddfSDavid du Colombier
3957dd7cddfSDavid du Colombier if((sd->stc.dither->flags & STC_DIRECT) ||
3967dd7cddfSDavid du Colombier ((sd->stc.bits == 8) &&
3977dd7cddfSDavid du Colombier (sd->stc.alg_item == 1))) {
3987dd7cddfSDavid du Colombier alg_line = NULL;
3997dd7cddfSDavid du Colombier } else {
400*593dc095SDavid du Colombier alg_line = gs_malloc(sd->memory, alg_size,sd->stc.alg_item,"stc_print_page/alg_line");
4017dd7cddfSDavid du Colombier if(alg_line == NULL) SORRY;
4027dd7cddfSDavid du Colombier }
4037dd7cddfSDavid du Colombier
4047dd7cddfSDavid du Colombier buf_size = sd->stc.dither->bufadd
4057dd7cddfSDavid du Colombier + alg_size*(sd->stc.dither->flags/STC_SCAN);
4067dd7cddfSDavid du Colombier if(buf_size > 0) {
407*593dc095SDavid du Colombier buf = gs_malloc(sd->memory, buf_size,sd->stc.alg_item,"stc_print_page/buf");
4087dd7cddfSDavid du Colombier if(buf == NULL) SORRY;
4097dd7cddfSDavid du Colombier } else {
4107dd7cddfSDavid du Colombier buf = NULL;
4117dd7cddfSDavid du Colombier }
4127dd7cddfSDavid du Colombier
4137dd7cddfSDavid du Colombier /*
4147dd7cddfSDavid du Colombier * compute the number of printer-buffers
4157dd7cddfSDavid du Colombier */
4167dd7cddfSDavid du Colombier
4177dd7cddfSDavid du Colombier for(sd->stc.prt_buf = 16; sd->stc.prt_buf < (sd->stc.escp_m * npass);
4187dd7cddfSDavid du Colombier sd->stc.prt_buf <<= 1);
4197dd7cddfSDavid du Colombier if(sd->color_info.num_components > 1) sd->stc.prt_buf *= 4;
4207dd7cddfSDavid du Colombier
421*593dc095SDavid du Colombier sd->stc.prt_width = gs_malloc(sd->memory, sd->stc.prt_buf,sizeof(int),
4227dd7cddfSDavid du Colombier "stc_print_page/prt_width");
4237dd7cddfSDavid du Colombier if(sd->stc.prt_width == NULL) SORRY;
4247dd7cddfSDavid du Colombier
425*593dc095SDavid du Colombier sd->stc.prt_data = gs_malloc(sd->memory, sd->stc.prt_buf,sizeof(byte *),
4267dd7cddfSDavid du Colombier "stc_print_page/prt_data");
4277dd7cddfSDavid du Colombier
4287dd7cddfSDavid du Colombier if(sd->stc.prt_data == NULL) {
4297dd7cddfSDavid du Colombier SORRY;
4307dd7cddfSDavid du Colombier } else {
4317dd7cddfSDavid du Colombier int i;
4327dd7cddfSDavid du Colombier
4337dd7cddfSDavid du Colombier for(i = 0; i < sd->stc.prt_buf; ++i) {
434*593dc095SDavid du Colombier sd->stc.prt_data[i] = gs_malloc(sd->memory, sd->stc.prt_size,1,
4357dd7cddfSDavid du Colombier "stc_print_page/prt");
4367dd7cddfSDavid du Colombier if(sd->stc.prt_data[i] == NULL) SORRY;
4377dd7cddfSDavid du Colombier }
4387dd7cddfSDavid du Colombier }
4397dd7cddfSDavid du Colombier
4407dd7cddfSDavid du Colombier sd->stc.seed_size = (sd->stc.prt_size + 2*sizeof(int) - 1)/sizeof(int);
4417dd7cddfSDavid du Colombier {
4427dd7cddfSDavid du Colombier int i;
4437dd7cddfSDavid du Colombier for(i = 0; i < sd->color_info.num_components; ++i) {
4447dd7cddfSDavid du Colombier if((flags & STCCOMP) == STCDELTA) {
445*593dc095SDavid du Colombier sd->stc.seed_row[i] = gs_malloc(sd->memory, sd->stc.seed_size,sizeof(int),
4467dd7cddfSDavid du Colombier "stc_print_page/seed_row");
4477dd7cddfSDavid du Colombier if(sd->stc.seed_row[i] == NULL) SORRY;
4487dd7cddfSDavid du Colombier else memset(sd->stc.seed_row[i],0,sd->stc.seed_size*sizeof(int));
4497dd7cddfSDavid du Colombier } else {
4507dd7cddfSDavid du Colombier sd->stc.seed_row[i] = NULL;
4517dd7cddfSDavid du Colombier }
4527dd7cddfSDavid du Colombier }
4537dd7cddfSDavid du Colombier while(i < countof(sd->stc.seed_row)) sd->stc.seed_row[i++] = NULL;
4547dd7cddfSDavid du Colombier }
4557dd7cddfSDavid du Colombier
4567dd7cddfSDavid du Colombier switch(flags & STCCOMP) {
4577dd7cddfSDavid du Colombier case STCPLAIN:
4587dd7cddfSDavid du Colombier sd->stc.escp_size = 64 + sd->stc.prt_size;
4597dd7cddfSDavid du Colombier break;
4607dd7cddfSDavid du Colombier case STCDELTA:
4617dd7cddfSDavid du Colombier sd->stc.escp_size = 64 + 2 * sd->stc.prt_size;
4627dd7cddfSDavid du Colombier break;
4637dd7cddfSDavid du Colombier default:
4647dd7cddfSDavid du Colombier sd->stc.escp_size = 64 +
4657dd7cddfSDavid du Colombier sd->stc.prt_size + (sd->stc.prt_size + 127)/128;
4667dd7cddfSDavid du Colombier break;
4677dd7cddfSDavid du Colombier }
4687dd7cddfSDavid du Colombier
469*593dc095SDavid du Colombier sd->stc.escp_data = gs_malloc(sd->memory, sd->stc.escp_size,1,
4707dd7cddfSDavid du Colombier "stc_print_page/escp_data");
4717dd7cddfSDavid du Colombier if(sd->stc.escp_data == NULL) SORRY;
4727dd7cddfSDavid du Colombier
4737dd7cddfSDavid du Colombier /*
4747dd7cddfSDavid du Colombier * If we're still ok, we can print something
4757dd7cddfSDavid du Colombier */
4767dd7cddfSDavid du Colombier
4777dd7cddfSDavid du Colombier if(OK4GO) {
4787dd7cddfSDavid du Colombier
4797dd7cddfSDavid du Colombier int ncolor;
4807dd7cddfSDavid du Colombier int buf_i;
4817dd7cddfSDavid du Colombier stc_proc_iconvert((*iconvert)) = stc_any_depth;
4827dd7cddfSDavid du Colombier
4837dd7cddfSDavid du Colombier /*
4847dd7cddfSDavid du Colombier * initialize col_line
4857dd7cddfSDavid du Colombier */
4867dd7cddfSDavid du Colombier if(sd->color_info.num_components == 3) {
4877dd7cddfSDavid du Colombier memset(col_line,RED|GREEN|BLUE,prt_pixels);
4887dd7cddfSDavid du Colombier } else {
4897dd7cddfSDavid du Colombier memset(col_line,0, prt_pixels);
4907dd7cddfSDavid du Colombier }
4917dd7cddfSDavid du Colombier
4927dd7cddfSDavid du Colombier /*
4937dd7cddfSDavid du Colombier * select proper conversion for input to algorithm
4947dd7cddfSDavid du Colombier */
4957dd7cddfSDavid du Colombier if( (sd->stc.dither->flags & STC_DIRECT ) ||
4967dd7cddfSDavid du Colombier ((sd->stc.bits == 8) &&
4977dd7cddfSDavid du Colombier (sd->stc.alg_item == 1)))
4987dd7cddfSDavid du Colombier iconvert = stc_any_direct;
4997dd7cddfSDavid du Colombier else if((sd->color_info.num_components == 3) &&
5007dd7cddfSDavid du Colombier (sd->color_info.depth == 24) &&
5017dd7cddfSDavid du Colombier (sizeof(long) == sd->stc.alg_item))
5027dd7cddfSDavid du Colombier iconvert = stc_rgb24_long;
5037dd7cddfSDavid du Colombier else if(sd->stc.flags & STCCMYK10) {
5047dd7cddfSDavid du Colombier if( ((sd->stc.dither->flags & STC_TYPE) == STC_BYTE) &&
5057dd7cddfSDavid du Colombier ( sd->stc.dither->minmax[0] == 0.0 ))
5067dd7cddfSDavid du Colombier iconvert = stc_cmyk10_dbyte;
5077dd7cddfSDavid du Colombier else if ((sd->stc.dither->flags & STC_TYPE) == STC_BYTE)
5087dd7cddfSDavid du Colombier iconvert = stc_cmyk10_byte;
5097dd7cddfSDavid du Colombier else if(((sd->stc.dither->flags & STC_TYPE) == STC_LONG) &&
5107dd7cddfSDavid du Colombier ( sd->stc.dither->minmax[0] == 0.0 ) &&
5117dd7cddfSDavid du Colombier ( sd->stc.dither->minmax[1] <= 1023.0 ))
5127dd7cddfSDavid du Colombier iconvert = stc_cmyk10_dlong;
5137dd7cddfSDavid du Colombier else if( (sd->stc.dither->flags & STC_TYPE) == STC_LONG)
5147dd7cddfSDavid du Colombier iconvert = stc_cmyk10_long;
5157dd7cddfSDavid du Colombier else
5167dd7cddfSDavid du Colombier iconvert = stc_cmyk10_float;
5177dd7cddfSDavid du Colombier }
5187dd7cddfSDavid du Colombier else if((sd->color_info.num_components == 4) &&
5197dd7cddfSDavid du Colombier (sd->color_info.depth == 32) &&
5207dd7cddfSDavid du Colombier (sizeof(long) == sd->stc.alg_item))
5217dd7cddfSDavid du Colombier iconvert = stc_cmyk32_long;
5227dd7cddfSDavid du Colombier
5237dd7cddfSDavid du Colombier /*
5247dd7cddfSDavid du Colombier * initialize the algorithm
5257dd7cddfSDavid du Colombier */
5267dd7cddfSDavid du Colombier
5277dd7cddfSDavid du Colombier if((*sd->stc.dither->fun)(sd,-prt_pixels,alg_line,buf,col_line) < 0)
5287dd7cddfSDavid du Colombier SORRY;
5297dd7cddfSDavid du Colombier
5307dd7cddfSDavid du Colombier /*
5317dd7cddfSDavid du Colombier * Main-Print-Loop
5327dd7cddfSDavid du Colombier */
5337dd7cddfSDavid du Colombier
5347dd7cddfSDavid du Colombier if(OK4GO) {
5357dd7cddfSDavid du Colombier #ifdef STC_SIGNAL
5367dd7cddfSDavid du Colombier sigset_t stc_int_mask, stc_int_save, stc_int_pending;
5377dd7cddfSDavid du Colombier
5387dd7cddfSDavid du Colombier sigemptyset(&stc_int_mask);
5397dd7cddfSDavid du Colombier sigaddset(&stc_int_mask,SIGINT);
5407dd7cddfSDavid du Colombier sigprocmask(SIG_BLOCK,&stc_int_mask, &stc_int_save);
5417dd7cddfSDavid du Colombier #endif /* STC_SIGNAL */
5427dd7cddfSDavid du Colombier
5437dd7cddfSDavid du Colombier
5447dd7cddfSDavid du Colombier if(sd->color_info.num_components > 1) ncolor = 4;
5457dd7cddfSDavid du Colombier else ncolor = 1;
5467dd7cddfSDavid du Colombier
5477dd7cddfSDavid du Colombier /*
5487dd7cddfSDavid du Colombier * Decide, wether we Adjust Linefeeds or not. (I hate it here)
5497dd7cddfSDavid du Colombier */
5507dd7cddfSDavid du Colombier if((0 == ((sd->stc.escp_m*sd->stc.escp_u) % 10)) &&
5517dd7cddfSDavid du Colombier (256 > ((sd->stc.escp_m*sd->stc.escp_u) / 10))) sd->stc.escp_lf = sd->stc.escp_m;
5527dd7cddfSDavid du Colombier else sd->stc.escp_lf = 0;
5537dd7cddfSDavid du Colombier
5547dd7cddfSDavid du Colombier /*
5557dd7cddfSDavid du Colombier * prepare run-values, then loop over scans
5567dd7cddfSDavid du Colombier */
5577dd7cddfSDavid du Colombier sd->stc.stc_y = 0; /* current printer y-Position */
5587dd7cddfSDavid du Colombier sd->stc.buf_y = 0; /* Top-Position within the buffer */
5597dd7cddfSDavid du Colombier sd->stc.prt_y = 0; /* physical position of the printer */
5607dd7cddfSDavid du Colombier buf_i = 0; /* next free line in buffer */
5617dd7cddfSDavid du Colombier sd->stc.flags &= ~STCPRINT; /* no data yet */
5627dd7cddfSDavid du Colombier
5637dd7cddfSDavid du Colombier while(sd->stc.stc_y < sd->stc.prt_scans) { /* Until all scans are processed */
5647dd7cddfSDavid du Colombier int need;
5657dd7cddfSDavid du Colombier
5667dd7cddfSDavid du Colombier need = sd->stc.stc_y + npass * sd->stc.escp_m;
5677dd7cddfSDavid du Colombier
5687dd7cddfSDavid du Colombier if(sd->stc.buf_y < need) { /* Nr. 5 (give me input) */
5697dd7cddfSDavid du Colombier
5707dd7cddfSDavid du Colombier /* read as much as the buffer can hold */
5717dd7cddfSDavid du Colombier if(ncolor == 1) need = sd->stc.stc_y + sd->stc.prt_buf;
5727dd7cddfSDavid du Colombier else need = sd->stc.stc_y + (sd->stc.prt_buf>>2);
5737dd7cddfSDavid du Colombier
5747dd7cddfSDavid du Colombier for(;sd->stc.buf_y < need;
5757dd7cddfSDavid du Colombier buf_i = (sd->stc.prt_buf-1) & (buf_i+ncolor),
5767dd7cddfSDavid du Colombier ++sd->stc.buf_y) {
5777dd7cddfSDavid du Colombier
5787dd7cddfSDavid du Colombier int color;
5797dd7cddfSDavid du Colombier byte *ext_data;
5807dd7cddfSDavid du Colombier byte *alg_data;
5817dd7cddfSDavid du Colombier
5827dd7cddfSDavid du Colombier /* initialize output data 1st -> may take shortcut */
5837dd7cddfSDavid du Colombier
5847dd7cddfSDavid du Colombier for(color = 0; color < ncolor; ++color) {
5857dd7cddfSDavid du Colombier memset(sd->stc.prt_data[buf_i+color],0,sd->stc.prt_size);
5867dd7cddfSDavid du Colombier sd->stc.prt_width[buf_i+color] = 0;
5877dd7cddfSDavid du Colombier }
5887dd7cddfSDavid du Colombier
5897dd7cddfSDavid du Colombier
5907dd7cddfSDavid du Colombier /* "read data", immediately continue if all is white */
5917dd7cddfSDavid du Colombier
5927dd7cddfSDavid du Colombier if(sd->stc.buf_y < sd->stc.prt_scans) { /* Test for White */
5937dd7cddfSDavid du Colombier
5947dd7cddfSDavid du Colombier gdev_prn_get_bits(pdev,sd->stc.buf_y,ext_line,&ext_data);
5957dd7cddfSDavid du Colombier
5967dd7cddfSDavid du Colombier color = stc_iswhite(sd,prt_pixels,ext_data) ? ext_size : 0;
5977dd7cddfSDavid du Colombier
5987dd7cddfSDavid du Colombier } else {
5997dd7cddfSDavid du Colombier
6007dd7cddfSDavid du Colombier color = ext_size;
6017dd7cddfSDavid du Colombier
6027dd7cddfSDavid du Colombier } /* Test for White */
6037dd7cddfSDavid du Colombier
6047dd7cddfSDavid du Colombier if(color >= ext_size) { /* bypass processing */
6057dd7cddfSDavid du Colombier
6067dd7cddfSDavid du Colombier if(sd->stc.dither->flags & STC_WHITE)
6077dd7cddfSDavid du Colombier (*sd->stc.dither->fun)(sd,prt_pixels,NULL,buf,col_line);
6087dd7cddfSDavid du Colombier continue;
6097dd7cddfSDavid du Colombier
6107dd7cddfSDavid du Colombier } /* bypass processing */
6117dd7cddfSDavid du Colombier
6127dd7cddfSDavid du Colombier /* convert data for the various cases */
6137dd7cddfSDavid du Colombier
6147dd7cddfSDavid du Colombier alg_data = (*iconvert)(sd,ext_data,prt_pixels,alg_line);
6157dd7cddfSDavid du Colombier
6167dd7cddfSDavid du Colombier
6177dd7cddfSDavid du Colombier /*
6187dd7cddfSDavid du Colombier * invoke the dithering-algorithm
6197dd7cddfSDavid du Colombier */
6207dd7cddfSDavid du Colombier
6217dd7cddfSDavid du Colombier (*sd->stc.dither->fun)(sd,prt_pixels,alg_data,buf,col_line);
6227dd7cddfSDavid du Colombier /*
6237dd7cddfSDavid du Colombier * convert col_line to printer-format (separate colors)
6247dd7cddfSDavid du Colombier */
6257dd7cddfSDavid du Colombier switch(sd->color_info.num_components) {
6267dd7cddfSDavid du Colombier case 1: /* Black & White: just merge into 8 Bytes */
6277dd7cddfSDavid du Colombier {
6287dd7cddfSDavid du Colombier byte *bytein,*byteout;
6297dd7cddfSDavid du Colombier int width;
6307dd7cddfSDavid du Colombier
6317dd7cddfSDavid du Colombier bytein = col_line;
6327dd7cddfSDavid du Colombier byteout = sd->stc.prt_data[buf_i];
6337dd7cddfSDavid du Colombier
6347dd7cddfSDavid du Colombier for(width = 1; width <= sd->stc.prt_size; ++width) {
6357dd7cddfSDavid du Colombier byte tmp = 0;
6367dd7cddfSDavid du Colombier byte i;
6377dd7cddfSDavid du Colombier
6387dd7cddfSDavid du Colombier for(i = 128; i; i >>= 1) if(*bytein++) tmp |= i;
6397dd7cddfSDavid du Colombier
6407dd7cddfSDavid du Colombier if(tmp != 0) sd->stc.prt_width[buf_i] = width;
6417dd7cddfSDavid du Colombier
6427dd7cddfSDavid du Colombier *byteout++ = tmp;
6437dd7cddfSDavid du Colombier }
6447dd7cddfSDavid du Colombier }
6457dd7cddfSDavid du Colombier break;
6467dd7cddfSDavid du Colombier case 3: /* convert rgb into cmyk */
6477dd7cddfSDavid du Colombier {
6487dd7cddfSDavid du Colombier byte *bytein;
6497dd7cddfSDavid du Colombier int width;
6507dd7cddfSDavid du Colombier
6517dd7cddfSDavid du Colombier bytein = col_line;
6527dd7cddfSDavid du Colombier
6537dd7cddfSDavid du Colombier for(width = 0; width < sd->stc.prt_size; ++width) {
6547dd7cddfSDavid du Colombier byte i,tmp,cmyk[4];
6557dd7cddfSDavid du Colombier
6567dd7cddfSDavid du Colombier memset(cmyk,0,4);
6577dd7cddfSDavid du Colombier
6587dd7cddfSDavid du Colombier for(i = 128; i; i >>= 1) {
6597dd7cddfSDavid du Colombier static const byte rgb2cmyk[] = {
6607dd7cddfSDavid du Colombier BLACK, /* 0->Black */
6617dd7cddfSDavid du Colombier CYAN | MAGENTA, /* 1->BLUE */
6627dd7cddfSDavid du Colombier CYAN | YELLOW, /* 2->GREEN */
6637dd7cddfSDavid du Colombier CYAN, /* 3->CYAN */
6647dd7cddfSDavid du Colombier MAGENTA | YELLOW, /* 4->RED */
6657dd7cddfSDavid du Colombier MAGENTA, /* 5->MAGENTA */
6667dd7cddfSDavid du Colombier YELLOW, /* 6->YELLOW */
6677dd7cddfSDavid du Colombier 0}; /* 7->WHITE */
6687dd7cddfSDavid du Colombier
6697dd7cddfSDavid du Colombier tmp = rgb2cmyk[(*bytein++) & 7];
6707dd7cddfSDavid du Colombier
6717dd7cddfSDavid du Colombier if(tmp & BLACK) cmyk[3] |= i;
6727dd7cddfSDavid du Colombier if(tmp & YELLOW) cmyk[2] |= i;
6737dd7cddfSDavid du Colombier if(tmp & MAGENTA) cmyk[1] |= i;
6747dd7cddfSDavid du Colombier if(tmp & CYAN) cmyk[0] |= i;
6757dd7cddfSDavid du Colombier }
6767dd7cddfSDavid du Colombier
6777dd7cddfSDavid du Colombier for(i = 0; i < 4; ++i) {
6787dd7cddfSDavid du Colombier if(cmyk[i] != 0) sd->stc.prt_width[buf_i+i] = width+1;
6797dd7cddfSDavid du Colombier sd->stc.prt_data[buf_i+i][width] = cmyk[i];
6807dd7cddfSDavid du Colombier }
6817dd7cddfSDavid du Colombier }
6827dd7cddfSDavid du Colombier }
6837dd7cddfSDavid du Colombier break;
6847dd7cddfSDavid du Colombier case 4: /* split cmyk */
6857dd7cddfSDavid du Colombier {
6867dd7cddfSDavid du Colombier byte *bytein;
6877dd7cddfSDavid du Colombier int width;
6887dd7cddfSDavid du Colombier
6897dd7cddfSDavid du Colombier bytein = col_line;
6907dd7cddfSDavid du Colombier
6917dd7cddfSDavid du Colombier for(width = 0; width < sd->stc.prt_size; ++width) {
6927dd7cddfSDavid du Colombier byte i,tmp,cmyk[4];
6937dd7cddfSDavid du Colombier
6947dd7cddfSDavid du Colombier memset(cmyk,0,4);
6957dd7cddfSDavid du Colombier
6967dd7cddfSDavid du Colombier for(i = 128; i; i >>= 1) {
6977dd7cddfSDavid du Colombier tmp = (*bytein++) & 15;
6987dd7cddfSDavid du Colombier if(tmp & BLACK) cmyk[3] |= i;
6997dd7cddfSDavid du Colombier if(tmp & YELLOW) cmyk[2] |= i;
7007dd7cddfSDavid du Colombier if(tmp & MAGENTA) cmyk[1] |= i;
7017dd7cddfSDavid du Colombier if(tmp & CYAN) cmyk[0] |= i;
7027dd7cddfSDavid du Colombier }
7037dd7cddfSDavid du Colombier
7047dd7cddfSDavid du Colombier for(i = 0; i < 4; ++i) {
7057dd7cddfSDavid du Colombier if(cmyk[i] != 0) sd->stc.prt_width[buf_i+i] = width+1;
7067dd7cddfSDavid du Colombier sd->stc.prt_data[buf_i+i][width] = cmyk[i];
7077dd7cddfSDavid du Colombier }
7087dd7cddfSDavid du Colombier }
7097dd7cddfSDavid du Colombier }
7107dd7cddfSDavid du Colombier break;
7117dd7cddfSDavid du Colombier default: break;
7127dd7cddfSDavid du Colombier }
7137dd7cddfSDavid du Colombier }
7147dd7cddfSDavid du Colombier } /* Nr. 5 (give me input) */
7157dd7cddfSDavid du Colombier
7167dd7cddfSDavid du Colombier /*
7177dd7cddfSDavid du Colombier * Nr. 5 has got enough input, now we should print it
7187dd7cddfSDavid du Colombier */
7197dd7cddfSDavid du Colombier if((flags & STCCOMP) == STCDELTA) stc_print_delta(sd,prn_stream);
7207dd7cddfSDavid du Colombier else if(npass > 1) stc_print_weave(sd,prn_stream);
7217dd7cddfSDavid du Colombier else stc_print_bands(sd,prn_stream);
7227dd7cddfSDavid du Colombier
7237dd7cddfSDavid du Colombier #ifdef STC_SIGNAL
7247dd7cddfSDavid du Colombier sigpending(&stc_int_pending);
7257dd7cddfSDavid du Colombier if(sigismember(&stc_int_pending,SIGINT)) {
7267dd7cddfSDavid du Colombier fputs("\033@[Aborted]\f", prn_stream);
7277dd7cddfSDavid du Colombier fflush(prn_stream);
7287dd7cddfSDavid du Colombier sigprocmask(SIG_SETMASK,&stc_int_save,NULL);
7297dd7cddfSDavid du Colombier break;
7307dd7cddfSDavid du Colombier }
7317dd7cddfSDavid du Colombier #endif /* STC_SIGNAL */
7327dd7cddfSDavid du Colombier
7337dd7cddfSDavid du Colombier } /* Until all scans are processed */
7347dd7cddfSDavid du Colombier
7357dd7cddfSDavid du Colombier if(sd->stc.flags & STCPRINT) {
7367dd7cddfSDavid du Colombier if((flags & STCCOMP) == STCDELTA) fputc(0xe3,prn_stream);
7377dd7cddfSDavid du Colombier fwrite(sd->stc.escp_release.data,1,sd->stc.escp_release.size,prn_stream);
7387dd7cddfSDavid du Colombier fflush(prn_stream);
7397dd7cddfSDavid du Colombier }
7407dd7cddfSDavid du Colombier #ifdef STC_SIGNAL
7417dd7cddfSDavid du Colombier sigprocmask(SIG_SETMASK,&stc_int_save,NULL);
7427dd7cddfSDavid du Colombier #endif /* STC_DIGNAL */
7437dd7cddfSDavid du Colombier
7447dd7cddfSDavid du Colombier }
7457dd7cddfSDavid du Colombier }
7467dd7cddfSDavid du Colombier
7477dd7cddfSDavid du Colombier /***
7487dd7cddfSDavid du Colombier *** Release the dynamic memory
7497dd7cddfSDavid du Colombier ***/
7507dd7cddfSDavid du Colombier
7517dd7cddfSDavid du Colombier if(ext_line != NULL)
752*593dc095SDavid du Colombier gs_free(sd->memory, ext_line,ext_size,1,"stc_print_page/ext_line");
7537dd7cddfSDavid du Colombier
7547dd7cddfSDavid du Colombier if(col_line != NULL)
755*593dc095SDavid du Colombier gs_free(sd->memory, col_line,prt_pixels,1,"stc_print_page/col_line");
7567dd7cddfSDavid du Colombier
7577dd7cddfSDavid du Colombier if(alg_line != NULL)
758*593dc095SDavid du Colombier gs_free(sd->memory, alg_line,alg_size,sd->stc.alg_item,
7597dd7cddfSDavid du Colombier "stc_print_page/alg_line");
7607dd7cddfSDavid du Colombier
7617dd7cddfSDavid du Colombier if(buf != NULL)
762*593dc095SDavid du Colombier gs_free(sd->memory, buf,buf_size,sd->stc.alg_item,"stc_print_page/buf");
7637dd7cddfSDavid du Colombier
7647dd7cddfSDavid du Colombier if(sd->stc.prt_width != NULL)
765*593dc095SDavid du Colombier gs_free(sd->memory, sd->stc.prt_width,sd->stc.prt_buf,sizeof(int),
7667dd7cddfSDavid du Colombier "stc_print_page/prt_width");
7677dd7cddfSDavid du Colombier
7687dd7cddfSDavid du Colombier if(sd->stc.prt_data != NULL) {
7697dd7cddfSDavid du Colombier int i;
7707dd7cddfSDavid du Colombier
7717dd7cddfSDavid du Colombier for(i = 0; i < sd->stc.prt_buf; ++i) {
7727dd7cddfSDavid du Colombier if(sd->stc.prt_data[i] != NULL)
773*593dc095SDavid du Colombier gs_free(sd->memory, sd->stc.prt_data[i],sd->stc.prt_size,1,
7747dd7cddfSDavid du Colombier "stc_print_page/prt");
7757dd7cddfSDavid du Colombier }
7767dd7cddfSDavid du Colombier
777*593dc095SDavid du Colombier gs_free(sd->memory, sd->stc.prt_data,sd->stc.prt_buf,sizeof(byte *),
7787dd7cddfSDavid du Colombier "stc_print_page/prt_data");
7797dd7cddfSDavid du Colombier }
7807dd7cddfSDavid du Colombier
7817dd7cddfSDavid du Colombier {
7827dd7cddfSDavid du Colombier int i;
7837dd7cddfSDavid du Colombier for(i = 0; i < sd->color_info.num_components; ++i) {
7847dd7cddfSDavid du Colombier if(sd->stc.seed_row[i] != NULL)
785*593dc095SDavid du Colombier gs_free(sd->memory, sd->stc.seed_row[i],sd->stc.seed_size,sizeof(int),
7867dd7cddfSDavid du Colombier "stc_print_page/seed_row");
7877dd7cddfSDavid du Colombier }
7887dd7cddfSDavid du Colombier }
7897dd7cddfSDavid du Colombier
7907dd7cddfSDavid du Colombier if(sd->stc.escp_data != NULL)
791*593dc095SDavid du Colombier gs_free(sd->memory, sd->stc.escp_data,sd->stc.escp_size,1,
7927dd7cddfSDavid du Colombier "stc_print_page/escp_data");
7937dd7cddfSDavid du Colombier
7947dd7cddfSDavid du Colombier return OK4GO ? 0 : gs_error_undefined;
7957dd7cddfSDavid du Colombier }
7967dd7cddfSDavid du Colombier
7977dd7cddfSDavid du Colombier /*
7987dd7cddfSDavid du Colombier * white-check
7997dd7cddfSDavid du Colombier */
8007dd7cddfSDavid du Colombier private bool
stc_iswhite(stcolor_device * sd,int prt_pixels,byte * ext_data)8017dd7cddfSDavid du Colombier stc_iswhite(stcolor_device *sd, int prt_pixels,byte *ext_data)
8027dd7cddfSDavid du Colombier {
8037dd7cddfSDavid du Colombier long b2do = (prt_pixels*sd->color_info.depth+7)>>3;
8047dd7cddfSDavid du Colombier int bcmp = 4 * countof(sd->stc.white_run);
8057dd7cddfSDavid du Colombier byte *wht = (byte *) sd->stc.white_run;
8067dd7cddfSDavid du Colombier
8077dd7cddfSDavid du Colombier while(b2do >= bcmp) {
8087dd7cddfSDavid du Colombier if(memcmp(ext_data,wht,bcmp)) break;
8097dd7cddfSDavid du Colombier ext_data += bcmp;
8107dd7cddfSDavid du Colombier b2do -= bcmp;
8117dd7cddfSDavid du Colombier }
8127dd7cddfSDavid du Colombier
8137dd7cddfSDavid du Colombier if((b2do > 0) && (b2do < bcmp))
8147dd7cddfSDavid du Colombier b2do = memcmp(ext_data,sd->stc.white_end,b2do);
8157dd7cddfSDavid du Colombier
8167dd7cddfSDavid du Colombier return b2do ? false : true;
8177dd7cddfSDavid du Colombier }
8187dd7cddfSDavid du Colombier
8197dd7cddfSDavid du Colombier /***
8207dd7cddfSDavid du Colombier *** A bunch of routines that convert gslines into algorithms format.
8217dd7cddfSDavid du Colombier ***/
8227dd7cddfSDavid du Colombier private byte *
stc_any_depth(stcolor_device * sd,byte * ext_data,int prt_pixels,byte * alg_line)8237dd7cddfSDavid du Colombier stc_any_depth(stcolor_device *sd,byte *ext_data,int prt_pixels,byte *alg_line)
8247dd7cddfSDavid du Colombier { /* general conversion */
8257dd7cddfSDavid du Colombier
8267dd7cddfSDavid du Colombier int p,c, niext, nbits;
8277dd7cddfSDavid du Colombier gx_color_index ciext,ci,cimsk,cvmsk;
8287dd7cddfSDavid du Colombier byte *ap = alg_line;
8297dd7cddfSDavid du Colombier
8307dd7cddfSDavid du Colombier nbits = sd->stc.bits;
8317dd7cddfSDavid du Colombier cvmsk = ((gx_color_index) 1<<nbits) - 1;
8327dd7cddfSDavid du Colombier
8337dd7cddfSDavid du Colombier /* it is nonsense to use this algorithm for this cases, but if it claims
8347dd7cddfSDavid du Colombier * generality, it should deliver correct results in this cases too */
8357dd7cddfSDavid du Colombier if(sd->color_info.depth == (sd->color_info.num_components<<3)) nbits = 8;
8367dd7cddfSDavid du Colombier
8377dd7cddfSDavid du Colombier cimsk = cvmsk;
8387dd7cddfSDavid du Colombier for(c = 1; c < sd->color_info.num_components; ++c)
8397dd7cddfSDavid du Colombier cimsk = (cimsk<<nbits) | cvmsk;
8407dd7cddfSDavid du Colombier
8417dd7cddfSDavid du Colombier ciext = 0;
8427dd7cddfSDavid du Colombier niext = 0;
8437dd7cddfSDavid du Colombier
8447dd7cddfSDavid du Colombier for(p = 0; p < prt_pixels; ++p) { /* over pixels */
8457dd7cddfSDavid du Colombier
8467dd7cddfSDavid du Colombier ci = ciext;
8477dd7cddfSDavid du Colombier for(c = sd->color_info.depth-niext; c >= 8; c -= 8)
8487dd7cddfSDavid du Colombier ci = (ci<<8) | *ext_data++;
8497dd7cddfSDavid du Colombier
8507dd7cddfSDavid du Colombier if(c > 0) { /* partial byte required */
8517dd7cddfSDavid du Colombier
8527dd7cddfSDavid du Colombier niext = 8 - c;
8537dd7cddfSDavid du Colombier ciext = *ext_data++;
8547dd7cddfSDavid du Colombier ci = (ci<<c) | (ciext>>niext);
8557dd7cddfSDavid du Colombier ciext &= (1L<<niext)-1;
8567dd7cddfSDavid du Colombier
8577dd7cddfSDavid du Colombier } else if(c < 0) { /* some bits left in ciext */
8587dd7cddfSDavid du Colombier
8597dd7cddfSDavid du Colombier niext = -c;
8607dd7cddfSDavid du Colombier ciext &= (1L<<niext)-1;
8617dd7cddfSDavid du Colombier ci = ci>>niext;
8627dd7cddfSDavid du Colombier
8637dd7cddfSDavid du Colombier } else { /* entire ciext used */
8647dd7cddfSDavid du Colombier
8657dd7cddfSDavid du Colombier niext = 0;
8667dd7cddfSDavid du Colombier ciext = 0;
8677dd7cddfSDavid du Colombier
8687dd7cddfSDavid du Colombier } /* ciext-adjust */
8697dd7cddfSDavid du Colombier
8707dd7cddfSDavid du Colombier ci &= cimsk;
8717dd7cddfSDavid du Colombier
8727dd7cddfSDavid du Colombier # define stc_storeapc(T) \
8737dd7cddfSDavid du Colombier ((T *)ap)[c] = ((T *)(sd->stc.vals[c]))[ci & cvmsk];
8747dd7cddfSDavid du Colombier
8757dd7cddfSDavid du Colombier for(c = sd->color_info.num_components; c--;) { /* comp */
8767dd7cddfSDavid du Colombier STC_TYPESWITCH(sd->stc.dither,stc_storeapc)
8777dd7cddfSDavid du Colombier ci >>= nbits;
8787dd7cddfSDavid du Colombier } /* comp */
8797dd7cddfSDavid du Colombier
8807dd7cddfSDavid du Colombier # undef stc_storeapc
8817dd7cddfSDavid du Colombier
8827dd7cddfSDavid du Colombier ap += sd->color_info.num_components * sd->stc.alg_item;
8837dd7cddfSDavid du Colombier
8847dd7cddfSDavid du Colombier } /* over pixels */
8857dd7cddfSDavid du Colombier
8867dd7cddfSDavid du Colombier return alg_line;
8877dd7cddfSDavid du Colombier } /* general conversion */
8887dd7cddfSDavid du Colombier
8897dd7cddfSDavid du Colombier /*
8907dd7cddfSDavid du Colombier * rgb-data with depth=24, can use a faster algorithm
8917dd7cddfSDavid du Colombier */
8927dd7cddfSDavid du Colombier private byte *
stc_rgb24_long(stcolor_device * sd,byte * ext_data,int prt_pixels,byte * alg_line)8937dd7cddfSDavid du Colombier stc_rgb24_long(stcolor_device *sd,byte *ext_data,int prt_pixels,byte *alg_line)
8947dd7cddfSDavid du Colombier { /* convert 3 bytes into appropriate long-Values */
8957dd7cddfSDavid du Colombier register int p;
8967dd7cddfSDavid du Colombier register long *out = (long *) alg_line;
8977dd7cddfSDavid du Colombier register long *rvals = (long *) (sd->stc.vals[0]);
8987dd7cddfSDavid du Colombier register long *gvals = (long *) (sd->stc.vals[1]);
8997dd7cddfSDavid du Colombier register long *bvals = (long *) (sd->stc.vals[2]);
9007dd7cddfSDavid du Colombier
9017dd7cddfSDavid du Colombier for(p = prt_pixels; p; --p) {
9027dd7cddfSDavid du Colombier *out++ = rvals[*ext_data++];
9037dd7cddfSDavid du Colombier *out++ = gvals[*ext_data++];
9047dd7cddfSDavid du Colombier *out++ = bvals[*ext_data++];
9057dd7cddfSDavid du Colombier }
9067dd7cddfSDavid du Colombier
9077dd7cddfSDavid du Colombier return alg_line;
9087dd7cddfSDavid du Colombier } /* convert 3 bytes into appropriate long-Values */
9097dd7cddfSDavid du Colombier
9107dd7cddfSDavid du Colombier /*
9117dd7cddfSDavid du Colombier * cmyk-data with depth=32, can use a faster algorithm
9127dd7cddfSDavid du Colombier */
9137dd7cddfSDavid du Colombier private byte *
stc_cmyk32_long(stcolor_device * sd,byte * ext_data,int prt_pixels,byte * alg_line)9147dd7cddfSDavid du Colombier stc_cmyk32_long(stcolor_device *sd,byte *ext_data,int prt_pixels,byte *alg_line)
9157dd7cddfSDavid du Colombier { /* convert 4 bytes into appropriate long-Values */
9167dd7cddfSDavid du Colombier register int p;
9177dd7cddfSDavid du Colombier register long *out = (long *) alg_line;
9187dd7cddfSDavid du Colombier register long *cvals = (long *) (sd->stc.vals[0]);
9197dd7cddfSDavid du Colombier register long *mvals = (long *) (sd->stc.vals[1]);
9207dd7cddfSDavid du Colombier register long *yvals = (long *) (sd->stc.vals[2]);
9217dd7cddfSDavid du Colombier register long *kvals = (long *) (sd->stc.vals[3]);
9227dd7cddfSDavid du Colombier
9237dd7cddfSDavid du Colombier for(p = prt_pixels; p; --p) {
9247dd7cddfSDavid du Colombier *out++ = cvals[*ext_data++];
9257dd7cddfSDavid du Colombier *out++ = mvals[*ext_data++];
9267dd7cddfSDavid du Colombier *out++ = yvals[*ext_data++];
9277dd7cddfSDavid du Colombier *out++ = kvals[*ext_data++];
9287dd7cddfSDavid du Colombier }
9297dd7cddfSDavid du Colombier
9307dd7cddfSDavid du Colombier return alg_line;
9317dd7cddfSDavid du Colombier } /* convert 4 bytes into appropriate long-Values */
9327dd7cddfSDavid du Colombier
9337dd7cddfSDavid du Colombier /*
9347dd7cddfSDavid du Colombier * handle indirect encoded cmyk-data
9357dd7cddfSDavid du Colombier */
9367dd7cddfSDavid du Colombier #define STC_CMYK10_ANY(T)\
9377dd7cddfSDavid du Colombier \
9387dd7cddfSDavid du Colombier register int p = prt_pixels; \
9397dd7cddfSDavid du Colombier register stc_pixel ci,k,n,mode; \
9407dd7cddfSDavid du Colombier register stc_pixel *in = (stc_pixel *) ext_data; \
9417dd7cddfSDavid du Colombier register T *out = (T *) alg_line; \
9427dd7cddfSDavid du Colombier register T *cv = (T *) sd->stc.vals[0]; \
9437dd7cddfSDavid du Colombier register T *mv = (T *) sd->stc.vals[1]; \
9447dd7cddfSDavid du Colombier register T *yv = (T *) sd->stc.vals[2]; \
9457dd7cddfSDavid du Colombier register T *kv = (T *) sd->stc.vals[3]; \
9467dd7cddfSDavid du Colombier \
9477dd7cddfSDavid du Colombier while(p--) { \
9487dd7cddfSDavid du Colombier ci = *in++; \
9497dd7cddfSDavid du Colombier mode = ci & 3; \
9507dd7cddfSDavid du Colombier k = (ci>>2) & 0x3ff; \
9517dd7cddfSDavid du Colombier if(mode == 3) { \
9527dd7cddfSDavid du Colombier *out++ = cv[0]; \
9537dd7cddfSDavid du Colombier *out++ = mv[0]; \
9547dd7cddfSDavid du Colombier *out++ = yv[0]; \
9557dd7cddfSDavid du Colombier *out++ = kv[k]; \
9567dd7cddfSDavid du Colombier } else { \
9577dd7cddfSDavid du Colombier out[3] = kv[k]; \
9587dd7cddfSDavid du Colombier n = (ci>>12) & 0x3ff; \
9597dd7cddfSDavid du Colombier if(mode == 2) { out[2] = yv[k]; } \
9607dd7cddfSDavid du Colombier else { out[2] = yv[n]; n = (ci>>22) & 0x3ff; } \
9617dd7cddfSDavid du Colombier if(mode == 1) { out[1] = mv[k]; } \
9627dd7cddfSDavid du Colombier else { out[1] = mv[n]; n = (ci>>22) & 0x3ff; } \
9637dd7cddfSDavid du Colombier if(mode == 0) out[0] = cv[k]; \
9647dd7cddfSDavid du Colombier else out[0] = cv[n]; \
9657dd7cddfSDavid du Colombier out += 4; \
9667dd7cddfSDavid du Colombier } \
9677dd7cddfSDavid du Colombier } \
9687dd7cddfSDavid du Colombier \
9697dd7cddfSDavid du Colombier return alg_line;
9707dd7cddfSDavid du Colombier
9717dd7cddfSDavid du Colombier private byte *
stc_cmyk10_byte(stcolor_device * sd,byte * ext_data,int prt_pixels,byte * alg_line)9727dd7cddfSDavid du Colombier stc_cmyk10_byte(stcolor_device *sd,
9737dd7cddfSDavid du Colombier byte *ext_data,int prt_pixels,byte *alg_line)
9747dd7cddfSDavid du Colombier {
9757dd7cddfSDavid du Colombier STC_CMYK10_ANY(byte)
9767dd7cddfSDavid du Colombier }
9777dd7cddfSDavid du Colombier private byte *
stc_cmyk10_long(stcolor_device * sd,byte * ext_data,int prt_pixels,byte * alg_line)9787dd7cddfSDavid du Colombier stc_cmyk10_long(stcolor_device *sd,
9797dd7cddfSDavid du Colombier byte *ext_data,int prt_pixels,byte *alg_line)
9807dd7cddfSDavid du Colombier {
9817dd7cddfSDavid du Colombier STC_CMYK10_ANY(long)
9827dd7cddfSDavid du Colombier }
9837dd7cddfSDavid du Colombier private byte *
stc_cmyk10_float(stcolor_device * sd,byte * ext_data,int prt_pixels,byte * alg_line)9847dd7cddfSDavid du Colombier stc_cmyk10_float(stcolor_device *sd,
9857dd7cddfSDavid du Colombier byte *ext_data,int prt_pixels,byte *alg_line)
9867dd7cddfSDavid du Colombier {
9877dd7cddfSDavid du Colombier STC_CMYK10_ANY(float)
9887dd7cddfSDavid du Colombier }
9897dd7cddfSDavid du Colombier
9907dd7cddfSDavid du Colombier #undef STC_CMYK10_ANY
9917dd7cddfSDavid du Colombier
9927dd7cddfSDavid du Colombier #define STC_CMYK10_DANY(T)\
9937dd7cddfSDavid du Colombier \
9947dd7cddfSDavid du Colombier register int p = prt_pixels; \
9957dd7cddfSDavid du Colombier register stc_pixel ci,k,n,mode; \
9967dd7cddfSDavid du Colombier register stc_pixel *in = (stc_pixel *) ext_data; \
9977dd7cddfSDavid du Colombier register T *out = (T *) alg_line; \
9987dd7cddfSDavid du Colombier \
9997dd7cddfSDavid du Colombier while(p--) { \
10007dd7cddfSDavid du Colombier ci = *in++; \
10017dd7cddfSDavid du Colombier mode = ci & 3; \
10027dd7cddfSDavid du Colombier k = (ci>>2) & 0x3ff; \
10037dd7cddfSDavid du Colombier if(mode == 3) { \
10047dd7cddfSDavid du Colombier *out++ = 0; \
10057dd7cddfSDavid du Colombier *out++ = 0; \
10067dd7cddfSDavid du Colombier *out++ = 0; \
10077dd7cddfSDavid du Colombier *out++ = k; \
10087dd7cddfSDavid du Colombier } else { \
10097dd7cddfSDavid du Colombier out[3] = k; \
10107dd7cddfSDavid du Colombier n = (ci>>12) & 0x3ff; \
10117dd7cddfSDavid du Colombier if(mode == 2) { out[2] = k; } \
10127dd7cddfSDavid du Colombier else { out[2] = n; n = (ci>>22) & 0x3ff; } \
10137dd7cddfSDavid du Colombier if(mode == 1) { out[1] = k; } \
10147dd7cddfSDavid du Colombier else { out[1] = n; n = (ci>>22) & 0x3ff; } \
10157dd7cddfSDavid du Colombier if(mode == 0) out[0] = k; \
10167dd7cddfSDavid du Colombier else out[0] = n; \
10177dd7cddfSDavid du Colombier out += 4; \
10187dd7cddfSDavid du Colombier } \
10197dd7cddfSDavid du Colombier } \
10207dd7cddfSDavid du Colombier \
10217dd7cddfSDavid du Colombier return alg_line;
10227dd7cddfSDavid du Colombier
10237dd7cddfSDavid du Colombier
10247dd7cddfSDavid du Colombier private byte *
stc_cmyk10_dbyte(stcolor_device * sd,byte * ext_data,int prt_pixels,byte * alg_line)10257dd7cddfSDavid du Colombier stc_cmyk10_dbyte(stcolor_device *sd,
10267dd7cddfSDavid du Colombier byte *ext_data,int prt_pixels,byte *alg_line)
10277dd7cddfSDavid du Colombier {
10287dd7cddfSDavid du Colombier STC_CMYK10_DANY(byte)
10297dd7cddfSDavid du Colombier }
10307dd7cddfSDavid du Colombier private byte *
stc_cmyk10_dlong(stcolor_device * sd,byte * ext_data,int prt_pixels,byte * alg_line)10317dd7cddfSDavid du Colombier stc_cmyk10_dlong(stcolor_device *sd,
10327dd7cddfSDavid du Colombier byte *ext_data,int prt_pixels,byte *alg_line)
10337dd7cddfSDavid du Colombier {
10347dd7cddfSDavid du Colombier STC_CMYK10_DANY(long)
10357dd7cddfSDavid du Colombier }
10367dd7cddfSDavid du Colombier
10377dd7cddfSDavid du Colombier #undef STC_CMYK10_DANY
10387dd7cddfSDavid du Colombier
10397dd7cddfSDavid du Colombier /*
10407dd7cddfSDavid du Colombier * if the algorithm uses bytes & bytes are in ext_data, use them
10417dd7cddfSDavid du Colombier */
10427dd7cddfSDavid du Colombier /*ARGSUSED*/
10437dd7cddfSDavid du Colombier private byte *
stc_any_direct(stcolor_device * sd,byte * ext_data,int prt_pixels,byte * alg_line)10447dd7cddfSDavid du Colombier stc_any_direct(stcolor_device *sd,byte *ext_data,int prt_pixels,byte *alg_line)
10457dd7cddfSDavid du Colombier { /* return ext_data */
10467dd7cddfSDavid du Colombier return ext_data;
10477dd7cddfSDavid du Colombier } /* return ext_data */
10487dd7cddfSDavid du Colombier
10497dd7cddfSDavid du Colombier /* ----------------------------------------------------------------------- */
10507dd7cddfSDavid du Colombier /* stc_rle: epson ESC/P2 RLE-Encoding
10517dd7cddfSDavid du Colombier */
10527dd7cddfSDavid du Colombier private int
stc_rle(byte * out,const byte * in,int width)10537dd7cddfSDavid du Colombier stc_rle(byte *out,const byte *in,int width)
10547dd7cddfSDavid du Colombier {
10557dd7cddfSDavid du Colombier
10567dd7cddfSDavid du Colombier int used = 0;
10577dd7cddfSDavid du Colombier int crun,cdata;
10587dd7cddfSDavid du Colombier byte run;
10597dd7cddfSDavid du Colombier
10607dd7cddfSDavid du Colombier if(in != NULL) { /* Data present */
10617dd7cddfSDavid du Colombier
10627dd7cddfSDavid du Colombier crun = 1;
10637dd7cddfSDavid du Colombier
10647dd7cddfSDavid du Colombier while(width > 0) { /* something to compress */
10657dd7cddfSDavid du Colombier
10667dd7cddfSDavid du Colombier run = in[0];
10677dd7cddfSDavid du Colombier
10687dd7cddfSDavid du Colombier while((width > crun) && (run == in[crun])) if(++crun == 129) break;
10697dd7cddfSDavid du Colombier
10707dd7cddfSDavid du Colombier if((crun > 2) || (crun == width)) { /* use this run */
10717dd7cddfSDavid du Colombier
10727dd7cddfSDavid du Colombier *out++ = (257 - crun) & 0xff; *out++ = run; used += 2;
10737dd7cddfSDavid du Colombier
10747dd7cddfSDavid du Colombier width -= crun; in += crun;
10757dd7cddfSDavid du Colombier crun = 1;
10767dd7cddfSDavid du Colombier
10777dd7cddfSDavid du Colombier } else { /* ignore this run */
10787dd7cddfSDavid du Colombier
10797dd7cddfSDavid du Colombier for(cdata = crun; (width > cdata) && (crun < 4);) {
10807dd7cddfSDavid du Colombier if(run == in[cdata]) crun += 1;
10817dd7cddfSDavid du Colombier else run = in[cdata], crun = 1;
10827dd7cddfSDavid du Colombier if(++cdata == 128) break;
10837dd7cddfSDavid du Colombier }
10847dd7cddfSDavid du Colombier
10857dd7cddfSDavid du Colombier if(crun < 3) crun = 0; /* ignore trailing run */
10867dd7cddfSDavid du Colombier else cdata -= crun;
10877dd7cddfSDavid du Colombier
10887dd7cddfSDavid du Colombier *out++ = cdata-1; used++;
10897dd7cddfSDavid du Colombier memcpy(out,in,cdata); used += cdata; out += cdata;
10907dd7cddfSDavid du Colombier
10917dd7cddfSDavid du Colombier width -= cdata; in += cdata;
10927dd7cddfSDavid du Colombier
10937dd7cddfSDavid du Colombier } /* use/ignore run */
10947dd7cddfSDavid du Colombier
10957dd7cddfSDavid du Colombier } /* something to compress */
10967dd7cddfSDavid du Colombier
10977dd7cddfSDavid du Colombier } else { /* Empty scans to fill bands */
10987dd7cddfSDavid du Colombier
10997dd7cddfSDavid du Colombier while(width > 0) {
11007dd7cddfSDavid du Colombier crun = width > 129 ? 129 : width;
11017dd7cddfSDavid du Colombier width -= crun;
11027dd7cddfSDavid du Colombier *out++ = (257 - crun) & 0xff;
11037dd7cddfSDavid du Colombier *out++ = 0;
11047dd7cddfSDavid du Colombier used += 2;
11057dd7cddfSDavid du Colombier }
11067dd7cddfSDavid du Colombier } /* Data present or empty */
11077dd7cddfSDavid du Colombier return used;
11087dd7cddfSDavid du Colombier }
11097dd7cddfSDavid du Colombier
11107dd7cddfSDavid du Colombier
11117dd7cddfSDavid du Colombier /*
11127dd7cddfSDavid du Colombier * Horizontal & vertical positioning, color-selection, "ESC ."
11137dd7cddfSDavid du Colombier */
11147dd7cddfSDavid du Colombier private int
stc_print_escpcmd(stcolor_device * sd,FILE * prn_stream,int escp_used,int color,int m,int wbytes)11157dd7cddfSDavid du Colombier stc_print_escpcmd(stcolor_device *sd, FILE *prn_stream,
11167dd7cddfSDavid du Colombier int escp_used, int color,int m,int wbytes)
11177dd7cddfSDavid du Colombier {
11187dd7cddfSDavid du Colombier
11197dd7cddfSDavid du Colombier int dy = sd->stc.stc_y - sd->stc.prt_y; /* number of units to skip */
11207dd7cddfSDavid du Colombier int nlf;
11217dd7cddfSDavid du Colombier
11227dd7cddfSDavid du Colombier /* ESC-R color codes, used only here */
11237dd7cddfSDavid du Colombier static const byte stc_colors[] = { 0x02, 0x01, 0x04, 0x00 }; /* CMYK */
11247dd7cddfSDavid du Colombier
11257dd7cddfSDavid du Colombier /*
11267dd7cddfSDavid du Colombier * initialize the printer, if necessary
11277dd7cddfSDavid du Colombier */
11287dd7cddfSDavid du Colombier if(0 == (sd->stc.flags & STCPRINT)) {
11297dd7cddfSDavid du Colombier
11307dd7cddfSDavid du Colombier fwrite(sd->stc.escp_init.data,1,sd->stc.escp_init.size,prn_stream);
11317dd7cddfSDavid du Colombier
11327dd7cddfSDavid du Colombier if(0 < sd->stc.escp_lf) { /* Adjust Linefeed */
11337dd7cddfSDavid du Colombier fputc('\033', prn_stream);
11347dd7cddfSDavid du Colombier fputc('+', prn_stream);
11357dd7cddfSDavid du Colombier fputc(((sd->stc.escp_m*sd->stc.escp_u) / 10),prn_stream);
11367dd7cddfSDavid du Colombier } /* Adjust Linefeed */
11377dd7cddfSDavid du Colombier sd->stc.flags |= STCPRINT;
11387dd7cddfSDavid du Colombier }
11397dd7cddfSDavid du Colombier
11407dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = '\r'; /* leftmost position */
11417dd7cddfSDavid du Colombier
11427dd7cddfSDavid du Colombier if(dy) { /* position the printer */
11437dd7cddfSDavid du Colombier if(( sd->stc.escp_lf > 0) && /* Linefeed allowed */
11447dd7cddfSDavid du Colombier ((dy % sd->stc.escp_lf) == 0)) /* and possible */
11457dd7cddfSDavid du Colombier nlf = dy / sd->stc.escp_lf;
11467dd7cddfSDavid du Colombier else nlf = 7;
11477dd7cddfSDavid du Colombier
11487dd7cddfSDavid du Colombier if(nlf > 6) {
11497dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = '\033';
11507dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = '(';
11517dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = 'V';
11527dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = '\002';
11537dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = '\000';
11547dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = sd->stc.stc_y & 0xff;
11557dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = (sd->stc.stc_y >> 8) & 0xff;
11567dd7cddfSDavid du Colombier } else {
11577dd7cddfSDavid du Colombier while(nlf--) sd->stc.escp_data[escp_used++] = '\n';
11587dd7cddfSDavid du Colombier }
11597dd7cddfSDavid du Colombier sd->stc.prt_y = sd->stc.stc_y;
11607dd7cddfSDavid du Colombier } /* position the printer */
11617dd7cddfSDavid du Colombier
11627dd7cddfSDavid du Colombier if((sd->color_info.num_components > 1) &&
11637dd7cddfSDavid du Colombier (sd->stc.escp_c != stc_colors[color])) { /* select color */
11647dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = '\033';
11657dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = 'r';
11667dd7cddfSDavid du Colombier sd->stc.escp_c = stc_colors[color];
11677dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = sd->stc.escp_c;
11687dd7cddfSDavid du Colombier } /* select color */
11697dd7cddfSDavid du Colombier
11707dd7cddfSDavid du Colombier /*
11717dd7cddfSDavid du Colombier * Build the command used
11727dd7cddfSDavid du Colombier */
11737dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = '\033';
11747dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = '.';
11757dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] =
11767dd7cddfSDavid du Colombier (sd->stc.flags & STCCOMP) == STCPLAIN ? 0 : 1;
11777dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = sd->stc.escp_v;
11787dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = sd->stc.escp_h;
11797dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = m;
11807dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = (wbytes<<3) & 0xff; /* width in Pixels */
11817dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = (wbytes>>5) & 0xff;
11827dd7cddfSDavid du Colombier
11837dd7cddfSDavid du Colombier return escp_used;
11847dd7cddfSDavid du Colombier }
11857dd7cddfSDavid du Colombier
11867dd7cddfSDavid du Colombier /*
11877dd7cddfSDavid du Colombier * compute width of a group of scanlines
11887dd7cddfSDavid du Colombier */
11897dd7cddfSDavid du Colombier private int
stc_bandwidth(stcolor_device * sd,int color,int m,int npass)11907dd7cddfSDavid du Colombier stc_bandwidth(stcolor_device *sd,int color,int m,int npass)
11917dd7cddfSDavid du Colombier {
11927dd7cddfSDavid du Colombier int ncolor = sd->color_info.num_components == 1 ? 1 : 4;
11937dd7cddfSDavid du Colombier int buf_a = (sd->stc.prt_buf-1) & (sd->stc.stc_y * ncolor + color);
11947dd7cddfSDavid du Colombier int w = 0;
11957dd7cddfSDavid du Colombier
11967dd7cddfSDavid du Colombier while(m-- > 0) { /* check width */
11977dd7cddfSDavid du Colombier if(sd->stc.prt_width[buf_a] > w) w = sd->stc.prt_width[buf_a];
11987dd7cddfSDavid du Colombier buf_a = (sd->stc.prt_buf-1) & (buf_a + ncolor * npass);
11997dd7cddfSDavid du Colombier } /* check width */
12007dd7cddfSDavid du Colombier
12017dd7cddfSDavid du Colombier return w;
12027dd7cddfSDavid du Colombier }
12037dd7cddfSDavid du Colombier
12047dd7cddfSDavid du Colombier /*
12057dd7cddfSDavid du Colombier * Multi-Pass Printing-Routine
12067dd7cddfSDavid du Colombier */
12077dd7cddfSDavid du Colombier private void
stc_print_weave(stcolor_device * sd,FILE * prn_stream)12087dd7cddfSDavid du Colombier stc_print_weave(stcolor_device *sd, FILE *prn_stream)
12097dd7cddfSDavid du Colombier {
12107dd7cddfSDavid du Colombier
12117dd7cddfSDavid du Colombier int escp_used,nprint,nspace,color,buf_a,iprint,w;
12127dd7cddfSDavid du Colombier
12137dd7cddfSDavid du Colombier int npass = sd->stc.escp_v / sd->stc.escp_u;
12147dd7cddfSDavid du Colombier int ncolor = sd->color_info.num_components == 1 ? 1 : 4;
12157dd7cddfSDavid du Colombier
12167dd7cddfSDavid du Colombier
12177dd7cddfSDavid du Colombier while(sd->stc.stc_y < sd->stc.prt_scans) {
12187dd7cddfSDavid du Colombier
12197dd7cddfSDavid du Colombier /*
12207dd7cddfSDavid du Colombier * compute spacing & used heads (seems to work with odd escp_m)
12217dd7cddfSDavid du Colombier */
12227dd7cddfSDavid du Colombier if(sd->stc.stc_y >= sd->stc.escp_m) { /* in normal mode */
12237dd7cddfSDavid du Colombier nprint = sd->stc.escp_m;
12247dd7cddfSDavid du Colombier nspace = sd->stc.escp_m;
12257dd7cddfSDavid du Colombier } else if((sd->stc.stc_y) < npass) { /* initialisation */
12267dd7cddfSDavid du Colombier nprint = sd->stc.escp_m - sd->stc.stc_y * ((sd->stc.escp_m+1)/npass);
12277dd7cddfSDavid du Colombier nspace = 1;
12287dd7cddfSDavid du Colombier } else { /* switch to normal */
12297dd7cddfSDavid du Colombier nprint = sd->stc.escp_m - sd->stc.stc_y * ((sd->stc.escp_m+1)/npass);
12307dd7cddfSDavid du Colombier nspace = sd->stc.escp_m - sd->stc.stc_y;
12317dd7cddfSDavid du Colombier }
12327dd7cddfSDavid du Colombier iprint = sd->stc.stc_y + npass * nprint;
12337dd7cddfSDavid du Colombier if(sd->stc.buf_y < iprint) break;
12347dd7cddfSDavid du Colombier
12357dd7cddfSDavid du Colombier escp_used = 0;
12367dd7cddfSDavid du Colombier for(color = 0; color < ncolor; ++color) { /* print the colors */
12377dd7cddfSDavid du Colombier
12387dd7cddfSDavid du Colombier if(0 == (w = stc_bandwidth(sd,color,nprint,npass))) continue;
12397dd7cddfSDavid du Colombier
12407dd7cddfSDavid du Colombier escp_used = stc_print_escpcmd(sd,prn_stream,
12417dd7cddfSDavid du Colombier escp_used,color,sd->stc.escp_m,w);
12427dd7cddfSDavid du Colombier
12437dd7cddfSDavid du Colombier buf_a = (sd->stc.prt_buf-1) & (sd->stc.stc_y * ncolor + color);
12447dd7cddfSDavid du Colombier for(iprint = 0; iprint < nprint; ++iprint) { /* send data */
12457dd7cddfSDavid du Colombier
12467dd7cddfSDavid du Colombier if((sd->stc.flags & STCCOMP) == STCPLAIN) {
12477dd7cddfSDavid du Colombier memcpy(sd->stc.escp_data+escp_used,sd->stc.prt_data[buf_a],w);
12487dd7cddfSDavid du Colombier escp_used += w;
12497dd7cddfSDavid du Colombier } else {
12507dd7cddfSDavid du Colombier escp_used += stc_rle(sd->stc.escp_data+escp_used,
12517dd7cddfSDavid du Colombier sd->stc.prt_data[buf_a],w);
12527dd7cddfSDavid du Colombier }
12537dd7cddfSDavid du Colombier
12547dd7cddfSDavid du Colombier fwrite(sd->stc.escp_data,1,escp_used,prn_stream);
12557dd7cddfSDavid du Colombier escp_used = 0;
12567dd7cddfSDavid du Colombier
12577dd7cddfSDavid du Colombier buf_a = (sd->stc.prt_buf-1) & (buf_a + ncolor * npass);
12587dd7cddfSDavid du Colombier
12597dd7cddfSDavid du Colombier } /* send data */
12607dd7cddfSDavid du Colombier
12617dd7cddfSDavid du Colombier while(iprint++ < sd->stc.escp_m) { /* add empty rows */
12627dd7cddfSDavid du Colombier
12637dd7cddfSDavid du Colombier if((sd->stc.flags & STCCOMP) == STCPLAIN) {
12647dd7cddfSDavid du Colombier memset(sd->stc.escp_data+escp_used,0,w);
12657dd7cddfSDavid du Colombier escp_used += w;
12667dd7cddfSDavid du Colombier } else {
12677dd7cddfSDavid du Colombier escp_used += stc_rle(sd->stc.escp_data+escp_used,NULL,w);
12687dd7cddfSDavid du Colombier }
12697dd7cddfSDavid du Colombier
12707dd7cddfSDavid du Colombier fwrite(sd->stc.escp_data,1,escp_used,prn_stream);
12717dd7cddfSDavid du Colombier escp_used = 0;
12727dd7cddfSDavid du Colombier } /* add empty rows */
12737dd7cddfSDavid du Colombier } /* print the colors */
12747dd7cddfSDavid du Colombier
12757dd7cddfSDavid du Colombier sd->stc.stc_y += nspace;
12767dd7cddfSDavid du Colombier }
12777dd7cddfSDavid du Colombier }
12787dd7cddfSDavid du Colombier
12797dd7cddfSDavid du Colombier /*
12807dd7cddfSDavid du Colombier * Single-Pass printing-Routine
12817dd7cddfSDavid du Colombier */
12827dd7cddfSDavid du Colombier private void
stc_print_bands(stcolor_device * sd,FILE * prn_stream)12837dd7cddfSDavid du Colombier stc_print_bands(stcolor_device *sd, FILE *prn_stream)
12847dd7cddfSDavid du Colombier {
12857dd7cddfSDavid du Colombier
12867dd7cddfSDavid du Colombier int escp_used,color,buf_a,iprint,w,m;
12877dd7cddfSDavid du Colombier
12887dd7cddfSDavid du Colombier int ncolor = sd->color_info.num_components == 1 ? 1 : 4;
12897dd7cddfSDavid du Colombier
12907dd7cddfSDavid du Colombier while(sd->stc.stc_y < sd->stc.prt_scans) {
12917dd7cddfSDavid du Colombier
12927dd7cddfSDavid du Colombier /*
12937dd7cddfSDavid du Colombier * find the begin of the band
12947dd7cddfSDavid du Colombier */
12957dd7cddfSDavid du Colombier for(w = 0; sd->stc.stc_y < sd->stc.buf_y; ++sd->stc.stc_y) {
12967dd7cddfSDavid du Colombier buf_a = (sd->stc.prt_buf-1) & (sd->stc.stc_y * ncolor);
12977dd7cddfSDavid du Colombier for(color = 0; color < ncolor; ++color)
12987dd7cddfSDavid du Colombier if(sd->stc.prt_width[buf_a+color] > w)
12997dd7cddfSDavid du Colombier w = sd->stc.prt_width[buf_a+color];
13007dd7cddfSDavid du Colombier if(w != 0) break;
13017dd7cddfSDavid du Colombier }
13027dd7cddfSDavid du Colombier if(w == 0) break;
13037dd7cddfSDavid du Colombier /*
13047dd7cddfSDavid du Colombier * adjust the band-height
13057dd7cddfSDavid du Colombier */
13067dd7cddfSDavid du Colombier w = sd->stc.prt_scans - sd->stc.stc_y;
13077dd7cddfSDavid du Colombier if((w < sd->stc.escp_m) && (sd->stc.escp_v != 40)) {
13087dd7cddfSDavid du Colombier if(w < 8) m = 1;
13097dd7cddfSDavid du Colombier else if(w < 24) m = 8;
13107dd7cddfSDavid du Colombier else m = 24;
13117dd7cddfSDavid du Colombier } else {
13127dd7cddfSDavid du Colombier m = sd->stc.escp_m;
13137dd7cddfSDavid du Colombier }
13147dd7cddfSDavid du Colombier
13157dd7cddfSDavid du Colombier if(sd->stc.buf_y < (sd->stc.stc_y+m)) break;
13167dd7cddfSDavid du Colombier
13177dd7cddfSDavid du Colombier escp_used = 0;
13187dd7cddfSDavid du Colombier for(color = 0; color < ncolor; ++color) { /* print the colors */
13197dd7cddfSDavid du Colombier
13207dd7cddfSDavid du Colombier if(0 == (w = stc_bandwidth(sd,color,m,1))) continue; /* shortcut */
13217dd7cddfSDavid du Colombier
13227dd7cddfSDavid du Colombier escp_used = stc_print_escpcmd(sd,prn_stream,escp_used,color,m,w);
13237dd7cddfSDavid du Colombier
13247dd7cddfSDavid du Colombier buf_a = (sd->stc.prt_buf-1) & (sd->stc.stc_y * ncolor + color);
13257dd7cddfSDavid du Colombier for(iprint = 0; iprint < m; ++iprint) { /* send data */
13267dd7cddfSDavid du Colombier
13277dd7cddfSDavid du Colombier if((sd->stc.flags & STCCOMP) == STCPLAIN) {
13287dd7cddfSDavid du Colombier memcpy(sd->stc.escp_data+escp_used,sd->stc.prt_data[buf_a],w);
13297dd7cddfSDavid du Colombier escp_used += w;
13307dd7cddfSDavid du Colombier } else {
13317dd7cddfSDavid du Colombier escp_used += stc_rle(sd->stc.escp_data+escp_used,
13327dd7cddfSDavid du Colombier sd->stc.prt_data[buf_a],w);
13337dd7cddfSDavid du Colombier }
13347dd7cddfSDavid du Colombier
13357dd7cddfSDavid du Colombier fwrite(sd->stc.escp_data,1,escp_used,prn_stream);
13367dd7cddfSDavid du Colombier escp_used = 0;
13377dd7cddfSDavid du Colombier
13387dd7cddfSDavid du Colombier buf_a = (sd->stc.prt_buf-1) & (buf_a + ncolor);
13397dd7cddfSDavid du Colombier
13407dd7cddfSDavid du Colombier } /* send data */
13417dd7cddfSDavid du Colombier
13427dd7cddfSDavid du Colombier } /* print the colors */
13437dd7cddfSDavid du Colombier
13447dd7cddfSDavid du Colombier sd->stc.stc_y += m;
13457dd7cddfSDavid du Colombier }
13467dd7cddfSDavid du Colombier }
13477dd7cddfSDavid du Colombier /* ----------------------------------------------------------------------- */
13487dd7cddfSDavid du Colombier
13497dd7cddfSDavid du Colombier private int
stc_deltarow(byte * out,const byte * in,int width,byte * seed)13507dd7cddfSDavid du Colombier stc_deltarow(byte *out,const byte *in,int width,byte *seed)
13517dd7cddfSDavid du Colombier {
13527dd7cddfSDavid du Colombier
13537dd7cddfSDavid du Colombier int istop,nmove,ndata,i,j;
13547dd7cddfSDavid du Colombier int *wseed = (int *) seed;
13557dd7cddfSDavid du Colombier int used = 0;
13567dd7cddfSDavid du Colombier
13577dd7cddfSDavid du Colombier seed += sizeof(int);
13587dd7cddfSDavid du Colombier
13597dd7cddfSDavid du Colombier if((in != NULL) && (width > 0)) { /* Data present */
13607dd7cddfSDavid du Colombier
13617dd7cddfSDavid du Colombier istop = width < wseed[0] ? wseed[0] : width;
13627dd7cddfSDavid du Colombier
13637dd7cddfSDavid du Colombier i = 0;
13647dd7cddfSDavid du Colombier while(i < istop) {
13657dd7cddfSDavid du Colombier
13667dd7cddfSDavid du Colombier for(j = i; j < istop; ++j) if(in[j] != seed[j]) break;
13677dd7cddfSDavid du Colombier
13687dd7cddfSDavid du Colombier nmove = j - i;
13697dd7cddfSDavid du Colombier
13707dd7cddfSDavid du Colombier if(nmove > 0) { /* issue a move */
13717dd7cddfSDavid du Colombier i = j;
13727dd7cddfSDavid du Colombier if(i == istop) break;
13737dd7cddfSDavid du Colombier
13747dd7cddfSDavid du Colombier if( nmove < 8) {
13757dd7cddfSDavid du Colombier out[used++] = 0x40 | nmove;
13767dd7cddfSDavid du Colombier } else if(nmove < 128) {
13777dd7cddfSDavid du Colombier out[used++] = 0x51;
13787dd7cddfSDavid du Colombier out[used++] = nmove;
13797dd7cddfSDavid du Colombier } else {
13807dd7cddfSDavid du Colombier out[used++] = 0x52;
13817dd7cddfSDavid du Colombier out[used++] = 0xff & nmove;
13827dd7cddfSDavid du Colombier out[used++] = 0xff & (nmove>>8);
13837dd7cddfSDavid du Colombier }
13847dd7cddfSDavid du Colombier } /* issue a move */
13857dd7cddfSDavid du Colombier
13867dd7cddfSDavid du Colombier /*
13877dd7cddfSDavid du Colombier * find the end of this run
13887dd7cddfSDavid du Colombier */
13897dd7cddfSDavid du Colombier nmove = 0;
13907dd7cddfSDavid du Colombier for(j = i+1; (j < istop) && ((nmove < 4)); ++j) {
13917dd7cddfSDavid du Colombier if(in[j] == seed[j]) nmove += 1;
13927dd7cddfSDavid du Colombier else nmove = 0;
13937dd7cddfSDavid du Colombier }
13947dd7cddfSDavid du Colombier
13957dd7cddfSDavid du Colombier ndata = j-i-nmove;
13967dd7cddfSDavid du Colombier
13977dd7cddfSDavid du Colombier nmove = stc_rle(out+used+3,in+i,ndata);
13987dd7cddfSDavid du Colombier if(nmove < 16) {
13997dd7cddfSDavid du Colombier out[used++] = 0x20 | nmove;
14007dd7cddfSDavid du Colombier for(j = 0; j < nmove; ++j) out[used+j] = out[used+j+2];
14017dd7cddfSDavid du Colombier } else if(nmove < 256) {
14027dd7cddfSDavid du Colombier out[used++] = 0x31;
14037dd7cddfSDavid du Colombier out[used++] = nmove;
14047dd7cddfSDavid du Colombier for(j = 0; j < nmove; ++j) out[used+j] = out[used+j+1];
14057dd7cddfSDavid du Colombier } else {
14067dd7cddfSDavid du Colombier out[used++] = 0x32;
14077dd7cddfSDavid du Colombier out[used++] = 0xff & nmove;
14087dd7cddfSDavid du Colombier out[used++] = 0xff & (nmove>>8);
14097dd7cddfSDavid du Colombier }
14107dd7cddfSDavid du Colombier used += nmove;
14117dd7cddfSDavid du Colombier i += ndata;
14127dd7cddfSDavid du Colombier }
14137dd7cddfSDavid du Colombier
14147dd7cddfSDavid du Colombier memcpy(seed,in,istop);
14157dd7cddfSDavid du Colombier wseed[0] = width;
14167dd7cddfSDavid du Colombier
14177dd7cddfSDavid du Colombier } else if(wseed[0] > 0) { /* blank line, but seed has data */
14187dd7cddfSDavid du Colombier
14197dd7cddfSDavid du Colombier out[used++] = 0xe1; /* clear row */
14207dd7cddfSDavid du Colombier memset(seed,0,wseed[0]);
14217dd7cddfSDavid du Colombier wseed[0] = 0;
14227dd7cddfSDavid du Colombier
14237dd7cddfSDavid du Colombier }
14247dd7cddfSDavid du Colombier
14257dd7cddfSDavid du Colombier return used;
14267dd7cddfSDavid du Colombier }
14277dd7cddfSDavid du Colombier
14287dd7cddfSDavid du Colombier /*
14297dd7cddfSDavid du Colombier * Slightly different single-pass printing
14307dd7cddfSDavid du Colombier */
14317dd7cddfSDavid du Colombier private void
stc_print_delta(stcolor_device * sd,FILE * prn_stream)14327dd7cddfSDavid du Colombier stc_print_delta(stcolor_device *sd, FILE *prn_stream)
14337dd7cddfSDavid du Colombier {
14347dd7cddfSDavid du Colombier
14357dd7cddfSDavid du Colombier int color,buf_a,w;
14367dd7cddfSDavid du Colombier int escp_used = 0;
14377dd7cddfSDavid du Colombier int ncolor = sd->color_info.num_components == 1 ? 1 : 4;
14387dd7cddfSDavid du Colombier
14397dd7cddfSDavid du Colombier while(sd->stc.stc_y < sd->stc.prt_scans) {
14407dd7cddfSDavid du Colombier
14417dd7cddfSDavid du Colombier /*
14427dd7cddfSDavid du Colombier * find the begin of the band
14437dd7cddfSDavid du Colombier */
14447dd7cddfSDavid du Colombier for(w = 0; sd->stc.stc_y < sd->stc.buf_y; ++sd->stc.stc_y) {
14457dd7cddfSDavid du Colombier buf_a = (sd->stc.prt_buf-1) & (sd->stc.stc_y * ncolor);
14467dd7cddfSDavid du Colombier for(color = 0; color < ncolor; ++color)
14477dd7cddfSDavid du Colombier if(sd->stc.prt_width[buf_a+color] > w)
14487dd7cddfSDavid du Colombier w = sd->stc.prt_width[buf_a+color];
14497dd7cddfSDavid du Colombier if(w != 0) break;
14507dd7cddfSDavid du Colombier }
14517dd7cddfSDavid du Colombier
14527dd7cddfSDavid du Colombier if(sd->stc.buf_y == sd->stc.stc_y) break;
14537dd7cddfSDavid du Colombier
14547dd7cddfSDavid du Colombier escp_used = 0;
14557dd7cddfSDavid du Colombier
14567dd7cddfSDavid du Colombier /*
14577dd7cddfSDavid du Colombier * Send Initialization & ESC . 3 once
14587dd7cddfSDavid du Colombier */
14597dd7cddfSDavid du Colombier if(0 == (sd->stc.flags & STCPRINT)) {
14607dd7cddfSDavid du Colombier
14617dd7cddfSDavid du Colombier sd->stc.flags |= STCPRINT;
14627dd7cddfSDavid du Colombier
14637dd7cddfSDavid du Colombier fwrite(sd->stc.escp_init.data,1,sd->stc.escp_init.size,prn_stream);
14647dd7cddfSDavid du Colombier
14657dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = '\033';
14667dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = '.';
14677dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = 3;
14687dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = sd->stc.escp_v;
14697dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = sd->stc.escp_h;
14707dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = sd->stc.escp_m;
14717dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = 0;
14727dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = 0;
14737dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = 0xe4; /* MOVXBYTE */
14747dd7cddfSDavid du Colombier }
14757dd7cddfSDavid du Colombier
14767dd7cddfSDavid du Colombier if(sd->stc.stc_y != sd->stc.prt_y) { /* really position the printer */
14777dd7cddfSDavid du Colombier w = sd->stc.stc_y - sd->stc.prt_y;
14787dd7cddfSDavid du Colombier if( w < 16) {
14797dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = 0x60 | w;
14807dd7cddfSDavid du Colombier } else if(w < 256) {
14817dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = 0x71;
14827dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = w;
14837dd7cddfSDavid du Colombier } else {
14847dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = 0x72;
14857dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = 0xff & w;
14867dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = 0xff & (w>>8);
14877dd7cddfSDavid du Colombier }
14887dd7cddfSDavid du Colombier sd->stc.prt_y = sd->stc.stc_y;
14897dd7cddfSDavid du Colombier } /* really position the printer */
14907dd7cddfSDavid du Colombier
14917dd7cddfSDavid du Colombier for(color = 0; color < ncolor; ++color) { /* print the colors */
14927dd7cddfSDavid du Colombier
14937dd7cddfSDavid du Colombier /* Color-Selection */
14947dd7cddfSDavid du Colombier if(color == (ncolor-1)) {
14957dd7cddfSDavid du Colombier sd->stc.escp_data[escp_used++] = 0x80; /* Black */
14967dd7cddfSDavid du Colombier } else {
14977dd7cddfSDavid du Colombier switch(color) {
14987dd7cddfSDavid du Colombier case 1: sd->stc.escp_data[escp_used++] = 0x81; break; /* M */
14997dd7cddfSDavid du Colombier case 2: sd->stc.escp_data[escp_used++] = 0x84; break; /* Y */
15007dd7cddfSDavid du Colombier default: sd->stc.escp_data[escp_used++] = 0x82; break; /* C */
15017dd7cddfSDavid du Colombier }
15027dd7cddfSDavid du Colombier }
15037dd7cddfSDavid du Colombier
15047dd7cddfSDavid du Colombier /* Data-Transfer */
15057dd7cddfSDavid du Colombier buf_a = (sd->stc.prt_buf-1) & (sd->stc.stc_y * ncolor + color);
15067dd7cddfSDavid du Colombier
15077dd7cddfSDavid du Colombier w = stc_deltarow(sd->stc.escp_data+escp_used,
15087dd7cddfSDavid du Colombier sd->stc.prt_data[buf_a],sd->stc.prt_width[buf_a],
15097dd7cddfSDavid du Colombier sd->stc.seed_row[color]);
15107dd7cddfSDavid du Colombier
15117dd7cddfSDavid du Colombier if(w == 0) escp_used -= 1;
15127dd7cddfSDavid du Colombier else escp_used += w;
15137dd7cddfSDavid du Colombier
15147dd7cddfSDavid du Colombier if(escp_used > 0) fwrite(sd->stc.escp_data,1,escp_used,prn_stream);
15157dd7cddfSDavid du Colombier escp_used = 0;
15167dd7cddfSDavid du Colombier
15177dd7cddfSDavid du Colombier } /* print the colors */
15187dd7cddfSDavid du Colombier
15197dd7cddfSDavid du Colombier sd->stc.stc_y += 1;
15207dd7cddfSDavid du Colombier
15217dd7cddfSDavid du Colombier }
15227dd7cddfSDavid du Colombier
15237dd7cddfSDavid du Colombier }
15247dd7cddfSDavid du Colombier
15257dd7cddfSDavid du Colombier /* ----------------------------------------------------------------------- */
15267dd7cddfSDavid du Colombier
15277dd7cddfSDavid du Colombier /***
15287dd7cddfSDavid du Colombier *** Free-Data: release the specific-Arrays
15297dd7cddfSDavid du Colombier ***/
15307dd7cddfSDavid du Colombier private void
stc_freedata(gs_memory_t * mem,stc_t * stc)1531*593dc095SDavid du Colombier stc_freedata(gs_memory_t *mem, stc_t *stc)
15327dd7cddfSDavid du Colombier {
15337dd7cddfSDavid du Colombier int i,j;
15347dd7cddfSDavid du Colombier
15357dd7cddfSDavid du Colombier for(i = 0; i < 4; ++i) {
15367dd7cddfSDavid du Colombier if(stc->code[i] != NULL) {
15377dd7cddfSDavid du Colombier
15387dd7cddfSDavid du Colombier for(j = 0; j < i; ++j) if(stc->code[i] == stc->code[j]) break;
15397dd7cddfSDavid du Colombier
1540*593dc095SDavid du Colombier if(i == j) gs_free(mem, stc->code[i],1<<stc->bits,sizeof(gx_color_value),
15417dd7cddfSDavid du Colombier "stcolor/code");
15427dd7cddfSDavid du Colombier }
15437dd7cddfSDavid du Colombier
15447dd7cddfSDavid du Colombier if(stc->vals[i] != NULL) {
15457dd7cddfSDavid du Colombier
15467dd7cddfSDavid du Colombier for(j = 0; j < i; ++j)
15477dd7cddfSDavid du Colombier if(stc->vals[i] == stc->vals[j]) break;
15487dd7cddfSDavid du Colombier
1549*593dc095SDavid du Colombier if(i == j) gs_free(mem, stc->vals[i],1<<stc->bits,sd->stc.alg_item,
15507dd7cddfSDavid du Colombier "stcolor/transfer");
15517dd7cddfSDavid du Colombier }
15527dd7cddfSDavid du Colombier }
15537dd7cddfSDavid du Colombier
15547dd7cddfSDavid du Colombier for(i = 0; i < 4; ++i) {
15557dd7cddfSDavid du Colombier stc->code[i] = NULL;
15567dd7cddfSDavid du Colombier stc->vals[i] = NULL;
15577dd7cddfSDavid du Colombier }
15587dd7cddfSDavid du Colombier }
15597dd7cddfSDavid du Colombier
15607dd7cddfSDavid du Colombier /***
15617dd7cddfSDavid du Colombier *** open the device and initialize margins & arrays
15627dd7cddfSDavid du Colombier ***/
15637dd7cddfSDavid du Colombier
15647dd7cddfSDavid du Colombier private int
stc_open(gx_device * pdev)15657dd7cddfSDavid du Colombier stc_open(gx_device *pdev) /* setup margins & arrays */
15667dd7cddfSDavid du Colombier {
15677dd7cddfSDavid du Colombier stcolor_device *sd = (stcolor_device *) pdev;
15687dd7cddfSDavid du Colombier int i,j,code;
15697dd7cddfSDavid du Colombier gx_color_index white;
15707dd7cddfSDavid du Colombier byte *bpw,*bpm;
15717dd7cddfSDavid du Colombier
15727dd7cddfSDavid du Colombier code = 0;
15737dd7cddfSDavid du Colombier /*
15747dd7cddfSDavid du Colombier * Establish Algorithm-Table, if not present
15757dd7cddfSDavid du Colombier */
15767dd7cddfSDavid du Colombier if(sd->stc.algorithms.size == 0) {
15777dd7cddfSDavid du Colombier gs_param_string *dp;
15787dd7cddfSDavid du Colombier for(i = 0; stc_dither[i].name != NULL; ++i); /* count 'em */
15797dd7cddfSDavid du Colombier sd->stc.algorithms.size = i;
1580*593dc095SDavid du Colombier dp = gs_malloc(sd->memory, i,sizeof(gs_param_string),
15817dd7cddfSDavid du Colombier "stcolor/algorithms");
15827dd7cddfSDavid du Colombier if(dp == NULL) {
15837dd7cddfSDavid du Colombier code = gs_error_VMerror;
15847dd7cddfSDavid du Colombier sd->stc.algorithms.size = 0;
15857dd7cddfSDavid du Colombier } else {
15867dd7cddfSDavid du Colombier sd->stc.algorithms.data = dp;
15877dd7cddfSDavid du Colombier sd->stc.algorithms.persistent = true;
15887dd7cddfSDavid du Colombier for(i = 0; stc_dither[i].name != NULL; ++i) {
15897dd7cddfSDavid du Colombier param_string_from_string(dp[i],stc_dither[i].name);
15907dd7cddfSDavid du Colombier }
15917dd7cddfSDavid du Colombier }
15927dd7cddfSDavid du Colombier }
15937dd7cddfSDavid du Colombier
15947dd7cddfSDavid du Colombier # define stc_sizeofitem(T) sd->stc.alg_item = sizeof(T)
15957dd7cddfSDavid du Colombier STC_TYPESWITCH(sd->stc.dither,stc_sizeofitem)
15967dd7cddfSDavid du Colombier
15977dd7cddfSDavid du Colombier stc_print_setup(sd);
15987dd7cddfSDavid du Colombier
15997dd7cddfSDavid du Colombier /*
16007dd7cddfSDavid du Colombier * Establish internal Value & Code-Arrays
16017dd7cddfSDavid du Colombier */
16027dd7cddfSDavid du Colombier
16037dd7cddfSDavid du Colombier
16047dd7cddfSDavid du Colombier for(i = 0; i < sd->color_info.num_components; ++i) { /* comp */
16057dd7cddfSDavid du Colombier
16067dd7cddfSDavid du Colombier if((sd->stc.sizc[i] > 1) && (sd->stc.extc[i] != NULL)) { /* code req. */
16077dd7cddfSDavid du Colombier
16087dd7cddfSDavid du Colombier for(j = 0; j < i; ++j) if(sd->stc.extc[i] == sd->stc.extc[j]) break;
16097dd7cddfSDavid du Colombier
16107dd7cddfSDavid du Colombier if(i == j) { /* new one */
1611*593dc095SDavid du Colombier sd->stc.code[i] = gs_malloc(sd->memory, 1<<sd->stc.bits,sizeof(gx_color_value),
16127dd7cddfSDavid du Colombier "stcolor/code");
16137dd7cddfSDavid du Colombier
16147dd7cddfSDavid du Colombier if(sd->stc.code[i] == NULL) { /* error */
16157dd7cddfSDavid du Colombier code = gs_error_VMerror;
16167dd7cddfSDavid du Colombier } else { /* success */
16177dd7cddfSDavid du Colombier /*
16187dd7cddfSDavid du Colombier * Try making things easier:
16197dd7cddfSDavid du Colombier * normalize values to 0.0/1.0-Range
16207dd7cddfSDavid du Colombier * X-Axis: Color-Values (implied)
16217dd7cddfSDavid du Colombier * Y-Values: Indices (given)
16227dd7cddfSDavid du Colombier */
16237dd7cddfSDavid du Colombier unsigned long ly,iy;
16247dd7cddfSDavid du Colombier double ystep,xstep,fx,fy;
16257dd7cddfSDavid du Colombier
16267dd7cddfSDavid du Colombier /* normalize */
16277dd7cddfSDavid du Colombier
16287dd7cddfSDavid du Colombier fx = 1e18;
16297dd7cddfSDavid du Colombier fy = -1e18;
16307dd7cddfSDavid du Colombier for(ly = 0; ly < sd->stc.sizc[i]; ++ly) {
16317dd7cddfSDavid du Colombier if(sd->stc.extc[i][ly] < fx) fx = sd->stc.extc[i][ly];
16327dd7cddfSDavid du Colombier if(sd->stc.extc[i][ly] > fy) fy = sd->stc.extc[i][ly];
16337dd7cddfSDavid du Colombier }
16347dd7cddfSDavid du Colombier if((fx != 0.0) || (fy != 1.0)) {
16357dd7cddfSDavid du Colombier fy = 1.0 / (fy - fx);
16367dd7cddfSDavid du Colombier for(ly = 0; ly < sd->stc.sizc[i]; ++ly)
16377dd7cddfSDavid du Colombier sd->stc.extc[i][ly] = fy * (sd->stc.extc[i][ly]-fx);
16387dd7cddfSDavid du Colombier }
16397dd7cddfSDavid du Colombier
16407dd7cddfSDavid du Colombier /* interpolate */
16417dd7cddfSDavid du Colombier ystep = 1.0 / (double)((1<<sd->stc.bits)-1);
16427dd7cddfSDavid du Colombier xstep = 1.0 / (double)( sd->stc.sizc[i] -1);
16437dd7cddfSDavid du Colombier
16447dd7cddfSDavid du Colombier iy = 0;
16457dd7cddfSDavid du Colombier for(ly = 0; ly < (1<<sd->stc.bits); ++ly) {
16467dd7cddfSDavid du Colombier fy = ystep * ly;
16477dd7cddfSDavid du Colombier while(((iy+1) < sd->stc.sizc[i]) &&
16487dd7cddfSDavid du Colombier ( fy > sd->stc.extc[i][iy+1])) ++iy;
16497dd7cddfSDavid du Colombier fx = iy + (fy - sd->stc.extc[i][iy])
16507dd7cddfSDavid du Colombier / (sd->stc.extc[i][iy+1] - sd->stc.extc[i][iy]);
16517dd7cddfSDavid du Colombier fx *= xstep * gx_max_color_value;
16527dd7cddfSDavid du Colombier
16537dd7cddfSDavid du Colombier fx = fx < 0.0 ? 0.0 :
16547dd7cddfSDavid du Colombier (fx > gx_max_color_value ? gx_max_color_value : fx);
16557dd7cddfSDavid du Colombier
1656*593dc095SDavid du Colombier sd->stc.code[i][ly] = (gx_color_value)fx;
16577dd7cddfSDavid du Colombier if((fx-sd->stc.code[i][ly]) >= 0.5) sd->stc.code[i][ly] += 1;
16587dd7cddfSDavid du Colombier }
16597dd7cddfSDavid du Colombier } /* error || success */
16607dd7cddfSDavid du Colombier
16617dd7cddfSDavid du Colombier } else { /* shared one */
16627dd7cddfSDavid du Colombier
16637dd7cddfSDavid du Colombier sd->stc.code[i] = sd->stc.code[j];
16647dd7cddfSDavid du Colombier
16657dd7cddfSDavid du Colombier } /* new || shared one */
16667dd7cddfSDavid du Colombier } /* code req. */
16677dd7cddfSDavid du Colombier
16687dd7cddfSDavid du Colombier if((sd->stc.sizv[i] > 1) && (sd->stc.extv[i] != NULL)) { /* vals req. */
16697dd7cddfSDavid du Colombier
16707dd7cddfSDavid du Colombier for(j = 0; j < i; ++j)
16717dd7cddfSDavid du Colombier if((sd->stc.extc[i] == sd->stc.extc[j]) &&
16727dd7cddfSDavid du Colombier (sd->stc.extv[i] == sd->stc.extv[j])) break;
16737dd7cddfSDavid du Colombier
16747dd7cddfSDavid du Colombier if(i == j) { /* new one */
16757dd7cddfSDavid du Colombier
16767dd7cddfSDavid du Colombier sd->stc.vals[i] =
1677*593dc095SDavid du Colombier gs_malloc(sd->memory, 1<<sd->stc.bits,sd->stc.alg_item,"stcolor/transfer");
16787dd7cddfSDavid du Colombier
16797dd7cddfSDavid du Colombier if(sd->stc.vals[i] == NULL) {
16807dd7cddfSDavid du Colombier
16817dd7cddfSDavid du Colombier code = gs_error_VMerror;
16827dd7cddfSDavid du Colombier
16837dd7cddfSDavid du Colombier } else { /* success */
16847dd7cddfSDavid du Colombier
16857dd7cddfSDavid du Colombier
16867dd7cddfSDavid du Colombier if(sd->stc.code[i] == NULL) { /* linear */
16877dd7cddfSDavid du Colombier
16887dd7cddfSDavid du Colombier byte *Out = sd->stc.vals[i];
16897dd7cddfSDavid du Colombier int Nout = 1<<sd->stc.bits;
16907dd7cddfSDavid du Colombier double Omin = sd->stc.dither->minmax[0];
16917dd7cddfSDavid du Colombier double Omax = sd->stc.dither->minmax[1];
16927dd7cddfSDavid du Colombier float *In = sd->stc.extv[i];
16937dd7cddfSDavid du Colombier int Nin = sd->stc.sizv[i];
16947dd7cddfSDavid du Colombier unsigned long I,io;
16957dd7cddfSDavid du Colombier double Istep,Ostep,Y;
16967dd7cddfSDavid du Colombier byte Ovb; long Ovl;
16977dd7cddfSDavid du Colombier
16987dd7cddfSDavid du Colombier Istep = 1.0 / (double) ((Nin)-1);
16997dd7cddfSDavid du Colombier Ostep = 1.0 / (double) ((Nout)-1);
17007dd7cddfSDavid du Colombier
17017dd7cddfSDavid du Colombier for(io = 0; io < (Nout); ++io) {
17027dd7cddfSDavid du Colombier I = (long)(io * ((Nin)-1))/((Nout)-1);
17037dd7cddfSDavid du Colombier
17047dd7cddfSDavid du Colombier if((I+1) < (Nin))
17057dd7cddfSDavid du Colombier Y = In[I] + (In[I+1]-In[I])
17067dd7cddfSDavid du Colombier * ((double) io * Ostep - (double)I * Istep)
17077dd7cddfSDavid du Colombier / (double) Istep;
17087dd7cddfSDavid du Colombier else
17097dd7cddfSDavid du Colombier Y = In[I] + (In[I]-In[I-1])
17107dd7cddfSDavid du Colombier * ((double) io * Ostep - (double)I * Istep)
17117dd7cddfSDavid du Colombier / (double) Istep;
17127dd7cddfSDavid du Colombier
17137dd7cddfSDavid du Colombier Y = Omin + (Omax-Omin) * Y;
17147dd7cddfSDavid du Colombier Y = Y < Omin ? Omin : (Y > Omax ? Omax : Y);
17157dd7cddfSDavid du Colombier
17167dd7cddfSDavid du Colombier
17177dd7cddfSDavid du Colombier switch(sd->stc.dither->flags & STC_TYPE) {
17187dd7cddfSDavid du Colombier case STC_BYTE:
1719*593dc095SDavid du Colombier Ovb = (byte)Y;
17207dd7cddfSDavid du Colombier if(((Y-Ovb) >= 0.5) && ((Ovb+1) <= Omax)) Ovb += 1;
17217dd7cddfSDavid du Colombier Out[io] = Ovb;
17227dd7cddfSDavid du Colombier break;
17237dd7cddfSDavid du Colombier case STC_LONG:
1724*593dc095SDavid du Colombier Ovl = (long)Y;
17257dd7cddfSDavid du Colombier if(((Y-Ovl) >= 0.5) && ((Ovl+1) <= Omax)) Ovl += 1;
17267dd7cddfSDavid du Colombier if(((Ovl-Y) >= 0.5) && ((Ovl-1) >= Omax)) Ovl -= 1;
17277dd7cddfSDavid du Colombier ((long *)Out)[io] = Ovl;
17287dd7cddfSDavid du Colombier break;
17297dd7cddfSDavid du Colombier default:
17307dd7cddfSDavid du Colombier ((float *)Out)[io] = Y;
17317dd7cddfSDavid du Colombier break;
17327dd7cddfSDavid du Colombier }
17337dd7cddfSDavid du Colombier }
17347dd7cddfSDavid du Colombier
17357dd7cddfSDavid du Colombier } else { /* encoded */
17367dd7cddfSDavid du Colombier unsigned long j,o;
17377dd7cddfSDavid du Colombier double xstep,x,y;
17387dd7cddfSDavid du Colombier
17397dd7cddfSDavid du Colombier xstep = 1.0 / (double) (sd->stc.sizv[i]-1);
17407dd7cddfSDavid du Colombier
17417dd7cddfSDavid du Colombier /*
17427dd7cddfSDavid du Colombier * The following differs in so far from the previous, that the desired
17437dd7cddfSDavid du Colombier * X-Values are stored in another array.
17447dd7cddfSDavid du Colombier */
17457dd7cddfSDavid du Colombier for(o = 0; o < (1<<sd->stc.bits); ++o) { /* code-loop */
17467dd7cddfSDavid du Colombier
17477dd7cddfSDavid du Colombier x = sd->stc.code[i][o]; x /= gx_max_color_value;
17487dd7cddfSDavid du Colombier
1749*593dc095SDavid du Colombier j = (unsigned long)(x / xstep);
17507dd7cddfSDavid du Colombier
17517dd7cddfSDavid du Colombier if((j+1) < sd->stc.sizv[i]) {
17527dd7cddfSDavid du Colombier y = sd->stc.extv[i][j];
17537dd7cddfSDavid du Colombier y += (sd->stc.extv[i][j+1]-y)*(x-(double)j*xstep)/xstep;
17547dd7cddfSDavid du Colombier } else {
17557dd7cddfSDavid du Colombier y = sd->stc.extv[i][j];
17567dd7cddfSDavid du Colombier y += (y-sd->stc.extv[i][j-1])*(x-(double)j*xstep)/xstep;
17577dd7cddfSDavid du Colombier }
17587dd7cddfSDavid du Colombier
17597dd7cddfSDavid du Colombier y = sd->stc.dither->minmax[0]
17607dd7cddfSDavid du Colombier +(sd->stc.dither->minmax[1]-sd->stc.dither->minmax[0])*y;
17617dd7cddfSDavid du Colombier
17627dd7cddfSDavid du Colombier # define stc_adjvals(T) \
1763*593dc095SDavid du Colombier ((T *)(sd->stc.vals[i]))[o] = (T)y; \
17647dd7cddfSDavid du Colombier \
17657dd7cddfSDavid du Colombier if(((y-((T *)(sd->stc.vals[i]))[o]) >= 0.5) && \
17667dd7cddfSDavid du Colombier ((1+((T *)(sd->stc.vals[i]))[o]) <= sd->stc.dither->minmax[1]))\
17677dd7cddfSDavid du Colombier ((T *)(sd->stc.vals[i]))[o] += 1; \
17687dd7cddfSDavid du Colombier \
17697dd7cddfSDavid du Colombier if(((((T *)(sd->stc.vals[i]))[o]-y) >= 0.5) && \
17707dd7cddfSDavid du Colombier ((((T *)(sd->stc.vals[i]))[o]-1) >= sd->stc.dither->minmax[0]))\
17717dd7cddfSDavid du Colombier ((T *)(sd->stc.vals[i]))[o] -= 1;
17727dd7cddfSDavid du Colombier
17737dd7cddfSDavid du Colombier STC_TYPESWITCH(sd->stc.dither,stc_adjvals)
17747dd7cddfSDavid du Colombier
17757dd7cddfSDavid du Colombier # undef stc_adjvals
17767dd7cddfSDavid du Colombier } /* code-loop */
17777dd7cddfSDavid du Colombier } /* lineaer / encoded */
17787dd7cddfSDavid du Colombier } /* error || success */
17797dd7cddfSDavid du Colombier
17807dd7cddfSDavid du Colombier } else { /* shared one */
17817dd7cddfSDavid du Colombier
17827dd7cddfSDavid du Colombier sd->stc.vals[i] = sd->stc.vals[j];
17837dd7cddfSDavid du Colombier
17847dd7cddfSDavid du Colombier } /* new || shared one */
17857dd7cddfSDavid du Colombier } /* vals req. */
17867dd7cddfSDavid du Colombier } /* comp */
17877dd7cddfSDavid du Colombier
17887dd7cddfSDavid du Colombier if(code == 0) {
1789*593dc095SDavid du Colombier gx_color_value cv[4];
17907dd7cddfSDavid du Colombier sd->stc.flags |= STCOK4GO;
17917dd7cddfSDavid du Colombier
17927dd7cddfSDavid du Colombier /*
17937dd7cddfSDavid du Colombier * Arrgh: open-procedure seems to be the right-place, but it is
17947dd7cddfSDavid du Colombier * necessary to establish the defaults for omitted procedures too.
17957dd7cddfSDavid du Colombier */
17967dd7cddfSDavid du Colombier
17977dd7cddfSDavid du Colombier switch(sd->color_info.num_components) { /* Establish color-procs */
17987dd7cddfSDavid du Colombier case 1:
17997dd7cddfSDavid du Colombier set_dev_proc(sd,map_rgb_color, stc_map_gray_color);
18007dd7cddfSDavid du Colombier set_dev_proc(sd,map_cmyk_color,gx_default_map_cmyk_color);
18017dd7cddfSDavid du Colombier set_dev_proc(sd,map_color_rgb, stc_map_color_gray);
1802*593dc095SDavid du Colombier set_dev_proc(sd,encode_color, stc_map_gray_color);
1803*593dc095SDavid du Colombier set_dev_proc(sd,decode_color, stc_map_color_gray);
1804*593dc095SDavid du Colombier cv[0] = cv[1] = cv[2] = gx_max_color_value;
1805*593dc095SDavid du Colombier white = stc_map_gray_color((gx_device *) sd, cv);
18067dd7cddfSDavid du Colombier break;
18077dd7cddfSDavid du Colombier case 3:
18087dd7cddfSDavid du Colombier set_dev_proc(sd,map_rgb_color, stc_map_rgb_color);
18097dd7cddfSDavid du Colombier set_dev_proc(sd,map_cmyk_color,gx_default_map_cmyk_color);
18107dd7cddfSDavid du Colombier set_dev_proc(sd,map_color_rgb, stc_map_color_rgb);
1811*593dc095SDavid du Colombier set_dev_proc(sd,encode_color, stc_map_rgb_color);
1812*593dc095SDavid du Colombier set_dev_proc(sd,decode_color, stc_map_color_rgb);
1813*593dc095SDavid du Colombier cv[0] = cv[1] = cv[2] = gx_max_color_value;
1814*593dc095SDavid du Colombier white = stc_map_rgb_color((gx_device *) sd, cv);
18157dd7cddfSDavid du Colombier break;
18167dd7cddfSDavid du Colombier default:
18177dd7cddfSDavid du Colombier set_dev_proc(sd,map_rgb_color, gx_default_map_rgb_color);
18187dd7cddfSDavid du Colombier if(sd->stc.flags & STCCMYK10) {
18197dd7cddfSDavid du Colombier set_dev_proc(sd,map_cmyk_color,stc_map_cmyk10_color);
18207dd7cddfSDavid du Colombier set_dev_proc(sd,map_color_rgb, stc_map_color_cmyk10);
1821*593dc095SDavid du Colombier set_dev_proc(sd,encode_color,stc_map_cmyk10_color);
1822*593dc095SDavid du Colombier set_dev_proc(sd,decode_color, stc_map_color_cmyk10);
1823*593dc095SDavid du Colombier cv[0] = cv[1] = cv[2] = cv[3] = 0;
1824*593dc095SDavid du Colombier white = stc_map_cmyk10_color((gx_device *) sd, cv);
18257dd7cddfSDavid du Colombier } else {
18267dd7cddfSDavid du Colombier set_dev_proc(sd,map_cmyk_color,stc_map_cmyk_color);
18277dd7cddfSDavid du Colombier set_dev_proc(sd,map_color_rgb, stc_map_color_cmyk);
1828*593dc095SDavid du Colombier set_dev_proc(sd,encode_color,stc_map_cmyk_color);
1829*593dc095SDavid du Colombier set_dev_proc(sd,decode_color, stc_map_color_cmyk);
1830*593dc095SDavid du Colombier cv[0] = cv[1] = cv[2] = cv[3] = 0;
1831*593dc095SDavid du Colombier white = stc_map_cmyk_color((gx_device *) sd,cv);
18327dd7cddfSDavid du Colombier }
18337dd7cddfSDavid du Colombier break; /* Establish color-procs */
18347dd7cddfSDavid du Colombier }
18357dd7cddfSDavid du Colombier
18367dd7cddfSDavid du Colombier
18377dd7cddfSDavid du Colombier /*
18387dd7cddfSDavid du Colombier * create at least a Byte
18397dd7cddfSDavid du Colombier */
18407dd7cddfSDavid du Colombier if(sd->color_info.depth < 2) white |= (white<<1);
18417dd7cddfSDavid du Colombier if(sd->color_info.depth < 4) white |= (white<<2);
18427dd7cddfSDavid du Colombier if(sd->color_info.depth < 8) white |= (white<<4);
18437dd7cddfSDavid du Colombier
18447dd7cddfSDavid du Colombier /*
18457dd7cddfSDavid du Colombier * copy the Bytes
18467dd7cddfSDavid du Colombier */
18477dd7cddfSDavid du Colombier bpw = (byte *) sd->stc.white_run;
18487dd7cddfSDavid du Colombier
18497dd7cddfSDavid du Colombier if(sd->color_info.depth < 16) {
18507dd7cddfSDavid du Colombier for(i = 0; i < sizeof(sd->stc.white_run); i += 1) {
18517dd7cddfSDavid du Colombier bpw[i] = 0xff & white;
18527dd7cddfSDavid du Colombier }
18537dd7cddfSDavid du Colombier } else if(sd->color_info.depth < 24) {
18547dd7cddfSDavid du Colombier for(i = 0; i < sizeof(sd->stc.white_run); i += 2) {
18557dd7cddfSDavid du Colombier bpw[i] = 0xff & (white>>8);
18567dd7cddfSDavid du Colombier bpw[i+1] = 0xff & white;
18577dd7cddfSDavid du Colombier }
18587dd7cddfSDavid du Colombier } else if(sd->color_info.depth < 32) {
18597dd7cddfSDavid du Colombier for(i = 0; i < sizeof(sd->stc.white_run); i += 3) {
18607dd7cddfSDavid du Colombier bpw[i] = 0xff & (white>>16);
18617dd7cddfSDavid du Colombier bpw[i+1] = 0xff & (white>> 8);
18627dd7cddfSDavid du Colombier bpw[i+2] = 0xff & white;
18637dd7cddfSDavid du Colombier }
18647dd7cddfSDavid du Colombier } else {
18657dd7cddfSDavid du Colombier for(i = 0; i < sizeof(sd->stc.white_run); i += 4) {
18667dd7cddfSDavid du Colombier bpw[i] = 0xff & (white>>24);
18677dd7cddfSDavid du Colombier bpw[i+1] = 0xff & (white>>16);
18687dd7cddfSDavid du Colombier bpw[i+2] = 0xff & (white>> 8);
18697dd7cddfSDavid du Colombier bpw[i+3] = 0xff & white;
18707dd7cddfSDavid du Colombier }
18717dd7cddfSDavid du Colombier }
18727dd7cddfSDavid du Colombier /*
18737dd7cddfSDavid du Colombier * compute the trailer
18747dd7cddfSDavid du Colombier */
1875*593dc095SDavid du Colombier j = (unsigned long)(sd->width -
1876*593dc095SDavid du Colombier (dev_l_margin(sd)+dev_r_margin(sd))*sd->x_pixels_per_inch);
18777dd7cddfSDavid du Colombier j = j * sd->color_info.depth; /* the Bit-count */
18787dd7cddfSDavid du Colombier j = j % (32*countof(sd->stc.white_run)); /* remaining Bits */
18797dd7cddfSDavid du Colombier
18807dd7cddfSDavid du Colombier bpm = (byte *) sd->stc.white_end;
18817dd7cddfSDavid du Colombier for(i = 0; i < (4*countof(sd->stc.white_end)); ++i) {
18827dd7cddfSDavid du Colombier if( j <= 0) {
18837dd7cddfSDavid du Colombier bpm[i] = 0;
18847dd7cddfSDavid du Colombier } else if(j >= 8) {
18857dd7cddfSDavid du Colombier bpm[i] = 0xff;
18867dd7cddfSDavid du Colombier j -= 8;
18877dd7cddfSDavid du Colombier } else {
18887dd7cddfSDavid du Colombier bpm[i] = 0xff ^ ((1<<(8-j))-1);
18897dd7cddfSDavid du Colombier j = 0;
18907dd7cddfSDavid du Colombier }
18917dd7cddfSDavid du Colombier bpm[i] &= bpw[i];
18927dd7cddfSDavid du Colombier }
18937dd7cddfSDavid du Colombier
18947dd7cddfSDavid du Colombier /*
18957dd7cddfSDavid du Colombier * Call super-class open
18967dd7cddfSDavid du Colombier */
18977dd7cddfSDavid du Colombier
18987dd7cddfSDavid du Colombier return gdev_prn_open(pdev);
18997dd7cddfSDavid du Colombier
19007dd7cddfSDavid du Colombier } else {
19017dd7cddfSDavid du Colombier
1902*593dc095SDavid du Colombier stc_freedata(sd->memory, &sd->stc);
19037dd7cddfSDavid du Colombier
19047dd7cddfSDavid du Colombier return_error(code);
19057dd7cddfSDavid du Colombier }
19067dd7cddfSDavid du Colombier
19077dd7cddfSDavid du Colombier }
19087dd7cddfSDavid du Colombier
19097dd7cddfSDavid du Colombier /***
19107dd7cddfSDavid du Colombier *** stc_close: release the internal data
19117dd7cddfSDavid du Colombier ***/
19127dd7cddfSDavid du Colombier private int
stc_close(gx_device * pdev)19137dd7cddfSDavid du Colombier stc_close(gx_device *pdev)
19147dd7cddfSDavid du Colombier {
1915*593dc095SDavid du Colombier stc_freedata(pdev->memory, &((stcolor_device *) pdev)->stc);
19167dd7cddfSDavid du Colombier ((stcolor_device *) pdev)->stc.flags &= ~STCOK4GO;
19177dd7cddfSDavid du Colombier return gdev_prn_close(pdev);
19187dd7cddfSDavid du Colombier }
19197dd7cddfSDavid du Colombier
19207dd7cddfSDavid du Colombier
19217dd7cddfSDavid du Colombier /***
19227dd7cddfSDavid du Colombier *** Function for Bit-Truncation, including direct-byte-transfer
19237dd7cddfSDavid du Colombier ***/
19247dd7cddfSDavid du Colombier private gx_color_value
stc_truncate(stcolor_device * sd,int i,gx_color_value v)19257dd7cddfSDavid du Colombier stc_truncate(stcolor_device *sd,int i,gx_color_value v)
19267dd7cddfSDavid du Colombier {
19277dd7cddfSDavid du Colombier
19287dd7cddfSDavid du Colombier if(sd->stc.bits < gx_color_value_bits) {
19297dd7cddfSDavid du Colombier if(sd->stc.code[i] != NULL) {
19307dd7cddfSDavid du Colombier /*
19317dd7cddfSDavid du Colombier * Perform binary search in the code-array
19327dd7cddfSDavid du Colombier */
19337dd7cddfSDavid du Colombier long s;
19347dd7cddfSDavid du Colombier gx_color_value *p;
19357dd7cddfSDavid du Colombier
19367dd7cddfSDavid du Colombier s = sd->stc.bits > 1 ? 1L<<(sd->stc.bits-2) : 0L;
19377dd7cddfSDavid du Colombier p = sd->stc.code[i]+(1L<<(sd->stc.bits-1));
19387dd7cddfSDavid du Colombier
19397dd7cddfSDavid du Colombier while(s > 0) {
19407dd7cddfSDavid du Colombier if(v > *p) {
19417dd7cddfSDavid du Colombier p += s;
19427dd7cddfSDavid du Colombier } else if(v < p[-1]) {
19437dd7cddfSDavid du Colombier p -= s;
19447dd7cddfSDavid du Colombier } else {
19457dd7cddfSDavid du Colombier if((v-p[-1]) < (p[0]-v)) p -= 1;
19467dd7cddfSDavid du Colombier break;
19477dd7cddfSDavid du Colombier }
19487dd7cddfSDavid du Colombier s >>= 1;
19497dd7cddfSDavid du Colombier }
19507dd7cddfSDavid du Colombier if((v-p[-1]) < (p[0]-v)) p -= 1;
19517dd7cddfSDavid du Colombier v = p - sd->stc.code[i];
19527dd7cddfSDavid du Colombier
19537dd7cddfSDavid du Colombier } else {
19547dd7cddfSDavid du Colombier
19557dd7cddfSDavid du Colombier v >>= gx_color_value_bits-sd->stc.bits;
19567dd7cddfSDavid du Colombier
19577dd7cddfSDavid du Colombier }
19587dd7cddfSDavid du Colombier
19597dd7cddfSDavid du Colombier /*
19607dd7cddfSDavid du Colombier V = (((1L<<D->stc.bits)-1)*V+(gx_max_color_value>>1))\
19617dd7cddfSDavid du Colombier /gx_max_color_value; \
19627dd7cddfSDavid du Colombier */
19637dd7cddfSDavid du Colombier }
19647dd7cddfSDavid du Colombier return v;
19657dd7cddfSDavid du Colombier }
19667dd7cddfSDavid du Colombier
19677dd7cddfSDavid du Colombier private gx_color_value
stc_truncate1(stcolor_device * sd,int i,gx_color_value v)19687dd7cddfSDavid du Colombier stc_truncate1(stcolor_device *sd,int i,gx_color_value v)
19697dd7cddfSDavid du Colombier {
19707dd7cddfSDavid du Colombier
19717dd7cddfSDavid du Colombier return sd->stc.vals[i][stc_truncate(sd,i,v)];
19727dd7cddfSDavid du Colombier }
19737dd7cddfSDavid du Colombier
19747dd7cddfSDavid du Colombier /***
19757dd7cddfSDavid du Colombier *** Expansion of indices for reverse-mapping
19767dd7cddfSDavid du Colombier ***/
19777dd7cddfSDavid du Colombier private gx_color_value
stc_expand(stcolor_device * sd,int i,gx_color_index col)19787dd7cddfSDavid du Colombier stc_expand(stcolor_device *sd,int i,gx_color_index col)
19797dd7cddfSDavid du Colombier {
19807dd7cddfSDavid du Colombier
19817dd7cddfSDavid du Colombier gx_color_index cv;
19827dd7cddfSDavid du Colombier gx_color_index l = (1<<sd->stc.bits)-1;
19837dd7cddfSDavid du Colombier
19847dd7cddfSDavid du Colombier if(sd->stc.code[i] != NULL) {
19857dd7cddfSDavid du Colombier
19867dd7cddfSDavid du Colombier cv = sd->stc.code[i][col & l];
19877dd7cddfSDavid du Colombier
19887dd7cddfSDavid du Colombier } else if(sd->stc.bits < gx_color_value_bits) {
19897dd7cddfSDavid du Colombier
19907dd7cddfSDavid du Colombier cv = (col & l)<<(gx_color_value_bits-sd->stc.bits);
19917dd7cddfSDavid du Colombier cv += (col & l)/l * ((1<<(gx_color_value_bits-sd->stc.bits))-1);
19927dd7cddfSDavid du Colombier
19937dd7cddfSDavid du Colombier } else if(sd->stc.bits > gx_color_value_bits) {
19947dd7cddfSDavid du Colombier
19957dd7cddfSDavid du Colombier cv = (col & l)>>(sd->stc.bits-gx_color_value_bits);
19967dd7cddfSDavid du Colombier
19977dd7cddfSDavid du Colombier } else {
19987dd7cddfSDavid du Colombier
19997dd7cddfSDavid du Colombier cv = col & l;
20007dd7cddfSDavid du Colombier
20017dd7cddfSDavid du Colombier }
20027dd7cddfSDavid du Colombier
20037dd7cddfSDavid du Colombier return cv;
20047dd7cddfSDavid du Colombier }
20057dd7cddfSDavid du Colombier
20067dd7cddfSDavid du Colombier /***
20077dd7cddfSDavid du Colombier *** color-mapping of gray-scales
20087dd7cddfSDavid du Colombier ***/
20097dd7cddfSDavid du Colombier private gx_color_index
stc_map_gray_color(gx_device * pdev,const gx_color_value cv[])2010*593dc095SDavid du Colombier stc_map_gray_color(gx_device *pdev, const gx_color_value cv[])
20117dd7cddfSDavid du Colombier {
20127dd7cddfSDavid du Colombier
20137dd7cddfSDavid du Colombier stcolor_device *sd = (stcolor_device *) pdev;
20147dd7cddfSDavid du Colombier gx_color_index rv;
2015*593dc095SDavid du Colombier gx_color_value r = cv[0];
2016*593dc095SDavid du Colombier gx_color_value g = cv[1];
2017*593dc095SDavid du Colombier gx_color_value b = cv[2];
20187dd7cddfSDavid du Colombier
20197dd7cddfSDavid du Colombier if((r == g) && (g == b)) {
20207dd7cddfSDavid du Colombier
20217dd7cddfSDavid du Colombier rv = gx_max_color_value - r;
20227dd7cddfSDavid du Colombier
20237dd7cddfSDavid du Colombier } else if(sd->stc.am != NULL) {
20247dd7cddfSDavid du Colombier float *m,fv;
20257dd7cddfSDavid du Colombier
20267dd7cddfSDavid du Colombier m = sd->stc.am;
20277dd7cddfSDavid du Colombier
20287dd7cddfSDavid du Colombier fv = gx_max_color_value;
20297dd7cddfSDavid du Colombier fv -= *m++ * (float) r; fv -= *m++ * (float) g; fv -= *m * (float) b;
20307dd7cddfSDavid du Colombier
20317dd7cddfSDavid du Colombier if( fv < 0.0) rv = 0;
20327dd7cddfSDavid du Colombier else if((fv+0.5) > gx_max_color_value) rv = gx_max_color_value;
2033*593dc095SDavid du Colombier else rv = (gx_color_index)(fv+0.5);
20347dd7cddfSDavid du Colombier
20357dd7cddfSDavid du Colombier } else {
20367dd7cddfSDavid du Colombier
20377dd7cddfSDavid du Colombier rv = ((gx_color_index)gx_max_color_value)<<3;
20387dd7cddfSDavid du Colombier rv -= (gx_color_index) 3 * r;
20397dd7cddfSDavid du Colombier rv -= (gx_color_index) 3 * g;
20407dd7cddfSDavid du Colombier rv -= ((gx_color_index)b)<<1;
20417dd7cddfSDavid du Colombier rv = (rv+4)>>3;
20427dd7cddfSDavid du Colombier if(rv > gx_max_color_value) rv = gx_max_color_value;
20437dd7cddfSDavid du Colombier
20447dd7cddfSDavid du Colombier }
20457dd7cddfSDavid du Colombier
20467dd7cddfSDavid du Colombier if(( sd->stc.bits == 8) &&
20477dd7cddfSDavid du Colombier ((sd->stc.dither->flags & STC_TYPE) == STC_BYTE))
20487dd7cddfSDavid du Colombier rv = stc_truncate1(sd,0,(gx_color_value)rv);
20497dd7cddfSDavid du Colombier else
20507dd7cddfSDavid du Colombier rv = stc_truncate(sd,0,(gx_color_value)rv);
20517dd7cddfSDavid du Colombier
20527dd7cddfSDavid du Colombier return rv;
20537dd7cddfSDavid du Colombier }
20547dd7cddfSDavid du Colombier
20557dd7cddfSDavid du Colombier private int
stc_map_color_gray(gx_device * pdev,gx_color_index color,gx_color_value prgb[3])20567dd7cddfSDavid du Colombier stc_map_color_gray(gx_device *pdev, gx_color_index color,gx_color_value prgb[3])
20577dd7cddfSDavid du Colombier {
20587dd7cddfSDavid du Colombier stcolor_device *sd = (stcolor_device *) pdev;
20597dd7cddfSDavid du Colombier gx_color_index l = ((gx_color_index)1<<sd->stc.bits)-1;
20607dd7cddfSDavid du Colombier
20617dd7cddfSDavid du Colombier prgb[0] = gx_max_color_value - stc_expand(sd,0,color & l);
20627dd7cddfSDavid du Colombier prgb[1] = prgb[0]; prgb[2] = prgb[0];
20637dd7cddfSDavid du Colombier
20647dd7cddfSDavid du Colombier return 0;
20657dd7cddfSDavid du Colombier }
20667dd7cddfSDavid du Colombier
20677dd7cddfSDavid du Colombier /***
20687dd7cddfSDavid du Colombier *** color-mapping of rgb-values
20697dd7cddfSDavid du Colombier ***/
20707dd7cddfSDavid du Colombier private gx_color_index
stc_map_rgb_color(gx_device * pdev,const gx_color_value cv[])2071*593dc095SDavid du Colombier stc_map_rgb_color(gx_device *pdev, const gx_color_value cv[])
20727dd7cddfSDavid du Colombier {
20737dd7cddfSDavid du Colombier
20747dd7cddfSDavid du Colombier stcolor_device *sd = (stcolor_device *) pdev;
20757dd7cddfSDavid du Colombier int shift = sd->color_info.depth == 24 ? 8 : sd->stc.bits;
20767dd7cddfSDavid du Colombier gx_color_index rv = 0;
2077*593dc095SDavid du Colombier gx_color_value r = cv[0];
2078*593dc095SDavid du Colombier gx_color_value g = cv[1];
2079*593dc095SDavid du Colombier gx_color_value b = cv[2];
20807dd7cddfSDavid du Colombier if((sd->stc.am != NULL) && ((r != g) || (g != b))) {
20817dd7cddfSDavid du Colombier float *m,fr,fg,fb,fv;
20827dd7cddfSDavid du Colombier
20837dd7cddfSDavid du Colombier m = sd->stc.am;
20847dd7cddfSDavid du Colombier fr = r; fg = g; fb = b;
20857dd7cddfSDavid du Colombier
20867dd7cddfSDavid du Colombier fv = *m++ * fr; fv += *m++ * fg; fv += *m++ * fb;
20877dd7cddfSDavid du Colombier
20887dd7cddfSDavid du Colombier if( fv < 0.0) r = 0;
20897dd7cddfSDavid du Colombier else if((fv+0.5) > gx_max_color_value) r = gx_max_color_value;
2090*593dc095SDavid du Colombier else r = (gx_color_value)(fv+0.5);
20917dd7cddfSDavid du Colombier
20927dd7cddfSDavid du Colombier fv = *m++ * fr; fv += *m++ * fg; fv += *m++ * fb;
20937dd7cddfSDavid du Colombier
20947dd7cddfSDavid du Colombier if( fv < 0.0) g = 0;
20957dd7cddfSDavid du Colombier else if((fv+0.5) > gx_max_color_value) g = gx_max_color_value;
2096*593dc095SDavid du Colombier else g = (gx_color_value)(fv+0.5);
20977dd7cddfSDavid du Colombier
20987dd7cddfSDavid du Colombier fv = *m++ * fr; fv += *m++ * fg; fv += *m++ * fb;
20997dd7cddfSDavid du Colombier
21007dd7cddfSDavid du Colombier if( fv < 0.0) b = 0;
21017dd7cddfSDavid du Colombier else if((fv+0.5) > gx_max_color_value) b = gx_max_color_value;
2102*593dc095SDavid du Colombier else b = (gx_color_value)(fv+0.5);
21037dd7cddfSDavid du Colombier
21047dd7cddfSDavid du Colombier }
21057dd7cddfSDavid du Colombier
21067dd7cddfSDavid du Colombier if(( sd->stc.bits == 8) &&
21077dd7cddfSDavid du Colombier ((sd->stc.dither->flags & STC_TYPE) == STC_BYTE)) {
21087dd7cddfSDavid du Colombier rv = stc_truncate1(sd,0,r);
21097dd7cddfSDavid du Colombier rv = (rv<<shift) | stc_truncate1(sd,1,g);
21107dd7cddfSDavid du Colombier rv = (rv<<shift) | stc_truncate1(sd,2,b);
21117dd7cddfSDavid du Colombier } else {
21127dd7cddfSDavid du Colombier rv = stc_truncate(sd,0,r);
21137dd7cddfSDavid du Colombier rv = (rv<<shift) | stc_truncate(sd,1,g);
21147dd7cddfSDavid du Colombier rv = (rv<<shift) | stc_truncate(sd,2,b);
21157dd7cddfSDavid du Colombier }
21167dd7cddfSDavid du Colombier
21177dd7cddfSDavid du Colombier return rv;
21187dd7cddfSDavid du Colombier }
21197dd7cddfSDavid du Colombier
21207dd7cddfSDavid du Colombier private int
stc_map_color_rgb(gx_device * pdev,gx_color_index color,gx_color_value prgb[3])21217dd7cddfSDavid du Colombier stc_map_color_rgb(gx_device *pdev, gx_color_index color,gx_color_value prgb[3])
21227dd7cddfSDavid du Colombier {
21237dd7cddfSDavid du Colombier
21247dd7cddfSDavid du Colombier stcolor_device *sd = (stcolor_device *) pdev;
21257dd7cddfSDavid du Colombier int shift = sd->color_info.depth == 24 ? 8 : sd->stc.bits;
21267dd7cddfSDavid du Colombier gx_color_index l = ((gx_color_index)1<<sd->stc.bits)-1;
21277dd7cddfSDavid du Colombier
21287dd7cddfSDavid du Colombier prgb[0] = stc_expand(sd,0,((color>>(shift<<1)) & l));
21297dd7cddfSDavid du Colombier prgb[1] = stc_expand(sd,1,((color>> shift ) & l));
21307dd7cddfSDavid du Colombier prgb[2] = stc_expand(sd,2,( color & l));
21317dd7cddfSDavid du Colombier
21327dd7cddfSDavid du Colombier return 0;
21337dd7cddfSDavid du Colombier }
21347dd7cddfSDavid du Colombier
21357dd7cddfSDavid du Colombier /***
21367dd7cddfSDavid du Colombier *** color-mapping of cmyk-values
21377dd7cddfSDavid du Colombier ***/
21387dd7cddfSDavid du Colombier private gx_color_index
stc_map_cmyk_color(gx_device * pdev,const gx_color_value cv[])2139*593dc095SDavid du Colombier stc_map_cmyk_color(gx_device *pdev, const gx_color_value cv[])
21407dd7cddfSDavid du Colombier {
21417dd7cddfSDavid du Colombier
21427dd7cddfSDavid du Colombier stcolor_device *sd = (stcolor_device *) pdev;
21437dd7cddfSDavid du Colombier int shift = sd->color_info.depth == 32 ? 8 : sd->stc.bits;
21447dd7cddfSDavid du Colombier gx_color_index rv = 0;
2145*593dc095SDavid du Colombier gx_color_value c = cv[0];
2146*593dc095SDavid du Colombier gx_color_value m = cv[1];
2147*593dc095SDavid du Colombier gx_color_value y = cv[2];
2148*593dc095SDavid du Colombier gx_color_value k = cv[3];
21497dd7cddfSDavid du Colombier
21507dd7cddfSDavid du Colombier if((c == m) && (m == y)) {
21517dd7cddfSDavid du Colombier
21527dd7cddfSDavid du Colombier k = c > k ? c : k;
21537dd7cddfSDavid du Colombier c = m = y = 0;
21547dd7cddfSDavid du Colombier
21557dd7cddfSDavid du Colombier if(( sd->stc.bits == 8) &&
21567dd7cddfSDavid du Colombier ((sd->stc.dither->flags & STC_TYPE) == STC_BYTE)) {
21577dd7cddfSDavid du Colombier k = stc_truncate1(sd,3,k);
21587dd7cddfSDavid du Colombier } else {
21597dd7cddfSDavid du Colombier k = stc_truncate(sd,3,k);
21607dd7cddfSDavid du Colombier }
21617dd7cddfSDavid du Colombier
21627dd7cddfSDavid du Colombier } else {
21637dd7cddfSDavid du Colombier
21647dd7cddfSDavid du Colombier if(sd->stc.am != NULL) {
21657dd7cddfSDavid du Colombier
21667dd7cddfSDavid du Colombier float *a,fc,fm,fy,fk,fv;
21677dd7cddfSDavid du Colombier
21687dd7cddfSDavid du Colombier if(k == 0) { /* no separated black yet */
21697dd7cddfSDavid du Colombier k = c < m ? c : m;
21707dd7cddfSDavid du Colombier k = k < y ? k : y;
21717dd7cddfSDavid du Colombier if(k) { /* no black at all */
21727dd7cddfSDavid du Colombier c -= k;
21737dd7cddfSDavid du Colombier m -= k;
21747dd7cddfSDavid du Colombier y -= k;
21757dd7cddfSDavid du Colombier } /* no black at all */
21767dd7cddfSDavid du Colombier } /* no separated black yet */
21777dd7cddfSDavid du Colombier
21787dd7cddfSDavid du Colombier a = sd->stc.am;
21797dd7cddfSDavid du Colombier fc = c; fm = m; fy = y; fk = k;
21807dd7cddfSDavid du Colombier
21817dd7cddfSDavid du Colombier fv = *a++ * fc; fv += *a++ * fm; fv += *a++ * fy; fv += *a++ * fk;
21827dd7cddfSDavid du Colombier if( fv < 0.0) c = 0;
21837dd7cddfSDavid du Colombier else if((fv+0.5) > gx_max_color_value) c = gx_max_color_value;
2184*593dc095SDavid du Colombier else c = (gx_color_value)(fv+0.5);
21857dd7cddfSDavid du Colombier
21867dd7cddfSDavid du Colombier fv = *a++ * fc; fv += *a++ * fm; fv += *a++ * fy; fv += *a++ * fk;
21877dd7cddfSDavid du Colombier if( fv < 0.0) m = 0;
21887dd7cddfSDavid du Colombier else if((fv+0.5) > gx_max_color_value) m = gx_max_color_value;
2189*593dc095SDavid du Colombier else m = (gx_color_value)(fv+0.5);
21907dd7cddfSDavid du Colombier
21917dd7cddfSDavid du Colombier fv = *a++ * fc; fv += *a++ * fm; fv += *a++ * fy; fv += *a++ * fk;
21927dd7cddfSDavid du Colombier if( fv < 0.0) y = 0;
21937dd7cddfSDavid du Colombier else if((fv+0.5) > gx_max_color_value) y = gx_max_color_value;
2194*593dc095SDavid du Colombier else y = (gx_color_value)(fv+0.5);
21957dd7cddfSDavid du Colombier
21967dd7cddfSDavid du Colombier fv = *a++ * fc; fv += *a++ * fm; fv += *a++ * fy; fv += *a++ * fk;
21977dd7cddfSDavid du Colombier if( fv < 0.0) k = 0;
21987dd7cddfSDavid du Colombier else if((fv+0.5) > gx_max_color_value) k = gx_max_color_value;
2199*593dc095SDavid du Colombier else k = (gx_color_value)(fv+0.5);
22007dd7cddfSDavid du Colombier
22017dd7cddfSDavid du Colombier } else if(k == 0) {
22027dd7cddfSDavid du Colombier
22037dd7cddfSDavid du Colombier k = c < m ? c : m;
22047dd7cddfSDavid du Colombier k = k < y ? k : y;
22057dd7cddfSDavid du Colombier }
22067dd7cddfSDavid du Colombier
22077dd7cddfSDavid du Colombier if(( sd->stc.bits == 8) &&
22087dd7cddfSDavid du Colombier ((sd->stc.dither->flags & STC_TYPE) == STC_BYTE)) {
22097dd7cddfSDavid du Colombier c = stc_truncate1(sd,0,c);
22107dd7cddfSDavid du Colombier m = stc_truncate1(sd,1,m);
22117dd7cddfSDavid du Colombier y = stc_truncate1(sd,2,y);
22127dd7cddfSDavid du Colombier k = stc_truncate1(sd,3,k);
22137dd7cddfSDavid du Colombier } else {
22147dd7cddfSDavid du Colombier c = stc_truncate(sd,0,c);
22157dd7cddfSDavid du Colombier m = stc_truncate(sd,1,m);
22167dd7cddfSDavid du Colombier y = stc_truncate(sd,2,y);
22177dd7cddfSDavid du Colombier k = stc_truncate(sd,3,k);
22187dd7cddfSDavid du Colombier }
22197dd7cddfSDavid du Colombier }
22207dd7cddfSDavid du Colombier
22217dd7cddfSDavid du Colombier rv = c;
22227dd7cddfSDavid du Colombier rv = (rv<<shift) | m;
22237dd7cddfSDavid du Colombier rv = (rv<<shift) | y;
22247dd7cddfSDavid du Colombier rv = (rv<<shift) | k;
22257dd7cddfSDavid du Colombier
22267dd7cddfSDavid du Colombier if(rv == gx_no_color_index) rv ^= 1;
22277dd7cddfSDavid du Colombier
22287dd7cddfSDavid du Colombier return rv;
22297dd7cddfSDavid du Colombier }
22307dd7cddfSDavid du Colombier
2231*593dc095SDavid du Colombier /* Modified to be a "decode_color" routine */
22327dd7cddfSDavid du Colombier private int
stc_map_color_cmyk(gx_device * pdev,gx_color_index color,gx_color_value cv[4])2233*593dc095SDavid du Colombier stc_map_color_cmyk(gx_device *pdev, gx_color_index color,gx_color_value cv[4])
22347dd7cddfSDavid du Colombier {
22357dd7cddfSDavid du Colombier
22367dd7cddfSDavid du Colombier stcolor_device *sd = (stcolor_device *) pdev;
22377dd7cddfSDavid du Colombier int shift = sd->color_info.depth == 32 ? 8 : sd->stc.bits;
22387dd7cddfSDavid du Colombier gx_color_index l = ((gx_color_index)1<<sd->stc.bits)-1;
22397dd7cddfSDavid du Colombier gx_color_value c,m,y,k;
22407dd7cddfSDavid du Colombier
22417dd7cddfSDavid du Colombier k = stc_expand(sd,3, color & l); color >>= shift;
22427dd7cddfSDavid du Colombier y = stc_expand(sd,2, color & l); color >>= shift;
22437dd7cddfSDavid du Colombier m = stc_expand(sd,1, color & l); color >>= shift;
22447dd7cddfSDavid du Colombier c = stc_expand(sd,0, color & l);
22457dd7cddfSDavid du Colombier
2246*593dc095SDavid du Colombier
2247*593dc095SDavid du Colombier cv[0] = c;
2248*593dc095SDavid du Colombier cv[1] = m;
2249*593dc095SDavid du Colombier cv[2] = y;
2250*593dc095SDavid du Colombier cv[3] = k;
2251*593dc095SDavid du Colombier
22527dd7cddfSDavid du Colombier return 0;
22537dd7cddfSDavid du Colombier }
22547dd7cddfSDavid du Colombier
22557dd7cddfSDavid du Colombier /***
22567dd7cddfSDavid du Colombier *** color-mapping of cmyk10-values
22577dd7cddfSDavid du Colombier ***/
22587dd7cddfSDavid du Colombier private gx_color_index
stc_map_cmyk10_color(gx_device * pdev,const gx_color_value cv[])2259*593dc095SDavid du Colombier stc_map_cmyk10_color(gx_device *pdev, const gx_color_value cv[])
22607dd7cddfSDavid du Colombier {
22617dd7cddfSDavid du Colombier
22627dd7cddfSDavid du Colombier stcolor_device *sd = (stcolor_device *) pdev;
22637dd7cddfSDavid du Colombier int mode;
22647dd7cddfSDavid du Colombier gx_color_index rv = 0;
22657dd7cddfSDavid du Colombier
2266*593dc095SDavid du Colombier gx_color_value c = cv[0];
2267*593dc095SDavid du Colombier gx_color_value m = cv[1];
2268*593dc095SDavid du Colombier gx_color_value y = cv[2];
2269*593dc095SDavid du Colombier gx_color_value k = cv[3];
2270*593dc095SDavid du Colombier
22717dd7cddfSDavid du Colombier if((c == m) && (m == y)) {
22727dd7cddfSDavid du Colombier
22737dd7cddfSDavid du Colombier k = c > k ? c : k;
22747dd7cddfSDavid du Colombier c = m = y = 0;
22757dd7cddfSDavid du Colombier mode = 3;
22767dd7cddfSDavid du Colombier
22777dd7cddfSDavid du Colombier } else {
22787dd7cddfSDavid du Colombier
22797dd7cddfSDavid du Colombier if(sd->stc.am != NULL) {
22807dd7cddfSDavid du Colombier
22817dd7cddfSDavid du Colombier float *a,fc,fm,fy,fk,fv;
22827dd7cddfSDavid du Colombier
22837dd7cddfSDavid du Colombier k = c < m ? c : m;
22847dd7cddfSDavid du Colombier k = k < y ? k : y;
22857dd7cddfSDavid du Colombier if(k) { /* no black at all */
22867dd7cddfSDavid du Colombier c -= k;
22877dd7cddfSDavid du Colombier m -= k;
22887dd7cddfSDavid du Colombier y -= k;
22897dd7cddfSDavid du Colombier } /* no black at all */
22907dd7cddfSDavid du Colombier
22917dd7cddfSDavid du Colombier a = sd->stc.am;
22927dd7cddfSDavid du Colombier fc = c; fm = m; fy = y; fk = k;
22937dd7cddfSDavid du Colombier
22947dd7cddfSDavid du Colombier fv = *a++ * fc; fv += *a++ * fm; fv += *a++ * fy; fv += *a++ * fk;
22957dd7cddfSDavid du Colombier if( fv < 0.0) c = 0;
22967dd7cddfSDavid du Colombier else if((fv+0.5) > gx_max_color_value) c = gx_max_color_value;
2297*593dc095SDavid du Colombier else c = (gx_color_value)(fv+0.5);
22987dd7cddfSDavid du Colombier
22997dd7cddfSDavid du Colombier fv = *a++ * fc; fv += *a++ * fm; fv += *a++ * fy; fv += *a++ * fk;
23007dd7cddfSDavid du Colombier if( fv < 0.0) m = 0;
23017dd7cddfSDavid du Colombier else if((fv+0.5) > gx_max_color_value) m = gx_max_color_value;
2302*593dc095SDavid du Colombier else m = (gx_color_value)(fv+0.5);
23037dd7cddfSDavid du Colombier
23047dd7cddfSDavid du Colombier fv = *a++ * fc; fv += *a++ * fm; fv += *a++ * fy; fv += *a++ * fk;
23057dd7cddfSDavid du Colombier if( fv < 0.0) y = 0;
23067dd7cddfSDavid du Colombier else if((fv+0.5) > gx_max_color_value) y = gx_max_color_value;
2307*593dc095SDavid du Colombier else y = (gx_color_value)(fv+0.5);
23087dd7cddfSDavid du Colombier
23097dd7cddfSDavid du Colombier }
23107dd7cddfSDavid du Colombier
23117dd7cddfSDavid du Colombier if(c < m) {
23127dd7cddfSDavid du Colombier if(c < y) { k = c; c = 0; mode = 0; }
23137dd7cddfSDavid du Colombier else { k = y; y = 0; mode = 2; }
23147dd7cddfSDavid du Colombier } else {
23157dd7cddfSDavid du Colombier if(m < y) { k = m; m = 0; mode = 1; }
23167dd7cddfSDavid du Colombier else { k = y; y = 0; mode = 2; }
23177dd7cddfSDavid du Colombier }
23187dd7cddfSDavid du Colombier }
23197dd7cddfSDavid du Colombier
23207dd7cddfSDavid du Colombier /*
23217dd7cddfSDavid du Colombier * truncate only the values that require it
23227dd7cddfSDavid du Colombier */
23237dd7cddfSDavid du Colombier if(c) c = stc_truncate(sd,0,c);
23247dd7cddfSDavid du Colombier if(m) m = stc_truncate(sd,1,m);
23257dd7cddfSDavid du Colombier if(y) y = stc_truncate(sd,2,y);
23267dd7cddfSDavid du Colombier if(k) k = stc_truncate(sd,3,k);
23277dd7cddfSDavid du Colombier
23287dd7cddfSDavid du Colombier /*
23297dd7cddfSDavid du Colombier * make sure that truncation-white becomes white.
23307dd7cddfSDavid du Colombier */
23317dd7cddfSDavid du Colombier if((c|m|y) == 0) mode = 3;
23327dd7cddfSDavid du Colombier
23337dd7cddfSDavid du Colombier /*
23347dd7cddfSDavid du Colombier * check wether value-arrays can be bypassed
23357dd7cddfSDavid du Colombier */
23367dd7cddfSDavid du Colombier if(((sd->stc.dither->flags & STC_TYPE) == STC_BYTE) &&
23377dd7cddfSDavid du Colombier ( sd->stc.dither->minmax[0] == 0.0 )) {
23387dd7cddfSDavid du Colombier c = sd->stc.vals[0][c];
23397dd7cddfSDavid du Colombier m = sd->stc.vals[1][m];
23407dd7cddfSDavid du Colombier y = sd->stc.vals[2][y];
23417dd7cddfSDavid du Colombier k = sd->stc.vals[3][k];
23427dd7cddfSDavid du Colombier } else if(((sd->stc.dither->flags & STC_TYPE) == STC_LONG) &&
23437dd7cddfSDavid du Colombier ( sd->stc.dither->minmax[0] == 0.0 ) &&
23447dd7cddfSDavid du Colombier ( sd->stc.dither->minmax[1] <= 1023.0 )) {
23457dd7cddfSDavid du Colombier c = ((long *)(sd->stc.vals[0]))[c];
23467dd7cddfSDavid du Colombier m = ((long *)(sd->stc.vals[1]))[m];
23477dd7cddfSDavid du Colombier y = ((long *)(sd->stc.vals[2]))[y];
23487dd7cddfSDavid du Colombier k = ((long *)(sd->stc.vals[3]))[k];
23497dd7cddfSDavid du Colombier } /* direct */
23507dd7cddfSDavid du Colombier /*
23517dd7cddfSDavid du Colombier * compute the long-representation of gx_color_index
23527dd7cddfSDavid du Colombier */
23537dd7cddfSDavid du Colombier switch(mode) {
23547dd7cddfSDavid du Colombier case 0:
23557dd7cddfSDavid du Colombier rv = (((gx_color_index) m)<<22)|
23567dd7cddfSDavid du Colombier (((gx_color_index) y)<<12)|
23577dd7cddfSDavid du Colombier (((gx_color_index) k)<< 2)|mode;
23587dd7cddfSDavid du Colombier break;
23597dd7cddfSDavid du Colombier case 1:
23607dd7cddfSDavid du Colombier rv = (((gx_color_index) c)<<22)|
23617dd7cddfSDavid du Colombier (((gx_color_index) y)<<12)|
23627dd7cddfSDavid du Colombier (((gx_color_index) k)<< 2)|mode;
23637dd7cddfSDavid du Colombier break;
23647dd7cddfSDavid du Colombier case 2:
23657dd7cddfSDavid du Colombier rv = (((gx_color_index) c)<<22)|
23667dd7cddfSDavid du Colombier (((gx_color_index) m)<<12)|
23677dd7cddfSDavid du Colombier (((gx_color_index) k)<< 2)|mode;
23687dd7cddfSDavid du Colombier break;
23697dd7cddfSDavid du Colombier default:
23707dd7cddfSDavid du Colombier rv = (((gx_color_index) k)<< 2)|mode;
23717dd7cddfSDavid du Colombier break;
23727dd7cddfSDavid du Colombier }
23737dd7cddfSDavid du Colombier
23747dd7cddfSDavid du Colombier /*
23757dd7cddfSDavid du Colombier * We may need some swapping
23767dd7cddfSDavid du Colombier */
23777dd7cddfSDavid du Colombier #if !arch_is_big_endian
23787dd7cddfSDavid du Colombier {
23797dd7cddfSDavid du Colombier union { stc_pixel cv; byte bv[4]; } ui,uo;
23807dd7cddfSDavid du Colombier ui.cv = rv;
23817dd7cddfSDavid du Colombier uo.bv[0] = ui.bv[3];
23827dd7cddfSDavid du Colombier uo.bv[1] = ui.bv[2];
23837dd7cddfSDavid du Colombier uo.bv[2] = ui.bv[1];
23847dd7cddfSDavid du Colombier uo.bv[3] = ui.bv[0];
23857dd7cddfSDavid du Colombier rv = uo.cv;
23867dd7cddfSDavid du Colombier }
23877dd7cddfSDavid du Colombier #endif
23887dd7cddfSDavid du Colombier return rv;
23897dd7cddfSDavid du Colombier }
23907dd7cddfSDavid du Colombier
23917dd7cddfSDavid du Colombier private int
stc_map_color_cmyk10(gx_device * pdev,gx_color_index color,gx_color_value cv[3])23927dd7cddfSDavid du Colombier stc_map_color_cmyk10(gx_device *pdev, gx_color_index color,
2393*593dc095SDavid du Colombier gx_color_value cv[3])
23947dd7cddfSDavid du Colombier {
23957dd7cddfSDavid du Colombier
23967dd7cddfSDavid du Colombier stcolor_device *sd = (stcolor_device *) pdev;
23977dd7cddfSDavid du Colombier gx_color_value c,m,y;
23987dd7cddfSDavid du Colombier
23997dd7cddfSDavid du Colombier /*
24007dd7cddfSDavid du Colombier * We may need some swapping
24017dd7cddfSDavid du Colombier */
24027dd7cddfSDavid du Colombier #if !arch_is_big_endian
24037dd7cddfSDavid du Colombier union { stc_pixel cv; byte bv[4]; } ui,uo;
24047dd7cddfSDavid du Colombier ui.cv = color;
24057dd7cddfSDavid du Colombier uo.bv[0] = ui.bv[3];
24067dd7cddfSDavid du Colombier uo.bv[1] = ui.bv[2];
24077dd7cddfSDavid du Colombier uo.bv[2] = ui.bv[1];
24087dd7cddfSDavid du Colombier uo.bv[3] = ui.bv[0];
24097dd7cddfSDavid du Colombier color = uo.cv;
24107dd7cddfSDavid du Colombier #endif
24117dd7cddfSDavid du Colombier
24127dd7cddfSDavid du Colombier c = stc_expand(sd,3,(color>>2)&0x3ff);
24137dd7cddfSDavid du Colombier
2414*593dc095SDavid du Colombier /* cast the 64 bit switch argument to work around broken HPUX 10 cc */
2415*593dc095SDavid du Colombier switch((int)(color & 3)) {
24167dd7cddfSDavid du Colombier case 0:
24177dd7cddfSDavid du Colombier m = stc_expand(sd,1,(color>>22) & 0x3ff);
24187dd7cddfSDavid du Colombier y = stc_expand(sd,2,(color>>12) & 0x3ff);
24197dd7cddfSDavid du Colombier break;
24207dd7cddfSDavid du Colombier case 1:
24217dd7cddfSDavid du Colombier m = c;
24227dd7cddfSDavid du Colombier c = stc_expand(sd,0,(color>>22) & 0x3ff);
24237dd7cddfSDavid du Colombier y = stc_expand(sd,2,(color>>12) & 0x3ff);
24247dd7cddfSDavid du Colombier break;
24257dd7cddfSDavid du Colombier case 2:
24267dd7cddfSDavid du Colombier y = c;
24277dd7cddfSDavid du Colombier c = stc_expand(sd,0,(color>>22) & 0x3ff);
24287dd7cddfSDavid du Colombier m = stc_expand(sd,1,(color>>12) & 0x3ff);
24297dd7cddfSDavid du Colombier break;
24307dd7cddfSDavid du Colombier default:
24317dd7cddfSDavid du Colombier m = c;
24327dd7cddfSDavid du Colombier y = c;
24337dd7cddfSDavid du Colombier break;
24347dd7cddfSDavid du Colombier }
24357dd7cddfSDavid du Colombier
2436*593dc095SDavid du Colombier cv[0] = c;
2437*593dc095SDavid du Colombier cv[1] = m;
2438*593dc095SDavid du Colombier cv[2] = y;
24397dd7cddfSDavid du Colombier
24407dd7cddfSDavid du Colombier return 0;
24417dd7cddfSDavid du Colombier }
24427dd7cddfSDavid du Colombier
24437dd7cddfSDavid du Colombier /***
24447dd7cddfSDavid du Colombier *** Macros for parameter-handling
24457dd7cddfSDavid du Colombier ***/
24467dd7cddfSDavid du Colombier
24477dd7cddfSDavid du Colombier #define set_param_array(A, D, S)\
24487dd7cddfSDavid du Colombier {A.data = D; A.size = S; A.persistent = false;}
24497dd7cddfSDavid du Colombier
24507dd7cddfSDavid du Colombier #define stc_write_null(N) \
24517dd7cddfSDavid du Colombier set_param_array(pfa,defext,countof(defext)) \
24527dd7cddfSDavid du Colombier code = param_write_null(plist,N); \
24537dd7cddfSDavid du Colombier if (code < 0) return code;
24547dd7cddfSDavid du Colombier
24557dd7cddfSDavid du Colombier #define stc_write_xarray(I,Coding,Transfer) \
24567dd7cddfSDavid du Colombier if(sd->stc.sizc[I] > 0) { \
24577dd7cddfSDavid du Colombier set_param_array(pfa, sd->stc.extc[I],sd->stc.sizc[I]) \
24587dd7cddfSDavid du Colombier code = param_write_float_array(plist,Coding,&pfa); \
24597dd7cddfSDavid du Colombier } else { \
24607dd7cddfSDavid du Colombier code = param_write_null(plist,Coding); \
24617dd7cddfSDavid du Colombier } \
24627dd7cddfSDavid du Colombier if ( code < 0 ) return code; \
24637dd7cddfSDavid du Colombier \
24647dd7cddfSDavid du Colombier if(sd->stc.sizv[I] > 0) \
24657dd7cddfSDavid du Colombier set_param_array(pfa, sd->stc.extv[I],sd->stc.sizv[I]) \
24667dd7cddfSDavid du Colombier else \
24677dd7cddfSDavid du Colombier set_param_array(pfa,defext,countof(defext)) \
24687dd7cddfSDavid du Colombier code = param_write_float_array(plist,Transfer,&pfa); \
24697dd7cddfSDavid du Colombier if ( code < 0 ) return code;
24707dd7cddfSDavid du Colombier
24717dd7cddfSDavid du Colombier #define stc_read_null(N) \
24727dd7cddfSDavid du Colombier code = param_read_null(plist,N); \
24737dd7cddfSDavid du Colombier if(code == gs_error_typecheck) \
24747dd7cddfSDavid du Colombier code = param_read_float_array(plist,N,&pfa); \
24757dd7cddfSDavid du Colombier if(code < 0) param_signal_error(plist,N,code); \
24767dd7cddfSDavid du Colombier error = error > code ? code : error;
24777dd7cddfSDavid du Colombier
24787dd7cddfSDavid du Colombier #define stc_read_xarray(I,Coding,Transfer) \
24797dd7cddfSDavid du Colombier code = param_read_float_array(plist,Coding,&pfa); \
24807dd7cddfSDavid du Colombier if((error == 0) && (code == 0)) { \
24817dd7cddfSDavid du Colombier if(pfa.size > 1) { \
24827dd7cddfSDavid du Colombier sd->stc.extc[I] = (float *) pfa.data; \
24837dd7cddfSDavid du Colombier sd->stc.sizc[I] = pfa.size; \
24847dd7cddfSDavid du Colombier } else { \
24857dd7cddfSDavid du Colombier code = gs_error_rangecheck; \
24867dd7cddfSDavid du Colombier } \
24877dd7cddfSDavid du Colombier } else if(code < 0) { \
24887dd7cddfSDavid du Colombier code = param_read_null(plist,Coding); \
24897dd7cddfSDavid du Colombier if(code == 0) { \
24907dd7cddfSDavid du Colombier sd->stc.extc[I] = NULL; \
24917dd7cddfSDavid du Colombier sd->stc.sizc[I] = 0; \
24927dd7cddfSDavid du Colombier } \
24937dd7cddfSDavid du Colombier } \
24947dd7cddfSDavid du Colombier if(code < 0) param_signal_error(plist,Coding,code); \
24957dd7cddfSDavid du Colombier error = error > code ? code : error; \
24967dd7cddfSDavid du Colombier code = param_read_float_array(plist,Transfer,&pfa); \
24977dd7cddfSDavid du Colombier if((error == 0) && (code == 0)) { \
24987dd7cddfSDavid du Colombier sd->stc.extv[I] = (float *) pfa.data; \
24997dd7cddfSDavid du Colombier sd->stc.sizv[I] = pfa.size; \
25007dd7cddfSDavid du Colombier } else if(code < 0) { \
25017dd7cddfSDavid du Colombier code = param_read_null(plist,Transfer); \
25027dd7cddfSDavid du Colombier if(code == 0) { \
25037dd7cddfSDavid du Colombier sd->stc.extv[I] = defext; \
25047dd7cddfSDavid du Colombier sd->stc.sizv[I] = countof(defext); \
25057dd7cddfSDavid du Colombier } \
25067dd7cddfSDavid du Colombier } \
25077dd7cddfSDavid du Colombier if(code < 0) param_signal_error(plist,Transfer,code); \
25087dd7cddfSDavid du Colombier error = error > code ? code : error;
25097dd7cddfSDavid du Colombier
25107dd7cddfSDavid du Colombier /***
25117dd7cddfSDavid du Colombier *** Get parameters == Make them accessable via PostScript
25127dd7cddfSDavid du Colombier ***/
25137dd7cddfSDavid du Colombier
25147dd7cddfSDavid du Colombier private int
stc_get_params(gx_device * pdev,gs_param_list * plist)25157dd7cddfSDavid du Colombier stc_get_params(gx_device *pdev, gs_param_list *plist)
25167dd7cddfSDavid du Colombier {
25177dd7cddfSDavid du Colombier int code,nc;
25187dd7cddfSDavid du Colombier gs_param_string ps;
25197dd7cddfSDavid du Colombier gs_param_float_array pfa;
25207dd7cddfSDavid du Colombier bool btmp;
25217dd7cddfSDavid du Colombier stcolor_device *sd = (stcolor_device *) pdev;
25227dd7cddfSDavid du Colombier
25237dd7cddfSDavid du Colombier code = gdev_prn_get_params(pdev, plist);
25247dd7cddfSDavid du Colombier if ( code < 0 ) return code;
25257dd7cddfSDavid du Colombier
25267dd7cddfSDavid du Colombier /*
25277dd7cddfSDavid du Colombier * Export some readonly-Parameters, used by stcinfo.ps
25287dd7cddfSDavid du Colombier */
25297dd7cddfSDavid du Colombier param_string_from_string(ps,"1.91");
25307dd7cddfSDavid du Colombier code = param_write_string(plist,"Version",&ps);
25317dd7cddfSDavid du Colombier if ( code < 0 ) return code;
25327dd7cddfSDavid du Colombier
25337dd7cddfSDavid du Colombier code = param_write_int(plist,"BitsPerComponent",&sd->stc.bits);
25347dd7cddfSDavid du Colombier if ( code < 0 ) return code;
25357dd7cddfSDavid du Colombier
25367dd7cddfSDavid du Colombier if(sd->stc.algorithms.size > 0) {
25377dd7cddfSDavid du Colombier code = param_write_string_array(plist,"Algorithms",&sd->stc.algorithms);
25387dd7cddfSDavid du Colombier } else {
25397dd7cddfSDavid du Colombier code = param_write_null(plist,"Algorithms");
25407dd7cddfSDavid du Colombier }
25417dd7cddfSDavid du Colombier if ( code < 0 ) return code;
25427dd7cddfSDavid du Colombier
25437dd7cddfSDavid du Colombier /*
25447dd7cddfSDavid du Colombier * Export OutputCode
25457dd7cddfSDavid du Colombier */
25467dd7cddfSDavid du Colombier switch(sd->stc.flags & STCCOMP) {
25477dd7cddfSDavid du Colombier case STCPLAIN: param_string_from_string(ps,"plain"); break;
25487dd7cddfSDavid du Colombier case STCDELTA: param_string_from_string(ps,"deltarow"); break;
25497dd7cddfSDavid du Colombier default: param_string_from_string(ps,"runlength"); break;
25507dd7cddfSDavid du Colombier }
25517dd7cddfSDavid du Colombier code = param_write_string(plist,"OutputCode",&ps);
25527dd7cddfSDavid du Colombier if ( code < 0 ) return code;
25537dd7cddfSDavid du Colombier /*
25547dd7cddfSDavid du Colombier * Export Model
25557dd7cddfSDavid du Colombier */
25567dd7cddfSDavid du Colombier switch(sd->stc.flags & STCMODEL) {
25577dd7cddfSDavid du Colombier case STCST800: param_string_from_string(ps,"st800"); break;
25587dd7cddfSDavid du Colombier case STCSTCII: param_string_from_string(ps,"stcii"); break;
25597dd7cddfSDavid du Colombier default: param_string_from_string(ps,"stc"); break;
25607dd7cddfSDavid du Colombier }
25617dd7cddfSDavid du Colombier code = param_write_string(plist,"Model",&ps);
25627dd7cddfSDavid du Colombier if ( code < 0 ) return code;
25637dd7cddfSDavid du Colombier
25647dd7cddfSDavid du Colombier /*
25657dd7cddfSDavid du Colombier * Export the booleans
25667dd7cddfSDavid du Colombier */
25677dd7cddfSDavid du Colombier #define stc_write_flag(Mask,Name) \
25687dd7cddfSDavid du Colombier btmp = sd->stc.flags & (Mask) ? true : false; \
25697dd7cddfSDavid du Colombier code = param_write_bool(plist,Name,&btmp); \
25707dd7cddfSDavid du Colombier if ( code < 0 ) return code;
25717dd7cddfSDavid du Colombier
25727dd7cddfSDavid du Colombier stc_write_flag(STCUNIDIR,"Unidirectional")
25737dd7cddfSDavid du Colombier stc_write_flag(STCUWEAVE,"Microweave")
25747dd7cddfSDavid du Colombier btmp = sd->stc.flags & (STCUNIDIR|STCUWEAVE) ? false : true;
25757dd7cddfSDavid du Colombier code = param_write_bool(plist,"Softweave",&btmp);
25767dd7cddfSDavid du Colombier if ( code < 0 ) return code;
25777dd7cddfSDavid du Colombier stc_write_flag(STCNWEAVE,"noWeave")
25787dd7cddfSDavid du Colombier stc_write_flag(STCDFLAG0, "Flag0")
25797dd7cddfSDavid du Colombier stc_write_flag(STCDFLAG1, "Flag1")
25807dd7cddfSDavid du Colombier stc_write_flag(STCDFLAG2, "Flag2")
25817dd7cddfSDavid du Colombier stc_write_flag(STCDFLAG3, "Flag3")
25827dd7cddfSDavid du Colombier stc_write_flag(STCDFLAG4, "Flag4")
25837dd7cddfSDavid du Colombier
25847dd7cddfSDavid du Colombier #undef stc_write_flag
25857dd7cddfSDavid du Colombier
25867dd7cddfSDavid du Colombier # define stc_write_int(Mask,Name,Val) \
25877dd7cddfSDavid du Colombier code = param_write_int(plist,Name,&Val); \
25887dd7cddfSDavid du Colombier if ( code < 0 ) return code
25897dd7cddfSDavid du Colombier
25907dd7cddfSDavid du Colombier stc_write_int(STCBAND, "escp_Band", sd->stc.escp_m);
25917dd7cddfSDavid du Colombier stc_write_int(STCWIDTH, "escp_Width", sd->stc.escp_width);
25927dd7cddfSDavid du Colombier stc_write_int(STCHEIGHT,"escp_Height",sd->stc.escp_height);
25937dd7cddfSDavid du Colombier stc_write_int(STCTOP, "escp_Top", sd->stc.escp_top);
25947dd7cddfSDavid du Colombier stc_write_int(STCBOTTOM,"escp_Bottom",sd->stc.escp_bottom);
25957dd7cddfSDavid du Colombier
25967dd7cddfSDavid du Colombier # undef stc_write_int
25977dd7cddfSDavid du Colombier
25987dd7cddfSDavid du Colombier code = param_write_string(plist,"escp_Init",&sd->stc.escp_init);
25997dd7cddfSDavid du Colombier code = param_write_string(plist,"escp_Release",&sd->stc.escp_release);
26007dd7cddfSDavid du Colombier
26017dd7cddfSDavid du Colombier if(sd->stc.dither != NULL) {
26027dd7cddfSDavid du Colombier param_string_from_string(ps,sd->stc.dither->name);
26037dd7cddfSDavid du Colombier code = param_write_string(plist,"Dithering",&ps);
26047dd7cddfSDavid du Colombier } else {
26057dd7cddfSDavid du Colombier code = param_write_null(plist,"Dithering");
26067dd7cddfSDavid du Colombier }
26077dd7cddfSDavid du Colombier if ( code < 0 ) return code;
26087dd7cddfSDavid du Colombier
26097dd7cddfSDavid du Colombier nc = sd->color_info.num_components;
26107dd7cddfSDavid du Colombier
26117dd7cddfSDavid du Colombier if(sd->stc.am != NULL) {
26127dd7cddfSDavid du Colombier if( nc == 1) set_param_array(pfa, sd->stc.am, 3)
26137dd7cddfSDavid du Colombier else if(nc == 3) set_param_array(pfa, sd->stc.am, 9)
26147dd7cddfSDavid du Colombier else set_param_array(pfa, sd->stc.am,16)
26157dd7cddfSDavid du Colombier code = param_write_float_array(plist,"ColorAdjustMatrix",&pfa);
26167dd7cddfSDavid du Colombier } else {
26177dd7cddfSDavid du Colombier code = param_write_null(plist,"ColorAdjustMatrix");
26187dd7cddfSDavid du Colombier }
26197dd7cddfSDavid du Colombier if ( code < 0 ) return code;
26207dd7cddfSDavid du Colombier
26217dd7cddfSDavid du Colombier if(nc == 1) { /* DeviceGray */
26227dd7cddfSDavid du Colombier
26237dd7cddfSDavid du Colombier stc_write_xarray(0,"Kcoding","Ktransfer");
26247dd7cddfSDavid du Colombier
26257dd7cddfSDavid du Colombier stc_write_null("Rcoding"); stc_write_null("Rtransfer");
26267dd7cddfSDavid du Colombier stc_write_null("Gcoding"); stc_write_null("Gtransfer");
26277dd7cddfSDavid du Colombier stc_write_null("Bcoding"); stc_write_null("Btransfer");
26287dd7cddfSDavid du Colombier
26297dd7cddfSDavid du Colombier stc_write_null("Ccoding"); stc_write_null("Ctransfer");
26307dd7cddfSDavid du Colombier stc_write_null("Mcoding"); stc_write_null("Mtransfer");
26317dd7cddfSDavid du Colombier stc_write_null("Ycoding"); stc_write_null("Ytransfer");
26327dd7cddfSDavid du Colombier
26337dd7cddfSDavid du Colombier } else if(nc == 3) { /* DeviceRGB */
26347dd7cddfSDavid du Colombier
26357dd7cddfSDavid du Colombier stc_write_xarray(0,"Rcoding","Rtransfer");
26367dd7cddfSDavid du Colombier stc_write_xarray(1,"Gcoding","Gtransfer");
26377dd7cddfSDavid du Colombier stc_write_xarray(2,"Bcoding","Btransfer");
26387dd7cddfSDavid du Colombier
26397dd7cddfSDavid du Colombier stc_write_null("Ccoding"); stc_write_null("Ctransfer");
26407dd7cddfSDavid du Colombier stc_write_null("Mcoding"); stc_write_null("Mtransfer");
26417dd7cddfSDavid du Colombier stc_write_null("Ycoding"); stc_write_null("Ytransfer");
26427dd7cddfSDavid du Colombier stc_write_null("Kcoding"); stc_write_null("Ktransfer");
26437dd7cddfSDavid du Colombier
26447dd7cddfSDavid du Colombier } else { /* DeviceCMYK */
26457dd7cddfSDavid du Colombier
26467dd7cddfSDavid du Colombier stc_write_xarray(0,"Ccoding","Ctransfer");
26477dd7cddfSDavid du Colombier stc_write_xarray(1,"Mcoding","Mtransfer");
26487dd7cddfSDavid du Colombier stc_write_xarray(2,"Ycoding","Ytransfer");
26497dd7cddfSDavid du Colombier stc_write_xarray(3,"Kcoding","Ktransfer");
26507dd7cddfSDavid du Colombier
26517dd7cddfSDavid du Colombier stc_write_null("Rcoding"); stc_write_null("Rtransfer");
26527dd7cddfSDavid du Colombier stc_write_null("Gcoding"); stc_write_null("Gtransfer");
26537dd7cddfSDavid du Colombier stc_write_null("Bcoding"); stc_write_null("Btransfer");
26547dd7cddfSDavid du Colombier
26557dd7cddfSDavid du Colombier }
26567dd7cddfSDavid du Colombier return code;
26577dd7cddfSDavid du Colombier }
26587dd7cddfSDavid du Colombier
26597dd7cddfSDavid du Colombier /***
26607dd7cddfSDavid du Colombier *** put parameters == Store them in the device-structure
26617dd7cddfSDavid du Colombier ***/
26627dd7cddfSDavid du Colombier
26637dd7cddfSDavid du Colombier private int
stc_put_params(gx_device * pdev,gs_param_list * plist)26647dd7cddfSDavid du Colombier stc_put_params(gx_device *pdev, gs_param_list *plist)
26657dd7cddfSDavid du Colombier {
26667dd7cddfSDavid du Colombier int code,error,i,l;
26677dd7cddfSDavid du Colombier bool b1,b2,b3;
26687dd7cddfSDavid du Colombier float fv,*fp;
26697dd7cddfSDavid du Colombier gs_param_string ps;
26707dd7cddfSDavid du Colombier gs_param_string_array psa;
26717dd7cddfSDavid du Colombier gs_param_float_array pfa;
26727dd7cddfSDavid du Colombier stcolor_device *sd = (stcolor_device *) pdev;
26737dd7cddfSDavid du Colombier gx_device_color_info oldcolor;
26747dd7cddfSDavid du Colombier stc_t oldstc;
26757dd7cddfSDavid du Colombier
26767dd7cddfSDavid du Colombier /*
26777dd7cddfSDavid du Colombier * save old Values
26787dd7cddfSDavid du Colombier */
26797dd7cddfSDavid du Colombier memcpy(&oldcolor,&sd->color_info,sizeof(oldcolor));
26807dd7cddfSDavid du Colombier memcpy(&oldstc ,&sd->stc ,sizeof(oldstc ));
26817dd7cddfSDavid du Colombier
26827dd7cddfSDavid du Colombier /*
26837dd7cddfSDavid du Colombier * Arrrgh:
26847dd7cddfSDavid du Colombier * With Version 3.4x and above my simple minded read-only Parameters
26857dd7cddfSDavid du Colombier * do not work any more. So read them here for heavens sake.
26867dd7cddfSDavid du Colombier */
26877dd7cddfSDavid du Colombier code = param_read_string(plist,"Version",&ps);
26887dd7cddfSDavid du Colombier code = param_read_int(plist,"BitsPerComponent",&i);
26897dd7cddfSDavid du Colombier code = param_read_string_array(plist,"Algorithms",&psa);
26907dd7cddfSDavid du Colombier
26917dd7cddfSDavid du Colombier /*
26927dd7cddfSDavid du Colombier * Fetch Major-Parameters (Model, Dithering, BitsPerPixel/BitsPerComponent)
26937dd7cddfSDavid du Colombier */
26947dd7cddfSDavid du Colombier error = 0;
26957dd7cddfSDavid du Colombier
26967dd7cddfSDavid du Colombier code = param_read_string(plist,"Model",&ps);
26977dd7cddfSDavid du Colombier if(code == 0) { /* Analyze the Model-String */
26987dd7cddfSDavid du Colombier /*
26997dd7cddfSDavid du Colombier * Arrgh: I should have known, that internal strings are not zero-terminated.
27007dd7cddfSDavid du Colombier */
27017dd7cddfSDavid du Colombier for(l = ps.size; (l > 0) && (ps.data[l-1] == 0); --l);
27027dd7cddfSDavid du Colombier # define stc_putcmp(Name) \
27037dd7cddfSDavid du Colombier ((strlen(Name) != l) || (0 != strncmp(Name, (const char *)ps.data,l)))
27047dd7cddfSDavid du Colombier
27057dd7cddfSDavid du Colombier sd->stc.flags &= ~STCMODEL;
27067dd7cddfSDavid du Colombier if( !stc_putcmp("st800")) sd->stc.flags |= STCST800;
27077dd7cddfSDavid du Colombier else if(!stc_putcmp("stcii")) sd->stc.flags |= STCSTCII;
27087dd7cddfSDavid du Colombier
27097dd7cddfSDavid du Colombier } /* Analyze the Model-String */
27107dd7cddfSDavid du Colombier if(code < 0) param_signal_error(plist,"Model",code);
27117dd7cddfSDavid du Colombier error = error > code ? code : error;
27127dd7cddfSDavid du Colombier
27137dd7cddfSDavid du Colombier /* If we're running for st800, #components must be 1 */
27147dd7cddfSDavid du Colombier if(((sd->stc.flags & STCMODEL) == STCST800) &&
27157dd7cddfSDavid du Colombier (( sd->color_info.num_components > 1) ||
27167dd7cddfSDavid du Colombier ( sd->stc.dither == NULL) ||
27177dd7cddfSDavid du Colombier ((sd->stc.dither->flags & 7) > 1))) {
27187dd7cddfSDavid du Colombier sd->color_info.num_components = 1;
27197dd7cddfSDavid du Colombier sd->stc.dither = NULL;
27207dd7cddfSDavid du Colombier }
27217dd7cddfSDavid du Colombier
27227dd7cddfSDavid du Colombier /* Weaving isn't a feature for the st800 */
27237dd7cddfSDavid du Colombier if((sd->stc.flags & STCMODEL) == STCST800) {
27247dd7cddfSDavid du Colombier sd->stc.flags &= ~STCUWEAVE;
27257dd7cddfSDavid du Colombier sd->stc.flags |= STCNWEAVE;
27267dd7cddfSDavid du Colombier } else if((sd->stc.flags & STCMODEL) == STCSTCII) { /* no SoftWeave */
27277dd7cddfSDavid du Colombier sd->stc.flags |= STCNWEAVE;
27287dd7cddfSDavid du Colombier }
27297dd7cddfSDavid du Colombier
27307dd7cddfSDavid du Colombier code = param_read_string(plist,"Dithering",&ps);
27317dd7cddfSDavid du Colombier if(code == 0) { /* lookup new value new value */
27327dd7cddfSDavid du Colombier
27337dd7cddfSDavid du Colombier for(l = ps.size; (l > 0) && (ps.data[l-1] == 0); --l);
27347dd7cddfSDavid du Colombier
27357dd7cddfSDavid du Colombier for(i = 0; stc_dither[i].name != NULL; ++i)
27367dd7cddfSDavid du Colombier if(!stc_putcmp(stc_dither[i].name)) break;
27377dd7cddfSDavid du Colombier
27387dd7cddfSDavid du Colombier } else if(sd->stc.dither != NULL) { /* compute index of given value */
27397dd7cddfSDavid du Colombier
27407dd7cddfSDavid du Colombier i = sd->stc.dither - stc_dither;
27417dd7cddfSDavid du Colombier
27427dd7cddfSDavid du Colombier } else { /* find matching value */
27437dd7cddfSDavid du Colombier
27447dd7cddfSDavid du Colombier for(i = 0; stc_dither[i].name != NULL; ++i)
27457dd7cddfSDavid du Colombier if((stc_dither[i].flags & 7) == sd->color_info.num_components) break;
27467dd7cddfSDavid du Colombier
27477dd7cddfSDavid du Colombier } /* we've got an index */
27487dd7cddfSDavid du Colombier
27497dd7cddfSDavid du Colombier if(stc_dither[i].name != NULL) { /* establish data */
27507dd7cddfSDavid du Colombier
27517dd7cddfSDavid du Colombier /*
27527dd7cddfSDavid du Colombier * Establish new dithering algorithm & color-model
27537dd7cddfSDavid du Colombier */
27547dd7cddfSDavid du Colombier sd->stc.dither = stc_dither+i;
27557dd7cddfSDavid du Colombier sd->color_info.num_components = sd->stc.dither->flags & 7;
27567dd7cddfSDavid du Colombier STC_TYPESWITCH(sd->stc.dither,stc_sizeofitem)
27577dd7cddfSDavid du Colombier # undef stc_sizeofitem
27587dd7cddfSDavid du Colombier if(((sd->stc.flags & STCMODEL) == STCST800) &&
27597dd7cddfSDavid du Colombier ( sd->color_info.num_components > 1 ))
27607dd7cddfSDavid du Colombier code = gs_error_rangecheck;
27617dd7cddfSDavid du Colombier
27627dd7cddfSDavid du Colombier /*
27637dd7cddfSDavid du Colombier * reset Parameters related to the color-model, if it changed
27647dd7cddfSDavid du Colombier */
27657dd7cddfSDavid du Colombier
27667dd7cddfSDavid du Colombier if(sd->color_info.num_components != oldcolor.num_components) {
27677dd7cddfSDavid du Colombier
27687dd7cddfSDavid du Colombier for(i = 0; i < sd->color_info.num_components; ++i) {
27697dd7cddfSDavid du Colombier sd->stc.extv[i] = (float *) defext;
27707dd7cddfSDavid du Colombier sd->stc.sizv[i] = countof(defext);
27717dd7cddfSDavid du Colombier
27727dd7cddfSDavid du Colombier sd->stc.extc[i] = NULL;
27737dd7cddfSDavid du Colombier sd->stc.sizc[i] = 0;
27747dd7cddfSDavid du Colombier
27757dd7cddfSDavid du Colombier }
27767dd7cddfSDavid du Colombier
27777dd7cddfSDavid du Colombier sd->stc.am = NULL;
27787dd7cddfSDavid du Colombier
27797dd7cddfSDavid du Colombier } else { /* guarantee, that extvals is present */
27807dd7cddfSDavid du Colombier
27817dd7cddfSDavid du Colombier for(i = 0; i < sd->color_info.num_components; ++i) {
27827dd7cddfSDavid du Colombier if(sd->stc.sizv[i] < 2) {
27837dd7cddfSDavid du Colombier sd->stc.extv[i] = (float *) defext;
27847dd7cddfSDavid du Colombier sd->stc.sizv[i] = countof(defext);
27857dd7cddfSDavid du Colombier }
27867dd7cddfSDavid du Colombier }
27877dd7cddfSDavid du Colombier }
27887dd7cddfSDavid du Colombier
27897dd7cddfSDavid du Colombier for(i = sd->color_info.num_components; i < 4; ++ i) { /* clear unused */
27907dd7cddfSDavid du Colombier sd->stc.extv[i] = NULL;
27917dd7cddfSDavid du Colombier sd->stc.sizv[i] = 0;
27927dd7cddfSDavid du Colombier sd->stc.vals[i] = NULL;
27937dd7cddfSDavid du Colombier
27947dd7cddfSDavid du Colombier sd->stc.extc[i] = NULL;
27957dd7cddfSDavid du Colombier sd->stc.sizc[i] = 0;
27967dd7cddfSDavid du Colombier sd->stc.code[i] = NULL;
27977dd7cddfSDavid du Colombier
27987dd7cddfSDavid du Colombier } /* clear unused */
27997dd7cddfSDavid du Colombier
28007dd7cddfSDavid du Colombier /*
28017dd7cddfSDavid du Colombier * Guess default depth from range of values
28027dd7cddfSDavid du Colombier */
28037dd7cddfSDavid du Colombier if((sd->stc.dither != oldstc.dither)||(oldstc.vals[0] == NULL)) {
28047dd7cddfSDavid du Colombier
28057dd7cddfSDavid du Colombier if((sd->stc.dither->flags & STC_CMYK10) != 0) {
28067dd7cddfSDavid du Colombier
28077dd7cddfSDavid du Colombier sd->stc.flags |= STCCMYK10;
28087dd7cddfSDavid du Colombier sd->stc.bits = 10;
28097dd7cddfSDavid du Colombier sd->color_info.depth = 32;
28107dd7cddfSDavid du Colombier
28117dd7cddfSDavid du Colombier } else {
28127dd7cddfSDavid du Colombier
28137dd7cddfSDavid du Colombier sd->stc.flags &= ~STCCMYK10;
28147dd7cddfSDavid du Colombier
28157dd7cddfSDavid du Colombier if((sd->stc.dither->flags & STC_FLOAT) != STC_FLOAT) {
28167dd7cddfSDavid du Colombier fv = 2.0;
28177dd7cddfSDavid du Colombier for(i = 1;(i < gx_color_value_bits) &&
28187dd7cddfSDavid du Colombier (fv <= (sd->stc.dither->minmax[1]-sd->stc.dither->minmax[0]));
28197dd7cddfSDavid du Colombier ++i) fv *= 2.0;
28207dd7cddfSDavid du Colombier
28217dd7cddfSDavid du Colombier } else {
28227dd7cddfSDavid du Colombier i = 8; /* arbitrary */
28237dd7cddfSDavid du Colombier }
28247dd7cddfSDavid du Colombier
28257dd7cddfSDavid du Colombier if((i*sd->color_info.num_components) > (sizeof(stc_pixel)*8)) {
28267dd7cddfSDavid du Colombier
28277dd7cddfSDavid du Colombier sd->stc.bits = (sizeof(stc_pixel)*8) /
28287dd7cddfSDavid du Colombier sd->color_info.num_components;
28297dd7cddfSDavid du Colombier sd->color_info.depth = sd->stc.bits * sd->color_info.num_components;
28307dd7cddfSDavid du Colombier
28317dd7cddfSDavid du Colombier } else {
28327dd7cddfSDavid du Colombier
28337dd7cddfSDavid du Colombier sd->stc.bits = i;
28347dd7cddfSDavid du Colombier sd->color_info.depth = sd->stc.bits * sd->color_info.num_components;
28357dd7cddfSDavid du Colombier
28367dd7cddfSDavid du Colombier }
28377dd7cddfSDavid du Colombier }
28387dd7cddfSDavid du Colombier }
28397dd7cddfSDavid du Colombier
28407dd7cddfSDavid du Colombier } else {
28417dd7cddfSDavid du Colombier
28427dd7cddfSDavid du Colombier code = gs_error_rangecheck;
28437dd7cddfSDavid du Colombier
28447dd7cddfSDavid du Colombier } /* verify new value */
28457dd7cddfSDavid du Colombier if(code < 0) param_signal_error(plist,"Dithering",code);
28467dd7cddfSDavid du Colombier error = error > code ? code : error;
28477dd7cddfSDavid du Colombier
28487dd7cddfSDavid du Colombier /*
28497dd7cddfSDavid du Colombier * now fetch the desired depth, if the algorithm allows it
28507dd7cddfSDavid du Colombier */
28517dd7cddfSDavid du Colombier /*
28527dd7cddfSDavid du Colombier * Arrrgh: We get code == 0, even if nobody sets BitsPerPixel.
28537dd7cddfSDavid du Colombier * The value is the old one, but this may cause trouble
28547dd7cddfSDavid du Colombier * with CMYK10.
28557dd7cddfSDavid du Colombier */
28567dd7cddfSDavid du Colombier code = param_read_int(plist, "BitsPerPixel", &i);
28577dd7cddfSDavid du Colombier if((error == 0) && (code == 0) &&
28587dd7cddfSDavid du Colombier (((sd->stc.flags & STCCMYK10) == 0) || (i != sd->color_info.depth))) {
28597dd7cddfSDavid du Colombier
28607dd7cddfSDavid du Colombier if((1 > i) || (i > (sizeof(stc_pixel)*8)))
28617dd7cddfSDavid du Colombier code = gs_error_rangecheck;
28627dd7cddfSDavid du Colombier else
28637dd7cddfSDavid du Colombier sd->color_info.depth = i;
28647dd7cddfSDavid du Colombier
28657dd7cddfSDavid du Colombier sd->stc.bits = i / sd->color_info.num_components;
28667dd7cddfSDavid du Colombier
28677dd7cddfSDavid du Colombier if(1 > sd->stc.bits) code = gs_error_rangecheck;
28687dd7cddfSDavid du Colombier
28697dd7cddfSDavid du Colombier if((sd->stc.dither->flags & STC_DIRECT) &&
28707dd7cddfSDavid du Colombier (sd->stc.dither->flags & STC_CMYK10))
28717dd7cddfSDavid du Colombier code = gs_error_rangecheck;
28727dd7cddfSDavid du Colombier else
28737dd7cddfSDavid du Colombier sd->stc.flags &= ~STCCMYK10;
28747dd7cddfSDavid du Colombier
28757dd7cddfSDavid du Colombier }
28767dd7cddfSDavid du Colombier if(code < 0) param_signal_error(plist,"BitsPerPixel",code);
28777dd7cddfSDavid du Colombier error = error > code ? code : error;
28787dd7cddfSDavid du Colombier
28797dd7cddfSDavid du Colombier /*
28807dd7cddfSDavid du Colombier * Fetch OutputCode
28817dd7cddfSDavid du Colombier */
28827dd7cddfSDavid du Colombier code = param_read_string(plist,"OutputCode",&ps);
28837dd7cddfSDavid du Colombier if(code == 0) { /* Analyze the OutputCode-String */
28847dd7cddfSDavid du Colombier
28857dd7cddfSDavid du Colombier for(l = ps.size; (l > 0) && (ps.data[l-1] == 0); --l);
28867dd7cddfSDavid du Colombier
28877dd7cddfSDavid du Colombier sd->stc.flags &= ~STCCOMP;
28887dd7cddfSDavid du Colombier if(!stc_putcmp("plain")) sd->stc.flags |= STCPLAIN;
28897dd7cddfSDavid du Colombier else if(!stc_putcmp("deltarow")) sd->stc.flags |= STCDELTA;
28907dd7cddfSDavid du Colombier
28917dd7cddfSDavid du Colombier } /* Analyze the OutputCode-String */
28927dd7cddfSDavid du Colombier if((sd->stc.flags & STCCOMP) == STCDELTA) {
28937dd7cddfSDavid du Colombier sd->stc.flags |= STCUWEAVE;
28947dd7cddfSDavid du Colombier sd->stc.flags &= ~STCNWEAVE;
28957dd7cddfSDavid du Colombier }
28967dd7cddfSDavid du Colombier if(code < 0) param_signal_error(plist,"OutputCode",code);
28977dd7cddfSDavid du Colombier error = error > code ? code : error;
28987dd7cddfSDavid du Colombier
28997dd7cddfSDavid du Colombier /*
29007dd7cddfSDavid du Colombier * fetch the weave-mode (noWeave wins)
29017dd7cddfSDavid du Colombier */
29027dd7cddfSDavid du Colombier b1 = sd->stc.flags & STCUWEAVE ? true : false;
29037dd7cddfSDavid du Colombier b2 = sd->stc.flags & STCNWEAVE ? true : false;
29047dd7cddfSDavid du Colombier b3 = sd->stc.flags & (STCUWEAVE|STCNWEAVE) ? false : true;
29057dd7cddfSDavid du Colombier
29067dd7cddfSDavid du Colombier code = param_read_bool(plist,"Microweave",&b1);
29077dd7cddfSDavid du Colombier if(code < 0) {
29087dd7cddfSDavid du Colombier param_signal_error(plist,"Microweave",code);
29097dd7cddfSDavid du Colombier } else if(code == 0) {
29107dd7cddfSDavid du Colombier if(b1) { b2 = false; b3 = false; }
29117dd7cddfSDavid du Colombier }
29127dd7cddfSDavid du Colombier error = error > code ? code : error;
29137dd7cddfSDavid du Colombier
29147dd7cddfSDavid du Colombier code = param_read_bool(plist,"noWeave",&b2);
29157dd7cddfSDavid du Colombier if(code < 0) {
29167dd7cddfSDavid du Colombier param_signal_error(plist,"noWeave",code);
29177dd7cddfSDavid du Colombier } else if (code == 0) {
29187dd7cddfSDavid du Colombier if(b2) { b1 = false; b3 = false; }
29197dd7cddfSDavid du Colombier }
29207dd7cddfSDavid du Colombier error = error > code ? code : error;
29217dd7cddfSDavid du Colombier
29227dd7cddfSDavid du Colombier code = param_read_bool(plist,"Softweave",&b3);
29237dd7cddfSDavid du Colombier if(code < 0) {
29247dd7cddfSDavid du Colombier param_signal_error(plist,"Softweave",code);
29257dd7cddfSDavid du Colombier } else if (code == 0) {
29267dd7cddfSDavid du Colombier if(b3) { b1 = false; b2 = false; }
29277dd7cddfSDavid du Colombier }
29287dd7cddfSDavid du Colombier error = error > code ? code : error;
29297dd7cddfSDavid du Colombier
29307dd7cddfSDavid du Colombier if(b1) sd->stc.flags |= STCUWEAVE;
29317dd7cddfSDavid du Colombier else sd->stc.flags &= ~STCUWEAVE;
29327dd7cddfSDavid du Colombier
29337dd7cddfSDavid du Colombier if(b2) sd->stc.flags |= STCNWEAVE;
29347dd7cddfSDavid du Colombier else sd->stc.flags &= ~STCNWEAVE;
29357dd7cddfSDavid du Colombier
29367dd7cddfSDavid du Colombier /*
29377dd7cddfSDavid du Colombier * Check the simple Flags
29387dd7cddfSDavid du Colombier */
29397dd7cddfSDavid du Colombier # define stc_read_flag(Mask,Name) \
29407dd7cddfSDavid du Colombier code = param_read_bool(plist,Name,&b1); \
29417dd7cddfSDavid du Colombier if(code < 0) { \
29427dd7cddfSDavid du Colombier param_signal_error(plist,Name,code); \
29437dd7cddfSDavid du Colombier } else if(code == 0) { \
29447dd7cddfSDavid du Colombier if(b1 == true) sd->stc.flags |= Mask; \
29457dd7cddfSDavid du Colombier else sd->stc.flags &= ~(Mask); \
29467dd7cddfSDavid du Colombier } \
29477dd7cddfSDavid du Colombier error = error > code ? code : error;
29487dd7cddfSDavid du Colombier
29497dd7cddfSDavid du Colombier stc_read_flag(STCUNIDIR,"Unidirectional")
29507dd7cddfSDavid du Colombier stc_read_flag(STCDFLAG0, "Flag0")
29517dd7cddfSDavid du Colombier stc_read_flag(STCDFLAG1, "Flag1")
29527dd7cddfSDavid du Colombier stc_read_flag(STCDFLAG2, "Flag2")
29537dd7cddfSDavid du Colombier stc_read_flag(STCDFLAG3, "Flag3")
29547dd7cddfSDavid du Colombier stc_read_flag(STCDFLAG4, "Flag4")
29557dd7cddfSDavid du Colombier
29567dd7cddfSDavid du Colombier /*
29577dd7cddfSDavid du Colombier * Now deal with the escp-Stuff
29587dd7cddfSDavid du Colombier */
29597dd7cddfSDavid du Colombier # define stc_read_int(Mask,Name,Val) \
29607dd7cddfSDavid du Colombier code = param_read_int(plist,Name,&Val); \
29617dd7cddfSDavid du Colombier if(code < 0) \
29627dd7cddfSDavid du Colombier param_signal_error(plist,Name,code); \
29637dd7cddfSDavid du Colombier else if(code == 0) \
29647dd7cddfSDavid du Colombier sd->stc.flags |= Mask; \
29657dd7cddfSDavid du Colombier error = error > code ? code : error
29667dd7cddfSDavid du Colombier
29677dd7cddfSDavid du Colombier stc_read_int(STCBAND, "escp_Band", sd->stc.escp_m);
29687dd7cddfSDavid du Colombier stc_read_int(STCWIDTH, "escp_Width", sd->stc.escp_width);
29697dd7cddfSDavid du Colombier stc_read_int(STCHEIGHT,"escp_Height",sd->stc.escp_height);
29707dd7cddfSDavid du Colombier stc_read_int(STCTOP, "escp_Top", sd->stc.escp_top);
29717dd7cddfSDavid du Colombier stc_read_int(STCBOTTOM,"escp_Bottom",sd->stc.escp_bottom);
29727dd7cddfSDavid du Colombier
29737dd7cddfSDavid du Colombier # undef stc_read_int
29747dd7cddfSDavid du Colombier
29757dd7cddfSDavid du Colombier code = param_read_string(plist,"escp_Init",&sd->stc.escp_init);
29767dd7cddfSDavid du Colombier if(code == 0) sd->stc.flags |= STCINIT;
29777dd7cddfSDavid du Colombier error = error > code ? code : error;
29787dd7cddfSDavid du Colombier
29797dd7cddfSDavid du Colombier code = param_read_string(plist,"escp_Release",&sd->stc.escp_release);
29807dd7cddfSDavid du Colombier if(code == 0) sd->stc.flags |= STCRELEASE;
29817dd7cddfSDavid du Colombier error = error > code ? code : error;
29827dd7cddfSDavid du Colombier
29837dd7cddfSDavid du Colombier /*
29847dd7cddfSDavid du Colombier * ColorAdjustMatrix must match the required size,
29857dd7cddfSDavid du Colombier * setting it explicitly to null, erases old matrix
29867dd7cddfSDavid du Colombier */
29877dd7cddfSDavid du Colombier code = param_read_float_array(plist,"ColorAdjustMatrix",&pfa);
29887dd7cddfSDavid du Colombier if((error == 0) && (code == 0)) {
29897dd7cddfSDavid du Colombier if(((sd->color_info.num_components == 1) && (pfa.size == 3)) ||
29907dd7cddfSDavid du Colombier ((sd->color_info.num_components == 3) && (pfa.size == 9)) ||
29917dd7cddfSDavid du Colombier ((sd->color_info.num_components == 4) && (pfa.size == 16)))
29927dd7cddfSDavid du Colombier sd->stc.am = (float *) pfa.data;
29937dd7cddfSDavid du Colombier else
29947dd7cddfSDavid du Colombier code = gs_error_rangecheck;
29957dd7cddfSDavid du Colombier } else if(code < 0) {
29967dd7cddfSDavid du Colombier code = param_read_null(plist,"ColorAdjustMatrix");
29977dd7cddfSDavid du Colombier if(code == 0) sd->stc.am = NULL;
29987dd7cddfSDavid du Colombier }
29997dd7cddfSDavid du Colombier if(code < 0) param_signal_error(plist,"ColorAdjustMatrix",code);
30007dd7cddfSDavid du Colombier error = error > code ? code : error;
30017dd7cddfSDavid du Colombier
30027dd7cddfSDavid du Colombier /*
30037dd7cddfSDavid du Colombier * Read the external array-Parameters
30047dd7cddfSDavid du Colombier */
30057dd7cddfSDavid du Colombier if(sd->color_info.num_components == 1) { /* DeviceGray */
30067dd7cddfSDavid du Colombier
30077dd7cddfSDavid du Colombier stc_read_xarray(0,"Kcoding","Ktransfer");
30087dd7cddfSDavid du Colombier
30097dd7cddfSDavid du Colombier stc_read_null("Rcoding"); stc_read_null("Rtransfer");
30107dd7cddfSDavid du Colombier stc_read_null("Gcoding"); stc_read_null("Gtransfer");
30117dd7cddfSDavid du Colombier stc_read_null("Bcoding"); stc_read_null("Btransfer");
30127dd7cddfSDavid du Colombier
30137dd7cddfSDavid du Colombier stc_read_null("Ccoding"); stc_read_null("Ctransfer");
30147dd7cddfSDavid du Colombier stc_read_null("Mcoding"); stc_read_null("Mtransfer");
30157dd7cddfSDavid du Colombier stc_read_null("Ycoding"); stc_read_null("Ytransfer");
30167dd7cddfSDavid du Colombier
30177dd7cddfSDavid du Colombier } else if(sd->color_info.num_components == 3) { /* DeviceRGB */
30187dd7cddfSDavid du Colombier
30197dd7cddfSDavid du Colombier stc_read_xarray(0,"Rcoding","Rtransfer");
30207dd7cddfSDavid du Colombier stc_read_xarray(1,"Gcoding","Gtransfer");
30217dd7cddfSDavid du Colombier stc_read_xarray(2,"Bcoding","Btransfer");
30227dd7cddfSDavid du Colombier
30237dd7cddfSDavid du Colombier stc_read_null("Ccoding"); stc_read_null("Ctransfer");
30247dd7cddfSDavid du Colombier stc_read_null("Mcoding"); stc_read_null("Mtransfer");
30257dd7cddfSDavid du Colombier stc_read_null("Ycoding"); stc_read_null("Ytransfer");
30267dd7cddfSDavid du Colombier stc_read_null("Kcoding"); stc_read_null("Ktransfer");
30277dd7cddfSDavid du Colombier
30287dd7cddfSDavid du Colombier } else { /* DeviceCMYK */
30297dd7cddfSDavid du Colombier
30307dd7cddfSDavid du Colombier stc_read_xarray(0,"Ccoding","Ctransfer");
30317dd7cddfSDavid du Colombier stc_read_xarray(1,"Mcoding","Mtransfer");
30327dd7cddfSDavid du Colombier stc_read_xarray(2,"Ycoding","Ytransfer");
30337dd7cddfSDavid du Colombier stc_read_xarray(3,"Kcoding","Ktransfer");
30347dd7cddfSDavid du Colombier
30357dd7cddfSDavid du Colombier stc_read_null("Rcoding"); stc_read_null("Rtransfer");
30367dd7cddfSDavid du Colombier stc_read_null("Gcoding"); stc_read_null("Gtransfer");
30377dd7cddfSDavid du Colombier stc_read_null("Bcoding"); stc_read_null("Btransfer");
30387dd7cddfSDavid du Colombier
30397dd7cddfSDavid du Colombier }
30407dd7cddfSDavid du Colombier /*
30417dd7cddfSDavid du Colombier * Update remaining color_info values
30427dd7cddfSDavid du Colombier */
30437dd7cddfSDavid du Colombier if(error == 0) {
30447dd7cddfSDavid du Colombier
30457dd7cddfSDavid du Colombier /* compute #values from the component-bits */
30467dd7cddfSDavid du Colombier sd->color_info.max_gray = sd->stc.bits < gx_color_value_bits ?
30477dd7cddfSDavid du Colombier (1<<sd->stc.bits)-1 : gx_max_color_value;
30487dd7cddfSDavid du Colombier
30497dd7cddfSDavid du Colombier /* An integer-algorithm might reduce the number of values */
30507dd7cddfSDavid du Colombier if(((sd->stc.dither->flags & STC_TYPE) != STC_FLOAT) &&
30517dd7cddfSDavid du Colombier ((sd->stc.dither->minmax[1]-sd->stc.dither->minmax[0]) <
30527dd7cddfSDavid du Colombier sd->color_info.max_gray))
3053*593dc095SDavid du Colombier sd->color_info.max_gray = (gx_color_value)
3054*593dc095SDavid du Colombier (sd->stc.dither->minmax[1]-sd->stc.dither->minmax[0]+0.5);
30557dd7cddfSDavid du Colombier
30567dd7cddfSDavid du Colombier sd->color_info.max_color = sd->color_info.num_components < 3 ? 0 :
30577dd7cddfSDavid du Colombier sd->color_info.max_gray;
30587dd7cddfSDavid du Colombier sd->color_info.dither_grays =
30597dd7cddfSDavid du Colombier sd->color_info.max_gray < gx_max_color_value ?
30607dd7cddfSDavid du Colombier sd->color_info.max_gray+1 : gx_max_color_value;
30617dd7cddfSDavid du Colombier sd->color_info.dither_colors = sd->color_info.num_components < 3 ? 0 :
30627dd7cddfSDavid du Colombier sd->color_info.dither_grays;
30637dd7cddfSDavid du Colombier }
30647dd7cddfSDavid du Colombier
30657dd7cddfSDavid du Colombier /*
30667dd7cddfSDavid du Colombier * Call superclass-Update
30677dd7cddfSDavid du Colombier */
30687dd7cddfSDavid du Colombier
30697dd7cddfSDavid du Colombier code = gdev_prn_put_params(pdev, plist);
30707dd7cddfSDavid du Colombier error = error > code ? code : error;
30717dd7cddfSDavid du Colombier
30727dd7cddfSDavid du Colombier /*
30737dd7cddfSDavid du Colombier * Arrrgh, writing BitsPerPixel is really *VERY* special:
30747dd7cddfSDavid du Colombier * gdev_prn_put_params verifies, that the external value
30757dd7cddfSDavid du Colombier * is written, if not, it raises a rangecheck-error.
30767dd7cddfSDavid du Colombier * On the other hand ghostscript is quite unhappy with odd
30777dd7cddfSDavid du Colombier * values, so we do the necessary rounding *AFTER* the
30787dd7cddfSDavid du Colombier * "superclass-Update".
30797dd7cddfSDavid du Colombier */
30807dd7cddfSDavid du Colombier
30817dd7cddfSDavid du Colombier if(sd->color_info.depth == 3) sd->color_info.depth = 4;
30827dd7cddfSDavid du Colombier else if(sd->color_info.depth > 4)
30837dd7cddfSDavid du Colombier sd->color_info.depth = (sd->color_info.depth+7) & ~7;
30847dd7cddfSDavid du Colombier
30857dd7cddfSDavid du Colombier /*
30867dd7cddfSDavid du Colombier * Allocate the storage for the arrays in memory
30877dd7cddfSDavid du Colombier */
30887dd7cddfSDavid du Colombier if(error == 0) { /* Allocate new external-arrays */
30897dd7cddfSDavid du Colombier
30907dd7cddfSDavid du Colombier for(i = 0; i < sd->color_info.num_components; ++i){ /* Active components */
30917dd7cddfSDavid du Colombier int j;
30927dd7cddfSDavid du Colombier
30937dd7cddfSDavid du Colombier if((sd->stc.extv[i] != oldstc.extv[i]) &&
30947dd7cddfSDavid du Colombier (sd->stc.extv[i] != defext )) { /* Value-Arrays */
30957dd7cddfSDavid du Colombier
30967dd7cddfSDavid du Colombier for(j = 0; j < i; ++j)
30977dd7cddfSDavid du Colombier if((sd->stc.sizv[j] == sd->stc.sizv[i]) &&
30987dd7cddfSDavid du Colombier (memcmp(sd->stc.extv[j],sd->stc.extv[i],
30997dd7cddfSDavid du Colombier sd->stc.sizv[i]*sizeof(float)) == 0)) break;
31007dd7cddfSDavid du Colombier
31017dd7cddfSDavid du Colombier if(j < i) {
31027dd7cddfSDavid du Colombier sd->stc.extv[i] = sd->stc.extv[j];
31037dd7cddfSDavid du Colombier } else {
3104*593dc095SDavid du Colombier fp = gs_malloc(sd->memory, sd->stc.sizv[i],sizeof(float),"stc_put_params");
31057dd7cddfSDavid du Colombier if(fp != NULL)
31067dd7cddfSDavid du Colombier memcpy(fp,sd->stc.extv[i],sd->stc.sizv[i]*sizeof(float));
31077dd7cddfSDavid du Colombier else
31087dd7cddfSDavid du Colombier code = gs_error_VMerror;
31097dd7cddfSDavid du Colombier sd->stc.extv[i] = fp;
31107dd7cddfSDavid du Colombier }
31117dd7cddfSDavid du Colombier } /* Value-Arrays */
31127dd7cddfSDavid du Colombier
31137dd7cddfSDavid du Colombier if((sd->stc.sizc[i] > 1) &&
31147dd7cddfSDavid du Colombier (sd->stc.extc[i] != oldstc.extc[i])) { /* Code-Arrays */
31157dd7cddfSDavid du Colombier
31167dd7cddfSDavid du Colombier for(j = 0; j < i; ++j)
31177dd7cddfSDavid du Colombier if((sd->stc.sizc[j] == sd->stc.sizc[i]) &&
31187dd7cddfSDavid du Colombier (memcmp(sd->stc.extc[j],sd->stc.extc[i],
31197dd7cddfSDavid du Colombier sd->stc.sizc[i]*sizeof(float)) == 0)) break;
31207dd7cddfSDavid du Colombier
31217dd7cddfSDavid du Colombier if(j < i) {
31227dd7cddfSDavid du Colombier sd->stc.extc[i] = sd->stc.extc[j];
31237dd7cddfSDavid du Colombier } else {
3124*593dc095SDavid du Colombier fp = gs_malloc(sd->memory, sd->stc.sizc[i],sizeof(float),"stc_put_params");
31257dd7cddfSDavid du Colombier if(fp != NULL)
31267dd7cddfSDavid du Colombier memcpy(fp,sd->stc.extc[i],sd->stc.sizc[i]*sizeof(float));
31277dd7cddfSDavid du Colombier else
31287dd7cddfSDavid du Colombier code = gs_error_VMerror;
31297dd7cddfSDavid du Colombier sd->stc.extc[i] = fp;
31307dd7cddfSDavid du Colombier }
31317dd7cddfSDavid du Colombier } /* Code-Arrays */
31327dd7cddfSDavid du Colombier
31337dd7cddfSDavid du Colombier } /* Active components */
31347dd7cddfSDavid du Colombier
31357dd7cddfSDavid du Colombier if((sd->stc.am != NULL) && (sd->stc.am != oldstc.am)) {
31367dd7cddfSDavid du Colombier if( sd->color_info.num_components == 1) i = 3;
31377dd7cddfSDavid du Colombier else if(sd->color_info.num_components == 3) i = 9;
31387dd7cddfSDavid du Colombier else i = 16;
3139*593dc095SDavid du Colombier fp = gs_malloc(sd->memory, i,sizeof(float),"stc_put_params");
31407dd7cddfSDavid du Colombier if(fp != NULL) memcpy(fp,sd->stc.am,i*sizeof(float));
31417dd7cddfSDavid du Colombier else code = gs_error_VMerror;
31427dd7cddfSDavid du Colombier sd->stc.am = fp;
31437dd7cddfSDavid du Colombier }
31447dd7cddfSDavid du Colombier
31457dd7cddfSDavid du Colombier if(sd->stc.escp_init.data != oldstc.escp_init.data) {
31467dd7cddfSDavid du Colombier byte *ip = NULL;
31477dd7cddfSDavid du Colombier
31487dd7cddfSDavid du Colombier if(sd->stc.escp_init.size > 0) {
3149*593dc095SDavid du Colombier ip = gs_malloc(sd->memory, sd->stc.escp_init.size,1,"stcolor/init");
31507dd7cddfSDavid du Colombier if(ip == NULL) {
31517dd7cddfSDavid du Colombier code = gs_error_VMerror;
31527dd7cddfSDavid du Colombier sd->stc.escp_init.size = 0;
31537dd7cddfSDavid du Colombier } else {
31547dd7cddfSDavid du Colombier memcpy(ip,sd->stc.escp_init.data,sd->stc.escp_init.size);
31557dd7cddfSDavid du Colombier }
31567dd7cddfSDavid du Colombier }
31577dd7cddfSDavid du Colombier sd->stc.escp_init.data = ip;
31587dd7cddfSDavid du Colombier sd->stc.escp_init.persistent = false;
31597dd7cddfSDavid du Colombier }
31607dd7cddfSDavid du Colombier
31617dd7cddfSDavid du Colombier if(sd->stc.escp_release.data != oldstc.escp_release.data) {
31627dd7cddfSDavid du Colombier byte *ip = NULL;
31637dd7cddfSDavid du Colombier
31647dd7cddfSDavid du Colombier if(sd->stc.escp_release.size > 0) {
3165*593dc095SDavid du Colombier ip = gs_malloc(sd->memory, sd->stc.escp_release.size,1,"stcolor/release");
31667dd7cddfSDavid du Colombier if(ip == NULL) {
31677dd7cddfSDavid du Colombier code = gs_error_VMerror;
31687dd7cddfSDavid du Colombier sd->stc.escp_release.size = 0;
31697dd7cddfSDavid du Colombier } else {
31707dd7cddfSDavid du Colombier memcpy(ip,sd->stc.escp_release.data,sd->stc.escp_release.size);
31717dd7cddfSDavid du Colombier }
31727dd7cddfSDavid du Colombier }
31737dd7cddfSDavid du Colombier sd->stc.escp_release.data = ip;
31747dd7cddfSDavid du Colombier sd->stc.escp_release.persistent = false;
31757dd7cddfSDavid du Colombier }
31767dd7cddfSDavid du Colombier
31777dd7cddfSDavid du Colombier if(code < 0) { /* free newly allocated arrays */
31787dd7cddfSDavid du Colombier
31797dd7cddfSDavid du Colombier if((sd->stc.am != NULL) && (sd->stc.am != oldstc.am)) {
31807dd7cddfSDavid du Colombier if( sd->color_info.num_components == 1) i = 3;
31817dd7cddfSDavid du Colombier else if(sd->color_info.num_components == 3) i = 9;
31827dd7cddfSDavid du Colombier else i = 16;
3183*593dc095SDavid du Colombier gs_free(sd->memory, sd->stc.am,i,sizeof(float),"stc_put_params");
31847dd7cddfSDavid du Colombier }
31857dd7cddfSDavid du Colombier
31867dd7cddfSDavid du Colombier if((sd->stc.escp_init.data != NULL) &&
31877dd7cddfSDavid du Colombier (sd->stc.escp_init.data != oldstc.escp_init.data))
3188*593dc095SDavid du Colombier gs_free(sd->memory, (byte *) sd->stc.escp_init.data,sd->stc.escp_init.size,1,
31897dd7cddfSDavid du Colombier "stcolor/init");
31907dd7cddfSDavid du Colombier
31917dd7cddfSDavid du Colombier if((sd->stc.escp_release.data != NULL) &&
31927dd7cddfSDavid du Colombier (sd->stc.escp_release.data != oldstc.escp_release.data))
3193*593dc095SDavid du Colombier gs_free(sd->memory, (byte *) sd->stc.escp_release.data,sd->stc.escp_release.
31947dd7cddfSDavid du Colombier size,1,"stcolor/release");
31957dd7cddfSDavid du Colombier
31967dd7cddfSDavid du Colombier for(i = 0; i < sd->color_info.num_components; ++i) { /* components */
31977dd7cddfSDavid du Colombier int j;
31987dd7cddfSDavid du Colombier
31997dd7cddfSDavid du Colombier if((sd->stc.extc[i] != NULL) &&
32007dd7cddfSDavid du Colombier (sd->stc.extc[i] != defext) &&
32017dd7cddfSDavid du Colombier (sd->stc.extc[i] != oldstc.extc[i])) {
32027dd7cddfSDavid du Colombier
32037dd7cddfSDavid du Colombier for(j = 0; j < i; ++j)
32047dd7cddfSDavid du Colombier if(sd->stc.extc[i] == sd->stc.extc[j]) break;
32057dd7cddfSDavid du Colombier
3206*593dc095SDavid du Colombier if(i == j) gs_free(sd->memory, sd->stc.extc[i],sd->stc.sizc[i],sizeof(float),
32077dd7cddfSDavid du Colombier "stc_put_params");
32087dd7cddfSDavid du Colombier }
32097dd7cddfSDavid du Colombier
32107dd7cddfSDavid du Colombier if((sd->stc.extv[i] != NULL) &&
32117dd7cddfSDavid du Colombier (sd->stc.extv[i] != oldstc.extv[i]) &&
32127dd7cddfSDavid du Colombier (sd->stc.extv[i] != defext)) {
32137dd7cddfSDavid du Colombier
32147dd7cddfSDavid du Colombier for(j = 0; j < i; ++j)
32157dd7cddfSDavid du Colombier if(sd->stc.extv[i] == sd->stc.extv[j]) break;
32167dd7cddfSDavid du Colombier
3217*593dc095SDavid du Colombier if(i == j) gs_free(sd->memory, sd->stc.extv[i],sd->stc.sizv[i],sizeof(float),
32187dd7cddfSDavid du Colombier "stc_put_params");
32197dd7cddfSDavid du Colombier }
32207dd7cddfSDavid du Colombier } /* components */
32217dd7cddfSDavid du Colombier } /* free newly allocated arrays */
32227dd7cddfSDavid du Colombier } /* Allocate new arrays */
32237dd7cddfSDavid du Colombier error = error > code ? code : error;
32247dd7cddfSDavid du Colombier
32257dd7cddfSDavid du Colombier /*
32267dd7cddfSDavid du Colombier * finally decide upon restore or release of old, unused data
32277dd7cddfSDavid du Colombier */
32287dd7cddfSDavid du Colombier if(error != 0) { /* Undo changes */
32297dd7cddfSDavid du Colombier
32307dd7cddfSDavid du Colombier memcpy(&sd->color_info,&oldcolor,sizeof(oldcolor));
32317dd7cddfSDavid du Colombier memcpy(&sd->stc ,&oldstc ,sizeof(oldstc ));
32327dd7cddfSDavid du Colombier } else { /* undo / release */
32337dd7cddfSDavid du Colombier
32347dd7cddfSDavid du Colombier if((oldstc.escp_init.data != NULL) &&
32357dd7cddfSDavid du Colombier (oldstc.escp_init.data != sd->stc.escp_init.data)) {
3236*593dc095SDavid du Colombier gs_free(sd->memory, (byte *)oldstc.escp_init.data,
32377dd7cddfSDavid du Colombier oldstc.escp_init.size,1,"stcolor/init");
32387dd7cddfSDavid du Colombier }
32397dd7cddfSDavid du Colombier
32407dd7cddfSDavid du Colombier if((oldstc.escp_release.data != NULL) &&
32417dd7cddfSDavid du Colombier (oldstc.escp_release.data != sd->stc.escp_release.data)) {
3242*593dc095SDavid du Colombier gs_free(sd->memory, (byte *)oldstc.escp_release.data,
32437dd7cddfSDavid du Colombier oldstc.escp_release.size,1,"stcolor/release");
32447dd7cddfSDavid du Colombier }
32457dd7cddfSDavid du Colombier
32467dd7cddfSDavid du Colombier if((oldstc.am != NULL) && (oldstc.am != sd->stc.am)) {
32477dd7cddfSDavid du Colombier if( oldcolor.num_components == 1) i = 3;
32487dd7cddfSDavid du Colombier else if(oldcolor.num_components == 3) i = 9;
32497dd7cddfSDavid du Colombier else i = 16;
3250*593dc095SDavid du Colombier gs_free(sd->memory, oldstc.am,i,sizeof(float),"stc_put_params");
32517dd7cddfSDavid du Colombier }
32527dd7cddfSDavid du Colombier
32537dd7cddfSDavid du Colombier for(i = 0; i < 4; ++i) {
32547dd7cddfSDavid du Colombier int j;
32557dd7cddfSDavid du Colombier
32567dd7cddfSDavid du Colombier if((oldstc.extc[i] != NULL) &&
32577dd7cddfSDavid du Colombier (oldstc.extc[i] != sd->stc.extc[i]) &&
32587dd7cddfSDavid du Colombier (oldstc.dither != NULL) &&
32597dd7cddfSDavid du Colombier (oldstc.extc[i] != defext)) {
32607dd7cddfSDavid du Colombier
32617dd7cddfSDavid du Colombier for(j = 0; j < i; ++j) if(oldstc.extc[i] == oldstc.extc[j]) break;
32627dd7cddfSDavid du Colombier
3263*593dc095SDavid du Colombier if(i == j) gs_free(sd->memory, oldstc.extc[i],oldstc.sizc[i],sizeof(float),
32647dd7cddfSDavid du Colombier "stc_put_params");
32657dd7cddfSDavid du Colombier }
32667dd7cddfSDavid du Colombier
32677dd7cddfSDavid du Colombier if((oldstc.extv[i] != NULL) &&
32687dd7cddfSDavid du Colombier (oldstc.extv[i] != sd->stc.extv[i]) &&
32697dd7cddfSDavid du Colombier (oldstc.extv[i] != defext)) {
32707dd7cddfSDavid du Colombier
32717dd7cddfSDavid du Colombier for(j = 0; j < i; ++j) if(oldstc.extv[i] == oldstc.extv[j]) break;
32727dd7cddfSDavid du Colombier
3273*593dc095SDavid du Colombier if(i == j) gs_free(sd->memory, oldstc.extv[i],oldstc.sizv[i],sizeof(float),
32747dd7cddfSDavid du Colombier "stc_put_params");
32757dd7cddfSDavid du Colombier }
32767dd7cddfSDavid du Colombier }
32777dd7cddfSDavid du Colombier
32787dd7cddfSDavid du Colombier /*
32797dd7cddfSDavid du Colombier * Close the device if colormodel changed or recomputation
32807dd7cddfSDavid du Colombier * of internal arrays is required
32817dd7cddfSDavid du Colombier */
32827dd7cddfSDavid du Colombier if(sd->is_open) { /* we might need to close it */
32837dd7cddfSDavid du Colombier bool doclose = false;
32847dd7cddfSDavid du Colombier if((sd->color_info.num_components != oldcolor.num_components) ||
32857dd7cddfSDavid du Colombier (sd->color_info.depth != oldcolor.depth ) ||
32867dd7cddfSDavid du Colombier (sd->stc.bits != oldstc.bits ) ||
32877dd7cddfSDavid du Colombier (sd->stc.dither != oldstc.dither ))
32887dd7cddfSDavid du Colombier doclose = true;
32897dd7cddfSDavid du Colombier
32907dd7cddfSDavid du Colombier for(i = 0; i < sd->color_info.num_components; ++i) {
32917dd7cddfSDavid du Colombier if(sd->stc.extv[i] != oldstc.extv[i]) doclose = true;
32927dd7cddfSDavid du Colombier if(sd->stc.extc[i] != oldstc.extc[i]) doclose = true;
32937dd7cddfSDavid du Colombier }
32947dd7cddfSDavid du Colombier if(doclose) {
3295*593dc095SDavid du Colombier stc_freedata(pdev->memory, &oldstc);
32967dd7cddfSDavid du Colombier for(i = 0; i < 4; ++i) {
32977dd7cddfSDavid du Colombier sd->stc.vals[i] = NULL;
32987dd7cddfSDavid du Colombier sd->stc.code[i] = NULL;
32997dd7cddfSDavid du Colombier }
33007dd7cddfSDavid du Colombier
33017dd7cddfSDavid du Colombier gs_closedevice(pdev);
33027dd7cddfSDavid du Colombier }
33037dd7cddfSDavid du Colombier } /* we might need to close it */
33047dd7cddfSDavid du Colombier
33057dd7cddfSDavid du Colombier }
33067dd7cddfSDavid du Colombier
33077dd7cddfSDavid du Colombier return error;
33087dd7cddfSDavid du Colombier }
33097dd7cddfSDavid du Colombier /*
33107dd7cddfSDavid du Colombier * 1Bit CMYK-Algorithm
33117dd7cddfSDavid du Colombier */
33127dd7cddfSDavid du Colombier
33137dd7cddfSDavid du Colombier private int
stc_gscmyk(stcolor_device * sdev,int npixel,byte * in,byte * buf,byte * out)33147dd7cddfSDavid du Colombier stc_gscmyk(stcolor_device *sdev,int npixel,byte *in,byte *buf,byte *out)
33157dd7cddfSDavid du Colombier {
33167dd7cddfSDavid du Colombier
33177dd7cddfSDavid du Colombier byte *ip = in;
33187dd7cddfSDavid du Colombier int error = 0;
33197dd7cddfSDavid du Colombier
33207dd7cddfSDavid du Colombier
33217dd7cddfSDavid du Colombier /* ============================================================= */
33227dd7cddfSDavid du Colombier if(npixel > 0) { /* npixel > 0 -> scanline-processing */
33237dd7cddfSDavid du Colombier /* ============================================================= */
33247dd7cddfSDavid du Colombier
33257dd7cddfSDavid du Colombier int p;
33267dd7cddfSDavid du Colombier
33277dd7cddfSDavid du Colombier /*
33287dd7cddfSDavid du Colombier * simply split the two pixels rsiding in a byte
33297dd7cddfSDavid du Colombier */
33307dd7cddfSDavid du Colombier for(p = npixel; p > 0; --p) { /* loop over pixels */
33317dd7cddfSDavid du Colombier byte tmp =*ip++;
33327dd7cddfSDavid du Colombier
33337dd7cddfSDavid du Colombier *out++ = (tmp>>4) & 15;
33347dd7cddfSDavid du Colombier if(--p <= 0) break;
33357dd7cddfSDavid du Colombier
33367dd7cddfSDavid du Colombier *out++ = tmp & 15;
33377dd7cddfSDavid du Colombier
33387dd7cddfSDavid du Colombier } /* loop over pixels */
33397dd7cddfSDavid du Colombier
33407dd7cddfSDavid du Colombier /* ============================================================= */
33417dd7cddfSDavid du Colombier } else { /* npixel <= 0 -> initialisation */
33427dd7cddfSDavid du Colombier /* ============================================================= */
33437dd7cddfSDavid du Colombier
33447dd7cddfSDavid du Colombier /* we didn't check for the white-calls above, so this may cause errors */
33457dd7cddfSDavid du Colombier if(sdev->stc.dither->flags & STC_WHITE) error = -1;
33467dd7cddfSDavid du Colombier
33477dd7cddfSDavid du Colombier /* if we're not setup for bytes, this is an error too */
33487dd7cddfSDavid du Colombier if((sdev->stc.dither->flags & STC_TYPE) != STC_BYTE) error = -2;
33497dd7cddfSDavid du Colombier
33507dd7cddfSDavid du Colombier /* This IS a direct-driver, so STC_DIRECT must be set! */
33517dd7cddfSDavid du Colombier if((sdev->stc.dither->flags & STC_DIRECT) == 0) error = -3;
33527dd7cddfSDavid du Colombier
33537dd7cddfSDavid du Colombier /* and cmyk-mode is the only supported mode */
33547dd7cddfSDavid du Colombier if(sdev->color_info.num_components != 4) error = -4;
33557dd7cddfSDavid du Colombier
33567dd7cddfSDavid du Colombier /* and we support only 4Bit-Depth here */
33577dd7cddfSDavid du Colombier if(sdev->color_info.depth != 4) error = -5;
33587dd7cddfSDavid du Colombier
33597dd7cddfSDavid du Colombier /* ============================================================= */
33607dd7cddfSDavid du Colombier } /* scanline-processing or initialisation */
33617dd7cddfSDavid du Colombier /* ============================================================= */
33627dd7cddfSDavid du Colombier
33637dd7cddfSDavid du Colombier return error;
33647dd7cddfSDavid du Colombier }
33657dd7cddfSDavid du Colombier
33667dd7cddfSDavid du Colombier /*
33677dd7cddfSDavid du Colombier * The following is an algorithm under test
33687dd7cddfSDavid du Colombier */
33697dd7cddfSDavid du Colombier private int
stc_hscmyk(stcolor_device * sdev,int npixel,byte * in,byte * buf,byte * out)33707dd7cddfSDavid du Colombier stc_hscmyk(stcolor_device *sdev,int npixel,byte *in,byte *buf,byte *out)
33717dd7cddfSDavid du Colombier {
33727dd7cddfSDavid du Colombier
33737dd7cddfSDavid du Colombier /* ============================================================= */
33747dd7cddfSDavid du Colombier if(npixel < 0) { /* npixel <= 0 -> initialisation */
33757dd7cddfSDavid du Colombier /* ============================================================= */
33767dd7cddfSDavid du Colombier
33777dd7cddfSDavid du Colombier int i,i2do;
33787dd7cddfSDavid du Colombier long *lp = (long *) buf;
33797dd7cddfSDavid du Colombier
33807dd7cddfSDavid du Colombier /* CMYK-only algorithm */
33817dd7cddfSDavid du Colombier if( sdev->color_info.num_components != 4) return -1;
33827dd7cddfSDavid du Colombier
33837dd7cddfSDavid du Colombier /*
33847dd7cddfSDavid du Colombier * check wether stcdither & TYPE are correct
33857dd7cddfSDavid du Colombier */
33867dd7cddfSDavid du Colombier if(( sdev->stc.dither == NULL) ||
33877dd7cddfSDavid du Colombier ((sdev->stc.dither->flags & STC_TYPE) != STC_LONG)) return -2;
33887dd7cddfSDavid du Colombier
33897dd7cddfSDavid du Colombier /*
33907dd7cddfSDavid du Colombier * check wether the buffer-size is sufficiently large
33917dd7cddfSDavid du Colombier */
33927dd7cddfSDavid du Colombier if(((sdev->stc.dither->flags/STC_SCAN) < 1) ||
33937dd7cddfSDavid du Colombier ( sdev->stc.dither->bufadd <
33947dd7cddfSDavid du Colombier (1 + 2*sdev->color_info.num_components))) return -3;
33957dd7cddfSDavid du Colombier
33967dd7cddfSDavid du Colombier /*
33977dd7cddfSDavid du Colombier * must have STC_CMYK10, STC_DIRECT, but not STC_WHITE
33987dd7cddfSDavid du Colombier */
33997dd7cddfSDavid du Colombier if((sdev->stc.dither->flags & STC_CMYK10) == 0) return -4;
34007dd7cddfSDavid du Colombier if((sdev->stc.dither->flags & STC_DIRECT) == 0) return -5;
34017dd7cddfSDavid du Colombier if((sdev->stc.dither->flags & STC_WHITE ) != 0) return -6;
34027dd7cddfSDavid du Colombier
34037dd7cddfSDavid du Colombier /*
34047dd7cddfSDavid du Colombier * Must have values between 0-1023.0
34057dd7cddfSDavid du Colombier */
34067dd7cddfSDavid du Colombier if((sdev->stc.dither->minmax[0] != 0.0) ||
34077dd7cddfSDavid du Colombier (sdev->stc.dither->minmax[1] != 1023.0)) return -7;
34087dd7cddfSDavid du Colombier /*
34097dd7cddfSDavid du Colombier * initialize buffer
34107dd7cddfSDavid du Colombier */
34117dd7cddfSDavid du Colombier
34127dd7cddfSDavid du Colombier i2do = 1 + 8 - 4 * npixel;
34137dd7cddfSDavid du Colombier lp[0] = 0;
34147dd7cddfSDavid du Colombier
34157dd7cddfSDavid du Colombier if(sdev->stc.flags & STCDFLAG0) {
34167dd7cddfSDavid du Colombier for(i = 1; i < i2do; ++i) lp[i] = 0;
34177dd7cddfSDavid du Colombier } else {
34187dd7cddfSDavid du Colombier for(i = 1; i < i2do; ++i) lp[i] = (rand() % 381) - 190;
34197dd7cddfSDavid du Colombier }
34207dd7cddfSDavid du Colombier
34217dd7cddfSDavid du Colombier /* ============================================================= */
34227dd7cddfSDavid du Colombier } else { /* npixel > 0 && in != NULL -> scanline-processing */
34237dd7cddfSDavid du Colombier /* ============================================================= */
34247dd7cddfSDavid du Colombier
34257dd7cddfSDavid du Colombier long errc[4],*errv;
34267dd7cddfSDavid du Colombier int step = buf[0] ? -1 : 1;
34277dd7cddfSDavid du Colombier stc_pixel *ip = (stc_pixel *) in;
34287dd7cddfSDavid du Colombier
34297dd7cddfSDavid du Colombier buf[0] = ~ buf[0];
34307dd7cddfSDavid du Colombier errv = (long *) buf + 5;
34317dd7cddfSDavid du Colombier
34327dd7cddfSDavid du Colombier if(step < 0) {
34337dd7cddfSDavid du Colombier ip += npixel-1;
34347dd7cddfSDavid du Colombier out += npixel-1;
34357dd7cddfSDavid du Colombier errv += 4*(npixel-1);
34367dd7cddfSDavid du Colombier }
34377dd7cddfSDavid du Colombier
34387dd7cddfSDavid du Colombier errc[0] = 0; errc[1] = 0; errc[2] = 0; errc[3] = 0;
34397dd7cddfSDavid du Colombier
34407dd7cddfSDavid du Colombier while(npixel-- > 0) {
34417dd7cddfSDavid du Colombier
34427dd7cddfSDavid du Colombier register stc_pixel ci,mode;
34437dd7cddfSDavid du Colombier register long k,v,n;
34447dd7cddfSDavid du Colombier register int pixel; /* internal pixel-value */
34457dd7cddfSDavid du Colombier
34467dd7cddfSDavid du Colombier ci = *ip; ip += step;
34477dd7cddfSDavid du Colombier
34487dd7cddfSDavid du Colombier mode = ci & 3;
34497dd7cddfSDavid du Colombier k = (ci>>2) & 0x3ff;
34507dd7cddfSDavid du Colombier pixel = 0;
34517dd7cddfSDavid du Colombier
34527dd7cddfSDavid du Colombier v = k+errv[3]+((7*errc[3])>>4);
34537dd7cddfSDavid du Colombier
34547dd7cddfSDavid du Colombier if(mode == 3) { /* only Black allowed to fire */
34557dd7cddfSDavid du Colombier
34567dd7cddfSDavid du Colombier if(v > 511) {
34577dd7cddfSDavid du Colombier v -= 1023;
34587dd7cddfSDavid du Colombier pixel = BLACK;
34597dd7cddfSDavid du Colombier }
34607dd7cddfSDavid du Colombier errv[3-(step<<2)] += ((3*v+8)>>4); /* 3/16 */
34617dd7cddfSDavid du Colombier errv[3] = ((5*v+errc[3]+8)>>4);/* 5/16 +1/16 (rest) */
34627dd7cddfSDavid du Colombier errc[3] = v;
34637dd7cddfSDavid du Colombier
34647dd7cddfSDavid du Colombier errv[0] = errv[0] < -190 ? -190 : errv[0] < 190 ? errv[0] : 190;
34657dd7cddfSDavid du Colombier errv[1] = errv[1] < -190 ? -190 : errv[1] < 190 ? errv[1] : 190;
34667dd7cddfSDavid du Colombier errv[2] = errv[2] < -190 ? -190 : errv[2] < 190 ? errv[2] : 190;
34677dd7cddfSDavid du Colombier
34687dd7cddfSDavid du Colombier errc[0] = 0; errc[1] = 0; errc[2] = 0;
34697dd7cddfSDavid du Colombier
34707dd7cddfSDavid du Colombier } else if(v > 511) { /* black known to fire */
34717dd7cddfSDavid du Colombier
34727dd7cddfSDavid du Colombier v -= 1023;
34737dd7cddfSDavid du Colombier pixel = BLACK;
34747dd7cddfSDavid du Colombier
34757dd7cddfSDavid du Colombier errv[3-(step<<2)] += ((3*v+8)>>4); /* 3/16 */
34767dd7cddfSDavid du Colombier errv[3] = ((5*v+errc[3]+8)>>4);/* 5/16 +1/16 (rest) */
34777dd7cddfSDavid du Colombier errc[3] = v;
34787dd7cddfSDavid du Colombier
34797dd7cddfSDavid du Colombier n = (ci>>12) & 0x3ff;
34807dd7cddfSDavid du Colombier
34817dd7cddfSDavid du Colombier if(mode == 2) { v = k; }
34827dd7cddfSDavid du Colombier else { v = n; n = (ci>>22) & 0x3ff; }
34837dd7cddfSDavid du Colombier
34847dd7cddfSDavid du Colombier v += errv[2]+((7*errc[2])>>4)-1023;
34857dd7cddfSDavid du Colombier if(v < -511) v = -511;
34867dd7cddfSDavid du Colombier errv[2-(step<<2)] += ((3*v+8)>>4); /* 3/16 */
34877dd7cddfSDavid du Colombier errv[2] = ((5*v+errc[2]+8)>>4);/* 5/16 +1/16 (rest) */
34887dd7cddfSDavid du Colombier errc[2] = v;
34897dd7cddfSDavid du Colombier
34907dd7cddfSDavid du Colombier if(mode == 1) { v = k; }
34917dd7cddfSDavid du Colombier else { v = n; n = (ci>>22) & 0x3ff; }
34927dd7cddfSDavid du Colombier
34937dd7cddfSDavid du Colombier v += errv[1]+((7*errc[1])>>4)-1023;
34947dd7cddfSDavid du Colombier if(v < -511) v = -511;
34957dd7cddfSDavid du Colombier errv[1-(step<<2)] += ((3*v+8)>>4); /* 3/16 */
34967dd7cddfSDavid du Colombier errv[1] = ((5*v+errc[1]+8)>>4);/* 5/16 +1/16 (rest) */
34977dd7cddfSDavid du Colombier errc[1] = v;
34987dd7cddfSDavid du Colombier
34997dd7cddfSDavid du Colombier if(mode == 0) v = k;
35007dd7cddfSDavid du Colombier else v = n;
35017dd7cddfSDavid du Colombier
35027dd7cddfSDavid du Colombier v += errv[0]+((7*errc[0])>>4)-1023;
35037dd7cddfSDavid du Colombier if(v < -511) v = -511;
35047dd7cddfSDavid du Colombier errv[0-(step<<2)] += ((3*v+8)>>4); /* 3/16 */
35057dd7cddfSDavid du Colombier errv[0] = ((5*v+errc[0]+8)>>4);/* 5/16 +1/16 (rest) */
35067dd7cddfSDavid du Colombier errc[0] = v;
35077dd7cddfSDavid du Colombier
35087dd7cddfSDavid du Colombier } else { /* Black does not fire initially */
35097dd7cddfSDavid du Colombier
35107dd7cddfSDavid du Colombier long kv = v; /* Black computed after colors */
35117dd7cddfSDavid du Colombier
35127dd7cddfSDavid du Colombier n = (ci>>12) & 0x3ff;
35137dd7cddfSDavid du Colombier
35147dd7cddfSDavid du Colombier if(mode == 2) { v = k; }
35157dd7cddfSDavid du Colombier else { v = n; n = (ci>>22) & 0x3ff; }
35167dd7cddfSDavid du Colombier
35177dd7cddfSDavid du Colombier v += errv[2]+((7*errc[2])>>4);
35187dd7cddfSDavid du Colombier if(v > 511) {
35197dd7cddfSDavid du Colombier pixel |= YELLOW;
35207dd7cddfSDavid du Colombier v -= 1023;
35217dd7cddfSDavid du Colombier }
35227dd7cddfSDavid du Colombier errv[2-(step<<2)] += ((3*v+8)>>4); /* 3/16 */
35237dd7cddfSDavid du Colombier errv[2] = ((5*v+errc[2]+8)>>4);/* 5/16 +1/16 (rest) */
35247dd7cddfSDavid du Colombier errc[2] = v;
35257dd7cddfSDavid du Colombier
35267dd7cddfSDavid du Colombier if(mode == 1) { v = k; }
35277dd7cddfSDavid du Colombier else { v = n; n = (ci>>22) & 0x3ff; }
35287dd7cddfSDavid du Colombier
35297dd7cddfSDavid du Colombier v += errv[1]+((7*errc[1])>>4);
35307dd7cddfSDavid du Colombier if(v > 511) {
35317dd7cddfSDavid du Colombier pixel |= MAGENTA;
35327dd7cddfSDavid du Colombier v -= 1023;
35337dd7cddfSDavid du Colombier }
35347dd7cddfSDavid du Colombier errv[1-(step<<2)] += ((3*v+8)>>4); /* 3/16 */
35357dd7cddfSDavid du Colombier errv[1] = ((5*v+errc[1]+8)>>4);/* 5/16 +1/16 (rest) */
35367dd7cddfSDavid du Colombier errc[1] = v;
35377dd7cddfSDavid du Colombier
35387dd7cddfSDavid du Colombier if(mode == 0) v = k;
35397dd7cddfSDavid du Colombier else v = n;
35407dd7cddfSDavid du Colombier
35417dd7cddfSDavid du Colombier v += errv[0]+((7*errc[0])>>4);
35427dd7cddfSDavid du Colombier if(v > 511) {
35437dd7cddfSDavid du Colombier pixel |= CYAN;
35447dd7cddfSDavid du Colombier v -= 1023;
35457dd7cddfSDavid du Colombier }
35467dd7cddfSDavid du Colombier errv[0-(step<<2)] += ((3*v+8)>>4); /* 3/16 */
35477dd7cddfSDavid du Colombier errv[0] = ((5*v+errc[0]+8)>>4);/* 5/16 +1/16 (rest) */
35487dd7cddfSDavid du Colombier errc[0] = v;
35497dd7cddfSDavid du Colombier
35507dd7cddfSDavid du Colombier v = kv;
35517dd7cddfSDavid du Colombier if(pixel == (CYAN|MAGENTA|YELLOW)) {
35527dd7cddfSDavid du Colombier pixel = BLACK;
35537dd7cddfSDavid du Colombier v = v > 511 ? v-1023 : -511;
35547dd7cddfSDavid du Colombier }
35557dd7cddfSDavid du Colombier errv[3-(step<<2)] += ((3*v+8)>>4); /* 3/16 */
35567dd7cddfSDavid du Colombier errv[3] = ((5*v+errc[3]+8)>>4);/* 5/16 +1/16 (rest) */
35577dd7cddfSDavid du Colombier errc[3] = v;
35587dd7cddfSDavid du Colombier
35597dd7cddfSDavid du Colombier }
35607dd7cddfSDavid du Colombier
35617dd7cddfSDavid du Colombier errv += step<<2;
35627dd7cddfSDavid du Colombier *out = pixel; out += step;
35637dd7cddfSDavid du Colombier
35647dd7cddfSDavid du Colombier } /* loop over pixels */
35657dd7cddfSDavid du Colombier
35667dd7cddfSDavid du Colombier /* ============================================================= */
35677dd7cddfSDavid du Colombier } /* initialisation, white or scanline-processing */
35687dd7cddfSDavid du Colombier /* ============================================================= */
35697dd7cddfSDavid du Colombier
35707dd7cddfSDavid du Colombier return 0;
35717dd7cddfSDavid du Colombier }
3572