1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571 |
- /* Copyright (C) 1995, 1996 Aladdin Enterprises. All rights reserved.
-
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied,
- modified or distributed except as expressly authorized under the terms
- of the license contained in the file LICENSE in this distribution.
-
- For more information about licensing, please refer to
- http://www.ghostscript.com/licensing/. For information on
- commercial licensing, go to http://www.artifex.com/licensing/ or
- contact Artifex Software, Inc., 101 Lucas Valley Road #110,
- San Rafael, CA 94903, U.S.A., +1(415)492-9861.
- */
- /* $Id: gdevstc.c,v 1.11 2004/11/22 19:25:57 giles Exp $*/
- /* Epson Stylus-Color Printer-Driver */
- /***
- *** This file was "copied" from gdevcdj.c (ghostscript-3.12), which was
- *** contributed by:
- *** George Cameron - g.cameron@biomed.abdn.ac.ukis
- *** Koert Zeilstra - koert@zen.cais.com
- *** Eckhard Rueggeberg - eckhard@ts.go.dlr.de
- ***
- *** Some of the ESC/P2-code was drawn from gdevescp.c, contributed by
- *** Richard Brown - rab@eos.ncsu.edu
- ***
- *** The POSIX-Interrupt-Code is from (Compile-Time-Option -DSTC_SIGNAL)
- *** Frederic Loyer - loyer@ensta.fr
- ***
- *** And several improvements are based on discussions with
- *** Brian Converse - BCONVERSE@ids.net
- *** Bill Davidson - bdavidson@ra.isisnet.com
- *** Gero Guenther - gero@cs.tu-berlin.de
- *** Jason Patterson - jason@reflections.com.au
- *** ? Rueschstroer - rue@ibe.med.uni-muenchen.de
- *** Steven Singer - S.Singer@ph.surrey.ac.uk
- ***
- *** And the remaining little rest, mainly the bugs, were written by me:
- *** Gunther Hess - gunther@elmos.de
- ***
- *** P.S.: there is some documentation, see devices.doc
- ***
- *** Revision-History:
- *** 16-DEC-1994 1.1 - initial Version (GS-Dithering & Plain-Write)
- ...
- *** 30-JAN-1995 1.11 - FS-Improvements, u/sWeave, 1/4/24-Bits
- *** 5-MAR-1995 1.12 - L. Peter Deutsch - updated put_params routine
- (first distributed version with gs3.33)
- *** 26-APR-1995 1.13 - merged Peters fixes with algorithmic changes:
- Changed 24Bit-Mode, added 32Bit-Mode (moves colors)
- [Arrgh: much better than 1.12, but patch was lost]
- *** 5-JUN-1995 1.14 - Added Color-Correction & Transfer-Curves
- (Several Beta-Testers, but not distributed)
- ...
- *** 24-JUL-1995 1.16 - Made dithering-Algorithms external-functions.
- (Mailed for Beta-Distribution)
- *** 10-AUG-1995 1.17 - Several Bug-Fixes and some new features:
- CMYK10-Coding added
- Readonly Parameters added
- "Algorithms", "BitsPerComponent", "Version"
- Parameters Flag0-4, Model, OutputCode
- (mailed for distribution)
- *** 14-SEP-1995 1.18 Fixes Bugs with Borland C (gs3.47)
- *** 23-SEP-1995 1.19 - reorganized printcode + bug-fixing
- *** 24-SEP-1995 1.20 - Little Cleanup for the release
- *** 25-SEP-1995 1.21 - Readonly-Parameters added to put_params.
- *** 31-Dec-1995 1.22 - Sanitary Engineering on the code
- *** 16-Jan-1996 1.23 - Added String escp_Release
- *** 8-May-1996 1.90 - Reintroduced Deltarow & Fixed MEMORY-BUG!
- ***/
- #include "gdevstc.h"
- #ifdef STC_SIGNAL
- # include <signal.h>
- #endif /* STC_SIGNAL */
- /***
- *** Mode-Table - the various algorithms
- *** (The intention is, that this source can live alone)
- ***/
- private stc_proc_dither(stc_gscmyk); /* resides in this file */
- private stc_proc_dither(stc_hscmyk); /* resides in this file */
- #include <stdlib.h> /* for rand, used in stc_hscmyk */
- private const stc_dither_t stc_dither[] = {
- {"gscmyk", stc_gscmyk, DeviceCMYK|STC_BYTE|STC_DIRECT,0,{0.0,1.0}},
- {"hscmyk", stc_hscmyk,
- DeviceCMYK|STC_LONG|STC_CMYK10|STC_DIRECT|1*STC_SCAN,1+2*4,
- {0.0, 1023.0}},
- STC_MODI
- { NULL , NULL , 0, 0,{0.0,0.0}}
- };
- /***
- *** forward-declarations of routines
- ***/
- /* Primary Device functions
- * (I've the idea to rename the driver to stc)
- */
- private dev_proc_print_page(stc_print_page);
- private dev_proc_open_device(stc_open);
- private dev_proc_close_device(stc_close);
- private dev_proc_get_params(stc_get_params);
- private dev_proc_put_params(stc_put_params);
- /*
- * Color-Mapping-functions.
- */
- /* routines for monochrome monochrome modi */
- private dev_proc_map_rgb_color(stc_map_gray_color);
- private dev_proc_map_color_rgb(stc_map_color_gray);
- /* routines for RGB-Modi */
- private dev_proc_map_rgb_color(stc_map_rgb_color);
- private dev_proc_map_color_rgb(stc_map_color_rgb);
- /* routines for general CMYK-Modi */
- private dev_proc_map_cmyk_color(stc_map_cmyk_color);
- private dev_proc_map_color_rgb(stc_map_color_cmyk);
- /* routines for 10Bit/Component CMYK */
- private dev_proc_map_cmyk_color(stc_map_cmyk10_color);
- private dev_proc_map_color_rgb(stc_map_color_cmyk10);
- /***
- *** Table of Device-Procedures
- ***/
- private gx_device_procs stcolor_procs = {
- stc_open,
- gx_default_get_initial_matrix,
- gx_default_sync_output,
- gdev_prn_output_page,
- stc_close,
- NULL,
- stc_map_color_cmyk,
- NULL, /* fill_rectangle */
- NULL, /* tile_rectangle */
- NULL, /* copy_mono */
- NULL, /* copy_color */
- NULL, /* draw_line */
- gx_default_get_bits,
- stc_get_params,
- stc_put_params,
- stc_map_cmyk_color
- };
- /***
- *** A local dummy-array for extvals
- ***/
- private float defext[] = { 0.0, 1.0 };
- /***
- *** Main device-control structure
- ***/
- stcolor_device far_data gs_stcolor_device = {
- prn_device_body(stcolor_device, stcolor_procs, "stcolor",
- DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
- X_DPI, Y_DPI,
- STC_L_MARGIN,STC_B_MARGIN,STC_R_MARGIN,STC_T_MARGIN,
- 4, 4, 1, 1, 2, 2, /* default: cmyk-direct */
- stc_print_page),
- {STCNWEAVE, /* stcflags: noWeave/bidirectional */
- 1, /* stcbits: matches the default */
- stc_dither, /* stcdither: first algorithm */
- NULL, /* stcam: NULL -> not used */
- { NULL, NULL, NULL, NULL}, /* extcode: none defined yet */
- { 0, 0, 0, 0}, /* sizcode: 0, since no extcode yet */
- { NULL, NULL, NULL, NULL}, /* stccode: computed by put_params */
- {defext,defext,defext,defext},/* extvals: default */
- { 2, 2, 2, 2}, /* sizvals: default countof(defext) */
- { NULL, NULL, NULL, NULL}, /* stcvals: computed by put_params */
- { 0, 0, 0}, /* white-run */
- { 0, 0, 0}, /* white-end */
- {NULL,0,false}, /* algorithm-table */
- {NULL,0,false}, /* initialization-String (BOP) */
- {NULL,0,false}, /* release-String (EOP) */
- 0,0,0,0, /* New escp-stuff */
- 1} /* itemsize used by algorithm */
- };
- /***
- *** Test for white scan-lines
- ***/
- private bool stc_iswhite(stcolor_device *, int, byte *);
- /***
- *** Functions used for conversion inside the print-loop
- ***/
- #define stc_proc_iconvert(Name) \
- byte * Name(stcolor_device *sd,byte *ext_data,int prt_pixels,byte *alg_line)
- private stc_proc_iconvert(stc_any_depth); /* general input-conversion */
- private stc_proc_iconvert(stc_rgb24_long); /* 24Bit RGB -> long's */
- private stc_proc_iconvert(stc_cmyk32_long); /* 32Bit CMYK -> long's */
- private stc_proc_iconvert(stc_any_direct); /* use ext_data as input */
- private stc_proc_iconvert(stc_cmyk10_byte); /* CMYK10->vals-> any type */
- private stc_proc_iconvert(stc_cmyk10_long); /* CMYK10->vals-> any type */
- private stc_proc_iconvert(stc_cmyk10_float); /* CMYK10->vals-> any type */
- private stc_proc_iconvert(stc_cmyk10_dbyte); /* CMYK10 direct bytes */
- private stc_proc_iconvert(stc_cmyk10_dlong); /* CMYK10 direct longs */
- /***
- *** Print-functions
- ***/
- private void stc_print_weave(stcolor_device *sd,FILE *prn_stream);
- private void stc_print_bands(stcolor_device *sd,FILE *prn_stream);
- private void stc_print_delta(stcolor_device *sd,FILE *prn_stream);
- private int stc_print_setup(stcolor_device *sd);
- /***
- *** compute the ESC/P2 specific values
- ***/
- private int
- stc_print_setup(stcolor_device *sd)
- {
- /*
- * Compute the resolution-parameters
- */
- sd->stc.escp_u = (int)(3600.0 / sd->y_pixels_per_inch); /* y-units */
- sd->stc.escp_h = (int)(3600.0 / sd->x_pixels_per_inch); /* x-units */
- sd->stc.escp_v = sd->stc.flags & (STCUWEAVE | STCNWEAVE) ?
- sd->stc.escp_u : 40;
- /*
- * Initialize color
- */
- sd->stc.escp_c = 0; /* preselect-black */
- /*
- * Band-Width
- */
- if((sd->stc.flags & STCBAND) == 0) {
- if(sd->stc.escp_v != sd->stc.escp_u) sd->stc.escp_m = 15;
- else if(STCSTCII == (sd->stc.flags & STCMODEL)) sd->stc.escp_m = 1;
- else if( sd->stc.flags & STCUWEAVE) sd->stc.escp_m = 1;
- else if((sd->stc.escp_v == sd->stc.escp_u) &&
- (sd->stc.escp_u == 5)) sd->stc.escp_m = 1;
- else sd->stc.escp_m = 1;
- }
- /*
- * Page-Dimensions
- */
- if((sd->stc.flags & STCWIDTH ) == 0)
- sd->stc.escp_width = (int)(sd->width -
- (dev_l_margin(sd)+dev_r_margin(sd))*sd->x_pixels_per_inch);
- if((sd->stc.flags & STCHEIGHT) == 0)
- sd->stc.escp_height = sd->height;
- if((sd->stc.flags & STCTOP) == 0)
- sd->stc.escp_top = (int)(dev_t_margin(sd)*sd->y_pixels_per_inch);
- if((sd->stc.flags & STCBOTTOM) == 0)
- sd->stc.escp_bottom = (int)(sd->height -
- dev_b_margin(sd)*sd->y_pixels_per_inch);
- if((sd->stc.flags & STCINIT) == 0) { /* No Initialization-String defined */
- int need = 8 /* Reset, Graphics-Mode 1 */
- + 6 /* MicroWeave */
- + 6 /* Select Units */
- + 7 /* Set Page-Length */
- + 9 /* Set Margins */
- + 3; /* Select Unidirectionality */
- byte *bp = (byte *) (sd->stc.escp_init.data);
- if(need != sd->stc.escp_init.size) { /* Reallocate */
- if(NULL != (bp = gs_malloc(sd->memory, need,1,"stcolor/init"))) { /* Replace */
- if(0 != sd->stc.escp_init.size)
- gs_free(sd->memory, (byte *)sd->stc.escp_init.data,sd->stc.escp_init.size,1,
- "stcolor/init");
- sd->stc.escp_init.data = bp;
- sd->stc.escp_init.size = need;
- sd->stc.escp_init.persistent = false;
- } else { /* Replace */
- return_error(gs_error_VMerror);
- }
- }
- if(need != 39) return_error(gs_error_unregistered);
- memcpy(bp,
- /* 1 1 11 1 11 1 1 1 2 22 2 2 22 2 22 3 3 3333 3 33*/
- /* 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*/
- "\033@\033(G\001\0\1\033(i\1\0w\033(U\001\000u\033(C\2\000hh\033(c\4\000ttbb\033U",
- need);
- if((sd->stc.flags & STCUWEAVE) != 0) bp[13] = '\1';
- else bp[13] = '\0';
- bp[19] = sd->stc.escp_u;
- bp[25] = sd->stc.escp_height & 0xff;
- bp[26] = (sd->stc.escp_height>>8) & 0xff;
- bp[32] = sd->stc.escp_top & 0xff;
- bp[33] = (sd->stc.escp_top>>8) & 0xff;
- bp[34] = sd->stc.escp_bottom & 0xff;
- bp[35] = (sd->stc.escp_bottom>>8) & 0xff;
- if(sd->stc.flags & STCUNIDIR) bp[38] = 1;
- else bp[38] = 0;
- } /* No Initialization-String defined */
- if((sd->stc.flags & STCRELEASE) == 0) { /* No Release-String defined */
- int need = 3; /* ESC @ \f */
- byte *bp = (byte *) (sd->stc.escp_release.data);
- if(need != sd->stc.escp_release.size) { /* Reallocate */
- if(NULL != (bp = gs_malloc(sd->memory, need,1,"stcolor/release"))) { /* Replace */
- if(0 != sd->stc.escp_release.size)
- gs_free(sd->memory, (byte *)sd->stc.escp_release.data,sd->stc.escp_release.size,1,
- "stcolor/release");
- sd->stc.escp_release.data = bp;
- sd->stc.escp_release.size = need;
- sd->stc.escp_release.persistent = false;
- } else { /* Replace */
- return_error(gs_error_VMerror);
- }
- }
- if(need != 3) return_error(gs_error_unregistered);
- memcpy(bp,"\033@\f",need);
- } /* No Release-String defined */
- return 0;
- }
- /***
- *** stc_print_page: here we go to do the nasty work
- ***/
- private int
- stc_print_page(gx_device_printer * pdev, FILE * prn_stream)
- {
- stcolor_device *sd = (stcolor_device *) pdev;
- long flags = sd == NULL ? 0 : sd->stc.flags;
- int npass; /* # of print-passes (softweave) */
- int ext_size; /* size of a ghostscript-scanline */
- byte *ext_line; /* dyn: for this scanline */
- int alg_size; /* size of a scanline for the dithering-algorithm */
- byte *alg_line; /* dyn: 1 scanline for the dithering-algorithm */
- int buf_size; /* size of the private-buffer for dither-function */
- byte *buf; /* dyn: the private buffer */
- int prt_pixels; /* Number of pixels printed */
- byte *col_line; /* A Line with a byte per pixel */
- #define OK4GO ((flags & STCOK4GO) != 0)
- #define SORRY ( flags &= ~STCOK4GO)
- if(0 > (npass = stc_print_setup(sd))) return_error(npass);
- npass = sd->stc.escp_v / sd->stc.escp_u;
- /***
- *** Allocate dynamic memory
- ***/
- ext_size = gdev_prn_raster(sd);
- ext_line = gs_malloc(sd->memory, ext_size,1,"stc_print_page/ext_line");
- if(ext_line == NULL) SORRY;
- prt_pixels = sd->stc.escp_width;
- sd->stc.prt_size = (prt_pixels+7)/8;
- prt_pixels = sd->stc.prt_size * 8;
- sd->stc.prt_scans = (int)(sd->height -
- (dev_t_margin(sd)+dev_b_margin(sd))*sd->y_pixels_per_inch);
- col_line = gs_malloc(sd->memory, prt_pixels,1,"stc_print_page/col_line");
- if(col_line == NULL) SORRY;
- alg_size = prt_pixels;
- alg_size *= sd->color_info.num_components;
- if((sd->stc.dither->flags & STC_DIRECT) ||
- ((sd->stc.bits == 8) &&
- (sd->stc.alg_item == 1))) {
- alg_line = NULL;
- } else {
- alg_line = gs_malloc(sd->memory, alg_size,sd->stc.alg_item,"stc_print_page/alg_line");
- if(alg_line == NULL) SORRY;
- }
- buf_size = sd->stc.dither->bufadd
- + alg_size*(sd->stc.dither->flags/STC_SCAN);
- if(buf_size > 0) {
- buf = gs_malloc(sd->memory, buf_size,sd->stc.alg_item,"stc_print_page/buf");
- if(buf == NULL) SORRY;
- } else {
- buf = NULL;
- }
- /*
- * compute the number of printer-buffers
- */
- for(sd->stc.prt_buf = 16; sd->stc.prt_buf < (sd->stc.escp_m * npass);
- sd->stc.prt_buf <<= 1);
- if(sd->color_info.num_components > 1) sd->stc.prt_buf *= 4;
- sd->stc.prt_width = gs_malloc(sd->memory, sd->stc.prt_buf,sizeof(int),
- "stc_print_page/prt_width");
- if(sd->stc.prt_width == NULL) SORRY;
- sd->stc.prt_data = gs_malloc(sd->memory, sd->stc.prt_buf,sizeof(byte *),
- "stc_print_page/prt_data");
- if(sd->stc.prt_data == NULL) {
- SORRY;
- } else {
- int i;
- for(i = 0; i < sd->stc.prt_buf; ++i) {
- sd->stc.prt_data[i] = gs_malloc(sd->memory, sd->stc.prt_size,1,
- "stc_print_page/prt");
- if(sd->stc.prt_data[i] == NULL) SORRY;
- }
- }
- sd->stc.seed_size = (sd->stc.prt_size + 2*sizeof(int) - 1)/sizeof(int);
- {
- int i;
- for(i = 0; i < sd->color_info.num_components; ++i) {
- if((flags & STCCOMP) == STCDELTA) {
- sd->stc.seed_row[i] = gs_malloc(sd->memory, sd->stc.seed_size,sizeof(int),
- "stc_print_page/seed_row");
- if(sd->stc.seed_row[i] == NULL) SORRY;
- else memset(sd->stc.seed_row[i],0,sd->stc.seed_size*sizeof(int));
- } else {
- sd->stc.seed_row[i] = NULL;
- }
- }
- while(i < countof(sd->stc.seed_row)) sd->stc.seed_row[i++] = NULL;
- }
- switch(flags & STCCOMP) {
- case STCPLAIN:
- sd->stc.escp_size = 64 + sd->stc.prt_size;
- break;
- case STCDELTA:
- sd->stc.escp_size = 64 + 2 * sd->stc.prt_size;
- break;
- default:
- sd->stc.escp_size = 64 +
- sd->stc.prt_size + (sd->stc.prt_size + 127)/128;
- break;
- }
- sd->stc.escp_data = gs_malloc(sd->memory, sd->stc.escp_size,1,
- "stc_print_page/escp_data");
- if(sd->stc.escp_data == NULL) SORRY;
- /*
- * If we're still ok, we can print something
- */
- if(OK4GO) {
- int ncolor;
- int buf_i;
- stc_proc_iconvert((*iconvert)) = stc_any_depth;
- /*
- * initialize col_line
- */
- if(sd->color_info.num_components == 3) {
- memset(col_line,RED|GREEN|BLUE,prt_pixels);
- } else {
- memset(col_line,0, prt_pixels);
- }
- /*
- * select proper conversion for input to algorithm
- */
- if( (sd->stc.dither->flags & STC_DIRECT ) ||
- ((sd->stc.bits == 8) &&
- (sd->stc.alg_item == 1)))
- iconvert = stc_any_direct;
- else if((sd->color_info.num_components == 3) &&
- (sd->color_info.depth == 24) &&
- (sizeof(long) == sd->stc.alg_item))
- iconvert = stc_rgb24_long;
- else if(sd->stc.flags & STCCMYK10) {
- if( ((sd->stc.dither->flags & STC_TYPE) == STC_BYTE) &&
- ( sd->stc.dither->minmax[0] == 0.0 ))
- iconvert = stc_cmyk10_dbyte;
- else if ((sd->stc.dither->flags & STC_TYPE) == STC_BYTE)
- iconvert = stc_cmyk10_byte;
- else if(((sd->stc.dither->flags & STC_TYPE) == STC_LONG) &&
- ( sd->stc.dither->minmax[0] == 0.0 ) &&
- ( sd->stc.dither->minmax[1] <= 1023.0 ))
- iconvert = stc_cmyk10_dlong;
- else if( (sd->stc.dither->flags & STC_TYPE) == STC_LONG)
- iconvert = stc_cmyk10_long;
- else
- iconvert = stc_cmyk10_float;
- }
- else if((sd->color_info.num_components == 4) &&
- (sd->color_info.depth == 32) &&
- (sizeof(long) == sd->stc.alg_item))
- iconvert = stc_cmyk32_long;
- /*
- * initialize the algorithm
- */
- if((*sd->stc.dither->fun)(sd,-prt_pixels,alg_line,buf,col_line) < 0)
- SORRY;
- /*
- * Main-Print-Loop
- */
- if(OK4GO) {
- #ifdef STC_SIGNAL
- sigset_t stc_int_mask, stc_int_save, stc_int_pending;
- sigemptyset(&stc_int_mask);
- sigaddset(&stc_int_mask,SIGINT);
- sigprocmask(SIG_BLOCK,&stc_int_mask, &stc_int_save);
- #endif /* STC_SIGNAL */
- if(sd->color_info.num_components > 1) ncolor = 4;
- else ncolor = 1;
- /*
- * Decide, wether we Adjust Linefeeds or not. (I hate it here)
- */
- if((0 == ((sd->stc.escp_m*sd->stc.escp_u) % 10)) &&
- (256 > ((sd->stc.escp_m*sd->stc.escp_u) / 10))) sd->stc.escp_lf = sd->stc.escp_m;
- else sd->stc.escp_lf = 0;
- /*
- * prepare run-values, then loop over scans
- */
- sd->stc.stc_y = 0; /* current printer y-Position */
- sd->stc.buf_y = 0; /* Top-Position within the buffer */
- sd->stc.prt_y = 0; /* physical position of the printer */
- buf_i = 0; /* next free line in buffer */
- sd->stc.flags &= ~STCPRINT; /* no data yet */
- while(sd->stc.stc_y < sd->stc.prt_scans) { /* Until all scans are processed */
- int need;
- need = sd->stc.stc_y + npass * sd->stc.escp_m;
- if(sd->stc.buf_y < need) { /* Nr. 5 (give me input) */
- /* read as much as the buffer can hold */
- if(ncolor == 1) need = sd->stc.stc_y + sd->stc.prt_buf;
- else need = sd->stc.stc_y + (sd->stc.prt_buf>>2);
- for(;sd->stc.buf_y < need;
- buf_i = (sd->stc.prt_buf-1) & (buf_i+ncolor),
- ++sd->stc.buf_y) {
- int color;
- byte *ext_data;
- byte *alg_data;
- /* initialize output data 1st -> may take shortcut */
- for(color = 0; color < ncolor; ++color) {
- memset(sd->stc.prt_data[buf_i+color],0,sd->stc.prt_size);
- sd->stc.prt_width[buf_i+color] = 0;
- }
- /* "read data", immediately continue if all is white */
- if(sd->stc.buf_y < sd->stc.prt_scans) { /* Test for White */
- gdev_prn_get_bits(pdev,sd->stc.buf_y,ext_line,&ext_data);
- color = stc_iswhite(sd,prt_pixels,ext_data) ? ext_size : 0;
- } else {
- color = ext_size;
- } /* Test for White */
- if(color >= ext_size) { /* bypass processing */
- if(sd->stc.dither->flags & STC_WHITE)
- (*sd->stc.dither->fun)(sd,prt_pixels,NULL,buf,col_line);
- continue;
- } /* bypass processing */
- /* convert data for the various cases */
- alg_data = (*iconvert)(sd,ext_data,prt_pixels,alg_line);
- /*
- * invoke the dithering-algorithm
- */
- (*sd->stc.dither->fun)(sd,prt_pixels,alg_data,buf,col_line);
- /*
- * convert col_line to printer-format (separate colors)
- */
- switch(sd->color_info.num_components) {
- case 1: /* Black & White: just merge into 8 Bytes */
- {
- byte *bytein,*byteout;
- int width;
- bytein = col_line;
- byteout = sd->stc.prt_data[buf_i];
- for(width = 1; width <= sd->stc.prt_size; ++width) {
- byte tmp = 0;
- byte i;
- for(i = 128; i; i >>= 1) if(*bytein++) tmp |= i;
- if(tmp != 0) sd->stc.prt_width[buf_i] = width;
- *byteout++ = tmp;
- }
- }
- break;
- case 3: /* convert rgb into cmyk */
- {
- byte *bytein;
- int width;
- bytein = col_line;
- for(width = 0; width < sd->stc.prt_size; ++width) {
- byte i,tmp,cmyk[4];
- memset(cmyk,0,4);
- for(i = 128; i; i >>= 1) {
- static const byte rgb2cmyk[] = {
- BLACK, /* 0->Black */
- CYAN | MAGENTA, /* 1->BLUE */
- CYAN | YELLOW, /* 2->GREEN */
- CYAN, /* 3->CYAN */
- MAGENTA | YELLOW, /* 4->RED */
- MAGENTA, /* 5->MAGENTA */
- YELLOW, /* 6->YELLOW */
- 0}; /* 7->WHITE */
- tmp = rgb2cmyk[(*bytein++) & 7];
- if(tmp & BLACK) cmyk[3] |= i;
- if(tmp & YELLOW) cmyk[2] |= i;
- if(tmp & MAGENTA) cmyk[1] |= i;
- if(tmp & CYAN) cmyk[0] |= i;
- }
- for(i = 0; i < 4; ++i) {
- if(cmyk[i] != 0) sd->stc.prt_width[buf_i+i] = width+1;
- sd->stc.prt_data[buf_i+i][width] = cmyk[i];
- }
- }
- }
- break;
- case 4: /* split cmyk */
- {
- byte *bytein;
- int width;
- bytein = col_line;
- for(width = 0; width < sd->stc.prt_size; ++width) {
- byte i,tmp,cmyk[4];
- memset(cmyk,0,4);
- for(i = 128; i; i >>= 1) {
- tmp = (*bytein++) & 15;
- if(tmp & BLACK) cmyk[3] |= i;
- if(tmp & YELLOW) cmyk[2] |= i;
- if(tmp & MAGENTA) cmyk[1] |= i;
- if(tmp & CYAN) cmyk[0] |= i;
- }
- for(i = 0; i < 4; ++i) {
- if(cmyk[i] != 0) sd->stc.prt_width[buf_i+i] = width+1;
- sd->stc.prt_data[buf_i+i][width] = cmyk[i];
- }
- }
- }
- break;
- default: break;
- }
- }
- } /* Nr. 5 (give me input) */
- /*
- * Nr. 5 has got enough input, now we should print it
- */
- if((flags & STCCOMP) == STCDELTA) stc_print_delta(sd,prn_stream);
- else if(npass > 1) stc_print_weave(sd,prn_stream);
- else stc_print_bands(sd,prn_stream);
- #ifdef STC_SIGNAL
- sigpending(&stc_int_pending);
- if(sigismember(&stc_int_pending,SIGINT)) {
- fputs("\033@[Aborted]\f", prn_stream);
- fflush(prn_stream);
- sigprocmask(SIG_SETMASK,&stc_int_save,NULL);
- break;
- }
- #endif /* STC_SIGNAL */
- } /* Until all scans are processed */
- if(sd->stc.flags & STCPRINT) {
- if((flags & STCCOMP) == STCDELTA) fputc(0xe3,prn_stream);
- fwrite(sd->stc.escp_release.data,1,sd->stc.escp_release.size,prn_stream);
- fflush(prn_stream);
- }
- #ifdef STC_SIGNAL
- sigprocmask(SIG_SETMASK,&stc_int_save,NULL);
- #endif /* STC_DIGNAL */
-
- }
- }
- /***
- *** Release the dynamic memory
- ***/
- if(ext_line != NULL)
- gs_free(sd->memory, ext_line,ext_size,1,"stc_print_page/ext_line");
- if(col_line != NULL)
- gs_free(sd->memory, col_line,prt_pixels,1,"stc_print_page/col_line");
- if(alg_line != NULL)
- gs_free(sd->memory, alg_line,alg_size,sd->stc.alg_item,
- "stc_print_page/alg_line");
- if(buf != NULL)
- gs_free(sd->memory, buf,buf_size,sd->stc.alg_item,"stc_print_page/buf");
- if(sd->stc.prt_width != NULL)
- gs_free(sd->memory, sd->stc.prt_width,sd->stc.prt_buf,sizeof(int),
- "stc_print_page/prt_width");
- if(sd->stc.prt_data != NULL) {
- int i;
- for(i = 0; i < sd->stc.prt_buf; ++i) {
- if(sd->stc.prt_data[i] != NULL)
- gs_free(sd->memory, sd->stc.prt_data[i],sd->stc.prt_size,1,
- "stc_print_page/prt");
- }
- gs_free(sd->memory, sd->stc.prt_data,sd->stc.prt_buf,sizeof(byte *),
- "stc_print_page/prt_data");
- }
- {
- int i;
- for(i = 0; i < sd->color_info.num_components; ++i) {
- if(sd->stc.seed_row[i] != NULL)
- gs_free(sd->memory, sd->stc.seed_row[i],sd->stc.seed_size,sizeof(int),
- "stc_print_page/seed_row");
- }
- }
- if(sd->stc.escp_data != NULL)
- gs_free(sd->memory, sd->stc.escp_data,sd->stc.escp_size,1,
- "stc_print_page/escp_data");
- return OK4GO ? 0 : gs_error_undefined;
- }
- /*
- * white-check
- */
- private bool
- stc_iswhite(stcolor_device *sd, int prt_pixels,byte *ext_data)
- {
- long b2do = (prt_pixels*sd->color_info.depth+7)>>3;
- int bcmp = 4 * countof(sd->stc.white_run);
- byte *wht = (byte *) sd->stc.white_run;
- while(b2do >= bcmp) {
- if(memcmp(ext_data,wht,bcmp)) break;
- ext_data += bcmp;
- b2do -= bcmp;
- }
- if((b2do > 0) && (b2do < bcmp))
- b2do = memcmp(ext_data,sd->stc.white_end,b2do);
- return b2do ? false : true;
- }
- /***
- *** A bunch of routines that convert gslines into algorithms format.
- ***/
- private byte *
- stc_any_depth(stcolor_device *sd,byte *ext_data,int prt_pixels,byte *alg_line)
- { /* general conversion */
- int p,c, niext, nbits;
- gx_color_index ciext,ci,cimsk,cvmsk;
- byte *ap = alg_line;
- nbits = sd->stc.bits;
- cvmsk = ((gx_color_index) 1<<nbits) - 1;
- /* it is nonsense to use this algorithm for this cases, but if it claims
- * generality, it should deliver correct results in this cases too */
- if(sd->color_info.depth == (sd->color_info.num_components<<3)) nbits = 8;
- cimsk = cvmsk;
- for(c = 1; c < sd->color_info.num_components; ++c)
- cimsk = (cimsk<<nbits) | cvmsk;
- ciext = 0;
- niext = 0;
- for(p = 0; p < prt_pixels; ++p) { /* over pixels */
- ci = ciext;
- for(c = sd->color_info.depth-niext; c >= 8; c -= 8)
- ci = (ci<<8) | *ext_data++;
- if(c > 0) { /* partial byte required */
- niext = 8 - c;
- ciext = *ext_data++;
- ci = (ci<<c) | (ciext>>niext);
- ciext &= (1L<<niext)-1;
- } else if(c < 0) { /* some bits left in ciext */
- niext = -c;
- ciext &= (1L<<niext)-1;
- ci = ci>>niext;
- } else { /* entire ciext used */
- niext = 0;
- ciext = 0;
- } /* ciext-adjust */
- ci &= cimsk;
- # define stc_storeapc(T) \
- ((T *)ap)[c] = ((T *)(sd->stc.vals[c]))[ci & cvmsk];
- for(c = sd->color_info.num_components; c--;) { /* comp */
- STC_TYPESWITCH(sd->stc.dither,stc_storeapc)
- ci >>= nbits;
- } /* comp */
- # undef stc_storeapc
- ap += sd->color_info.num_components * sd->stc.alg_item;
- } /* over pixels */
- return alg_line;
- } /* general conversion */
- /*
- * rgb-data with depth=24, can use a faster algorithm
- */
- private byte *
- stc_rgb24_long(stcolor_device *sd,byte *ext_data,int prt_pixels,byte *alg_line)
- { /* convert 3 bytes into appropriate long-Values */
- register int p;
- register long *out = (long *) alg_line;
- register long *rvals = (long *) (sd->stc.vals[0]);
- register long *gvals = (long *) (sd->stc.vals[1]);
- register long *bvals = (long *) (sd->stc.vals[2]);
- for(p = prt_pixels; p; --p) {
- *out++ = rvals[*ext_data++];
- *out++ = gvals[*ext_data++];
- *out++ = bvals[*ext_data++];
- }
- return alg_line;
- } /* convert 3 bytes into appropriate long-Values */
- /*
- * cmyk-data with depth=32, can use a faster algorithm
- */
- private byte *
- stc_cmyk32_long(stcolor_device *sd,byte *ext_data,int prt_pixels,byte *alg_line)
- { /* convert 4 bytes into appropriate long-Values */
- register int p;
- register long *out = (long *) alg_line;
- register long *cvals = (long *) (sd->stc.vals[0]);
- register long *mvals = (long *) (sd->stc.vals[1]);
- register long *yvals = (long *) (sd->stc.vals[2]);
- register long *kvals = (long *) (sd->stc.vals[3]);
- for(p = prt_pixels; p; --p) {
- *out++ = cvals[*ext_data++];
- *out++ = mvals[*ext_data++];
- *out++ = yvals[*ext_data++];
- *out++ = kvals[*ext_data++];
- }
- return alg_line;
- } /* convert 4 bytes into appropriate long-Values */
- /*
- * handle indirect encoded cmyk-data
- */
- #define STC_CMYK10_ANY(T)\
- \
- register int p = prt_pixels; \
- register stc_pixel ci,k,n,mode; \
- register stc_pixel *in = (stc_pixel *) ext_data; \
- register T *out = (T *) alg_line; \
- register T *cv = (T *) sd->stc.vals[0]; \
- register T *mv = (T *) sd->stc.vals[1]; \
- register T *yv = (T *) sd->stc.vals[2]; \
- register T *kv = (T *) sd->stc.vals[3]; \
- \
- while(p--) { \
- ci = *in++; \
- mode = ci & 3; \
- k = (ci>>2) & 0x3ff; \
- if(mode == 3) { \
- *out++ = cv[0]; \
- *out++ = mv[0]; \
- *out++ = yv[0]; \
- *out++ = kv[k]; \
- } else { \
- out[3] = kv[k]; \
- n = (ci>>12) & 0x3ff; \
- if(mode == 2) { out[2] = yv[k]; } \
- else { out[2] = yv[n]; n = (ci>>22) & 0x3ff; } \
- if(mode == 1) { out[1] = mv[k]; } \
- else { out[1] = mv[n]; n = (ci>>22) & 0x3ff; } \
- if(mode == 0) out[0] = cv[k]; \
- else out[0] = cv[n]; \
- out += 4; \
- } \
- } \
- \
- return alg_line;
- private byte *
- stc_cmyk10_byte(stcolor_device *sd,
- byte *ext_data,int prt_pixels,byte *alg_line)
- {
- STC_CMYK10_ANY(byte)
- }
- private byte *
- stc_cmyk10_long(stcolor_device *sd,
- byte *ext_data,int prt_pixels,byte *alg_line)
- {
- STC_CMYK10_ANY(long)
- }
- private byte *
- stc_cmyk10_float(stcolor_device *sd,
- byte *ext_data,int prt_pixels,byte *alg_line)
- {
- STC_CMYK10_ANY(float)
- }
- #undef STC_CMYK10_ANY
- #define STC_CMYK10_DANY(T)\
- \
- register int p = prt_pixels; \
- register stc_pixel ci,k,n,mode; \
- register stc_pixel *in = (stc_pixel *) ext_data; \
- register T *out = (T *) alg_line; \
- \
- while(p--) { \
- ci = *in++; \
- mode = ci & 3; \
- k = (ci>>2) & 0x3ff; \
- if(mode == 3) { \
- *out++ = 0; \
- *out++ = 0; \
- *out++ = 0; \
- *out++ = k; \
- } else { \
- out[3] = k; \
- n = (ci>>12) & 0x3ff; \
- if(mode == 2) { out[2] = k; } \
- else { out[2] = n; n = (ci>>22) & 0x3ff; } \
- if(mode == 1) { out[1] = k; } \
- else { out[1] = n; n = (ci>>22) & 0x3ff; } \
- if(mode == 0) out[0] = k; \
- else out[0] = n; \
- out += 4; \
- } \
- } \
- \
- return alg_line;
- private byte *
- stc_cmyk10_dbyte(stcolor_device *sd,
- byte *ext_data,int prt_pixels,byte *alg_line)
- {
- STC_CMYK10_DANY(byte)
- }
- private byte *
- stc_cmyk10_dlong(stcolor_device *sd,
- byte *ext_data,int prt_pixels,byte *alg_line)
- {
- STC_CMYK10_DANY(long)
- }
- #undef STC_CMYK10_DANY
- /*
- * if the algorithm uses bytes & bytes are in ext_data, use them
- */
- /*ARGSUSED*/
- private byte *
- stc_any_direct(stcolor_device *sd,byte *ext_data,int prt_pixels,byte *alg_line)
- { /* return ext_data */
- return ext_data;
- } /* return ext_data */
- /* ----------------------------------------------------------------------- */
- /* stc_rle: epson ESC/P2 RLE-Encoding
- */
- private int
- stc_rle(byte *out,const byte *in,int width)
- {
- int used = 0;
- int crun,cdata;
- byte run;
- if(in != NULL) { /* Data present */
- crun = 1;
- while(width > 0) { /* something to compress */
- run = in[0];
- while((width > crun) && (run == in[crun])) if(++crun == 129) break;
- if((crun > 2) || (crun == width)) { /* use this run */
- *out++ = (257 - crun) & 0xff; *out++ = run; used += 2;
- width -= crun; in += crun;
- crun = 1;
- } else { /* ignore this run */
- for(cdata = crun; (width > cdata) && (crun < 4);) {
- if(run == in[cdata]) crun += 1;
- else run = in[cdata], crun = 1;
- if(++cdata == 128) break;
- }
- if(crun < 3) crun = 0; /* ignore trailing run */
- else cdata -= crun;
- *out++ = cdata-1; used++;
- memcpy(out,in,cdata); used += cdata; out += cdata;
- width -= cdata; in += cdata;
- } /* use/ignore run */
- } /* something to compress */
- } else { /* Empty scans to fill bands */
- while(width > 0) {
- crun = width > 129 ? 129 : width;
- width -= crun;
- *out++ = (257 - crun) & 0xff;
- *out++ = 0;
- used += 2;
- }
- } /* Data present or empty */
- return used;
- }
- /*
- * Horizontal & vertical positioning, color-selection, "ESC ."
- */
- private int
- stc_print_escpcmd(stcolor_device *sd, FILE *prn_stream,
- int escp_used, int color,int m,int wbytes)
- {
- int dy = sd->stc.stc_y - sd->stc.prt_y; /* number of units to skip */
- int nlf;
- /* ESC-R color codes, used only here */
- static const byte stc_colors[] = { 0x02, 0x01, 0x04, 0x00 }; /* CMYK */
- /*
- * initialize the printer, if necessary
- */
- if(0 == (sd->stc.flags & STCPRINT)) {
- fwrite(sd->stc.escp_init.data,1,sd->stc.escp_init.size,prn_stream);
- if(0 < sd->stc.escp_lf) { /* Adjust Linefeed */
- fputc('\033', prn_stream);
- fputc('+', prn_stream);
- fputc(((sd->stc.escp_m*sd->stc.escp_u) / 10),prn_stream);
- } /* Adjust Linefeed */
- sd->stc.flags |= STCPRINT;
- }
- sd->stc.escp_data[escp_used++] = '\r'; /* leftmost position */
- if(dy) { /* position the printer */
- if(( sd->stc.escp_lf > 0) && /* Linefeed allowed */
- ((dy % sd->stc.escp_lf) == 0)) /* and possible */
- nlf = dy / sd->stc.escp_lf;
- else nlf = 7;
-
- if(nlf > 6) {
- sd->stc.escp_data[escp_used++] = '\033';
- sd->stc.escp_data[escp_used++] = '(';
- sd->stc.escp_data[escp_used++] = 'V';
- sd->stc.escp_data[escp_used++] = '\002';
- sd->stc.escp_data[escp_used++] = '\000';
- sd->stc.escp_data[escp_used++] = sd->stc.stc_y & 0xff;
- sd->stc.escp_data[escp_used++] = (sd->stc.stc_y >> 8) & 0xff;
- } else {
- while(nlf--) sd->stc.escp_data[escp_used++] = '\n';
- }
- sd->stc.prt_y = sd->stc.stc_y;
- } /* position the printer */
- if((sd->color_info.num_components > 1) &&
- (sd->stc.escp_c != stc_colors[color])) { /* select color */
- sd->stc.escp_data[escp_used++] = '\033';
- sd->stc.escp_data[escp_used++] = 'r';
- sd->stc.escp_c = stc_colors[color];
- sd->stc.escp_data[escp_used++] = sd->stc.escp_c;
- } /* select color */
- /*
- * Build the command used
- */
- sd->stc.escp_data[escp_used++] = '\033';
- sd->stc.escp_data[escp_used++] = '.';
- sd->stc.escp_data[escp_used++] =
- (sd->stc.flags & STCCOMP) == STCPLAIN ? 0 : 1;
- sd->stc.escp_data[escp_used++] = sd->stc.escp_v;
- sd->stc.escp_data[escp_used++] = sd->stc.escp_h;
- sd->stc.escp_data[escp_used++] = m;
- sd->stc.escp_data[escp_used++] = (wbytes<<3) & 0xff; /* width in Pixels */
- sd->stc.escp_data[escp_used++] = (wbytes>>5) & 0xff;
- return escp_used;
- }
- /*
- * compute width of a group of scanlines
- */
- private int
- stc_bandwidth(stcolor_device *sd,int color,int m,int npass)
- {
- int ncolor = sd->color_info.num_components == 1 ? 1 : 4;
- int buf_a = (sd->stc.prt_buf-1) & (sd->stc.stc_y * ncolor + color);
- int w = 0;
- while(m-- > 0) { /* check width */
- if(sd->stc.prt_width[buf_a] > w) w = sd->stc.prt_width[buf_a];
- buf_a = (sd->stc.prt_buf-1) & (buf_a + ncolor * npass);
- } /* check width */
- return w;
- }
- /*
- * Multi-Pass Printing-Routine
- */
- private void
- stc_print_weave(stcolor_device *sd, FILE *prn_stream)
- {
- int escp_used,nprint,nspace,color,buf_a,iprint,w;
- int npass = sd->stc.escp_v / sd->stc.escp_u;
- int ncolor = sd->color_info.num_components == 1 ? 1 : 4;
- while(sd->stc.stc_y < sd->stc.prt_scans) {
- /*
- * compute spacing & used heads (seems to work with odd escp_m)
- */
- if(sd->stc.stc_y >= sd->stc.escp_m) { /* in normal mode */
- nprint = sd->stc.escp_m;
- nspace = sd->stc.escp_m;
- } else if((sd->stc.stc_y) < npass) { /* initialisation */
- nprint = sd->stc.escp_m - sd->stc.stc_y * ((sd->stc.escp_m+1)/npass);
- nspace = 1;
- } else { /* switch to normal */
- nprint = sd->stc.escp_m - sd->stc.stc_y * ((sd->stc.escp_m+1)/npass);
- nspace = sd->stc.escp_m - sd->stc.stc_y;
- }
- iprint = sd->stc.stc_y + npass * nprint;
- if(sd->stc.buf_y < iprint) break;
- escp_used = 0;
- for(color = 0; color < ncolor; ++color) { /* print the colors */
- if(0 == (w = stc_bandwidth(sd,color,nprint,npass))) continue;
- escp_used = stc_print_escpcmd(sd,prn_stream,
- escp_used,color,sd->stc.escp_m,w);
- buf_a = (sd->stc.prt_buf-1) & (sd->stc.stc_y * ncolor + color);
- for(iprint = 0; iprint < nprint; ++iprint) { /* send data */
- if((sd->stc.flags & STCCOMP) == STCPLAIN) {
- memcpy(sd->stc.escp_data+escp_used,sd->stc.prt_data[buf_a],w);
- escp_used += w;
- } else {
- escp_used += stc_rle(sd->stc.escp_data+escp_used,
- sd->stc.prt_data[buf_a],w);
- }
- fwrite(sd->stc.escp_data,1,escp_used,prn_stream);
- escp_used = 0;
- buf_a = (sd->stc.prt_buf-1) & (buf_a + ncolor * npass);
- } /* send data */
- while(iprint++ < sd->stc.escp_m) { /* add empty rows */
- if((sd->stc.flags & STCCOMP) == STCPLAIN) {
- memset(sd->stc.escp_data+escp_used,0,w);
- escp_used += w;
- } else {
- escp_used += stc_rle(sd->stc.escp_data+escp_used,NULL,w);
- }
- fwrite(sd->stc.escp_data,1,escp_used,prn_stream);
- escp_used = 0;
- } /* add empty rows */
- } /* print the colors */
- sd->stc.stc_y += nspace;
- }
- }
- /*
- * Single-Pass printing-Routine
- */
- private void
- stc_print_bands(stcolor_device *sd, FILE *prn_stream)
- {
- int escp_used,color,buf_a,iprint,w,m;
- int ncolor = sd->color_info.num_components == 1 ? 1 : 4;
- while(sd->stc.stc_y < sd->stc.prt_scans) {
- /*
- * find the begin of the band
- */
- for(w = 0; sd->stc.stc_y < sd->stc.buf_y; ++sd->stc.stc_y) {
- buf_a = (sd->stc.prt_buf-1) & (sd->stc.stc_y * ncolor);
- for(color = 0; color < ncolor; ++color)
- if(sd->stc.prt_width[buf_a+color] > w)
- w = sd->stc.prt_width[buf_a+color];
- if(w != 0) break;
- }
- if(w == 0) break;
- /*
- * adjust the band-height
- */
- w = sd->stc.prt_scans - sd->stc.stc_y;
- if((w < sd->stc.escp_m) && (sd->stc.escp_v != 40)) {
- if(w < 8) m = 1;
- else if(w < 24) m = 8;
- else m = 24;
- } else {
- m = sd->stc.escp_m;
- }
- if(sd->stc.buf_y < (sd->stc.stc_y+m)) break;
- escp_used = 0;
- for(color = 0; color < ncolor; ++color) { /* print the colors */
- if(0 == (w = stc_bandwidth(sd,color,m,1))) continue; /* shortcut */
- escp_used = stc_print_escpcmd(sd,prn_stream,escp_used,color,m,w);
- buf_a = (sd->stc.prt_buf-1) & (sd->stc.stc_y * ncolor + color);
- for(iprint = 0; iprint < m; ++iprint) { /* send data */
- if((sd->stc.flags & STCCOMP) == STCPLAIN) {
- memcpy(sd->stc.escp_data+escp_used,sd->stc.prt_data[buf_a],w);
- escp_used += w;
- } else {
- escp_used += stc_rle(sd->stc.escp_data+escp_used,
- sd->stc.prt_data[buf_a],w);
- }
- fwrite(sd->stc.escp_data,1,escp_used,prn_stream);
- escp_used = 0;
- buf_a = (sd->stc.prt_buf-1) & (buf_a + ncolor);
- } /* send data */
- } /* print the colors */
- sd->stc.stc_y += m;
- }
- }
- /* ----------------------------------------------------------------------- */
- private int
- stc_deltarow(byte *out,const byte *in,int width,byte *seed)
- {
- int istop,nmove,ndata,i,j;
- int *wseed = (int *) seed;
- int used = 0;
- seed += sizeof(int);
- if((in != NULL) && (width > 0)) { /* Data present */
- istop = width < wseed[0] ? wseed[0] : width;
- i = 0;
- while(i < istop) {
- for(j = i; j < istop; ++j) if(in[j] != seed[j]) break;
- nmove = j - i;
- if(nmove > 0) { /* issue a move */
- i = j;
- if(i == istop) break;
- if( nmove < 8) {
- out[used++] = 0x40 | nmove;
- } else if(nmove < 128) {
- out[used++] = 0x51;
- out[used++] = nmove;
- } else {
- out[used++] = 0x52;
- out[used++] = 0xff & nmove;
- out[used++] = 0xff & (nmove>>8);
- }
- } /* issue a move */
- /*
- * find the end of this run
- */
- nmove = 0;
- for(j = i+1; (j < istop) && ((nmove < 4)); ++j) {
- if(in[j] == seed[j]) nmove += 1;
- else nmove = 0;
- }
- ndata = j-i-nmove;
- nmove = stc_rle(out+used+3,in+i,ndata);
- if(nmove < 16) {
- out[used++] = 0x20 | nmove;
- for(j = 0; j < nmove; ++j) out[used+j] = out[used+j+2];
- } else if(nmove < 256) {
- out[used++] = 0x31;
- out[used++] = nmove;
- for(j = 0; j < nmove; ++j) out[used+j] = out[used+j+1];
- } else {
- out[used++] = 0x32;
- out[used++] = 0xff & nmove;
- out[used++] = 0xff & (nmove>>8);
- }
- used += nmove;
- i += ndata;
- }
- memcpy(seed,in,istop);
- wseed[0] = width;
- } else if(wseed[0] > 0) { /* blank line, but seed has data */
- out[used++] = 0xe1; /* clear row */
- memset(seed,0,wseed[0]);
- wseed[0] = 0;
- }
- return used;
- }
- /*
- * Slightly different single-pass printing
- */
- private void
- stc_print_delta(stcolor_device *sd, FILE *prn_stream)
- {
- int color,buf_a,w;
- int escp_used = 0;
- int ncolor = sd->color_info.num_components == 1 ? 1 : 4;
- while(sd->stc.stc_y < sd->stc.prt_scans) {
- /*
- * find the begin of the band
- */
- for(w = 0; sd->stc.stc_y < sd->stc.buf_y; ++sd->stc.stc_y) {
- buf_a = (sd->stc.prt_buf-1) & (sd->stc.stc_y * ncolor);
- for(color = 0; color < ncolor; ++color)
- if(sd->stc.prt_width[buf_a+color] > w)
- w = sd->stc.prt_width[buf_a+color];
- if(w != 0) break;
- }
- if(sd->stc.buf_y == sd->stc.stc_y) break;
- escp_used = 0;
- /*
- * Send Initialization & ESC . 3 once
- */
- if(0 == (sd->stc.flags & STCPRINT)) {
- sd->stc.flags |= STCPRINT;
- fwrite(sd->stc.escp_init.data,1,sd->stc.escp_init.size,prn_stream);
- sd->stc.escp_data[escp_used++] = '\033';
- sd->stc.escp_data[escp_used++] = '.';
- sd->stc.escp_data[escp_used++] = 3;
- sd->stc.escp_data[escp_used++] = sd->stc.escp_v;
- sd->stc.escp_data[escp_used++] = sd->stc.escp_h;
- sd->stc.escp_data[escp_used++] = sd->stc.escp_m;
- sd->stc.escp_data[escp_used++] = 0;
- sd->stc.escp_data[escp_used++] = 0;
- sd->stc.escp_data[escp_used++] = 0xe4; /* MOVXBYTE */
- }
- if(sd->stc.stc_y != sd->stc.prt_y) { /* really position the printer */
- w = sd->stc.stc_y - sd->stc.prt_y;
- if( w < 16) {
- sd->stc.escp_data[escp_used++] = 0x60 | w;
- } else if(w < 256) {
- sd->stc.escp_data[escp_used++] = 0x71;
- sd->stc.escp_data[escp_used++] = w;
- } else {
- sd->stc.escp_data[escp_used++] = 0x72;
- sd->stc.escp_data[escp_used++] = 0xff & w;
- sd->stc.escp_data[escp_used++] = 0xff & (w>>8);
- }
- sd->stc.prt_y = sd->stc.stc_y;
- } /* really position the printer */
- for(color = 0; color < ncolor; ++color) { /* print the colors */
- /* Color-Selection */
- if(color == (ncolor-1)) {
- sd->stc.escp_data[escp_used++] = 0x80; /* Black */
- } else {
- switch(color) {
- case 1: sd->stc.escp_data[escp_used++] = 0x81; break; /* M */
- case 2: sd->stc.escp_data[escp_used++] = 0x84; break; /* Y */
- default: sd->stc.escp_data[escp_used++] = 0x82; break; /* C */
- }
- }
- /* Data-Transfer */
- buf_a = (sd->stc.prt_buf-1) & (sd->stc.stc_y * ncolor + color);
- w = stc_deltarow(sd->stc.escp_data+escp_used,
- sd->stc.prt_data[buf_a],sd->stc.prt_width[buf_a],
- sd->stc.seed_row[color]);
- if(w == 0) escp_used -= 1;
- else escp_used += w;
- if(escp_used > 0) fwrite(sd->stc.escp_data,1,escp_used,prn_stream);
- escp_used = 0;
- } /* print the colors */
- sd->stc.stc_y += 1;
- }
- }
- /* ----------------------------------------------------------------------- */
- /***
- *** Free-Data: release the specific-Arrays
- ***/
- private void
- stc_freedata(gs_memory_t *mem, stc_t *stc)
- {
- int i,j;
- for(i = 0; i < 4; ++i) {
- if(stc->code[i] != NULL) {
- for(j = 0; j < i; ++j) if(stc->code[i] == stc->code[j]) break;
- if(i == j) gs_free(mem, stc->code[i],1<<stc->bits,sizeof(gx_color_value),
- "stcolor/code");
- }
- if(stc->vals[i] != NULL) {
- for(j = 0; j < i; ++j)
- if(stc->vals[i] == stc->vals[j]) break;
- if(i == j) gs_free(mem, stc->vals[i],1<<stc->bits,sd->stc.alg_item,
- "stcolor/transfer");
- }
- }
- for(i = 0; i < 4; ++i) {
- stc->code[i] = NULL;
- stc->vals[i] = NULL;
- }
- }
- /***
- *** open the device and initialize margins & arrays
- ***/
- private int
- stc_open(gx_device *pdev) /* setup margins & arrays */
- {
- stcolor_device *sd = (stcolor_device *) pdev;
- int i,j,code;
- gx_color_index white;
- byte *bpw,*bpm;
- code = 0;
- /*
- * Establish Algorithm-Table, if not present
- */
- if(sd->stc.algorithms.size == 0) {
- gs_param_string *dp;
- for(i = 0; stc_dither[i].name != NULL; ++i); /* count 'em */
- sd->stc.algorithms.size = i;
- dp = gs_malloc(sd->memory, i,sizeof(gs_param_string),
- "stcolor/algorithms");
- if(dp == NULL) {
- code = gs_error_VMerror;
- sd->stc.algorithms.size = 0;
- } else {
- sd->stc.algorithms.data = dp;
- sd->stc.algorithms.persistent = true;
- for(i = 0; stc_dither[i].name != NULL; ++i) {
- param_string_from_string(dp[i],stc_dither[i].name);
- }
- }
- }
- # define stc_sizeofitem(T) sd->stc.alg_item = sizeof(T)
- STC_TYPESWITCH(sd->stc.dither,stc_sizeofitem)
- stc_print_setup(sd);
- /*
- * Establish internal Value & Code-Arrays
- */
- for(i = 0; i < sd->color_info.num_components; ++i) { /* comp */
- if((sd->stc.sizc[i] > 1) && (sd->stc.extc[i] != NULL)) { /* code req. */
- for(j = 0; j < i; ++j) if(sd->stc.extc[i] == sd->stc.extc[j]) break;
- if(i == j) { /* new one */
- sd->stc.code[i] = gs_malloc(sd->memory, 1<<sd->stc.bits,sizeof(gx_color_value),
- "stcolor/code");
- if(sd->stc.code[i] == NULL) { /* error */
- code = gs_error_VMerror;
- } else { /* success */
- /*
- * Try making things easier:
- * normalize values to 0.0/1.0-Range
- * X-Axis: Color-Values (implied)
- * Y-Values: Indices (given)
- */
- unsigned long ly,iy;
- double ystep,xstep,fx,fy;
- /* normalize */
- fx = 1e18;
- fy = -1e18;
- for(ly = 0; ly < sd->stc.sizc[i]; ++ly) {
- if(sd->stc.extc[i][ly] < fx) fx = sd->stc.extc[i][ly];
- if(sd->stc.extc[i][ly] > fy) fy = sd->stc.extc[i][ly];
- }
- if((fx != 0.0) || (fy != 1.0)) {
- fy = 1.0 / (fy - fx);
- for(ly = 0; ly < sd->stc.sizc[i]; ++ly)
- sd->stc.extc[i][ly] = fy * (sd->stc.extc[i][ly]-fx);
- }
- /* interpolate */
- ystep = 1.0 / (double)((1<<sd->stc.bits)-1);
- xstep = 1.0 / (double)( sd->stc.sizc[i] -1);
- iy = 0;
- for(ly = 0; ly < (1<<sd->stc.bits); ++ly) {
- fy = ystep * ly;
- while(((iy+1) < sd->stc.sizc[i]) &&
- ( fy > sd->stc.extc[i][iy+1])) ++iy;
- fx = iy + (fy - sd->stc.extc[i][iy])
- / (sd->stc.extc[i][iy+1] - sd->stc.extc[i][iy]);
- fx *= xstep * gx_max_color_value;
- fx = fx < 0.0 ? 0.0 :
- (fx > gx_max_color_value ? gx_max_color_value : fx);
- sd->stc.code[i][ly] = (gx_color_value)fx;
- if((fx-sd->stc.code[i][ly]) >= 0.5) sd->stc.code[i][ly] += 1;
- }
- } /* error || success */
- } else { /* shared one */
- sd->stc.code[i] = sd->stc.code[j];
- } /* new || shared one */
- } /* code req. */
- if((sd->stc.sizv[i] > 1) && (sd->stc.extv[i] != NULL)) { /* vals req. */
- for(j = 0; j < i; ++j)
- if((sd->stc.extc[i] == sd->stc.extc[j]) &&
- (sd->stc.extv[i] == sd->stc.extv[j])) break;
- if(i == j) { /* new one */
- sd->stc.vals[i] =
- gs_malloc(sd->memory, 1<<sd->stc.bits,sd->stc.alg_item,"stcolor/transfer");
- if(sd->stc.vals[i] == NULL) {
- code = gs_error_VMerror;
- } else { /* success */
- if(sd->stc.code[i] == NULL) { /* linear */
- byte *Out = sd->stc.vals[i];
- int Nout = 1<<sd->stc.bits;
- double Omin = sd->stc.dither->minmax[0];
- double Omax = sd->stc.dither->minmax[1];
- float *In = sd->stc.extv[i];
- int Nin = sd->stc.sizv[i];
- unsigned long I,io;
- double Istep,Ostep,Y;
- byte Ovb; long Ovl;
- Istep = 1.0 / (double) ((Nin)-1);
- Ostep = 1.0 / (double) ((Nout)-1);
- for(io = 0; io < (Nout); ++io) {
- I = (long)(io * ((Nin)-1))/((Nout)-1);
- if((I+1) < (Nin))
- Y = In[I] + (In[I+1]-In[I])
- * ((double) io * Ostep - (double)I * Istep)
- / (double) Istep;
- else
- Y = In[I] + (In[I]-In[I-1])
- * ((double) io * Ostep - (double)I * Istep)
- / (double) Istep;
- Y = Omin + (Omax-Omin) * Y;
- Y = Y < Omin ? Omin : (Y > Omax ? Omax : Y);
- switch(sd->stc.dither->flags & STC_TYPE) {
- case STC_BYTE:
- Ovb = (byte)Y;
- if(((Y-Ovb) >= 0.5) && ((Ovb+1) <= Omax)) Ovb += 1;
- Out[io] = Ovb;
- break;
- case STC_LONG:
- Ovl = (long)Y;
- if(((Y-Ovl) >= 0.5) && ((Ovl+1) <= Omax)) Ovl += 1;
- if(((Ovl-Y) >= 0.5) && ((Ovl-1) >= Omax)) Ovl -= 1;
- ((long *)Out)[io] = Ovl;
- break;
- default:
- ((float *)Out)[io] = Y;
- break;
- }
- }
- } else { /* encoded */
- unsigned long j,o;
- double xstep,x,y;
- xstep = 1.0 / (double) (sd->stc.sizv[i]-1);
- /*
- * The following differs in so far from the previous, that the desired
- * X-Values are stored in another array.
- */
- for(o = 0; o < (1<<sd->stc.bits); ++o) { /* code-loop */
- x = sd->stc.code[i][o]; x /= gx_max_color_value;
- j = (unsigned long)(x / xstep);
- if((j+1) < sd->stc.sizv[i]) {
- y = sd->stc.extv[i][j];
- y += (sd->stc.extv[i][j+1]-y)*(x-(double)j*xstep)/xstep;
- } else {
- y = sd->stc.extv[i][j];
- y += (y-sd->stc.extv[i][j-1])*(x-(double)j*xstep)/xstep;
- }
- y = sd->stc.dither->minmax[0]
- +(sd->stc.dither->minmax[1]-sd->stc.dither->minmax[0])*y;
- # define stc_adjvals(T) \
- ((T *)(sd->stc.vals[i]))[o] = (T)y; \
- \
- if(((y-((T *)(sd->stc.vals[i]))[o]) >= 0.5) && \
- ((1+((T *)(sd->stc.vals[i]))[o]) <= sd->stc.dither->minmax[1]))\
- ((T *)(sd->stc.vals[i]))[o] += 1; \
- \
- if(((((T *)(sd->stc.vals[i]))[o]-y) >= 0.5) && \
- ((((T *)(sd->stc.vals[i]))[o]-1) >= sd->stc.dither->minmax[0]))\
- ((T *)(sd->stc.vals[i]))[o] -= 1;
- STC_TYPESWITCH(sd->stc.dither,stc_adjvals)
- # undef stc_adjvals
- } /* code-loop */
- } /* lineaer / encoded */
- } /* error || success */
- } else { /* shared one */
- sd->stc.vals[i] = sd->stc.vals[j];
- } /* new || shared one */
- } /* vals req. */
- } /* comp */
- if(code == 0) {
- gx_color_value cv[4];
- sd->stc.flags |= STCOK4GO;
- /*
- * Arrgh: open-procedure seems to be the right-place, but it is
- * necessary to establish the defaults for omitted procedures too.
- */
- switch(sd->color_info.num_components) { /* Establish color-procs */
- case 1:
- set_dev_proc(sd,map_rgb_color, stc_map_gray_color);
- set_dev_proc(sd,map_cmyk_color,gx_default_map_cmyk_color);
- set_dev_proc(sd,map_color_rgb, stc_map_color_gray);
- set_dev_proc(sd,encode_color, stc_map_gray_color);
- set_dev_proc(sd,decode_color, stc_map_color_gray);
- cv[0] = cv[1] = cv[2] = gx_max_color_value;
- white = stc_map_gray_color((gx_device *) sd, cv);
- break;
- case 3:
- set_dev_proc(sd,map_rgb_color, stc_map_rgb_color);
- set_dev_proc(sd,map_cmyk_color,gx_default_map_cmyk_color);
- set_dev_proc(sd,map_color_rgb, stc_map_color_rgb);
- set_dev_proc(sd,encode_color, stc_map_rgb_color);
- set_dev_proc(sd,decode_color, stc_map_color_rgb);
- cv[0] = cv[1] = cv[2] = gx_max_color_value;
- white = stc_map_rgb_color((gx_device *) sd, cv);
- break;
- default:
- set_dev_proc(sd,map_rgb_color, gx_default_map_rgb_color);
- if(sd->stc.flags & STCCMYK10) {
- set_dev_proc(sd,map_cmyk_color,stc_map_cmyk10_color);
- set_dev_proc(sd,map_color_rgb, stc_map_color_cmyk10);
- set_dev_proc(sd,encode_color,stc_map_cmyk10_color);
- set_dev_proc(sd,decode_color, stc_map_color_cmyk10);
- cv[0] = cv[1] = cv[2] = cv[3] = 0;
- white = stc_map_cmyk10_color((gx_device *) sd, cv);
- } else {
- set_dev_proc(sd,map_cmyk_color,stc_map_cmyk_color);
- set_dev_proc(sd,map_color_rgb, stc_map_color_cmyk);
- set_dev_proc(sd,encode_color,stc_map_cmyk_color);
- set_dev_proc(sd,decode_color, stc_map_color_cmyk);
- cv[0] = cv[1] = cv[2] = cv[3] = 0;
- white = stc_map_cmyk_color((gx_device *) sd,cv);
- }
- break; /* Establish color-procs */
- }
- /*
- * create at least a Byte
- */
- if(sd->color_info.depth < 2) white |= (white<<1);
- if(sd->color_info.depth < 4) white |= (white<<2);
- if(sd->color_info.depth < 8) white |= (white<<4);
- /*
- * copy the Bytes
- */
- bpw = (byte *) sd->stc.white_run;
- if(sd->color_info.depth < 16) {
- for(i = 0; i < sizeof(sd->stc.white_run); i += 1) {
- bpw[i] = 0xff & white;
- }
- } else if(sd->color_info.depth < 24) {
- for(i = 0; i < sizeof(sd->stc.white_run); i += 2) {
- bpw[i] = 0xff & (white>>8);
- bpw[i+1] = 0xff & white;
- }
- } else if(sd->color_info.depth < 32) {
- for(i = 0; i < sizeof(sd->stc.white_run); i += 3) {
- bpw[i] = 0xff & (white>>16);
- bpw[i+1] = 0xff & (white>> 8);
- bpw[i+2] = 0xff & white;
- }
- } else {
- for(i = 0; i < sizeof(sd->stc.white_run); i += 4) {
- bpw[i] = 0xff & (white>>24);
- bpw[i+1] = 0xff & (white>>16);
- bpw[i+2] = 0xff & (white>> 8);
- bpw[i+3] = 0xff & white;
- }
- }
- /*
- * compute the trailer
- */
- j = (unsigned long)(sd->width -
- (dev_l_margin(sd)+dev_r_margin(sd))*sd->x_pixels_per_inch);
- j = j * sd->color_info.depth; /* the Bit-count */
- j = j % (32*countof(sd->stc.white_run)); /* remaining Bits */
- bpm = (byte *) sd->stc.white_end;
- for(i = 0; i < (4*countof(sd->stc.white_end)); ++i) {
- if( j <= 0) {
- bpm[i] = 0;
- } else if(j >= 8) {
- bpm[i] = 0xff;
- j -= 8;
- } else {
- bpm[i] = 0xff ^ ((1<<(8-j))-1);
- j = 0;
- }
- bpm[i] &= bpw[i];
- }
- /*
- * Call super-class open
- */
- return gdev_prn_open(pdev);
- } else {
- stc_freedata(sd->memory, &sd->stc);
- return_error(code);
- }
- }
- /***
- *** stc_close: release the internal data
- ***/
- private int
- stc_close(gx_device *pdev)
- {
- stc_freedata(pdev->memory, &((stcolor_device *) pdev)->stc);
- ((stcolor_device *) pdev)->stc.flags &= ~STCOK4GO;
- return gdev_prn_close(pdev);
- }
- /***
- *** Function for Bit-Truncation, including direct-byte-transfer
- ***/
- private gx_color_value
- stc_truncate(stcolor_device *sd,int i,gx_color_value v)
- {
- if(sd->stc.bits < gx_color_value_bits) {
- if(sd->stc.code[i] != NULL) {
- /*
- * Perform binary search in the code-array
- */
- long s;
- gx_color_value *p;
- s = sd->stc.bits > 1 ? 1L<<(sd->stc.bits-2) : 0L;
- p = sd->stc.code[i]+(1L<<(sd->stc.bits-1));
- while(s > 0) {
- if(v > *p) {
- p += s;
- } else if(v < p[-1]) {
- p -= s;
- } else {
- if((v-p[-1]) < (p[0]-v)) p -= 1;
- break;
- }
- s >>= 1;
- }
- if((v-p[-1]) < (p[0]-v)) p -= 1;
- v = p - sd->stc.code[i];
- } else {
- v >>= gx_color_value_bits-sd->stc.bits;
- }
- /*
- V = (((1L<<D->stc.bits)-1)*V+(gx_max_color_value>>1))\
- /gx_max_color_value; \
- */
- }
- return v;
- }
- private gx_color_value
- stc_truncate1(stcolor_device *sd,int i,gx_color_value v)
- {
- return sd->stc.vals[i][stc_truncate(sd,i,v)];
- }
- /***
- *** Expansion of indices for reverse-mapping
- ***/
- private gx_color_value
- stc_expand(stcolor_device *sd,int i,gx_color_index col)
- {
- gx_color_index cv;
- gx_color_index l = (1<<sd->stc.bits)-1;
- if(sd->stc.code[i] != NULL) {
- cv = sd->stc.code[i][col & l];
- } else if(sd->stc.bits < gx_color_value_bits) {
- cv = (col & l)<<(gx_color_value_bits-sd->stc.bits);
- cv += (col & l)/l * ((1<<(gx_color_value_bits-sd->stc.bits))-1);
- } else if(sd->stc.bits > gx_color_value_bits) {
- cv = (col & l)>>(sd->stc.bits-gx_color_value_bits);
- } else {
- cv = col & l;
- }
- return cv;
- }
- /***
- *** color-mapping of gray-scales
- ***/
- private gx_color_index
- stc_map_gray_color(gx_device *pdev, const gx_color_value cv[])
- {
- stcolor_device *sd = (stcolor_device *) pdev;
- gx_color_index rv;
- gx_color_value r = cv[0];
- gx_color_value g = cv[1];
- gx_color_value b = cv[2];
- if((r == g) && (g == b)) {
- rv = gx_max_color_value - r;
- } else if(sd->stc.am != NULL) {
- float *m,fv;
- m = sd->stc.am;
- fv = gx_max_color_value;
- fv -= *m++ * (float) r; fv -= *m++ * (float) g; fv -= *m * (float) b;
- if( fv < 0.0) rv = 0;
- else if((fv+0.5) > gx_max_color_value) rv = gx_max_color_value;
- else rv = (gx_color_index)(fv+0.5);
- } else {
- rv = ((gx_color_index)gx_max_color_value)<<3;
- rv -= (gx_color_index) 3 * r;
- rv -= (gx_color_index) 3 * g;
- rv -= ((gx_color_index)b)<<1;
- rv = (rv+4)>>3;
- if(rv > gx_max_color_value) rv = gx_max_color_value;
- }
- if(( sd->stc.bits == 8) &&
- ((sd->stc.dither->flags & STC_TYPE) == STC_BYTE))
- rv = stc_truncate1(sd,0,(gx_color_value)rv);
- else
- rv = stc_truncate(sd,0,(gx_color_value)rv);
- return rv;
- }
- private int
- stc_map_color_gray(gx_device *pdev, gx_color_index color,gx_color_value prgb[3])
- {
- stcolor_device *sd = (stcolor_device *) pdev;
- gx_color_index l = ((gx_color_index)1<<sd->stc.bits)-1;
- prgb[0] = gx_max_color_value - stc_expand(sd,0,color & l);
- prgb[1] = prgb[0]; prgb[2] = prgb[0];
- return 0;
- }
- /***
- *** color-mapping of rgb-values
- ***/
- private gx_color_index
- stc_map_rgb_color(gx_device *pdev, const gx_color_value cv[])
- {
- stcolor_device *sd = (stcolor_device *) pdev;
- int shift = sd->color_info.depth == 24 ? 8 : sd->stc.bits;
- gx_color_index rv = 0;
- gx_color_value r = cv[0];
- gx_color_value g = cv[1];
- gx_color_value b = cv[2];
- if((sd->stc.am != NULL) && ((r != g) || (g != b))) {
- float *m,fr,fg,fb,fv;
- m = sd->stc.am;
- fr = r; fg = g; fb = b;
- fv = *m++ * fr; fv += *m++ * fg; fv += *m++ * fb;
- if( fv < 0.0) r = 0;
- else if((fv+0.5) > gx_max_color_value) r = gx_max_color_value;
- else r = (gx_color_value)(fv+0.5);
- fv = *m++ * fr; fv += *m++ * fg; fv += *m++ * fb;
- if( fv < 0.0) g = 0;
- else if((fv+0.5) > gx_max_color_value) g = gx_max_color_value;
- else g = (gx_color_value)(fv+0.5);
- fv = *m++ * fr; fv += *m++ * fg; fv += *m++ * fb;
- if( fv < 0.0) b = 0;
- else if((fv+0.5) > gx_max_color_value) b = gx_max_color_value;
- else b = (gx_color_value)(fv+0.5);
- }
- if(( sd->stc.bits == 8) &&
- ((sd->stc.dither->flags & STC_TYPE) == STC_BYTE)) {
- rv = stc_truncate1(sd,0,r);
- rv = (rv<<shift) | stc_truncate1(sd,1,g);
- rv = (rv<<shift) | stc_truncate1(sd,2,b);
- } else {
- rv = stc_truncate(sd,0,r);
- rv = (rv<<shift) | stc_truncate(sd,1,g);
- rv = (rv<<shift) | stc_truncate(sd,2,b);
- }
- return rv;
- }
- private int
- stc_map_color_rgb(gx_device *pdev, gx_color_index color,gx_color_value prgb[3])
- {
- stcolor_device *sd = (stcolor_device *) pdev;
- int shift = sd->color_info.depth == 24 ? 8 : sd->stc.bits;
- gx_color_index l = ((gx_color_index)1<<sd->stc.bits)-1;
- prgb[0] = stc_expand(sd,0,((color>>(shift<<1)) & l));
- prgb[1] = stc_expand(sd,1,((color>> shift ) & l));
- prgb[2] = stc_expand(sd,2,( color & l));
- return 0;
- }
- /***
- *** color-mapping of cmyk-values
- ***/
- private gx_color_index
- stc_map_cmyk_color(gx_device *pdev, const gx_color_value cv[])
- {
- stcolor_device *sd = (stcolor_device *) pdev;
- int shift = sd->color_info.depth == 32 ? 8 : sd->stc.bits;
- gx_color_index rv = 0;
- gx_color_value c = cv[0];
- gx_color_value m = cv[1];
- gx_color_value y = cv[2];
- gx_color_value k = cv[3];
- if((c == m) && (m == y)) {
- k = c > k ? c : k;
- c = m = y = 0;
- if(( sd->stc.bits == 8) &&
- ((sd->stc.dither->flags & STC_TYPE) == STC_BYTE)) {
- k = stc_truncate1(sd,3,k);
- } else {
- k = stc_truncate(sd,3,k);
- }
- } else {
- if(sd->stc.am != NULL) {
- float *a,fc,fm,fy,fk,fv;
- if(k == 0) { /* no separated black yet */
- k = c < m ? c : m;
- k = k < y ? k : y;
- if(k) { /* no black at all */
- c -= k;
- m -= k;
- y -= k;
- } /* no black at all */
- } /* no separated black yet */
- a = sd->stc.am;
- fc = c; fm = m; fy = y; fk = k;
- fv = *a++ * fc; fv += *a++ * fm; fv += *a++ * fy; fv += *a++ * fk;
- if( fv < 0.0) c = 0;
- else if((fv+0.5) > gx_max_color_value) c = gx_max_color_value;
- else c = (gx_color_value)(fv+0.5);
- fv = *a++ * fc; fv += *a++ * fm; fv += *a++ * fy; fv += *a++ * fk;
- if( fv < 0.0) m = 0;
- else if((fv+0.5) > gx_max_color_value) m = gx_max_color_value;
- else m = (gx_color_value)(fv+0.5);
- fv = *a++ * fc; fv += *a++ * fm; fv += *a++ * fy; fv += *a++ * fk;
- if( fv < 0.0) y = 0;
- else if((fv+0.5) > gx_max_color_value) y = gx_max_color_value;
- else y = (gx_color_value)(fv+0.5);
- fv = *a++ * fc; fv += *a++ * fm; fv += *a++ * fy; fv += *a++ * fk;
- if( fv < 0.0) k = 0;
- else if((fv+0.5) > gx_max_color_value) k = gx_max_color_value;
- else k = (gx_color_value)(fv+0.5);
- } else if(k == 0) {
- k = c < m ? c : m;
- k = k < y ? k : y;
- }
- if(( sd->stc.bits == 8) &&
- ((sd->stc.dither->flags & STC_TYPE) == STC_BYTE)) {
- c = stc_truncate1(sd,0,c);
- m = stc_truncate1(sd,1,m);
- y = stc_truncate1(sd,2,y);
- k = stc_truncate1(sd,3,k);
- } else {
- c = stc_truncate(sd,0,c);
- m = stc_truncate(sd,1,m);
- y = stc_truncate(sd,2,y);
- k = stc_truncate(sd,3,k);
- }
- }
- rv = c;
- rv = (rv<<shift) | m;
- rv = (rv<<shift) | y;
- rv = (rv<<shift) | k;
- if(rv == gx_no_color_index) rv ^= 1;
- return rv;
- }
- /* Modified to be a "decode_color" routine */
- private int
- stc_map_color_cmyk(gx_device *pdev, gx_color_index color,gx_color_value cv[4])
- {
- stcolor_device *sd = (stcolor_device *) pdev;
- int shift = sd->color_info.depth == 32 ? 8 : sd->stc.bits;
- gx_color_index l = ((gx_color_index)1<<sd->stc.bits)-1;
- gx_color_value c,m,y,k;
- k = stc_expand(sd,3, color & l); color >>= shift;
- y = stc_expand(sd,2, color & l); color >>= shift;
- m = stc_expand(sd,1, color & l); color >>= shift;
- c = stc_expand(sd,0, color & l);
-
- cv[0] = c;
- cv[1] = m;
- cv[2] = y;
- cv[3] = k;
-
- return 0;
- }
- /***
- *** color-mapping of cmyk10-values
- ***/
- private gx_color_index
- stc_map_cmyk10_color(gx_device *pdev, const gx_color_value cv[])
- {
- stcolor_device *sd = (stcolor_device *) pdev;
- int mode;
- gx_color_index rv = 0;
- gx_color_value c = cv[0];
- gx_color_value m = cv[1];
- gx_color_value y = cv[2];
- gx_color_value k = cv[3];
- if((c == m) && (m == y)) {
- k = c > k ? c : k;
- c = m = y = 0;
- mode = 3;
- } else {
- if(sd->stc.am != NULL) {
- float *a,fc,fm,fy,fk,fv;
- k = c < m ? c : m;
- k = k < y ? k : y;
- if(k) { /* no black at all */
- c -= k;
- m -= k;
- y -= k;
- } /* no black at all */
- a = sd->stc.am;
- fc = c; fm = m; fy = y; fk = k;
- fv = *a++ * fc; fv += *a++ * fm; fv += *a++ * fy; fv += *a++ * fk;
- if( fv < 0.0) c = 0;
- else if((fv+0.5) > gx_max_color_value) c = gx_max_color_value;
- else c = (gx_color_value)(fv+0.5);
- fv = *a++ * fc; fv += *a++ * fm; fv += *a++ * fy; fv += *a++ * fk;
- if( fv < 0.0) m = 0;
- else if((fv+0.5) > gx_max_color_value) m = gx_max_color_value;
- else m = (gx_color_value)(fv+0.5);
- fv = *a++ * fc; fv += *a++ * fm; fv += *a++ * fy; fv += *a++ * fk;
- if( fv < 0.0) y = 0;
- else if((fv+0.5) > gx_max_color_value) y = gx_max_color_value;
- else y = (gx_color_value)(fv+0.5);
- }
- if(c < m) {
- if(c < y) { k = c; c = 0; mode = 0; }
- else { k = y; y = 0; mode = 2; }
- } else {
- if(m < y) { k = m; m = 0; mode = 1; }
- else { k = y; y = 0; mode = 2; }
- }
- }
- /*
- * truncate only the values that require it
- */
- if(c) c = stc_truncate(sd,0,c);
- if(m) m = stc_truncate(sd,1,m);
- if(y) y = stc_truncate(sd,2,y);
- if(k) k = stc_truncate(sd,3,k);
- /*
- * make sure that truncation-white becomes white.
- */
- if((c|m|y) == 0) mode = 3;
- /*
- * check wether value-arrays can be bypassed
- */
- if(((sd->stc.dither->flags & STC_TYPE) == STC_BYTE) &&
- ( sd->stc.dither->minmax[0] == 0.0 )) {
- c = sd->stc.vals[0][c];
- m = sd->stc.vals[1][m];
- y = sd->stc.vals[2][y];
- k = sd->stc.vals[3][k];
- } else if(((sd->stc.dither->flags & STC_TYPE) == STC_LONG) &&
- ( sd->stc.dither->minmax[0] == 0.0 ) &&
- ( sd->stc.dither->minmax[1] <= 1023.0 )) {
- c = ((long *)(sd->stc.vals[0]))[c];
- m = ((long *)(sd->stc.vals[1]))[m];
- y = ((long *)(sd->stc.vals[2]))[y];
- k = ((long *)(sd->stc.vals[3]))[k];
- } /* direct */
- /*
- * compute the long-representation of gx_color_index
- */
- switch(mode) {
- case 0:
- rv = (((gx_color_index) m)<<22)|
- (((gx_color_index) y)<<12)|
- (((gx_color_index) k)<< 2)|mode;
- break;
- case 1:
- rv = (((gx_color_index) c)<<22)|
- (((gx_color_index) y)<<12)|
- (((gx_color_index) k)<< 2)|mode;
- break;
- case 2:
- rv = (((gx_color_index) c)<<22)|
- (((gx_color_index) m)<<12)|
- (((gx_color_index) k)<< 2)|mode;
- break;
- default:
- rv = (((gx_color_index) k)<< 2)|mode;
- break;
- }
- /*
- * We may need some swapping
- */
- #if !arch_is_big_endian
- {
- union { stc_pixel cv; byte bv[4]; } ui,uo;
- ui.cv = rv;
- uo.bv[0] = ui.bv[3];
- uo.bv[1] = ui.bv[2];
- uo.bv[2] = ui.bv[1];
- uo.bv[3] = ui.bv[0];
- rv = uo.cv;
- }
- #endif
- return rv;
- }
- private int
- stc_map_color_cmyk10(gx_device *pdev, gx_color_index color,
- gx_color_value cv[3])
- {
- stcolor_device *sd = (stcolor_device *) pdev;
- gx_color_value c,m,y;
- /*
- * We may need some swapping
- */
- #if !arch_is_big_endian
- union { stc_pixel cv; byte bv[4]; } ui,uo;
- ui.cv = color;
- uo.bv[0] = ui.bv[3];
- uo.bv[1] = ui.bv[2];
- uo.bv[2] = ui.bv[1];
- uo.bv[3] = ui.bv[0];
- color = uo.cv;
- #endif
- c = stc_expand(sd,3,(color>>2)&0x3ff);
- /* cast the 64 bit switch argument to work around broken HPUX 10 cc */
- switch((int)(color & 3)) {
- case 0:
- m = stc_expand(sd,1,(color>>22) & 0x3ff);
- y = stc_expand(sd,2,(color>>12) & 0x3ff);
- break;
- case 1:
- m = c;
- c = stc_expand(sd,0,(color>>22) & 0x3ff);
- y = stc_expand(sd,2,(color>>12) & 0x3ff);
- break;
- case 2:
- y = c;
- c = stc_expand(sd,0,(color>>22) & 0x3ff);
- m = stc_expand(sd,1,(color>>12) & 0x3ff);
- break;
- default:
- m = c;
- y = c;
- break;
- }
- cv[0] = c;
- cv[1] = m;
- cv[2] = y;
- return 0;
- }
- /***
- *** Macros for parameter-handling
- ***/
- #define set_param_array(A, D, S)\
- {A.data = D; A.size = S; A.persistent = false;}
- #define stc_write_null(N) \
- set_param_array(pfa,defext,countof(defext)) \
- code = param_write_null(plist,N); \
- if (code < 0) return code;
- #define stc_write_xarray(I,Coding,Transfer) \
- if(sd->stc.sizc[I] > 0) { \
- set_param_array(pfa, sd->stc.extc[I],sd->stc.sizc[I]) \
- code = param_write_float_array(plist,Coding,&pfa); \
- } else { \
- code = param_write_null(plist,Coding); \
- } \
- if ( code < 0 ) return code; \
- \
- if(sd->stc.sizv[I] > 0) \
- set_param_array(pfa, sd->stc.extv[I],sd->stc.sizv[I]) \
- else \
- set_param_array(pfa,defext,countof(defext)) \
- code = param_write_float_array(plist,Transfer,&pfa); \
- if ( code < 0 ) return code;
- #define stc_read_null(N) \
- code = param_read_null(plist,N); \
- if(code == gs_error_typecheck) \
- code = param_read_float_array(plist,N,&pfa); \
- if(code < 0) param_signal_error(plist,N,code); \
- error = error > code ? code : error;
- #define stc_read_xarray(I,Coding,Transfer) \
- code = param_read_float_array(plist,Coding,&pfa); \
- if((error == 0) && (code == 0)) { \
- if(pfa.size > 1) { \
- sd->stc.extc[I] = (float *) pfa.data; \
- sd->stc.sizc[I] = pfa.size; \
- } else { \
- code = gs_error_rangecheck; \
- } \
- } else if(code < 0) { \
- code = param_read_null(plist,Coding); \
- if(code == 0) { \
- sd->stc.extc[I] = NULL; \
- sd->stc.sizc[I] = 0; \
- } \
- } \
- if(code < 0) param_signal_error(plist,Coding,code); \
- error = error > code ? code : error; \
- code = param_read_float_array(plist,Transfer,&pfa); \
- if((error == 0) && (code == 0)) { \
- sd->stc.extv[I] = (float *) pfa.data; \
- sd->stc.sizv[I] = pfa.size; \
- } else if(code < 0) { \
- code = param_read_null(plist,Transfer); \
- if(code == 0) { \
- sd->stc.extv[I] = defext; \
- sd->stc.sizv[I] = countof(defext); \
- } \
- } \
- if(code < 0) param_signal_error(plist,Transfer,code); \
- error = error > code ? code : error;
- /***
- *** Get parameters == Make them accessable via PostScript
- ***/
- private int
- stc_get_params(gx_device *pdev, gs_param_list *plist)
- {
- int code,nc;
- gs_param_string ps;
- gs_param_float_array pfa;
- bool btmp;
- stcolor_device *sd = (stcolor_device *) pdev;
- code = gdev_prn_get_params(pdev, plist);
- if ( code < 0 ) return code;
- /*
- * Export some readonly-Parameters, used by stcinfo.ps
- */
- param_string_from_string(ps,"1.91");
- code = param_write_string(plist,"Version",&ps);
- if ( code < 0 ) return code;
- code = param_write_int(plist,"BitsPerComponent",&sd->stc.bits);
- if ( code < 0 ) return code;
- if(sd->stc.algorithms.size > 0) {
- code = param_write_string_array(plist,"Algorithms",&sd->stc.algorithms);
- } else {
- code = param_write_null(plist,"Algorithms");
- }
- if ( code < 0 ) return code;
- /*
- * Export OutputCode
- */
- switch(sd->stc.flags & STCCOMP) {
- case STCPLAIN: param_string_from_string(ps,"plain"); break;
- case STCDELTA: param_string_from_string(ps,"deltarow"); break;
- default: param_string_from_string(ps,"runlength"); break;
- }
- code = param_write_string(plist,"OutputCode",&ps);
- if ( code < 0 ) return code;
- /*
- * Export Model
- */
- switch(sd->stc.flags & STCMODEL) {
- case STCST800: param_string_from_string(ps,"st800"); break;
- case STCSTCII: param_string_from_string(ps,"stcii"); break;
- default: param_string_from_string(ps,"stc"); break;
- }
- code = param_write_string(plist,"Model",&ps);
- if ( code < 0 ) return code;
- /*
- * Export the booleans
- */
- #define stc_write_flag(Mask,Name) \
- btmp = sd->stc.flags & (Mask) ? true : false; \
- code = param_write_bool(plist,Name,&btmp); \
- if ( code < 0 ) return code;
- stc_write_flag(STCUNIDIR,"Unidirectional")
- stc_write_flag(STCUWEAVE,"Microweave")
- btmp = sd->stc.flags & (STCUNIDIR|STCUWEAVE) ? false : true;
- code = param_write_bool(plist,"Softweave",&btmp);
- if ( code < 0 ) return code;
- stc_write_flag(STCNWEAVE,"noWeave")
- stc_write_flag(STCDFLAG0, "Flag0")
- stc_write_flag(STCDFLAG1, "Flag1")
- stc_write_flag(STCDFLAG2, "Flag2")
- stc_write_flag(STCDFLAG3, "Flag3")
- stc_write_flag(STCDFLAG4, "Flag4")
- #undef stc_write_flag
- # define stc_write_int(Mask,Name,Val) \
- code = param_write_int(plist,Name,&Val); \
- if ( code < 0 ) return code
- stc_write_int(STCBAND, "escp_Band", sd->stc.escp_m);
- stc_write_int(STCWIDTH, "escp_Width", sd->stc.escp_width);
- stc_write_int(STCHEIGHT,"escp_Height",sd->stc.escp_height);
- stc_write_int(STCTOP, "escp_Top", sd->stc.escp_top);
- stc_write_int(STCBOTTOM,"escp_Bottom",sd->stc.escp_bottom);
- # undef stc_write_int
- code = param_write_string(plist,"escp_Init",&sd->stc.escp_init);
- code = param_write_string(plist,"escp_Release",&sd->stc.escp_release);
- if(sd->stc.dither != NULL) {
- param_string_from_string(ps,sd->stc.dither->name);
- code = param_write_string(plist,"Dithering",&ps);
- } else {
- code = param_write_null(plist,"Dithering");
- }
- if ( code < 0 ) return code;
- nc = sd->color_info.num_components;
- if(sd->stc.am != NULL) {
- if( nc == 1) set_param_array(pfa, sd->stc.am, 3)
- else if(nc == 3) set_param_array(pfa, sd->stc.am, 9)
- else set_param_array(pfa, sd->stc.am,16)
- code = param_write_float_array(plist,"ColorAdjustMatrix",&pfa);
- } else {
- code = param_write_null(plist,"ColorAdjustMatrix");
- }
- if ( code < 0 ) return code;
- if(nc == 1) { /* DeviceGray */
- stc_write_xarray(0,"Kcoding","Ktransfer");
- stc_write_null("Rcoding"); stc_write_null("Rtransfer");
- stc_write_null("Gcoding"); stc_write_null("Gtransfer");
- stc_write_null("Bcoding"); stc_write_null("Btransfer");
- stc_write_null("Ccoding"); stc_write_null("Ctransfer");
- stc_write_null("Mcoding"); stc_write_null("Mtransfer");
- stc_write_null("Ycoding"); stc_write_null("Ytransfer");
- } else if(nc == 3) { /* DeviceRGB */
- stc_write_xarray(0,"Rcoding","Rtransfer");
- stc_write_xarray(1,"Gcoding","Gtransfer");
- stc_write_xarray(2,"Bcoding","Btransfer");
- stc_write_null("Ccoding"); stc_write_null("Ctransfer");
- stc_write_null("Mcoding"); stc_write_null("Mtransfer");
- stc_write_null("Ycoding"); stc_write_null("Ytransfer");
- stc_write_null("Kcoding"); stc_write_null("Ktransfer");
- } else { /* DeviceCMYK */
- stc_write_xarray(0,"Ccoding","Ctransfer");
- stc_write_xarray(1,"Mcoding","Mtransfer");
- stc_write_xarray(2,"Ycoding","Ytransfer");
- stc_write_xarray(3,"Kcoding","Ktransfer");
- stc_write_null("Rcoding"); stc_write_null("Rtransfer");
- stc_write_null("Gcoding"); stc_write_null("Gtransfer");
- stc_write_null("Bcoding"); stc_write_null("Btransfer");
- }
- return code;
- }
- /***
- *** put parameters == Store them in the device-structure
- ***/
- private int
- stc_put_params(gx_device *pdev, gs_param_list *plist)
- {
- int code,error,i,l;
- bool b1,b2,b3;
- float fv,*fp;
- gs_param_string ps;
- gs_param_string_array psa;
- gs_param_float_array pfa;
- stcolor_device *sd = (stcolor_device *) pdev;
- gx_device_color_info oldcolor;
- stc_t oldstc;
- /*
- * save old Values
- */
- memcpy(&oldcolor,&sd->color_info,sizeof(oldcolor));
- memcpy(&oldstc ,&sd->stc ,sizeof(oldstc ));
- /*
- * Arrrgh:
- * With Version 3.4x and above my simple minded read-only Parameters
- * do not work any more. So read them here for heavens sake.
- */
- code = param_read_string(plist,"Version",&ps);
- code = param_read_int(plist,"BitsPerComponent",&i);
- code = param_read_string_array(plist,"Algorithms",&psa);
- /*
- * Fetch Major-Parameters (Model, Dithering, BitsPerPixel/BitsPerComponent)
- */
- error = 0;
- code = param_read_string(plist,"Model",&ps);
- if(code == 0) { /* Analyze the Model-String */
- /*
- * Arrgh: I should have known, that internal strings are not zero-terminated.
- */
- for(l = ps.size; (l > 0) && (ps.data[l-1] == 0); --l);
- # define stc_putcmp(Name) \
- ((strlen(Name) != l) || (0 != strncmp(Name, (const char *)ps.data,l)))
- sd->stc.flags &= ~STCMODEL;
- if( !stc_putcmp("st800")) sd->stc.flags |= STCST800;
- else if(!stc_putcmp("stcii")) sd->stc.flags |= STCSTCII;
- } /* Analyze the Model-String */
- if(code < 0) param_signal_error(plist,"Model",code);
- error = error > code ? code : error;
- /* If we're running for st800, #components must be 1 */
- if(((sd->stc.flags & STCMODEL) == STCST800) &&
- (( sd->color_info.num_components > 1) ||
- ( sd->stc.dither == NULL) ||
- ((sd->stc.dither->flags & 7) > 1))) {
- sd->color_info.num_components = 1;
- sd->stc.dither = NULL;
- }
- /* Weaving isn't a feature for the st800 */
- if((sd->stc.flags & STCMODEL) == STCST800) {
- sd->stc.flags &= ~STCUWEAVE;
- sd->stc.flags |= STCNWEAVE;
- } else if((sd->stc.flags & STCMODEL) == STCSTCII) { /* no SoftWeave */
- sd->stc.flags |= STCNWEAVE;
- }
- code = param_read_string(plist,"Dithering",&ps);
- if(code == 0) { /* lookup new value new value */
- for(l = ps.size; (l > 0) && (ps.data[l-1] == 0); --l);
- for(i = 0; stc_dither[i].name != NULL; ++i)
- if(!stc_putcmp(stc_dither[i].name)) break;
- } else if(sd->stc.dither != NULL) { /* compute index of given value */
- i = sd->stc.dither - stc_dither;
- } else { /* find matching value */
- for(i = 0; stc_dither[i].name != NULL; ++i)
- if((stc_dither[i].flags & 7) == sd->color_info.num_components) break;
- } /* we've got an index */
- if(stc_dither[i].name != NULL) { /* establish data */
- /*
- * Establish new dithering algorithm & color-model
- */
- sd->stc.dither = stc_dither+i;
- sd->color_info.num_components = sd->stc.dither->flags & 7;
- STC_TYPESWITCH(sd->stc.dither,stc_sizeofitem)
- # undef stc_sizeofitem
- if(((sd->stc.flags & STCMODEL) == STCST800) &&
- ( sd->color_info.num_components > 1 ))
- code = gs_error_rangecheck;
- /*
- * reset Parameters related to the color-model, if it changed
- */
- if(sd->color_info.num_components != oldcolor.num_components) {
- for(i = 0; i < sd->color_info.num_components; ++i) {
- sd->stc.extv[i] = (float *) defext;
- sd->stc.sizv[i] = countof(defext);
- sd->stc.extc[i] = NULL;
- sd->stc.sizc[i] = 0;
- }
- sd->stc.am = NULL;
- } else { /* guarantee, that extvals is present */
- for(i = 0; i < sd->color_info.num_components; ++i) {
- if(sd->stc.sizv[i] < 2) {
- sd->stc.extv[i] = (float *) defext;
- sd->stc.sizv[i] = countof(defext);
- }
- }
- }
- for(i = sd->color_info.num_components; i < 4; ++ i) { /* clear unused */
- sd->stc.extv[i] = NULL;
- sd->stc.sizv[i] = 0;
- sd->stc.vals[i] = NULL;
- sd->stc.extc[i] = NULL;
- sd->stc.sizc[i] = 0;
- sd->stc.code[i] = NULL;
- } /* clear unused */
- /*
- * Guess default depth from range of values
- */
- if((sd->stc.dither != oldstc.dither)||(oldstc.vals[0] == NULL)) {
- if((sd->stc.dither->flags & STC_CMYK10) != 0) {
- sd->stc.flags |= STCCMYK10;
- sd->stc.bits = 10;
- sd->color_info.depth = 32;
- } else {
- sd->stc.flags &= ~STCCMYK10;
- if((sd->stc.dither->flags & STC_FLOAT) != STC_FLOAT) {
- fv = 2.0;
- for(i = 1;(i < gx_color_value_bits) &&
- (fv <= (sd->stc.dither->minmax[1]-sd->stc.dither->minmax[0]));
- ++i) fv *= 2.0;
- } else {
- i = 8; /* arbitrary */
- }
- if((i*sd->color_info.num_components) > (sizeof(stc_pixel)*8)) {
- sd->stc.bits = (sizeof(stc_pixel)*8) /
- sd->color_info.num_components;
- sd->color_info.depth = sd->stc.bits * sd->color_info.num_components;
- } else {
- sd->stc.bits = i;
- sd->color_info.depth = sd->stc.bits * sd->color_info.num_components;
- }
- }
- }
- } else {
- code = gs_error_rangecheck;
- } /* verify new value */
- if(code < 0) param_signal_error(plist,"Dithering",code);
- error = error > code ? code : error;
- /*
- * now fetch the desired depth, if the algorithm allows it
- */
- /*
- * Arrrgh: We get code == 0, even if nobody sets BitsPerPixel.
- * The value is the old one, but this may cause trouble
- * with CMYK10.
- */
- code = param_read_int(plist, "BitsPerPixel", &i);
- if((error == 0) && (code == 0) &&
- (((sd->stc.flags & STCCMYK10) == 0) || (i != sd->color_info.depth))) {
- if((1 > i) || (i > (sizeof(stc_pixel)*8)))
- code = gs_error_rangecheck;
- else
- sd->color_info.depth = i;
- sd->stc.bits = i / sd->color_info.num_components;
- if(1 > sd->stc.bits) code = gs_error_rangecheck;
- if((sd->stc.dither->flags & STC_DIRECT) &&
- (sd->stc.dither->flags & STC_CMYK10))
- code = gs_error_rangecheck;
- else
- sd->stc.flags &= ~STCCMYK10;
- }
- if(code < 0) param_signal_error(plist,"BitsPerPixel",code);
- error = error > code ? code : error;
- /*
- * Fetch OutputCode
- */
- code = param_read_string(plist,"OutputCode",&ps);
- if(code == 0) { /* Analyze the OutputCode-String */
- for(l = ps.size; (l > 0) && (ps.data[l-1] == 0); --l);
- sd->stc.flags &= ~STCCOMP;
- if(!stc_putcmp("plain")) sd->stc.flags |= STCPLAIN;
- else if(!stc_putcmp("deltarow")) sd->stc.flags |= STCDELTA;
- } /* Analyze the OutputCode-String */
- if((sd->stc.flags & STCCOMP) == STCDELTA) {
- sd->stc.flags |= STCUWEAVE;
- sd->stc.flags &= ~STCNWEAVE;
- }
- if(code < 0) param_signal_error(plist,"OutputCode",code);
- error = error > code ? code : error;
- /*
- * fetch the weave-mode (noWeave wins)
- */
- b1 = sd->stc.flags & STCUWEAVE ? true : false;
- b2 = sd->stc.flags & STCNWEAVE ? true : false;
- b3 = sd->stc.flags & (STCUWEAVE|STCNWEAVE) ? false : true;
- code = param_read_bool(plist,"Microweave",&b1);
- if(code < 0) {
- param_signal_error(plist,"Microweave",code);
- } else if(code == 0) {
- if(b1) { b2 = false; b3 = false; }
- }
- error = error > code ? code : error;
- code = param_read_bool(plist,"noWeave",&b2);
- if(code < 0) {
- param_signal_error(plist,"noWeave",code);
- } else if (code == 0) {
- if(b2) { b1 = false; b3 = false; }
- }
- error = error > code ? code : error;
- code = param_read_bool(plist,"Softweave",&b3);
- if(code < 0) {
- param_signal_error(plist,"Softweave",code);
- } else if (code == 0) {
- if(b3) { b1 = false; b2 = false; }
- }
- error = error > code ? code : error;
- if(b1) sd->stc.flags |= STCUWEAVE;
- else sd->stc.flags &= ~STCUWEAVE;
- if(b2) sd->stc.flags |= STCNWEAVE;
- else sd->stc.flags &= ~STCNWEAVE;
- /*
- * Check the simple Flags
- */
- # define stc_read_flag(Mask,Name) \
- code = param_read_bool(plist,Name,&b1); \
- if(code < 0) { \
- param_signal_error(plist,Name,code); \
- } else if(code == 0) { \
- if(b1 == true) sd->stc.flags |= Mask; \
- else sd->stc.flags &= ~(Mask); \
- } \
- error = error > code ? code : error;
- stc_read_flag(STCUNIDIR,"Unidirectional")
- stc_read_flag(STCDFLAG0, "Flag0")
- stc_read_flag(STCDFLAG1, "Flag1")
- stc_read_flag(STCDFLAG2, "Flag2")
- stc_read_flag(STCDFLAG3, "Flag3")
- stc_read_flag(STCDFLAG4, "Flag4")
- /*
- * Now deal with the escp-Stuff
- */
- # define stc_read_int(Mask,Name,Val) \
- code = param_read_int(plist,Name,&Val); \
- if(code < 0) \
- param_signal_error(plist,Name,code); \
- else if(code == 0) \
- sd->stc.flags |= Mask; \
- error = error > code ? code : error
- stc_read_int(STCBAND, "escp_Band", sd->stc.escp_m);
- stc_read_int(STCWIDTH, "escp_Width", sd->stc.escp_width);
- stc_read_int(STCHEIGHT,"escp_Height",sd->stc.escp_height);
- stc_read_int(STCTOP, "escp_Top", sd->stc.escp_top);
- stc_read_int(STCBOTTOM,"escp_Bottom",sd->stc.escp_bottom);
- # undef stc_read_int
- code = param_read_string(plist,"escp_Init",&sd->stc.escp_init);
- if(code == 0) sd->stc.flags |= STCINIT;
- error = error > code ? code : error;
- code = param_read_string(plist,"escp_Release",&sd->stc.escp_release);
- if(code == 0) sd->stc.flags |= STCRELEASE;
- error = error > code ? code : error;
- /*
- * ColorAdjustMatrix must match the required size,
- * setting it explicitly to null, erases old matrix
- */
- code = param_read_float_array(plist,"ColorAdjustMatrix",&pfa);
- if((error == 0) && (code == 0)) {
- if(((sd->color_info.num_components == 1) && (pfa.size == 3)) ||
- ((sd->color_info.num_components == 3) && (pfa.size == 9)) ||
- ((sd->color_info.num_components == 4) && (pfa.size == 16)))
- sd->stc.am = (float *) pfa.data;
- else
- code = gs_error_rangecheck;
- } else if(code < 0) {
- code = param_read_null(plist,"ColorAdjustMatrix");
- if(code == 0) sd->stc.am = NULL;
- }
- if(code < 0) param_signal_error(plist,"ColorAdjustMatrix",code);
- error = error > code ? code : error;
- /*
- * Read the external array-Parameters
- */
- if(sd->color_info.num_components == 1) { /* DeviceGray */
- stc_read_xarray(0,"Kcoding","Ktransfer");
- stc_read_null("Rcoding"); stc_read_null("Rtransfer");
- stc_read_null("Gcoding"); stc_read_null("Gtransfer");
- stc_read_null("Bcoding"); stc_read_null("Btransfer");
- stc_read_null("Ccoding"); stc_read_null("Ctransfer");
- stc_read_null("Mcoding"); stc_read_null("Mtransfer");
- stc_read_null("Ycoding"); stc_read_null("Ytransfer");
- } else if(sd->color_info.num_components == 3) { /* DeviceRGB */
- stc_read_xarray(0,"Rcoding","Rtransfer");
- stc_read_xarray(1,"Gcoding","Gtransfer");
- stc_read_xarray(2,"Bcoding","Btransfer");
- stc_read_null("Ccoding"); stc_read_null("Ctransfer");
- stc_read_null("Mcoding"); stc_read_null("Mtransfer");
- stc_read_null("Ycoding"); stc_read_null("Ytransfer");
- stc_read_null("Kcoding"); stc_read_null("Ktransfer");
- } else { /* DeviceCMYK */
- stc_read_xarray(0,"Ccoding","Ctransfer");
- stc_read_xarray(1,"Mcoding","Mtransfer");
- stc_read_xarray(2,"Ycoding","Ytransfer");
- stc_read_xarray(3,"Kcoding","Ktransfer");
- stc_read_null("Rcoding"); stc_read_null("Rtransfer");
- stc_read_null("Gcoding"); stc_read_null("Gtransfer");
- stc_read_null("Bcoding"); stc_read_null("Btransfer");
- }
- /*
- * Update remaining color_info values
- */
- if(error == 0) {
- /* compute #values from the component-bits */
- sd->color_info.max_gray = sd->stc.bits < gx_color_value_bits ?
- (1<<sd->stc.bits)-1 : gx_max_color_value;
- /* An integer-algorithm might reduce the number of values */
- if(((sd->stc.dither->flags & STC_TYPE) != STC_FLOAT) &&
- ((sd->stc.dither->minmax[1]-sd->stc.dither->minmax[0]) <
- sd->color_info.max_gray))
- sd->color_info.max_gray = (gx_color_value)
- (sd->stc.dither->minmax[1]-sd->stc.dither->minmax[0]+0.5);
- sd->color_info.max_color = sd->color_info.num_components < 3 ? 0 :
- sd->color_info.max_gray;
- sd->color_info.dither_grays =
- sd->color_info.max_gray < gx_max_color_value ?
- sd->color_info.max_gray+1 : gx_max_color_value;
- sd->color_info.dither_colors = sd->color_info.num_components < 3 ? 0 :
- sd->color_info.dither_grays;
- }
- /*
- * Call superclass-Update
- */
- code = gdev_prn_put_params(pdev, plist);
- error = error > code ? code : error;
- /*
- * Arrrgh, writing BitsPerPixel is really *VERY* special:
- * gdev_prn_put_params verifies, that the external value
- * is written, if not, it raises a rangecheck-error.
- * On the other hand ghostscript is quite unhappy with odd
- * values, so we do the necessary rounding *AFTER* the
- * "superclass-Update".
- */
- if(sd->color_info.depth == 3) sd->color_info.depth = 4;
- else if(sd->color_info.depth > 4)
- sd->color_info.depth = (sd->color_info.depth+7) & ~7;
- /*
- * Allocate the storage for the arrays in memory
- */
- if(error == 0) { /* Allocate new external-arrays */
- for(i = 0; i < sd->color_info.num_components; ++i){ /* Active components */
- int j;
- if((sd->stc.extv[i] != oldstc.extv[i]) &&
- (sd->stc.extv[i] != defext )) { /* Value-Arrays */
- for(j = 0; j < i; ++j)
- if((sd->stc.sizv[j] == sd->stc.sizv[i]) &&
- (memcmp(sd->stc.extv[j],sd->stc.extv[i],
- sd->stc.sizv[i]*sizeof(float)) == 0)) break;
- if(j < i) {
- sd->stc.extv[i] = sd->stc.extv[j];
- } else {
- fp = gs_malloc(sd->memory, sd->stc.sizv[i],sizeof(float),"stc_put_params");
- if(fp != NULL)
- memcpy(fp,sd->stc.extv[i],sd->stc.sizv[i]*sizeof(float));
- else
- code = gs_error_VMerror;
- sd->stc.extv[i] = fp;
- }
- } /* Value-Arrays */
- if((sd->stc.sizc[i] > 1) &&
- (sd->stc.extc[i] != oldstc.extc[i])) { /* Code-Arrays */
- for(j = 0; j < i; ++j)
- if((sd->stc.sizc[j] == sd->stc.sizc[i]) &&
- (memcmp(sd->stc.extc[j],sd->stc.extc[i],
- sd->stc.sizc[i]*sizeof(float)) == 0)) break;
- if(j < i) {
- sd->stc.extc[i] = sd->stc.extc[j];
- } else {
- fp = gs_malloc(sd->memory, sd->stc.sizc[i],sizeof(float),"stc_put_params");
- if(fp != NULL)
- memcpy(fp,sd->stc.extc[i],sd->stc.sizc[i]*sizeof(float));
- else
- code = gs_error_VMerror;
- sd->stc.extc[i] = fp;
- }
- } /* Code-Arrays */
- } /* Active components */
- if((sd->stc.am != NULL) && (sd->stc.am != oldstc.am)) {
- if( sd->color_info.num_components == 1) i = 3;
- else if(sd->color_info.num_components == 3) i = 9;
- else i = 16;
- fp = gs_malloc(sd->memory, i,sizeof(float),"stc_put_params");
- if(fp != NULL) memcpy(fp,sd->stc.am,i*sizeof(float));
- else code = gs_error_VMerror;
- sd->stc.am = fp;
- }
- if(sd->stc.escp_init.data != oldstc.escp_init.data) {
- byte *ip = NULL;
- if(sd->stc.escp_init.size > 0) {
- ip = gs_malloc(sd->memory, sd->stc.escp_init.size,1,"stcolor/init");
- if(ip == NULL) {
- code = gs_error_VMerror;
- sd->stc.escp_init.size = 0;
- } else {
- memcpy(ip,sd->stc.escp_init.data,sd->stc.escp_init.size);
- }
- }
- sd->stc.escp_init.data = ip;
- sd->stc.escp_init.persistent = false;
- }
- if(sd->stc.escp_release.data != oldstc.escp_release.data) {
- byte *ip = NULL;
- if(sd->stc.escp_release.size > 0) {
- ip = gs_malloc(sd->memory, sd->stc.escp_release.size,1,"stcolor/release");
- if(ip == NULL) {
- code = gs_error_VMerror;
- sd->stc.escp_release.size = 0;
- } else {
- memcpy(ip,sd->stc.escp_release.data,sd->stc.escp_release.size);
- }
- }
- sd->stc.escp_release.data = ip;
- sd->stc.escp_release.persistent = false;
- }
- if(code < 0) { /* free newly allocated arrays */
- if((sd->stc.am != NULL) && (sd->stc.am != oldstc.am)) {
- if( sd->color_info.num_components == 1) i = 3;
- else if(sd->color_info.num_components == 3) i = 9;
- else i = 16;
- gs_free(sd->memory, sd->stc.am,i,sizeof(float),"stc_put_params");
- }
- if((sd->stc.escp_init.data != NULL) &&
- (sd->stc.escp_init.data != oldstc.escp_init.data))
- gs_free(sd->memory, (byte *) sd->stc.escp_init.data,sd->stc.escp_init.size,1,
- "stcolor/init");
- if((sd->stc.escp_release.data != NULL) &&
- (sd->stc.escp_release.data != oldstc.escp_release.data))
- gs_free(sd->memory, (byte *) sd->stc.escp_release.data,sd->stc.escp_release.
- size,1,"stcolor/release");
- for(i = 0; i < sd->color_info.num_components; ++i) { /* components */
- int j;
- if((sd->stc.extc[i] != NULL) &&
- (sd->stc.extc[i] != defext) &&
- (sd->stc.extc[i] != oldstc.extc[i])) {
- for(j = 0; j < i; ++j)
- if(sd->stc.extc[i] == sd->stc.extc[j]) break;
- if(i == j) gs_free(sd->memory, sd->stc.extc[i],sd->stc.sizc[i],sizeof(float),
- "stc_put_params");
- }
- if((sd->stc.extv[i] != NULL) &&
- (sd->stc.extv[i] != oldstc.extv[i]) &&
- (sd->stc.extv[i] != defext)) {
- for(j = 0; j < i; ++j)
- if(sd->stc.extv[i] == sd->stc.extv[j]) break;
- if(i == j) gs_free(sd->memory, sd->stc.extv[i],sd->stc.sizv[i],sizeof(float),
- "stc_put_params");
- }
- } /* components */
- } /* free newly allocated arrays */
- } /* Allocate new arrays */
- error = error > code ? code : error;
- /*
- * finally decide upon restore or release of old, unused data
- */
- if(error != 0) { /* Undo changes */
- memcpy(&sd->color_info,&oldcolor,sizeof(oldcolor));
- memcpy(&sd->stc ,&oldstc ,sizeof(oldstc ));
- } else { /* undo / release */
- if((oldstc.escp_init.data != NULL) &&
- (oldstc.escp_init.data != sd->stc.escp_init.data)) {
- gs_free(sd->memory, (byte *)oldstc.escp_init.data,
- oldstc.escp_init.size,1,"stcolor/init");
- }
- if((oldstc.escp_release.data != NULL) &&
- (oldstc.escp_release.data != sd->stc.escp_release.data)) {
- gs_free(sd->memory, (byte *)oldstc.escp_release.data,
- oldstc.escp_release.size,1,"stcolor/release");
- }
- if((oldstc.am != NULL) && (oldstc.am != sd->stc.am)) {
- if( oldcolor.num_components == 1) i = 3;
- else if(oldcolor.num_components == 3) i = 9;
- else i = 16;
- gs_free(sd->memory, oldstc.am,i,sizeof(float),"stc_put_params");
- }
- for(i = 0; i < 4; ++i) {
- int j;
- if((oldstc.extc[i] != NULL) &&
- (oldstc.extc[i] != sd->stc.extc[i]) &&
- (oldstc.dither != NULL) &&
- (oldstc.extc[i] != defext)) {
- for(j = 0; j < i; ++j) if(oldstc.extc[i] == oldstc.extc[j]) break;
- if(i == j) gs_free(sd->memory, oldstc.extc[i],oldstc.sizc[i],sizeof(float),
- "stc_put_params");
- }
- if((oldstc.extv[i] != NULL) &&
- (oldstc.extv[i] != sd->stc.extv[i]) &&
- (oldstc.extv[i] != defext)) {
- for(j = 0; j < i; ++j) if(oldstc.extv[i] == oldstc.extv[j]) break;
- if(i == j) gs_free(sd->memory, oldstc.extv[i],oldstc.sizv[i],sizeof(float),
- "stc_put_params");
- }
- }
- /*
- * Close the device if colormodel changed or recomputation
- * of internal arrays is required
- */
- if(sd->is_open) { /* we might need to close it */
- bool doclose = false;
- if((sd->color_info.num_components != oldcolor.num_components) ||
- (sd->color_info.depth != oldcolor.depth ) ||
- (sd->stc.bits != oldstc.bits ) ||
- (sd->stc.dither != oldstc.dither ))
- doclose = true;
- for(i = 0; i < sd->color_info.num_components; ++i) {
- if(sd->stc.extv[i] != oldstc.extv[i]) doclose = true;
- if(sd->stc.extc[i] != oldstc.extc[i]) doclose = true;
- }
- if(doclose) {
- stc_freedata(pdev->memory, &oldstc);
- for(i = 0; i < 4; ++i) {
- sd->stc.vals[i] = NULL;
- sd->stc.code[i] = NULL;
- }
- gs_closedevice(pdev);
- }
- } /* we might need to close it */
- }
- return error;
- }
- /*
- * 1Bit CMYK-Algorithm
- */
- private int
- stc_gscmyk(stcolor_device *sdev,int npixel,byte *in,byte *buf,byte *out)
- {
- byte *ip = in;
- int error = 0;
- /* ============================================================= */
- if(npixel > 0) { /* npixel > 0 -> scanline-processing */
- /* ============================================================= */
- int p;
- /*
- * simply split the two pixels rsiding in a byte
- */
- for(p = npixel; p > 0; --p) { /* loop over pixels */
- byte tmp =*ip++;
- *out++ = (tmp>>4) & 15;
- if(--p <= 0) break;
- *out++ = tmp & 15;
- } /* loop over pixels */
- /* ============================================================= */
- } else { /* npixel <= 0 -> initialisation */
- /* ============================================================= */
- /* we didn't check for the white-calls above, so this may cause errors */
- if(sdev->stc.dither->flags & STC_WHITE) error = -1;
- /* if we're not setup for bytes, this is an error too */
- if((sdev->stc.dither->flags & STC_TYPE) != STC_BYTE) error = -2;
- /* This IS a direct-driver, so STC_DIRECT must be set! */
- if((sdev->stc.dither->flags & STC_DIRECT) == 0) error = -3;
- /* and cmyk-mode is the only supported mode */
- if(sdev->color_info.num_components != 4) error = -4;
- /* and we support only 4Bit-Depth here */
- if(sdev->color_info.depth != 4) error = -5;
- /* ============================================================= */
- } /* scanline-processing or initialisation */
- /* ============================================================= */
- return error;
- }
- /*
- * The following is an algorithm under test
- */
- private int
- stc_hscmyk(stcolor_device *sdev,int npixel,byte *in,byte *buf,byte *out)
- {
- /* ============================================================= */
- if(npixel < 0) { /* npixel <= 0 -> initialisation */
- /* ============================================================= */
- int i,i2do;
- long *lp = (long *) buf;
- /* CMYK-only algorithm */
- if( sdev->color_info.num_components != 4) return -1;
- /*
- * check wether stcdither & TYPE are correct
- */
- if(( sdev->stc.dither == NULL) ||
- ((sdev->stc.dither->flags & STC_TYPE) != STC_LONG)) return -2;
- /*
- * check wether the buffer-size is sufficiently large
- */
- if(((sdev->stc.dither->flags/STC_SCAN) < 1) ||
- ( sdev->stc.dither->bufadd <
- (1 + 2*sdev->color_info.num_components))) return -3;
- /*
- * must have STC_CMYK10, STC_DIRECT, but not STC_WHITE
- */
- if((sdev->stc.dither->flags & STC_CMYK10) == 0) return -4;
- if((sdev->stc.dither->flags & STC_DIRECT) == 0) return -5;
- if((sdev->stc.dither->flags & STC_WHITE ) != 0) return -6;
- /*
- * Must have values between 0-1023.0
- */
- if((sdev->stc.dither->minmax[0] != 0.0) ||
- (sdev->stc.dither->minmax[1] != 1023.0)) return -7;
- /*
- * initialize buffer
- */
- i2do = 1 + 8 - 4 * npixel;
- lp[0] = 0;
- if(sdev->stc.flags & STCDFLAG0) {
- for(i = 1; i < i2do; ++i) lp[i] = 0;
- } else {
- for(i = 1; i < i2do; ++i) lp[i] = (rand() % 381) - 190;
- }
- /* ============================================================= */
- } else { /* npixel > 0 && in != NULL -> scanline-processing */
- /* ============================================================= */
- long errc[4],*errv;
- int step = buf[0] ? -1 : 1;
- stc_pixel *ip = (stc_pixel *) in;
- buf[0] = ~ buf[0];
- errv = (long *) buf + 5;
- if(step < 0) {
- ip += npixel-1;
- out += npixel-1;
- errv += 4*(npixel-1);
- }
- errc[0] = 0; errc[1] = 0; errc[2] = 0; errc[3] = 0;
- while(npixel-- > 0) {
- register stc_pixel ci,mode;
- register long k,v,n;
- register int pixel; /* internal pixel-value */
- ci = *ip; ip += step;
- mode = ci & 3;
- k = (ci>>2) & 0x3ff;
- pixel = 0;
- v = k+errv[3]+((7*errc[3])>>4);
- if(mode == 3) { /* only Black allowed to fire */
- if(v > 511) {
- v -= 1023;
- pixel = BLACK;
- }
- errv[3-(step<<2)] += ((3*v+8)>>4); /* 3/16 */
- errv[3] = ((5*v+errc[3]+8)>>4);/* 5/16 +1/16 (rest) */
- errc[3] = v;
- errv[0] = errv[0] < -190 ? -190 : errv[0] < 190 ? errv[0] : 190;
- errv[1] = errv[1] < -190 ? -190 : errv[1] < 190 ? errv[1] : 190;
- errv[2] = errv[2] < -190 ? -190 : errv[2] < 190 ? errv[2] : 190;
- errc[0] = 0; errc[1] = 0; errc[2] = 0;
- } else if(v > 511) { /* black known to fire */
- v -= 1023;
- pixel = BLACK;
- errv[3-(step<<2)] += ((3*v+8)>>4); /* 3/16 */
- errv[3] = ((5*v+errc[3]+8)>>4);/* 5/16 +1/16 (rest) */
- errc[3] = v;
- n = (ci>>12) & 0x3ff;
- if(mode == 2) { v = k; }
- else { v = n; n = (ci>>22) & 0x3ff; }
- v += errv[2]+((7*errc[2])>>4)-1023;
- if(v < -511) v = -511;
- errv[2-(step<<2)] += ((3*v+8)>>4); /* 3/16 */
- errv[2] = ((5*v+errc[2]+8)>>4);/* 5/16 +1/16 (rest) */
- errc[2] = v;
- if(mode == 1) { v = k; }
- else { v = n; n = (ci>>22) & 0x3ff; }
- v += errv[1]+((7*errc[1])>>4)-1023;
- if(v < -511) v = -511;
- errv[1-(step<<2)] += ((3*v+8)>>4); /* 3/16 */
- errv[1] = ((5*v+errc[1]+8)>>4);/* 5/16 +1/16 (rest) */
- errc[1] = v;
- if(mode == 0) v = k;
- else v = n;
- v += errv[0]+((7*errc[0])>>4)-1023;
- if(v < -511) v = -511;
- errv[0-(step<<2)] += ((3*v+8)>>4); /* 3/16 */
- errv[0] = ((5*v+errc[0]+8)>>4);/* 5/16 +1/16 (rest) */
- errc[0] = v;
- } else { /* Black does not fire initially */
- long kv = v; /* Black computed after colors */
- n = (ci>>12) & 0x3ff;
- if(mode == 2) { v = k; }
- else { v = n; n = (ci>>22) & 0x3ff; }
- v += errv[2]+((7*errc[2])>>4);
- if(v > 511) {
- pixel |= YELLOW;
- v -= 1023;
- }
- errv[2-(step<<2)] += ((3*v+8)>>4); /* 3/16 */
- errv[2] = ((5*v+errc[2]+8)>>4);/* 5/16 +1/16 (rest) */
- errc[2] = v;
- if(mode == 1) { v = k; }
- else { v = n; n = (ci>>22) & 0x3ff; }
- v += errv[1]+((7*errc[1])>>4);
- if(v > 511) {
- pixel |= MAGENTA;
- v -= 1023;
- }
- errv[1-(step<<2)] += ((3*v+8)>>4); /* 3/16 */
- errv[1] = ((5*v+errc[1]+8)>>4);/* 5/16 +1/16 (rest) */
- errc[1] = v;
- if(mode == 0) v = k;
- else v = n;
- v += errv[0]+((7*errc[0])>>4);
- if(v > 511) {
- pixel |= CYAN;
- v -= 1023;
- }
- errv[0-(step<<2)] += ((3*v+8)>>4); /* 3/16 */
- errv[0] = ((5*v+errc[0]+8)>>4);/* 5/16 +1/16 (rest) */
- errc[0] = v;
- v = kv;
- if(pixel == (CYAN|MAGENTA|YELLOW)) {
- pixel = BLACK;
- v = v > 511 ? v-1023 : -511;
- }
- errv[3-(step<<2)] += ((3*v+8)>>4); /* 3/16 */
- errv[3] = ((5*v+errc[3]+8)>>4);/* 5/16 +1/16 (rest) */
- errc[3] = v;
- }
- errv += step<<2;
- *out = pixel; out += step;
- } /* loop over pixels */
- /* ============================================================= */
- } /* initialisation, white or scanline-processing */
- /* ============================================================= */
- return 0;
- }
|