gdevstc.c 116 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571
  1. /* Copyright (C) 1995, 1996 Aladdin Enterprises. All rights reserved.
  2. This software is provided AS-IS with no warranty, either express or
  3. implied.
  4. This software is distributed under license and may not be copied,
  5. modified or distributed except as expressly authorized under the terms
  6. of the license contained in the file LICENSE in this distribution.
  7. For more information about licensing, please refer to
  8. http://www.ghostscript.com/licensing/. For information on
  9. commercial licensing, go to http://www.artifex.com/licensing/ or
  10. contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  11. San Rafael, CA 94903, U.S.A., +1(415)492-9861.
  12. */
  13. /* $Id: gdevstc.c,v 1.11 2004/11/22 19:25:57 giles Exp $*/
  14. /* Epson Stylus-Color Printer-Driver */
  15. /***
  16. *** This file was "copied" from gdevcdj.c (ghostscript-3.12), which was
  17. *** contributed by:
  18. *** George Cameron - g.cameron@biomed.abdn.ac.ukis
  19. *** Koert Zeilstra - koert@zen.cais.com
  20. *** Eckhard Rueggeberg - eckhard@ts.go.dlr.de
  21. ***
  22. *** Some of the ESC/P2-code was drawn from gdevescp.c, contributed by
  23. *** Richard Brown - rab@eos.ncsu.edu
  24. ***
  25. *** The POSIX-Interrupt-Code is from (Compile-Time-Option -DSTC_SIGNAL)
  26. *** Frederic Loyer - loyer@ensta.fr
  27. ***
  28. *** And several improvements are based on discussions with
  29. *** Brian Converse - BCONVERSE@ids.net
  30. *** Bill Davidson - bdavidson@ra.isisnet.com
  31. *** Gero Guenther - gero@cs.tu-berlin.de
  32. *** Jason Patterson - jason@reflections.com.au
  33. *** ? Rueschstroer - rue@ibe.med.uni-muenchen.de
  34. *** Steven Singer - S.Singer@ph.surrey.ac.uk
  35. ***
  36. *** And the remaining little rest, mainly the bugs, were written by me:
  37. *** Gunther Hess - gunther@elmos.de
  38. ***
  39. *** P.S.: there is some documentation, see devices.doc
  40. ***
  41. *** Revision-History:
  42. *** 16-DEC-1994 1.1 - initial Version (GS-Dithering & Plain-Write)
  43. ...
  44. *** 30-JAN-1995 1.11 - FS-Improvements, u/sWeave, 1/4/24-Bits
  45. *** 5-MAR-1995 1.12 - L. Peter Deutsch - updated put_params routine
  46. (first distributed version with gs3.33)
  47. *** 26-APR-1995 1.13 - merged Peters fixes with algorithmic changes:
  48. Changed 24Bit-Mode, added 32Bit-Mode (moves colors)
  49. [Arrgh: much better than 1.12, but patch was lost]
  50. *** 5-JUN-1995 1.14 - Added Color-Correction & Transfer-Curves
  51. (Several Beta-Testers, but not distributed)
  52. ...
  53. *** 24-JUL-1995 1.16 - Made dithering-Algorithms external-functions.
  54. (Mailed for Beta-Distribution)
  55. *** 10-AUG-1995 1.17 - Several Bug-Fixes and some new features:
  56. CMYK10-Coding added
  57. Readonly Parameters added
  58. "Algorithms", "BitsPerComponent", "Version"
  59. Parameters Flag0-4, Model, OutputCode
  60. (mailed for distribution)
  61. *** 14-SEP-1995 1.18 Fixes Bugs with Borland C (gs3.47)
  62. *** 23-SEP-1995 1.19 - reorganized printcode + bug-fixing
  63. *** 24-SEP-1995 1.20 - Little Cleanup for the release
  64. *** 25-SEP-1995 1.21 - Readonly-Parameters added to put_params.
  65. *** 31-Dec-1995 1.22 - Sanitary Engineering on the code
  66. *** 16-Jan-1996 1.23 - Added String escp_Release
  67. *** 8-May-1996 1.90 - Reintroduced Deltarow & Fixed MEMORY-BUG!
  68. ***/
  69. #include "gdevstc.h"
  70. #ifdef STC_SIGNAL
  71. # include <signal.h>
  72. #endif /* STC_SIGNAL */
  73. /***
  74. *** Mode-Table - the various algorithms
  75. *** (The intention is, that this source can live alone)
  76. ***/
  77. private stc_proc_dither(stc_gscmyk); /* resides in this file */
  78. private stc_proc_dither(stc_hscmyk); /* resides in this file */
  79. #include <stdlib.h> /* for rand, used in stc_hscmyk */
  80. private const stc_dither_t stc_dither[] = {
  81. {"gscmyk", stc_gscmyk, DeviceCMYK|STC_BYTE|STC_DIRECT,0,{0.0,1.0}},
  82. {"hscmyk", stc_hscmyk,
  83. DeviceCMYK|STC_LONG|STC_CMYK10|STC_DIRECT|1*STC_SCAN,1+2*4,
  84. {0.0, 1023.0}},
  85. STC_MODI
  86. { NULL , NULL , 0, 0,{0.0,0.0}}
  87. };
  88. /***
  89. *** forward-declarations of routines
  90. ***/
  91. /* Primary Device functions
  92. * (I've the idea to rename the driver to stc)
  93. */
  94. private dev_proc_print_page(stc_print_page);
  95. private dev_proc_open_device(stc_open);
  96. private dev_proc_close_device(stc_close);
  97. private dev_proc_get_params(stc_get_params);
  98. private dev_proc_put_params(stc_put_params);
  99. /*
  100. * Color-Mapping-functions.
  101. */
  102. /* routines for monochrome monochrome modi */
  103. private dev_proc_map_rgb_color(stc_map_gray_color);
  104. private dev_proc_map_color_rgb(stc_map_color_gray);
  105. /* routines for RGB-Modi */
  106. private dev_proc_map_rgb_color(stc_map_rgb_color);
  107. private dev_proc_map_color_rgb(stc_map_color_rgb);
  108. /* routines for general CMYK-Modi */
  109. private dev_proc_map_cmyk_color(stc_map_cmyk_color);
  110. private dev_proc_map_color_rgb(stc_map_color_cmyk);
  111. /* routines for 10Bit/Component CMYK */
  112. private dev_proc_map_cmyk_color(stc_map_cmyk10_color);
  113. private dev_proc_map_color_rgb(stc_map_color_cmyk10);
  114. /***
  115. *** Table of Device-Procedures
  116. ***/
  117. private gx_device_procs stcolor_procs = {
  118. stc_open,
  119. gx_default_get_initial_matrix,
  120. gx_default_sync_output,
  121. gdev_prn_output_page,
  122. stc_close,
  123. NULL,
  124. stc_map_color_cmyk,
  125. NULL, /* fill_rectangle */
  126. NULL, /* tile_rectangle */
  127. NULL, /* copy_mono */
  128. NULL, /* copy_color */
  129. NULL, /* draw_line */
  130. gx_default_get_bits,
  131. stc_get_params,
  132. stc_put_params,
  133. stc_map_cmyk_color
  134. };
  135. /***
  136. *** A local dummy-array for extvals
  137. ***/
  138. private float defext[] = { 0.0, 1.0 };
  139. /***
  140. *** Main device-control structure
  141. ***/
  142. stcolor_device far_data gs_stcolor_device = {
  143. prn_device_body(stcolor_device, stcolor_procs, "stcolor",
  144. DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
  145. X_DPI, Y_DPI,
  146. STC_L_MARGIN,STC_B_MARGIN,STC_R_MARGIN,STC_T_MARGIN,
  147. 4, 4, 1, 1, 2, 2, /* default: cmyk-direct */
  148. stc_print_page),
  149. {STCNWEAVE, /* stcflags: noWeave/bidirectional */
  150. 1, /* stcbits: matches the default */
  151. stc_dither, /* stcdither: first algorithm */
  152. NULL, /* stcam: NULL -> not used */
  153. { NULL, NULL, NULL, NULL}, /* extcode: none defined yet */
  154. { 0, 0, 0, 0}, /* sizcode: 0, since no extcode yet */
  155. { NULL, NULL, NULL, NULL}, /* stccode: computed by put_params */
  156. {defext,defext,defext,defext},/* extvals: default */
  157. { 2, 2, 2, 2}, /* sizvals: default countof(defext) */
  158. { NULL, NULL, NULL, NULL}, /* stcvals: computed by put_params */
  159. { 0, 0, 0}, /* white-run */
  160. { 0, 0, 0}, /* white-end */
  161. {NULL,0,false}, /* algorithm-table */
  162. {NULL,0,false}, /* initialization-String (BOP) */
  163. {NULL,0,false}, /* release-String (EOP) */
  164. 0,0,0,0, /* New escp-stuff */
  165. 1} /* itemsize used by algorithm */
  166. };
  167. /***
  168. *** Test for white scan-lines
  169. ***/
  170. private bool stc_iswhite(stcolor_device *, int, byte *);
  171. /***
  172. *** Functions used for conversion inside the print-loop
  173. ***/
  174. #define stc_proc_iconvert(Name) \
  175. byte * Name(stcolor_device *sd,byte *ext_data,int prt_pixels,byte *alg_line)
  176. private stc_proc_iconvert(stc_any_depth); /* general input-conversion */
  177. private stc_proc_iconvert(stc_rgb24_long); /* 24Bit RGB -> long's */
  178. private stc_proc_iconvert(stc_cmyk32_long); /* 32Bit CMYK -> long's */
  179. private stc_proc_iconvert(stc_any_direct); /* use ext_data as input */
  180. private stc_proc_iconvert(stc_cmyk10_byte); /* CMYK10->vals-> any type */
  181. private stc_proc_iconvert(stc_cmyk10_long); /* CMYK10->vals-> any type */
  182. private stc_proc_iconvert(stc_cmyk10_float); /* CMYK10->vals-> any type */
  183. private stc_proc_iconvert(stc_cmyk10_dbyte); /* CMYK10 direct bytes */
  184. private stc_proc_iconvert(stc_cmyk10_dlong); /* CMYK10 direct longs */
  185. /***
  186. *** Print-functions
  187. ***/
  188. private void stc_print_weave(stcolor_device *sd,FILE *prn_stream);
  189. private void stc_print_bands(stcolor_device *sd,FILE *prn_stream);
  190. private void stc_print_delta(stcolor_device *sd,FILE *prn_stream);
  191. private int stc_print_setup(stcolor_device *sd);
  192. /***
  193. *** compute the ESC/P2 specific values
  194. ***/
  195. private int
  196. stc_print_setup(stcolor_device *sd)
  197. {
  198. /*
  199. * Compute the resolution-parameters
  200. */
  201. sd->stc.escp_u = (int)(3600.0 / sd->y_pixels_per_inch); /* y-units */
  202. sd->stc.escp_h = (int)(3600.0 / sd->x_pixels_per_inch); /* x-units */
  203. sd->stc.escp_v = sd->stc.flags & (STCUWEAVE | STCNWEAVE) ?
  204. sd->stc.escp_u : 40;
  205. /*
  206. * Initialize color
  207. */
  208. sd->stc.escp_c = 0; /* preselect-black */
  209. /*
  210. * Band-Width
  211. */
  212. if((sd->stc.flags & STCBAND) == 0) {
  213. if(sd->stc.escp_v != sd->stc.escp_u) sd->stc.escp_m = 15;
  214. else if(STCSTCII == (sd->stc.flags & STCMODEL)) sd->stc.escp_m = 1;
  215. else if( sd->stc.flags & STCUWEAVE) sd->stc.escp_m = 1;
  216. else if((sd->stc.escp_v == sd->stc.escp_u) &&
  217. (sd->stc.escp_u == 5)) sd->stc.escp_m = 1;
  218. else sd->stc.escp_m = 1;
  219. }
  220. /*
  221. * Page-Dimensions
  222. */
  223. if((sd->stc.flags & STCWIDTH ) == 0)
  224. sd->stc.escp_width = (int)(sd->width -
  225. (dev_l_margin(sd)+dev_r_margin(sd))*sd->x_pixels_per_inch);
  226. if((sd->stc.flags & STCHEIGHT) == 0)
  227. sd->stc.escp_height = sd->height;
  228. if((sd->stc.flags & STCTOP) == 0)
  229. sd->stc.escp_top = (int)(dev_t_margin(sd)*sd->y_pixels_per_inch);
  230. if((sd->stc.flags & STCBOTTOM) == 0)
  231. sd->stc.escp_bottom = (int)(sd->height -
  232. dev_b_margin(sd)*sd->y_pixels_per_inch);
  233. if((sd->stc.flags & STCINIT) == 0) { /* No Initialization-String defined */
  234. int need = 8 /* Reset, Graphics-Mode 1 */
  235. + 6 /* MicroWeave */
  236. + 6 /* Select Units */
  237. + 7 /* Set Page-Length */
  238. + 9 /* Set Margins */
  239. + 3; /* Select Unidirectionality */
  240. byte *bp = (byte *) (sd->stc.escp_init.data);
  241. if(need != sd->stc.escp_init.size) { /* Reallocate */
  242. if(NULL != (bp = gs_malloc(sd->memory, need,1,"stcolor/init"))) { /* Replace */
  243. if(0 != sd->stc.escp_init.size)
  244. gs_free(sd->memory, (byte *)sd->stc.escp_init.data,sd->stc.escp_init.size,1,
  245. "stcolor/init");
  246. sd->stc.escp_init.data = bp;
  247. sd->stc.escp_init.size = need;
  248. sd->stc.escp_init.persistent = false;
  249. } else { /* Replace */
  250. return_error(gs_error_VMerror);
  251. }
  252. }
  253. if(need != 39) return_error(gs_error_unregistered);
  254. memcpy(bp,
  255. /* 1 1 11 1 11 1 1 1 2 22 2 2 22 2 22 3 3 3333 3 33*/
  256. /* 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*/
  257. "\033@\033(G\001\0\1\033(i\1\0w\033(U\001\000u\033(C\2\000hh\033(c\4\000ttbb\033U",
  258. need);
  259. if((sd->stc.flags & STCUWEAVE) != 0) bp[13] = '\1';
  260. else bp[13] = '\0';
  261. bp[19] = sd->stc.escp_u;
  262. bp[25] = sd->stc.escp_height & 0xff;
  263. bp[26] = (sd->stc.escp_height>>8) & 0xff;
  264. bp[32] = sd->stc.escp_top & 0xff;
  265. bp[33] = (sd->stc.escp_top>>8) & 0xff;
  266. bp[34] = sd->stc.escp_bottom & 0xff;
  267. bp[35] = (sd->stc.escp_bottom>>8) & 0xff;
  268. if(sd->stc.flags & STCUNIDIR) bp[38] = 1;
  269. else bp[38] = 0;
  270. } /* No Initialization-String defined */
  271. if((sd->stc.flags & STCRELEASE) == 0) { /* No Release-String defined */
  272. int need = 3; /* ESC @ \f */
  273. byte *bp = (byte *) (sd->stc.escp_release.data);
  274. if(need != sd->stc.escp_release.size) { /* Reallocate */
  275. if(NULL != (bp = gs_malloc(sd->memory, need,1,"stcolor/release"))) { /* Replace */
  276. if(0 != sd->stc.escp_release.size)
  277. gs_free(sd->memory, (byte *)sd->stc.escp_release.data,sd->stc.escp_release.size,1,
  278. "stcolor/release");
  279. sd->stc.escp_release.data = bp;
  280. sd->stc.escp_release.size = need;
  281. sd->stc.escp_release.persistent = false;
  282. } else { /* Replace */
  283. return_error(gs_error_VMerror);
  284. }
  285. }
  286. if(need != 3) return_error(gs_error_unregistered);
  287. memcpy(bp,"\033@\f",need);
  288. } /* No Release-String defined */
  289. return 0;
  290. }
  291. /***
  292. *** stc_print_page: here we go to do the nasty work
  293. ***/
  294. private int
  295. stc_print_page(gx_device_printer * pdev, FILE * prn_stream)
  296. {
  297. stcolor_device *sd = (stcolor_device *) pdev;
  298. long flags = sd == NULL ? 0 : sd->stc.flags;
  299. int npass; /* # of print-passes (softweave) */
  300. int ext_size; /* size of a ghostscript-scanline */
  301. byte *ext_line; /* dyn: for this scanline */
  302. int alg_size; /* size of a scanline for the dithering-algorithm */
  303. byte *alg_line; /* dyn: 1 scanline for the dithering-algorithm */
  304. int buf_size; /* size of the private-buffer for dither-function */
  305. byte *buf; /* dyn: the private buffer */
  306. int prt_pixels; /* Number of pixels printed */
  307. byte *col_line; /* A Line with a byte per pixel */
  308. #define OK4GO ((flags & STCOK4GO) != 0)
  309. #define SORRY ( flags &= ~STCOK4GO)
  310. if(0 > (npass = stc_print_setup(sd))) return_error(npass);
  311. npass = sd->stc.escp_v / sd->stc.escp_u;
  312. /***
  313. *** Allocate dynamic memory
  314. ***/
  315. ext_size = gdev_prn_raster(sd);
  316. ext_line = gs_malloc(sd->memory, ext_size,1,"stc_print_page/ext_line");
  317. if(ext_line == NULL) SORRY;
  318. prt_pixels = sd->stc.escp_width;
  319. sd->stc.prt_size = (prt_pixels+7)/8;
  320. prt_pixels = sd->stc.prt_size * 8;
  321. sd->stc.prt_scans = (int)(sd->height -
  322. (dev_t_margin(sd)+dev_b_margin(sd))*sd->y_pixels_per_inch);
  323. col_line = gs_malloc(sd->memory, prt_pixels,1,"stc_print_page/col_line");
  324. if(col_line == NULL) SORRY;
  325. alg_size = prt_pixels;
  326. alg_size *= sd->color_info.num_components;
  327. if((sd->stc.dither->flags & STC_DIRECT) ||
  328. ((sd->stc.bits == 8) &&
  329. (sd->stc.alg_item == 1))) {
  330. alg_line = NULL;
  331. } else {
  332. alg_line = gs_malloc(sd->memory, alg_size,sd->stc.alg_item,"stc_print_page/alg_line");
  333. if(alg_line == NULL) SORRY;
  334. }
  335. buf_size = sd->stc.dither->bufadd
  336. + alg_size*(sd->stc.dither->flags/STC_SCAN);
  337. if(buf_size > 0) {
  338. buf = gs_malloc(sd->memory, buf_size,sd->stc.alg_item,"stc_print_page/buf");
  339. if(buf == NULL) SORRY;
  340. } else {
  341. buf = NULL;
  342. }
  343. /*
  344. * compute the number of printer-buffers
  345. */
  346. for(sd->stc.prt_buf = 16; sd->stc.prt_buf < (sd->stc.escp_m * npass);
  347. sd->stc.prt_buf <<= 1);
  348. if(sd->color_info.num_components > 1) sd->stc.prt_buf *= 4;
  349. sd->stc.prt_width = gs_malloc(sd->memory, sd->stc.prt_buf,sizeof(int),
  350. "stc_print_page/prt_width");
  351. if(sd->stc.prt_width == NULL) SORRY;
  352. sd->stc.prt_data = gs_malloc(sd->memory, sd->stc.prt_buf,sizeof(byte *),
  353. "stc_print_page/prt_data");
  354. if(sd->stc.prt_data == NULL) {
  355. SORRY;
  356. } else {
  357. int i;
  358. for(i = 0; i < sd->stc.prt_buf; ++i) {
  359. sd->stc.prt_data[i] = gs_malloc(sd->memory, sd->stc.prt_size,1,
  360. "stc_print_page/prt");
  361. if(sd->stc.prt_data[i] == NULL) SORRY;
  362. }
  363. }
  364. sd->stc.seed_size = (sd->stc.prt_size + 2*sizeof(int) - 1)/sizeof(int);
  365. {
  366. int i;
  367. for(i = 0; i < sd->color_info.num_components; ++i) {
  368. if((flags & STCCOMP) == STCDELTA) {
  369. sd->stc.seed_row[i] = gs_malloc(sd->memory, sd->stc.seed_size,sizeof(int),
  370. "stc_print_page/seed_row");
  371. if(sd->stc.seed_row[i] == NULL) SORRY;
  372. else memset(sd->stc.seed_row[i],0,sd->stc.seed_size*sizeof(int));
  373. } else {
  374. sd->stc.seed_row[i] = NULL;
  375. }
  376. }
  377. while(i < countof(sd->stc.seed_row)) sd->stc.seed_row[i++] = NULL;
  378. }
  379. switch(flags & STCCOMP) {
  380. case STCPLAIN:
  381. sd->stc.escp_size = 64 + sd->stc.prt_size;
  382. break;
  383. case STCDELTA:
  384. sd->stc.escp_size = 64 + 2 * sd->stc.prt_size;
  385. break;
  386. default:
  387. sd->stc.escp_size = 64 +
  388. sd->stc.prt_size + (sd->stc.prt_size + 127)/128;
  389. break;
  390. }
  391. sd->stc.escp_data = gs_malloc(sd->memory, sd->stc.escp_size,1,
  392. "stc_print_page/escp_data");
  393. if(sd->stc.escp_data == NULL) SORRY;
  394. /*
  395. * If we're still ok, we can print something
  396. */
  397. if(OK4GO) {
  398. int ncolor;
  399. int buf_i;
  400. stc_proc_iconvert((*iconvert)) = stc_any_depth;
  401. /*
  402. * initialize col_line
  403. */
  404. if(sd->color_info.num_components == 3) {
  405. memset(col_line,RED|GREEN|BLUE,prt_pixels);
  406. } else {
  407. memset(col_line,0, prt_pixels);
  408. }
  409. /*
  410. * select proper conversion for input to algorithm
  411. */
  412. if( (sd->stc.dither->flags & STC_DIRECT ) ||
  413. ((sd->stc.bits == 8) &&
  414. (sd->stc.alg_item == 1)))
  415. iconvert = stc_any_direct;
  416. else if((sd->color_info.num_components == 3) &&
  417. (sd->color_info.depth == 24) &&
  418. (sizeof(long) == sd->stc.alg_item))
  419. iconvert = stc_rgb24_long;
  420. else if(sd->stc.flags & STCCMYK10) {
  421. if( ((sd->stc.dither->flags & STC_TYPE) == STC_BYTE) &&
  422. ( sd->stc.dither->minmax[0] == 0.0 ))
  423. iconvert = stc_cmyk10_dbyte;
  424. else if ((sd->stc.dither->flags & STC_TYPE) == STC_BYTE)
  425. iconvert = stc_cmyk10_byte;
  426. else if(((sd->stc.dither->flags & STC_TYPE) == STC_LONG) &&
  427. ( sd->stc.dither->minmax[0] == 0.0 ) &&
  428. ( sd->stc.dither->minmax[1] <= 1023.0 ))
  429. iconvert = stc_cmyk10_dlong;
  430. else if( (sd->stc.dither->flags & STC_TYPE) == STC_LONG)
  431. iconvert = stc_cmyk10_long;
  432. else
  433. iconvert = stc_cmyk10_float;
  434. }
  435. else if((sd->color_info.num_components == 4) &&
  436. (sd->color_info.depth == 32) &&
  437. (sizeof(long) == sd->stc.alg_item))
  438. iconvert = stc_cmyk32_long;
  439. /*
  440. * initialize the algorithm
  441. */
  442. if((*sd->stc.dither->fun)(sd,-prt_pixels,alg_line,buf,col_line) < 0)
  443. SORRY;
  444. /*
  445. * Main-Print-Loop
  446. */
  447. if(OK4GO) {
  448. #ifdef STC_SIGNAL
  449. sigset_t stc_int_mask, stc_int_save, stc_int_pending;
  450. sigemptyset(&stc_int_mask);
  451. sigaddset(&stc_int_mask,SIGINT);
  452. sigprocmask(SIG_BLOCK,&stc_int_mask, &stc_int_save);
  453. #endif /* STC_SIGNAL */
  454. if(sd->color_info.num_components > 1) ncolor = 4;
  455. else ncolor = 1;
  456. /*
  457. * Decide, wether we Adjust Linefeeds or not. (I hate it here)
  458. */
  459. if((0 == ((sd->stc.escp_m*sd->stc.escp_u) % 10)) &&
  460. (256 > ((sd->stc.escp_m*sd->stc.escp_u) / 10))) sd->stc.escp_lf = sd->stc.escp_m;
  461. else sd->stc.escp_lf = 0;
  462. /*
  463. * prepare run-values, then loop over scans
  464. */
  465. sd->stc.stc_y = 0; /* current printer y-Position */
  466. sd->stc.buf_y = 0; /* Top-Position within the buffer */
  467. sd->stc.prt_y = 0; /* physical position of the printer */
  468. buf_i = 0; /* next free line in buffer */
  469. sd->stc.flags &= ~STCPRINT; /* no data yet */
  470. while(sd->stc.stc_y < sd->stc.prt_scans) { /* Until all scans are processed */
  471. int need;
  472. need = sd->stc.stc_y + npass * sd->stc.escp_m;
  473. if(sd->stc.buf_y < need) { /* Nr. 5 (give me input) */
  474. /* read as much as the buffer can hold */
  475. if(ncolor == 1) need = sd->stc.stc_y + sd->stc.prt_buf;
  476. else need = sd->stc.stc_y + (sd->stc.prt_buf>>2);
  477. for(;sd->stc.buf_y < need;
  478. buf_i = (sd->stc.prt_buf-1) & (buf_i+ncolor),
  479. ++sd->stc.buf_y) {
  480. int color;
  481. byte *ext_data;
  482. byte *alg_data;
  483. /* initialize output data 1st -> may take shortcut */
  484. for(color = 0; color < ncolor; ++color) {
  485. memset(sd->stc.prt_data[buf_i+color],0,sd->stc.prt_size);
  486. sd->stc.prt_width[buf_i+color] = 0;
  487. }
  488. /* "read data", immediately continue if all is white */
  489. if(sd->stc.buf_y < sd->stc.prt_scans) { /* Test for White */
  490. gdev_prn_get_bits(pdev,sd->stc.buf_y,ext_line,&ext_data);
  491. color = stc_iswhite(sd,prt_pixels,ext_data) ? ext_size : 0;
  492. } else {
  493. color = ext_size;
  494. } /* Test for White */
  495. if(color >= ext_size) { /* bypass processing */
  496. if(sd->stc.dither->flags & STC_WHITE)
  497. (*sd->stc.dither->fun)(sd,prt_pixels,NULL,buf,col_line);
  498. continue;
  499. } /* bypass processing */
  500. /* convert data for the various cases */
  501. alg_data = (*iconvert)(sd,ext_data,prt_pixels,alg_line);
  502. /*
  503. * invoke the dithering-algorithm
  504. */
  505. (*sd->stc.dither->fun)(sd,prt_pixels,alg_data,buf,col_line);
  506. /*
  507. * convert col_line to printer-format (separate colors)
  508. */
  509. switch(sd->color_info.num_components) {
  510. case 1: /* Black & White: just merge into 8 Bytes */
  511. {
  512. byte *bytein,*byteout;
  513. int width;
  514. bytein = col_line;
  515. byteout = sd->stc.prt_data[buf_i];
  516. for(width = 1; width <= sd->stc.prt_size; ++width) {
  517. byte tmp = 0;
  518. byte i;
  519. for(i = 128; i; i >>= 1) if(*bytein++) tmp |= i;
  520. if(tmp != 0) sd->stc.prt_width[buf_i] = width;
  521. *byteout++ = tmp;
  522. }
  523. }
  524. break;
  525. case 3: /* convert rgb into cmyk */
  526. {
  527. byte *bytein;
  528. int width;
  529. bytein = col_line;
  530. for(width = 0; width < sd->stc.prt_size; ++width) {
  531. byte i,tmp,cmyk[4];
  532. memset(cmyk,0,4);
  533. for(i = 128; i; i >>= 1) {
  534. static const byte rgb2cmyk[] = {
  535. BLACK, /* 0->Black */
  536. CYAN | MAGENTA, /* 1->BLUE */
  537. CYAN | YELLOW, /* 2->GREEN */
  538. CYAN, /* 3->CYAN */
  539. MAGENTA | YELLOW, /* 4->RED */
  540. MAGENTA, /* 5->MAGENTA */
  541. YELLOW, /* 6->YELLOW */
  542. 0}; /* 7->WHITE */
  543. tmp = rgb2cmyk[(*bytein++) & 7];
  544. if(tmp & BLACK) cmyk[3] |= i;
  545. if(tmp & YELLOW) cmyk[2] |= i;
  546. if(tmp & MAGENTA) cmyk[1] |= i;
  547. if(tmp & CYAN) cmyk[0] |= i;
  548. }
  549. for(i = 0; i < 4; ++i) {
  550. if(cmyk[i] != 0) sd->stc.prt_width[buf_i+i] = width+1;
  551. sd->stc.prt_data[buf_i+i][width] = cmyk[i];
  552. }
  553. }
  554. }
  555. break;
  556. case 4: /* split cmyk */
  557. {
  558. byte *bytein;
  559. int width;
  560. bytein = col_line;
  561. for(width = 0; width < sd->stc.prt_size; ++width) {
  562. byte i,tmp,cmyk[4];
  563. memset(cmyk,0,4);
  564. for(i = 128; i; i >>= 1) {
  565. tmp = (*bytein++) & 15;
  566. if(tmp & BLACK) cmyk[3] |= i;
  567. if(tmp & YELLOW) cmyk[2] |= i;
  568. if(tmp & MAGENTA) cmyk[1] |= i;
  569. if(tmp & CYAN) cmyk[0] |= i;
  570. }
  571. for(i = 0; i < 4; ++i) {
  572. if(cmyk[i] != 0) sd->stc.prt_width[buf_i+i] = width+1;
  573. sd->stc.prt_data[buf_i+i][width] = cmyk[i];
  574. }
  575. }
  576. }
  577. break;
  578. default: break;
  579. }
  580. }
  581. } /* Nr. 5 (give me input) */
  582. /*
  583. * Nr. 5 has got enough input, now we should print it
  584. */
  585. if((flags & STCCOMP) == STCDELTA) stc_print_delta(sd,prn_stream);
  586. else if(npass > 1) stc_print_weave(sd,prn_stream);
  587. else stc_print_bands(sd,prn_stream);
  588. #ifdef STC_SIGNAL
  589. sigpending(&stc_int_pending);
  590. if(sigismember(&stc_int_pending,SIGINT)) {
  591. fputs("\033@[Aborted]\f", prn_stream);
  592. fflush(prn_stream);
  593. sigprocmask(SIG_SETMASK,&stc_int_save,NULL);
  594. break;
  595. }
  596. #endif /* STC_SIGNAL */
  597. } /* Until all scans are processed */
  598. if(sd->stc.flags & STCPRINT) {
  599. if((flags & STCCOMP) == STCDELTA) fputc(0xe3,prn_stream);
  600. fwrite(sd->stc.escp_release.data,1,sd->stc.escp_release.size,prn_stream);
  601. fflush(prn_stream);
  602. }
  603. #ifdef STC_SIGNAL
  604. sigprocmask(SIG_SETMASK,&stc_int_save,NULL);
  605. #endif /* STC_DIGNAL */
  606. }
  607. }
  608. /***
  609. *** Release the dynamic memory
  610. ***/
  611. if(ext_line != NULL)
  612. gs_free(sd->memory, ext_line,ext_size,1,"stc_print_page/ext_line");
  613. if(col_line != NULL)
  614. gs_free(sd->memory, col_line,prt_pixels,1,"stc_print_page/col_line");
  615. if(alg_line != NULL)
  616. gs_free(sd->memory, alg_line,alg_size,sd->stc.alg_item,
  617. "stc_print_page/alg_line");
  618. if(buf != NULL)
  619. gs_free(sd->memory, buf,buf_size,sd->stc.alg_item,"stc_print_page/buf");
  620. if(sd->stc.prt_width != NULL)
  621. gs_free(sd->memory, sd->stc.prt_width,sd->stc.prt_buf,sizeof(int),
  622. "stc_print_page/prt_width");
  623. if(sd->stc.prt_data != NULL) {
  624. int i;
  625. for(i = 0; i < sd->stc.prt_buf; ++i) {
  626. if(sd->stc.prt_data[i] != NULL)
  627. gs_free(sd->memory, sd->stc.prt_data[i],sd->stc.prt_size,1,
  628. "stc_print_page/prt");
  629. }
  630. gs_free(sd->memory, sd->stc.prt_data,sd->stc.prt_buf,sizeof(byte *),
  631. "stc_print_page/prt_data");
  632. }
  633. {
  634. int i;
  635. for(i = 0; i < sd->color_info.num_components; ++i) {
  636. if(sd->stc.seed_row[i] != NULL)
  637. gs_free(sd->memory, sd->stc.seed_row[i],sd->stc.seed_size,sizeof(int),
  638. "stc_print_page/seed_row");
  639. }
  640. }
  641. if(sd->stc.escp_data != NULL)
  642. gs_free(sd->memory, sd->stc.escp_data,sd->stc.escp_size,1,
  643. "stc_print_page/escp_data");
  644. return OK4GO ? 0 : gs_error_undefined;
  645. }
  646. /*
  647. * white-check
  648. */
  649. private bool
  650. stc_iswhite(stcolor_device *sd, int prt_pixels,byte *ext_data)
  651. {
  652. long b2do = (prt_pixels*sd->color_info.depth+7)>>3;
  653. int bcmp = 4 * countof(sd->stc.white_run);
  654. byte *wht = (byte *) sd->stc.white_run;
  655. while(b2do >= bcmp) {
  656. if(memcmp(ext_data,wht,bcmp)) break;
  657. ext_data += bcmp;
  658. b2do -= bcmp;
  659. }
  660. if((b2do > 0) && (b2do < bcmp))
  661. b2do = memcmp(ext_data,sd->stc.white_end,b2do);
  662. return b2do ? false : true;
  663. }
  664. /***
  665. *** A bunch of routines that convert gslines into algorithms format.
  666. ***/
  667. private byte *
  668. stc_any_depth(stcolor_device *sd,byte *ext_data,int prt_pixels,byte *alg_line)
  669. { /* general conversion */
  670. int p,c, niext, nbits;
  671. gx_color_index ciext,ci,cimsk,cvmsk;
  672. byte *ap = alg_line;
  673. nbits = sd->stc.bits;
  674. cvmsk = ((gx_color_index) 1<<nbits) - 1;
  675. /* it is nonsense to use this algorithm for this cases, but if it claims
  676. * generality, it should deliver correct results in this cases too */
  677. if(sd->color_info.depth == (sd->color_info.num_components<<3)) nbits = 8;
  678. cimsk = cvmsk;
  679. for(c = 1; c < sd->color_info.num_components; ++c)
  680. cimsk = (cimsk<<nbits) | cvmsk;
  681. ciext = 0;
  682. niext = 0;
  683. for(p = 0; p < prt_pixels; ++p) { /* over pixels */
  684. ci = ciext;
  685. for(c = sd->color_info.depth-niext; c >= 8; c -= 8)
  686. ci = (ci<<8) | *ext_data++;
  687. if(c > 0) { /* partial byte required */
  688. niext = 8 - c;
  689. ciext = *ext_data++;
  690. ci = (ci<<c) | (ciext>>niext);
  691. ciext &= (1L<<niext)-1;
  692. } else if(c < 0) { /* some bits left in ciext */
  693. niext = -c;
  694. ciext &= (1L<<niext)-1;
  695. ci = ci>>niext;
  696. } else { /* entire ciext used */
  697. niext = 0;
  698. ciext = 0;
  699. } /* ciext-adjust */
  700. ci &= cimsk;
  701. # define stc_storeapc(T) \
  702. ((T *)ap)[c] = ((T *)(sd->stc.vals[c]))[ci & cvmsk];
  703. for(c = sd->color_info.num_components; c--;) { /* comp */
  704. STC_TYPESWITCH(sd->stc.dither,stc_storeapc)
  705. ci >>= nbits;
  706. } /* comp */
  707. # undef stc_storeapc
  708. ap += sd->color_info.num_components * sd->stc.alg_item;
  709. } /* over pixels */
  710. return alg_line;
  711. } /* general conversion */
  712. /*
  713. * rgb-data with depth=24, can use a faster algorithm
  714. */
  715. private byte *
  716. stc_rgb24_long(stcolor_device *sd,byte *ext_data,int prt_pixels,byte *alg_line)
  717. { /* convert 3 bytes into appropriate long-Values */
  718. register int p;
  719. register long *out = (long *) alg_line;
  720. register long *rvals = (long *) (sd->stc.vals[0]);
  721. register long *gvals = (long *) (sd->stc.vals[1]);
  722. register long *bvals = (long *) (sd->stc.vals[2]);
  723. for(p = prt_pixels; p; --p) {
  724. *out++ = rvals[*ext_data++];
  725. *out++ = gvals[*ext_data++];
  726. *out++ = bvals[*ext_data++];
  727. }
  728. return alg_line;
  729. } /* convert 3 bytes into appropriate long-Values */
  730. /*
  731. * cmyk-data with depth=32, can use a faster algorithm
  732. */
  733. private byte *
  734. stc_cmyk32_long(stcolor_device *sd,byte *ext_data,int prt_pixels,byte *alg_line)
  735. { /* convert 4 bytes into appropriate long-Values */
  736. register int p;
  737. register long *out = (long *) alg_line;
  738. register long *cvals = (long *) (sd->stc.vals[0]);
  739. register long *mvals = (long *) (sd->stc.vals[1]);
  740. register long *yvals = (long *) (sd->stc.vals[2]);
  741. register long *kvals = (long *) (sd->stc.vals[3]);
  742. for(p = prt_pixels; p; --p) {
  743. *out++ = cvals[*ext_data++];
  744. *out++ = mvals[*ext_data++];
  745. *out++ = yvals[*ext_data++];
  746. *out++ = kvals[*ext_data++];
  747. }
  748. return alg_line;
  749. } /* convert 4 bytes into appropriate long-Values */
  750. /*
  751. * handle indirect encoded cmyk-data
  752. */
  753. #define STC_CMYK10_ANY(T)\
  754. \
  755. register int p = prt_pixels; \
  756. register stc_pixel ci,k,n,mode; \
  757. register stc_pixel *in = (stc_pixel *) ext_data; \
  758. register T *out = (T *) alg_line; \
  759. register T *cv = (T *) sd->stc.vals[0]; \
  760. register T *mv = (T *) sd->stc.vals[1]; \
  761. register T *yv = (T *) sd->stc.vals[2]; \
  762. register T *kv = (T *) sd->stc.vals[3]; \
  763. \
  764. while(p--) { \
  765. ci = *in++; \
  766. mode = ci & 3; \
  767. k = (ci>>2) & 0x3ff; \
  768. if(mode == 3) { \
  769. *out++ = cv[0]; \
  770. *out++ = mv[0]; \
  771. *out++ = yv[0]; \
  772. *out++ = kv[k]; \
  773. } else { \
  774. out[3] = kv[k]; \
  775. n = (ci>>12) & 0x3ff; \
  776. if(mode == 2) { out[2] = yv[k]; } \
  777. else { out[2] = yv[n]; n = (ci>>22) & 0x3ff; } \
  778. if(mode == 1) { out[1] = mv[k]; } \
  779. else { out[1] = mv[n]; n = (ci>>22) & 0x3ff; } \
  780. if(mode == 0) out[0] = cv[k]; \
  781. else out[0] = cv[n]; \
  782. out += 4; \
  783. } \
  784. } \
  785. \
  786. return alg_line;
  787. private byte *
  788. stc_cmyk10_byte(stcolor_device *sd,
  789. byte *ext_data,int prt_pixels,byte *alg_line)
  790. {
  791. STC_CMYK10_ANY(byte)
  792. }
  793. private byte *
  794. stc_cmyk10_long(stcolor_device *sd,
  795. byte *ext_data,int prt_pixels,byte *alg_line)
  796. {
  797. STC_CMYK10_ANY(long)
  798. }
  799. private byte *
  800. stc_cmyk10_float(stcolor_device *sd,
  801. byte *ext_data,int prt_pixels,byte *alg_line)
  802. {
  803. STC_CMYK10_ANY(float)
  804. }
  805. #undef STC_CMYK10_ANY
  806. #define STC_CMYK10_DANY(T)\
  807. \
  808. register int p = prt_pixels; \
  809. register stc_pixel ci,k,n,mode; \
  810. register stc_pixel *in = (stc_pixel *) ext_data; \
  811. register T *out = (T *) alg_line; \
  812. \
  813. while(p--) { \
  814. ci = *in++; \
  815. mode = ci & 3; \
  816. k = (ci>>2) & 0x3ff; \
  817. if(mode == 3) { \
  818. *out++ = 0; \
  819. *out++ = 0; \
  820. *out++ = 0; \
  821. *out++ = k; \
  822. } else { \
  823. out[3] = k; \
  824. n = (ci>>12) & 0x3ff; \
  825. if(mode == 2) { out[2] = k; } \
  826. else { out[2] = n; n = (ci>>22) & 0x3ff; } \
  827. if(mode == 1) { out[1] = k; } \
  828. else { out[1] = n; n = (ci>>22) & 0x3ff; } \
  829. if(mode == 0) out[0] = k; \
  830. else out[0] = n; \
  831. out += 4; \
  832. } \
  833. } \
  834. \
  835. return alg_line;
  836. private byte *
  837. stc_cmyk10_dbyte(stcolor_device *sd,
  838. byte *ext_data,int prt_pixels,byte *alg_line)
  839. {
  840. STC_CMYK10_DANY(byte)
  841. }
  842. private byte *
  843. stc_cmyk10_dlong(stcolor_device *sd,
  844. byte *ext_data,int prt_pixels,byte *alg_line)
  845. {
  846. STC_CMYK10_DANY(long)
  847. }
  848. #undef STC_CMYK10_DANY
  849. /*
  850. * if the algorithm uses bytes & bytes are in ext_data, use them
  851. */
  852. /*ARGSUSED*/
  853. private byte *
  854. stc_any_direct(stcolor_device *sd,byte *ext_data,int prt_pixels,byte *alg_line)
  855. { /* return ext_data */
  856. return ext_data;
  857. } /* return ext_data */
  858. /* ----------------------------------------------------------------------- */
  859. /* stc_rle: epson ESC/P2 RLE-Encoding
  860. */
  861. private int
  862. stc_rle(byte *out,const byte *in,int width)
  863. {
  864. int used = 0;
  865. int crun,cdata;
  866. byte run;
  867. if(in != NULL) { /* Data present */
  868. crun = 1;
  869. while(width > 0) { /* something to compress */
  870. run = in[0];
  871. while((width > crun) && (run == in[crun])) if(++crun == 129) break;
  872. if((crun > 2) || (crun == width)) { /* use this run */
  873. *out++ = (257 - crun) & 0xff; *out++ = run; used += 2;
  874. width -= crun; in += crun;
  875. crun = 1;
  876. } else { /* ignore this run */
  877. for(cdata = crun; (width > cdata) && (crun < 4);) {
  878. if(run == in[cdata]) crun += 1;
  879. else run = in[cdata], crun = 1;
  880. if(++cdata == 128) break;
  881. }
  882. if(crun < 3) crun = 0; /* ignore trailing run */
  883. else cdata -= crun;
  884. *out++ = cdata-1; used++;
  885. memcpy(out,in,cdata); used += cdata; out += cdata;
  886. width -= cdata; in += cdata;
  887. } /* use/ignore run */
  888. } /* something to compress */
  889. } else { /* Empty scans to fill bands */
  890. while(width > 0) {
  891. crun = width > 129 ? 129 : width;
  892. width -= crun;
  893. *out++ = (257 - crun) & 0xff;
  894. *out++ = 0;
  895. used += 2;
  896. }
  897. } /* Data present or empty */
  898. return used;
  899. }
  900. /*
  901. * Horizontal & vertical positioning, color-selection, "ESC ."
  902. */
  903. private int
  904. stc_print_escpcmd(stcolor_device *sd, FILE *prn_stream,
  905. int escp_used, int color,int m,int wbytes)
  906. {
  907. int dy = sd->stc.stc_y - sd->stc.prt_y; /* number of units to skip */
  908. int nlf;
  909. /* ESC-R color codes, used only here */
  910. static const byte stc_colors[] = { 0x02, 0x01, 0x04, 0x00 }; /* CMYK */
  911. /*
  912. * initialize the printer, if necessary
  913. */
  914. if(0 == (sd->stc.flags & STCPRINT)) {
  915. fwrite(sd->stc.escp_init.data,1,sd->stc.escp_init.size,prn_stream);
  916. if(0 < sd->stc.escp_lf) { /* Adjust Linefeed */
  917. fputc('\033', prn_stream);
  918. fputc('+', prn_stream);
  919. fputc(((sd->stc.escp_m*sd->stc.escp_u) / 10),prn_stream);
  920. } /* Adjust Linefeed */
  921. sd->stc.flags |= STCPRINT;
  922. }
  923. sd->stc.escp_data[escp_used++] = '\r'; /* leftmost position */
  924. if(dy) { /* position the printer */
  925. if(( sd->stc.escp_lf > 0) && /* Linefeed allowed */
  926. ((dy % sd->stc.escp_lf) == 0)) /* and possible */
  927. nlf = dy / sd->stc.escp_lf;
  928. else nlf = 7;
  929. if(nlf > 6) {
  930. sd->stc.escp_data[escp_used++] = '\033';
  931. sd->stc.escp_data[escp_used++] = '(';
  932. sd->stc.escp_data[escp_used++] = 'V';
  933. sd->stc.escp_data[escp_used++] = '\002';
  934. sd->stc.escp_data[escp_used++] = '\000';
  935. sd->stc.escp_data[escp_used++] = sd->stc.stc_y & 0xff;
  936. sd->stc.escp_data[escp_used++] = (sd->stc.stc_y >> 8) & 0xff;
  937. } else {
  938. while(nlf--) sd->stc.escp_data[escp_used++] = '\n';
  939. }
  940. sd->stc.prt_y = sd->stc.stc_y;
  941. } /* position the printer */
  942. if((sd->color_info.num_components > 1) &&
  943. (sd->stc.escp_c != stc_colors[color])) { /* select color */
  944. sd->stc.escp_data[escp_used++] = '\033';
  945. sd->stc.escp_data[escp_used++] = 'r';
  946. sd->stc.escp_c = stc_colors[color];
  947. sd->stc.escp_data[escp_used++] = sd->stc.escp_c;
  948. } /* select color */
  949. /*
  950. * Build the command used
  951. */
  952. sd->stc.escp_data[escp_used++] = '\033';
  953. sd->stc.escp_data[escp_used++] = '.';
  954. sd->stc.escp_data[escp_used++] =
  955. (sd->stc.flags & STCCOMP) == STCPLAIN ? 0 : 1;
  956. sd->stc.escp_data[escp_used++] = sd->stc.escp_v;
  957. sd->stc.escp_data[escp_used++] = sd->stc.escp_h;
  958. sd->stc.escp_data[escp_used++] = m;
  959. sd->stc.escp_data[escp_used++] = (wbytes<<3) & 0xff; /* width in Pixels */
  960. sd->stc.escp_data[escp_used++] = (wbytes>>5) & 0xff;
  961. return escp_used;
  962. }
  963. /*
  964. * compute width of a group of scanlines
  965. */
  966. private int
  967. stc_bandwidth(stcolor_device *sd,int color,int m,int npass)
  968. {
  969. int ncolor = sd->color_info.num_components == 1 ? 1 : 4;
  970. int buf_a = (sd->stc.prt_buf-1) & (sd->stc.stc_y * ncolor + color);
  971. int w = 0;
  972. while(m-- > 0) { /* check width */
  973. if(sd->stc.prt_width[buf_a] > w) w = sd->stc.prt_width[buf_a];
  974. buf_a = (sd->stc.prt_buf-1) & (buf_a + ncolor * npass);
  975. } /* check width */
  976. return w;
  977. }
  978. /*
  979. * Multi-Pass Printing-Routine
  980. */
  981. private void
  982. stc_print_weave(stcolor_device *sd, FILE *prn_stream)
  983. {
  984. int escp_used,nprint,nspace,color,buf_a,iprint,w;
  985. int npass = sd->stc.escp_v / sd->stc.escp_u;
  986. int ncolor = sd->color_info.num_components == 1 ? 1 : 4;
  987. while(sd->stc.stc_y < sd->stc.prt_scans) {
  988. /*
  989. * compute spacing & used heads (seems to work with odd escp_m)
  990. */
  991. if(sd->stc.stc_y >= sd->stc.escp_m) { /* in normal mode */
  992. nprint = sd->stc.escp_m;
  993. nspace = sd->stc.escp_m;
  994. } else if((sd->stc.stc_y) < npass) { /* initialisation */
  995. nprint = sd->stc.escp_m - sd->stc.stc_y * ((sd->stc.escp_m+1)/npass);
  996. nspace = 1;
  997. } else { /* switch to normal */
  998. nprint = sd->stc.escp_m - sd->stc.stc_y * ((sd->stc.escp_m+1)/npass);
  999. nspace = sd->stc.escp_m - sd->stc.stc_y;
  1000. }
  1001. iprint = sd->stc.stc_y + npass * nprint;
  1002. if(sd->stc.buf_y < iprint) break;
  1003. escp_used = 0;
  1004. for(color = 0; color < ncolor; ++color) { /* print the colors */
  1005. if(0 == (w = stc_bandwidth(sd,color,nprint,npass))) continue;
  1006. escp_used = stc_print_escpcmd(sd,prn_stream,
  1007. escp_used,color,sd->stc.escp_m,w);
  1008. buf_a = (sd->stc.prt_buf-1) & (sd->stc.stc_y * ncolor + color);
  1009. for(iprint = 0; iprint < nprint; ++iprint) { /* send data */
  1010. if((sd->stc.flags & STCCOMP) == STCPLAIN) {
  1011. memcpy(sd->stc.escp_data+escp_used,sd->stc.prt_data[buf_a],w);
  1012. escp_used += w;
  1013. } else {
  1014. escp_used += stc_rle(sd->stc.escp_data+escp_used,
  1015. sd->stc.prt_data[buf_a],w);
  1016. }
  1017. fwrite(sd->stc.escp_data,1,escp_used,prn_stream);
  1018. escp_used = 0;
  1019. buf_a = (sd->stc.prt_buf-1) & (buf_a + ncolor * npass);
  1020. } /* send data */
  1021. while(iprint++ < sd->stc.escp_m) { /* add empty rows */
  1022. if((sd->stc.flags & STCCOMP) == STCPLAIN) {
  1023. memset(sd->stc.escp_data+escp_used,0,w);
  1024. escp_used += w;
  1025. } else {
  1026. escp_used += stc_rle(sd->stc.escp_data+escp_used,NULL,w);
  1027. }
  1028. fwrite(sd->stc.escp_data,1,escp_used,prn_stream);
  1029. escp_used = 0;
  1030. } /* add empty rows */
  1031. } /* print the colors */
  1032. sd->stc.stc_y += nspace;
  1033. }
  1034. }
  1035. /*
  1036. * Single-Pass printing-Routine
  1037. */
  1038. private void
  1039. stc_print_bands(stcolor_device *sd, FILE *prn_stream)
  1040. {
  1041. int escp_used,color,buf_a,iprint,w,m;
  1042. int ncolor = sd->color_info.num_components == 1 ? 1 : 4;
  1043. while(sd->stc.stc_y < sd->stc.prt_scans) {
  1044. /*
  1045. * find the begin of the band
  1046. */
  1047. for(w = 0; sd->stc.stc_y < sd->stc.buf_y; ++sd->stc.stc_y) {
  1048. buf_a = (sd->stc.prt_buf-1) & (sd->stc.stc_y * ncolor);
  1049. for(color = 0; color < ncolor; ++color)
  1050. if(sd->stc.prt_width[buf_a+color] > w)
  1051. w = sd->stc.prt_width[buf_a+color];
  1052. if(w != 0) break;
  1053. }
  1054. if(w == 0) break;
  1055. /*
  1056. * adjust the band-height
  1057. */
  1058. w = sd->stc.prt_scans - sd->stc.stc_y;
  1059. if((w < sd->stc.escp_m) && (sd->stc.escp_v != 40)) {
  1060. if(w < 8) m = 1;
  1061. else if(w < 24) m = 8;
  1062. else m = 24;
  1063. } else {
  1064. m = sd->stc.escp_m;
  1065. }
  1066. if(sd->stc.buf_y < (sd->stc.stc_y+m)) break;
  1067. escp_used = 0;
  1068. for(color = 0; color < ncolor; ++color) { /* print the colors */
  1069. if(0 == (w = stc_bandwidth(sd,color,m,1))) continue; /* shortcut */
  1070. escp_used = stc_print_escpcmd(sd,prn_stream,escp_used,color,m,w);
  1071. buf_a = (sd->stc.prt_buf-1) & (sd->stc.stc_y * ncolor + color);
  1072. for(iprint = 0; iprint < m; ++iprint) { /* send data */
  1073. if((sd->stc.flags & STCCOMP) == STCPLAIN) {
  1074. memcpy(sd->stc.escp_data+escp_used,sd->stc.prt_data[buf_a],w);
  1075. escp_used += w;
  1076. } else {
  1077. escp_used += stc_rle(sd->stc.escp_data+escp_used,
  1078. sd->stc.prt_data[buf_a],w);
  1079. }
  1080. fwrite(sd->stc.escp_data,1,escp_used,prn_stream);
  1081. escp_used = 0;
  1082. buf_a = (sd->stc.prt_buf-1) & (buf_a + ncolor);
  1083. } /* send data */
  1084. } /* print the colors */
  1085. sd->stc.stc_y += m;
  1086. }
  1087. }
  1088. /* ----------------------------------------------------------------------- */
  1089. private int
  1090. stc_deltarow(byte *out,const byte *in,int width,byte *seed)
  1091. {
  1092. int istop,nmove,ndata,i,j;
  1093. int *wseed = (int *) seed;
  1094. int used = 0;
  1095. seed += sizeof(int);
  1096. if((in != NULL) && (width > 0)) { /* Data present */
  1097. istop = width < wseed[0] ? wseed[0] : width;
  1098. i = 0;
  1099. while(i < istop) {
  1100. for(j = i; j < istop; ++j) if(in[j] != seed[j]) break;
  1101. nmove = j - i;
  1102. if(nmove > 0) { /* issue a move */
  1103. i = j;
  1104. if(i == istop) break;
  1105. if( nmove < 8) {
  1106. out[used++] = 0x40 | nmove;
  1107. } else if(nmove < 128) {
  1108. out[used++] = 0x51;
  1109. out[used++] = nmove;
  1110. } else {
  1111. out[used++] = 0x52;
  1112. out[used++] = 0xff & nmove;
  1113. out[used++] = 0xff & (nmove>>8);
  1114. }
  1115. } /* issue a move */
  1116. /*
  1117. * find the end of this run
  1118. */
  1119. nmove = 0;
  1120. for(j = i+1; (j < istop) && ((nmove < 4)); ++j) {
  1121. if(in[j] == seed[j]) nmove += 1;
  1122. else nmove = 0;
  1123. }
  1124. ndata = j-i-nmove;
  1125. nmove = stc_rle(out+used+3,in+i,ndata);
  1126. if(nmove < 16) {
  1127. out[used++] = 0x20 | nmove;
  1128. for(j = 0; j < nmove; ++j) out[used+j] = out[used+j+2];
  1129. } else if(nmove < 256) {
  1130. out[used++] = 0x31;
  1131. out[used++] = nmove;
  1132. for(j = 0; j < nmove; ++j) out[used+j] = out[used+j+1];
  1133. } else {
  1134. out[used++] = 0x32;
  1135. out[used++] = 0xff & nmove;
  1136. out[used++] = 0xff & (nmove>>8);
  1137. }
  1138. used += nmove;
  1139. i += ndata;
  1140. }
  1141. memcpy(seed,in,istop);
  1142. wseed[0] = width;
  1143. } else if(wseed[0] > 0) { /* blank line, but seed has data */
  1144. out[used++] = 0xe1; /* clear row */
  1145. memset(seed,0,wseed[0]);
  1146. wseed[0] = 0;
  1147. }
  1148. return used;
  1149. }
  1150. /*
  1151. * Slightly different single-pass printing
  1152. */
  1153. private void
  1154. stc_print_delta(stcolor_device *sd, FILE *prn_stream)
  1155. {
  1156. int color,buf_a,w;
  1157. int escp_used = 0;
  1158. int ncolor = sd->color_info.num_components == 1 ? 1 : 4;
  1159. while(sd->stc.stc_y < sd->stc.prt_scans) {
  1160. /*
  1161. * find the begin of the band
  1162. */
  1163. for(w = 0; sd->stc.stc_y < sd->stc.buf_y; ++sd->stc.stc_y) {
  1164. buf_a = (sd->stc.prt_buf-1) & (sd->stc.stc_y * ncolor);
  1165. for(color = 0; color < ncolor; ++color)
  1166. if(sd->stc.prt_width[buf_a+color] > w)
  1167. w = sd->stc.prt_width[buf_a+color];
  1168. if(w != 0) break;
  1169. }
  1170. if(sd->stc.buf_y == sd->stc.stc_y) break;
  1171. escp_used = 0;
  1172. /*
  1173. * Send Initialization & ESC . 3 once
  1174. */
  1175. if(0 == (sd->stc.flags & STCPRINT)) {
  1176. sd->stc.flags |= STCPRINT;
  1177. fwrite(sd->stc.escp_init.data,1,sd->stc.escp_init.size,prn_stream);
  1178. sd->stc.escp_data[escp_used++] = '\033';
  1179. sd->stc.escp_data[escp_used++] = '.';
  1180. sd->stc.escp_data[escp_used++] = 3;
  1181. sd->stc.escp_data[escp_used++] = sd->stc.escp_v;
  1182. sd->stc.escp_data[escp_used++] = sd->stc.escp_h;
  1183. sd->stc.escp_data[escp_used++] = sd->stc.escp_m;
  1184. sd->stc.escp_data[escp_used++] = 0;
  1185. sd->stc.escp_data[escp_used++] = 0;
  1186. sd->stc.escp_data[escp_used++] = 0xe4; /* MOVXBYTE */
  1187. }
  1188. if(sd->stc.stc_y != sd->stc.prt_y) { /* really position the printer */
  1189. w = sd->stc.stc_y - sd->stc.prt_y;
  1190. if( w < 16) {
  1191. sd->stc.escp_data[escp_used++] = 0x60 | w;
  1192. } else if(w < 256) {
  1193. sd->stc.escp_data[escp_used++] = 0x71;
  1194. sd->stc.escp_data[escp_used++] = w;
  1195. } else {
  1196. sd->stc.escp_data[escp_used++] = 0x72;
  1197. sd->stc.escp_data[escp_used++] = 0xff & w;
  1198. sd->stc.escp_data[escp_used++] = 0xff & (w>>8);
  1199. }
  1200. sd->stc.prt_y = sd->stc.stc_y;
  1201. } /* really position the printer */
  1202. for(color = 0; color < ncolor; ++color) { /* print the colors */
  1203. /* Color-Selection */
  1204. if(color == (ncolor-1)) {
  1205. sd->stc.escp_data[escp_used++] = 0x80; /* Black */
  1206. } else {
  1207. switch(color) {
  1208. case 1: sd->stc.escp_data[escp_used++] = 0x81; break; /* M */
  1209. case 2: sd->stc.escp_data[escp_used++] = 0x84; break; /* Y */
  1210. default: sd->stc.escp_data[escp_used++] = 0x82; break; /* C */
  1211. }
  1212. }
  1213. /* Data-Transfer */
  1214. buf_a = (sd->stc.prt_buf-1) & (sd->stc.stc_y * ncolor + color);
  1215. w = stc_deltarow(sd->stc.escp_data+escp_used,
  1216. sd->stc.prt_data[buf_a],sd->stc.prt_width[buf_a],
  1217. sd->stc.seed_row[color]);
  1218. if(w == 0) escp_used -= 1;
  1219. else escp_used += w;
  1220. if(escp_used > 0) fwrite(sd->stc.escp_data,1,escp_used,prn_stream);
  1221. escp_used = 0;
  1222. } /* print the colors */
  1223. sd->stc.stc_y += 1;
  1224. }
  1225. }
  1226. /* ----------------------------------------------------------------------- */
  1227. /***
  1228. *** Free-Data: release the specific-Arrays
  1229. ***/
  1230. private void
  1231. stc_freedata(gs_memory_t *mem, stc_t *stc)
  1232. {
  1233. int i,j;
  1234. for(i = 0; i < 4; ++i) {
  1235. if(stc->code[i] != NULL) {
  1236. for(j = 0; j < i; ++j) if(stc->code[i] == stc->code[j]) break;
  1237. if(i == j) gs_free(mem, stc->code[i],1<<stc->bits,sizeof(gx_color_value),
  1238. "stcolor/code");
  1239. }
  1240. if(stc->vals[i] != NULL) {
  1241. for(j = 0; j < i; ++j)
  1242. if(stc->vals[i] == stc->vals[j]) break;
  1243. if(i == j) gs_free(mem, stc->vals[i],1<<stc->bits,sd->stc.alg_item,
  1244. "stcolor/transfer");
  1245. }
  1246. }
  1247. for(i = 0; i < 4; ++i) {
  1248. stc->code[i] = NULL;
  1249. stc->vals[i] = NULL;
  1250. }
  1251. }
  1252. /***
  1253. *** open the device and initialize margins & arrays
  1254. ***/
  1255. private int
  1256. stc_open(gx_device *pdev) /* setup margins & arrays */
  1257. {
  1258. stcolor_device *sd = (stcolor_device *) pdev;
  1259. int i,j,code;
  1260. gx_color_index white;
  1261. byte *bpw,*bpm;
  1262. code = 0;
  1263. /*
  1264. * Establish Algorithm-Table, if not present
  1265. */
  1266. if(sd->stc.algorithms.size == 0) {
  1267. gs_param_string *dp;
  1268. for(i = 0; stc_dither[i].name != NULL; ++i); /* count 'em */
  1269. sd->stc.algorithms.size = i;
  1270. dp = gs_malloc(sd->memory, i,sizeof(gs_param_string),
  1271. "stcolor/algorithms");
  1272. if(dp == NULL) {
  1273. code = gs_error_VMerror;
  1274. sd->stc.algorithms.size = 0;
  1275. } else {
  1276. sd->stc.algorithms.data = dp;
  1277. sd->stc.algorithms.persistent = true;
  1278. for(i = 0; stc_dither[i].name != NULL; ++i) {
  1279. param_string_from_string(dp[i],stc_dither[i].name);
  1280. }
  1281. }
  1282. }
  1283. # define stc_sizeofitem(T) sd->stc.alg_item = sizeof(T)
  1284. STC_TYPESWITCH(sd->stc.dither,stc_sizeofitem)
  1285. stc_print_setup(sd);
  1286. /*
  1287. * Establish internal Value & Code-Arrays
  1288. */
  1289. for(i = 0; i < sd->color_info.num_components; ++i) { /* comp */
  1290. if((sd->stc.sizc[i] > 1) && (sd->stc.extc[i] != NULL)) { /* code req. */
  1291. for(j = 0; j < i; ++j) if(sd->stc.extc[i] == sd->stc.extc[j]) break;
  1292. if(i == j) { /* new one */
  1293. sd->stc.code[i] = gs_malloc(sd->memory, 1<<sd->stc.bits,sizeof(gx_color_value),
  1294. "stcolor/code");
  1295. if(sd->stc.code[i] == NULL) { /* error */
  1296. code = gs_error_VMerror;
  1297. } else { /* success */
  1298. /*
  1299. * Try making things easier:
  1300. * normalize values to 0.0/1.0-Range
  1301. * X-Axis: Color-Values (implied)
  1302. * Y-Values: Indices (given)
  1303. */
  1304. unsigned long ly,iy;
  1305. double ystep,xstep,fx,fy;
  1306. /* normalize */
  1307. fx = 1e18;
  1308. fy = -1e18;
  1309. for(ly = 0; ly < sd->stc.sizc[i]; ++ly) {
  1310. if(sd->stc.extc[i][ly] < fx) fx = sd->stc.extc[i][ly];
  1311. if(sd->stc.extc[i][ly] > fy) fy = sd->stc.extc[i][ly];
  1312. }
  1313. if((fx != 0.0) || (fy != 1.0)) {
  1314. fy = 1.0 / (fy - fx);
  1315. for(ly = 0; ly < sd->stc.sizc[i]; ++ly)
  1316. sd->stc.extc[i][ly] = fy * (sd->stc.extc[i][ly]-fx);
  1317. }
  1318. /* interpolate */
  1319. ystep = 1.0 / (double)((1<<sd->stc.bits)-1);
  1320. xstep = 1.0 / (double)( sd->stc.sizc[i] -1);
  1321. iy = 0;
  1322. for(ly = 0; ly < (1<<sd->stc.bits); ++ly) {
  1323. fy = ystep * ly;
  1324. while(((iy+1) < sd->stc.sizc[i]) &&
  1325. ( fy > sd->stc.extc[i][iy+1])) ++iy;
  1326. fx = iy + (fy - sd->stc.extc[i][iy])
  1327. / (sd->stc.extc[i][iy+1] - sd->stc.extc[i][iy]);
  1328. fx *= xstep * gx_max_color_value;
  1329. fx = fx < 0.0 ? 0.0 :
  1330. (fx > gx_max_color_value ? gx_max_color_value : fx);
  1331. sd->stc.code[i][ly] = (gx_color_value)fx;
  1332. if((fx-sd->stc.code[i][ly]) >= 0.5) sd->stc.code[i][ly] += 1;
  1333. }
  1334. } /* error || success */
  1335. } else { /* shared one */
  1336. sd->stc.code[i] = sd->stc.code[j];
  1337. } /* new || shared one */
  1338. } /* code req. */
  1339. if((sd->stc.sizv[i] > 1) && (sd->stc.extv[i] != NULL)) { /* vals req. */
  1340. for(j = 0; j < i; ++j)
  1341. if((sd->stc.extc[i] == sd->stc.extc[j]) &&
  1342. (sd->stc.extv[i] == sd->stc.extv[j])) break;
  1343. if(i == j) { /* new one */
  1344. sd->stc.vals[i] =
  1345. gs_malloc(sd->memory, 1<<sd->stc.bits,sd->stc.alg_item,"stcolor/transfer");
  1346. if(sd->stc.vals[i] == NULL) {
  1347. code = gs_error_VMerror;
  1348. } else { /* success */
  1349. if(sd->stc.code[i] == NULL) { /* linear */
  1350. byte *Out = sd->stc.vals[i];
  1351. int Nout = 1<<sd->stc.bits;
  1352. double Omin = sd->stc.dither->minmax[0];
  1353. double Omax = sd->stc.dither->minmax[1];
  1354. float *In = sd->stc.extv[i];
  1355. int Nin = sd->stc.sizv[i];
  1356. unsigned long I,io;
  1357. double Istep,Ostep,Y;
  1358. byte Ovb; long Ovl;
  1359. Istep = 1.0 / (double) ((Nin)-1);
  1360. Ostep = 1.0 / (double) ((Nout)-1);
  1361. for(io = 0; io < (Nout); ++io) {
  1362. I = (long)(io * ((Nin)-1))/((Nout)-1);
  1363. if((I+1) < (Nin))
  1364. Y = In[I] + (In[I+1]-In[I])
  1365. * ((double) io * Ostep - (double)I * Istep)
  1366. / (double) Istep;
  1367. else
  1368. Y = In[I] + (In[I]-In[I-1])
  1369. * ((double) io * Ostep - (double)I * Istep)
  1370. / (double) Istep;
  1371. Y = Omin + (Omax-Omin) * Y;
  1372. Y = Y < Omin ? Omin : (Y > Omax ? Omax : Y);
  1373. switch(sd->stc.dither->flags & STC_TYPE) {
  1374. case STC_BYTE:
  1375. Ovb = (byte)Y;
  1376. if(((Y-Ovb) >= 0.5) && ((Ovb+1) <= Omax)) Ovb += 1;
  1377. Out[io] = Ovb;
  1378. break;
  1379. case STC_LONG:
  1380. Ovl = (long)Y;
  1381. if(((Y-Ovl) >= 0.5) && ((Ovl+1) <= Omax)) Ovl += 1;
  1382. if(((Ovl-Y) >= 0.5) && ((Ovl-1) >= Omax)) Ovl -= 1;
  1383. ((long *)Out)[io] = Ovl;
  1384. break;
  1385. default:
  1386. ((float *)Out)[io] = Y;
  1387. break;
  1388. }
  1389. }
  1390. } else { /* encoded */
  1391. unsigned long j,o;
  1392. double xstep,x,y;
  1393. xstep = 1.0 / (double) (sd->stc.sizv[i]-1);
  1394. /*
  1395. * The following differs in so far from the previous, that the desired
  1396. * X-Values are stored in another array.
  1397. */
  1398. for(o = 0; o < (1<<sd->stc.bits); ++o) { /* code-loop */
  1399. x = sd->stc.code[i][o]; x /= gx_max_color_value;
  1400. j = (unsigned long)(x / xstep);
  1401. if((j+1) < sd->stc.sizv[i]) {
  1402. y = sd->stc.extv[i][j];
  1403. y += (sd->stc.extv[i][j+1]-y)*(x-(double)j*xstep)/xstep;
  1404. } else {
  1405. y = sd->stc.extv[i][j];
  1406. y += (y-sd->stc.extv[i][j-1])*(x-(double)j*xstep)/xstep;
  1407. }
  1408. y = sd->stc.dither->minmax[0]
  1409. +(sd->stc.dither->minmax[1]-sd->stc.dither->minmax[0])*y;
  1410. # define stc_adjvals(T) \
  1411. ((T *)(sd->stc.vals[i]))[o] = (T)y; \
  1412. \
  1413. if(((y-((T *)(sd->stc.vals[i]))[o]) >= 0.5) && \
  1414. ((1+((T *)(sd->stc.vals[i]))[o]) <= sd->stc.dither->minmax[1]))\
  1415. ((T *)(sd->stc.vals[i]))[o] += 1; \
  1416. \
  1417. if(((((T *)(sd->stc.vals[i]))[o]-y) >= 0.5) && \
  1418. ((((T *)(sd->stc.vals[i]))[o]-1) >= sd->stc.dither->minmax[0]))\
  1419. ((T *)(sd->stc.vals[i]))[o] -= 1;
  1420. STC_TYPESWITCH(sd->stc.dither,stc_adjvals)
  1421. # undef stc_adjvals
  1422. } /* code-loop */
  1423. } /* lineaer / encoded */
  1424. } /* error || success */
  1425. } else { /* shared one */
  1426. sd->stc.vals[i] = sd->stc.vals[j];
  1427. } /* new || shared one */
  1428. } /* vals req. */
  1429. } /* comp */
  1430. if(code == 0) {
  1431. gx_color_value cv[4];
  1432. sd->stc.flags |= STCOK4GO;
  1433. /*
  1434. * Arrgh: open-procedure seems to be the right-place, but it is
  1435. * necessary to establish the defaults for omitted procedures too.
  1436. */
  1437. switch(sd->color_info.num_components) { /* Establish color-procs */
  1438. case 1:
  1439. set_dev_proc(sd,map_rgb_color, stc_map_gray_color);
  1440. set_dev_proc(sd,map_cmyk_color,gx_default_map_cmyk_color);
  1441. set_dev_proc(sd,map_color_rgb, stc_map_color_gray);
  1442. set_dev_proc(sd,encode_color, stc_map_gray_color);
  1443. set_dev_proc(sd,decode_color, stc_map_color_gray);
  1444. cv[0] = cv[1] = cv[2] = gx_max_color_value;
  1445. white = stc_map_gray_color((gx_device *) sd, cv);
  1446. break;
  1447. case 3:
  1448. set_dev_proc(sd,map_rgb_color, stc_map_rgb_color);
  1449. set_dev_proc(sd,map_cmyk_color,gx_default_map_cmyk_color);
  1450. set_dev_proc(sd,map_color_rgb, stc_map_color_rgb);
  1451. set_dev_proc(sd,encode_color, stc_map_rgb_color);
  1452. set_dev_proc(sd,decode_color, stc_map_color_rgb);
  1453. cv[0] = cv[1] = cv[2] = gx_max_color_value;
  1454. white = stc_map_rgb_color((gx_device *) sd, cv);
  1455. break;
  1456. default:
  1457. set_dev_proc(sd,map_rgb_color, gx_default_map_rgb_color);
  1458. if(sd->stc.flags & STCCMYK10) {
  1459. set_dev_proc(sd,map_cmyk_color,stc_map_cmyk10_color);
  1460. set_dev_proc(sd,map_color_rgb, stc_map_color_cmyk10);
  1461. set_dev_proc(sd,encode_color,stc_map_cmyk10_color);
  1462. set_dev_proc(sd,decode_color, stc_map_color_cmyk10);
  1463. cv[0] = cv[1] = cv[2] = cv[3] = 0;
  1464. white = stc_map_cmyk10_color((gx_device *) sd, cv);
  1465. } else {
  1466. set_dev_proc(sd,map_cmyk_color,stc_map_cmyk_color);
  1467. set_dev_proc(sd,map_color_rgb, stc_map_color_cmyk);
  1468. set_dev_proc(sd,encode_color,stc_map_cmyk_color);
  1469. set_dev_proc(sd,decode_color, stc_map_color_cmyk);
  1470. cv[0] = cv[1] = cv[2] = cv[3] = 0;
  1471. white = stc_map_cmyk_color((gx_device *) sd,cv);
  1472. }
  1473. break; /* Establish color-procs */
  1474. }
  1475. /*
  1476. * create at least a Byte
  1477. */
  1478. if(sd->color_info.depth < 2) white |= (white<<1);
  1479. if(sd->color_info.depth < 4) white |= (white<<2);
  1480. if(sd->color_info.depth < 8) white |= (white<<4);
  1481. /*
  1482. * copy the Bytes
  1483. */
  1484. bpw = (byte *) sd->stc.white_run;
  1485. if(sd->color_info.depth < 16) {
  1486. for(i = 0; i < sizeof(sd->stc.white_run); i += 1) {
  1487. bpw[i] = 0xff & white;
  1488. }
  1489. } else if(sd->color_info.depth < 24) {
  1490. for(i = 0; i < sizeof(sd->stc.white_run); i += 2) {
  1491. bpw[i] = 0xff & (white>>8);
  1492. bpw[i+1] = 0xff & white;
  1493. }
  1494. } else if(sd->color_info.depth < 32) {
  1495. for(i = 0; i < sizeof(sd->stc.white_run); i += 3) {
  1496. bpw[i] = 0xff & (white>>16);
  1497. bpw[i+1] = 0xff & (white>> 8);
  1498. bpw[i+2] = 0xff & white;
  1499. }
  1500. } else {
  1501. for(i = 0; i < sizeof(sd->stc.white_run); i += 4) {
  1502. bpw[i] = 0xff & (white>>24);
  1503. bpw[i+1] = 0xff & (white>>16);
  1504. bpw[i+2] = 0xff & (white>> 8);
  1505. bpw[i+3] = 0xff & white;
  1506. }
  1507. }
  1508. /*
  1509. * compute the trailer
  1510. */
  1511. j = (unsigned long)(sd->width -
  1512. (dev_l_margin(sd)+dev_r_margin(sd))*sd->x_pixels_per_inch);
  1513. j = j * sd->color_info.depth; /* the Bit-count */
  1514. j = j % (32*countof(sd->stc.white_run)); /* remaining Bits */
  1515. bpm = (byte *) sd->stc.white_end;
  1516. for(i = 0; i < (4*countof(sd->stc.white_end)); ++i) {
  1517. if( j <= 0) {
  1518. bpm[i] = 0;
  1519. } else if(j >= 8) {
  1520. bpm[i] = 0xff;
  1521. j -= 8;
  1522. } else {
  1523. bpm[i] = 0xff ^ ((1<<(8-j))-1);
  1524. j = 0;
  1525. }
  1526. bpm[i] &= bpw[i];
  1527. }
  1528. /*
  1529. * Call super-class open
  1530. */
  1531. return gdev_prn_open(pdev);
  1532. } else {
  1533. stc_freedata(sd->memory, &sd->stc);
  1534. return_error(code);
  1535. }
  1536. }
  1537. /***
  1538. *** stc_close: release the internal data
  1539. ***/
  1540. private int
  1541. stc_close(gx_device *pdev)
  1542. {
  1543. stc_freedata(pdev->memory, &((stcolor_device *) pdev)->stc);
  1544. ((stcolor_device *) pdev)->stc.flags &= ~STCOK4GO;
  1545. return gdev_prn_close(pdev);
  1546. }
  1547. /***
  1548. *** Function for Bit-Truncation, including direct-byte-transfer
  1549. ***/
  1550. private gx_color_value
  1551. stc_truncate(stcolor_device *sd,int i,gx_color_value v)
  1552. {
  1553. if(sd->stc.bits < gx_color_value_bits) {
  1554. if(sd->stc.code[i] != NULL) {
  1555. /*
  1556. * Perform binary search in the code-array
  1557. */
  1558. long s;
  1559. gx_color_value *p;
  1560. s = sd->stc.bits > 1 ? 1L<<(sd->stc.bits-2) : 0L;
  1561. p = sd->stc.code[i]+(1L<<(sd->stc.bits-1));
  1562. while(s > 0) {
  1563. if(v > *p) {
  1564. p += s;
  1565. } else if(v < p[-1]) {
  1566. p -= s;
  1567. } else {
  1568. if((v-p[-1]) < (p[0]-v)) p -= 1;
  1569. break;
  1570. }
  1571. s >>= 1;
  1572. }
  1573. if((v-p[-1]) < (p[0]-v)) p -= 1;
  1574. v = p - sd->stc.code[i];
  1575. } else {
  1576. v >>= gx_color_value_bits-sd->stc.bits;
  1577. }
  1578. /*
  1579. V = (((1L<<D->stc.bits)-1)*V+(gx_max_color_value>>1))\
  1580. /gx_max_color_value; \
  1581. */
  1582. }
  1583. return v;
  1584. }
  1585. private gx_color_value
  1586. stc_truncate1(stcolor_device *sd,int i,gx_color_value v)
  1587. {
  1588. return sd->stc.vals[i][stc_truncate(sd,i,v)];
  1589. }
  1590. /***
  1591. *** Expansion of indices for reverse-mapping
  1592. ***/
  1593. private gx_color_value
  1594. stc_expand(stcolor_device *sd,int i,gx_color_index col)
  1595. {
  1596. gx_color_index cv;
  1597. gx_color_index l = (1<<sd->stc.bits)-1;
  1598. if(sd->stc.code[i] != NULL) {
  1599. cv = sd->stc.code[i][col & l];
  1600. } else if(sd->stc.bits < gx_color_value_bits) {
  1601. cv = (col & l)<<(gx_color_value_bits-sd->stc.bits);
  1602. cv += (col & l)/l * ((1<<(gx_color_value_bits-sd->stc.bits))-1);
  1603. } else if(sd->stc.bits > gx_color_value_bits) {
  1604. cv = (col & l)>>(sd->stc.bits-gx_color_value_bits);
  1605. } else {
  1606. cv = col & l;
  1607. }
  1608. return cv;
  1609. }
  1610. /***
  1611. *** color-mapping of gray-scales
  1612. ***/
  1613. private gx_color_index
  1614. stc_map_gray_color(gx_device *pdev, const gx_color_value cv[])
  1615. {
  1616. stcolor_device *sd = (stcolor_device *) pdev;
  1617. gx_color_index rv;
  1618. gx_color_value r = cv[0];
  1619. gx_color_value g = cv[1];
  1620. gx_color_value b = cv[2];
  1621. if((r == g) && (g == b)) {
  1622. rv = gx_max_color_value - r;
  1623. } else if(sd->stc.am != NULL) {
  1624. float *m,fv;
  1625. m = sd->stc.am;
  1626. fv = gx_max_color_value;
  1627. fv -= *m++ * (float) r; fv -= *m++ * (float) g; fv -= *m * (float) b;
  1628. if( fv < 0.0) rv = 0;
  1629. else if((fv+0.5) > gx_max_color_value) rv = gx_max_color_value;
  1630. else rv = (gx_color_index)(fv+0.5);
  1631. } else {
  1632. rv = ((gx_color_index)gx_max_color_value)<<3;
  1633. rv -= (gx_color_index) 3 * r;
  1634. rv -= (gx_color_index) 3 * g;
  1635. rv -= ((gx_color_index)b)<<1;
  1636. rv = (rv+4)>>3;
  1637. if(rv > gx_max_color_value) rv = gx_max_color_value;
  1638. }
  1639. if(( sd->stc.bits == 8) &&
  1640. ((sd->stc.dither->flags & STC_TYPE) == STC_BYTE))
  1641. rv = stc_truncate1(sd,0,(gx_color_value)rv);
  1642. else
  1643. rv = stc_truncate(sd,0,(gx_color_value)rv);
  1644. return rv;
  1645. }
  1646. private int
  1647. stc_map_color_gray(gx_device *pdev, gx_color_index color,gx_color_value prgb[3])
  1648. {
  1649. stcolor_device *sd = (stcolor_device *) pdev;
  1650. gx_color_index l = ((gx_color_index)1<<sd->stc.bits)-1;
  1651. prgb[0] = gx_max_color_value - stc_expand(sd,0,color & l);
  1652. prgb[1] = prgb[0]; prgb[2] = prgb[0];
  1653. return 0;
  1654. }
  1655. /***
  1656. *** color-mapping of rgb-values
  1657. ***/
  1658. private gx_color_index
  1659. stc_map_rgb_color(gx_device *pdev, const gx_color_value cv[])
  1660. {
  1661. stcolor_device *sd = (stcolor_device *) pdev;
  1662. int shift = sd->color_info.depth == 24 ? 8 : sd->stc.bits;
  1663. gx_color_index rv = 0;
  1664. gx_color_value r = cv[0];
  1665. gx_color_value g = cv[1];
  1666. gx_color_value b = cv[2];
  1667. if((sd->stc.am != NULL) && ((r != g) || (g != b))) {
  1668. float *m,fr,fg,fb,fv;
  1669. m = sd->stc.am;
  1670. fr = r; fg = g; fb = b;
  1671. fv = *m++ * fr; fv += *m++ * fg; fv += *m++ * fb;
  1672. if( fv < 0.0) r = 0;
  1673. else if((fv+0.5) > gx_max_color_value) r = gx_max_color_value;
  1674. else r = (gx_color_value)(fv+0.5);
  1675. fv = *m++ * fr; fv += *m++ * fg; fv += *m++ * fb;
  1676. if( fv < 0.0) g = 0;
  1677. else if((fv+0.5) > gx_max_color_value) g = gx_max_color_value;
  1678. else g = (gx_color_value)(fv+0.5);
  1679. fv = *m++ * fr; fv += *m++ * fg; fv += *m++ * fb;
  1680. if( fv < 0.0) b = 0;
  1681. else if((fv+0.5) > gx_max_color_value) b = gx_max_color_value;
  1682. else b = (gx_color_value)(fv+0.5);
  1683. }
  1684. if(( sd->stc.bits == 8) &&
  1685. ((sd->stc.dither->flags & STC_TYPE) == STC_BYTE)) {
  1686. rv = stc_truncate1(sd,0,r);
  1687. rv = (rv<<shift) | stc_truncate1(sd,1,g);
  1688. rv = (rv<<shift) | stc_truncate1(sd,2,b);
  1689. } else {
  1690. rv = stc_truncate(sd,0,r);
  1691. rv = (rv<<shift) | stc_truncate(sd,1,g);
  1692. rv = (rv<<shift) | stc_truncate(sd,2,b);
  1693. }
  1694. return rv;
  1695. }
  1696. private int
  1697. stc_map_color_rgb(gx_device *pdev, gx_color_index color,gx_color_value prgb[3])
  1698. {
  1699. stcolor_device *sd = (stcolor_device *) pdev;
  1700. int shift = sd->color_info.depth == 24 ? 8 : sd->stc.bits;
  1701. gx_color_index l = ((gx_color_index)1<<sd->stc.bits)-1;
  1702. prgb[0] = stc_expand(sd,0,((color>>(shift<<1)) & l));
  1703. prgb[1] = stc_expand(sd,1,((color>> shift ) & l));
  1704. prgb[2] = stc_expand(sd,2,( color & l));
  1705. return 0;
  1706. }
  1707. /***
  1708. *** color-mapping of cmyk-values
  1709. ***/
  1710. private gx_color_index
  1711. stc_map_cmyk_color(gx_device *pdev, const gx_color_value cv[])
  1712. {
  1713. stcolor_device *sd = (stcolor_device *) pdev;
  1714. int shift = sd->color_info.depth == 32 ? 8 : sd->stc.bits;
  1715. gx_color_index rv = 0;
  1716. gx_color_value c = cv[0];
  1717. gx_color_value m = cv[1];
  1718. gx_color_value y = cv[2];
  1719. gx_color_value k = cv[3];
  1720. if((c == m) && (m == y)) {
  1721. k = c > k ? c : k;
  1722. c = m = y = 0;
  1723. if(( sd->stc.bits == 8) &&
  1724. ((sd->stc.dither->flags & STC_TYPE) == STC_BYTE)) {
  1725. k = stc_truncate1(sd,3,k);
  1726. } else {
  1727. k = stc_truncate(sd,3,k);
  1728. }
  1729. } else {
  1730. if(sd->stc.am != NULL) {
  1731. float *a,fc,fm,fy,fk,fv;
  1732. if(k == 0) { /* no separated black yet */
  1733. k = c < m ? c : m;
  1734. k = k < y ? k : y;
  1735. if(k) { /* no black at all */
  1736. c -= k;
  1737. m -= k;
  1738. y -= k;
  1739. } /* no black at all */
  1740. } /* no separated black yet */
  1741. a = sd->stc.am;
  1742. fc = c; fm = m; fy = y; fk = k;
  1743. fv = *a++ * fc; fv += *a++ * fm; fv += *a++ * fy; fv += *a++ * fk;
  1744. if( fv < 0.0) c = 0;
  1745. else if((fv+0.5) > gx_max_color_value) c = gx_max_color_value;
  1746. else c = (gx_color_value)(fv+0.5);
  1747. fv = *a++ * fc; fv += *a++ * fm; fv += *a++ * fy; fv += *a++ * fk;
  1748. if( fv < 0.0) m = 0;
  1749. else if((fv+0.5) > gx_max_color_value) m = gx_max_color_value;
  1750. else m = (gx_color_value)(fv+0.5);
  1751. fv = *a++ * fc; fv += *a++ * fm; fv += *a++ * fy; fv += *a++ * fk;
  1752. if( fv < 0.0) y = 0;
  1753. else if((fv+0.5) > gx_max_color_value) y = gx_max_color_value;
  1754. else y = (gx_color_value)(fv+0.5);
  1755. fv = *a++ * fc; fv += *a++ * fm; fv += *a++ * fy; fv += *a++ * fk;
  1756. if( fv < 0.0) k = 0;
  1757. else if((fv+0.5) > gx_max_color_value) k = gx_max_color_value;
  1758. else k = (gx_color_value)(fv+0.5);
  1759. } else if(k == 0) {
  1760. k = c < m ? c : m;
  1761. k = k < y ? k : y;
  1762. }
  1763. if(( sd->stc.bits == 8) &&
  1764. ((sd->stc.dither->flags & STC_TYPE) == STC_BYTE)) {
  1765. c = stc_truncate1(sd,0,c);
  1766. m = stc_truncate1(sd,1,m);
  1767. y = stc_truncate1(sd,2,y);
  1768. k = stc_truncate1(sd,3,k);
  1769. } else {
  1770. c = stc_truncate(sd,0,c);
  1771. m = stc_truncate(sd,1,m);
  1772. y = stc_truncate(sd,2,y);
  1773. k = stc_truncate(sd,3,k);
  1774. }
  1775. }
  1776. rv = c;
  1777. rv = (rv<<shift) | m;
  1778. rv = (rv<<shift) | y;
  1779. rv = (rv<<shift) | k;
  1780. if(rv == gx_no_color_index) rv ^= 1;
  1781. return rv;
  1782. }
  1783. /* Modified to be a "decode_color" routine */
  1784. private int
  1785. stc_map_color_cmyk(gx_device *pdev, gx_color_index color,gx_color_value cv[4])
  1786. {
  1787. stcolor_device *sd = (stcolor_device *) pdev;
  1788. int shift = sd->color_info.depth == 32 ? 8 : sd->stc.bits;
  1789. gx_color_index l = ((gx_color_index)1<<sd->stc.bits)-1;
  1790. gx_color_value c,m,y,k;
  1791. k = stc_expand(sd,3, color & l); color >>= shift;
  1792. y = stc_expand(sd,2, color & l); color >>= shift;
  1793. m = stc_expand(sd,1, color & l); color >>= shift;
  1794. c = stc_expand(sd,0, color & l);
  1795. cv[0] = c;
  1796. cv[1] = m;
  1797. cv[2] = y;
  1798. cv[3] = k;
  1799. return 0;
  1800. }
  1801. /***
  1802. *** color-mapping of cmyk10-values
  1803. ***/
  1804. private gx_color_index
  1805. stc_map_cmyk10_color(gx_device *pdev, const gx_color_value cv[])
  1806. {
  1807. stcolor_device *sd = (stcolor_device *) pdev;
  1808. int mode;
  1809. gx_color_index rv = 0;
  1810. gx_color_value c = cv[0];
  1811. gx_color_value m = cv[1];
  1812. gx_color_value y = cv[2];
  1813. gx_color_value k = cv[3];
  1814. if((c == m) && (m == y)) {
  1815. k = c > k ? c : k;
  1816. c = m = y = 0;
  1817. mode = 3;
  1818. } else {
  1819. if(sd->stc.am != NULL) {
  1820. float *a,fc,fm,fy,fk,fv;
  1821. k = c < m ? c : m;
  1822. k = k < y ? k : y;
  1823. if(k) { /* no black at all */
  1824. c -= k;
  1825. m -= k;
  1826. y -= k;
  1827. } /* no black at all */
  1828. a = sd->stc.am;
  1829. fc = c; fm = m; fy = y; fk = k;
  1830. fv = *a++ * fc; fv += *a++ * fm; fv += *a++ * fy; fv += *a++ * fk;
  1831. if( fv < 0.0) c = 0;
  1832. else if((fv+0.5) > gx_max_color_value) c = gx_max_color_value;
  1833. else c = (gx_color_value)(fv+0.5);
  1834. fv = *a++ * fc; fv += *a++ * fm; fv += *a++ * fy; fv += *a++ * fk;
  1835. if( fv < 0.0) m = 0;
  1836. else if((fv+0.5) > gx_max_color_value) m = gx_max_color_value;
  1837. else m = (gx_color_value)(fv+0.5);
  1838. fv = *a++ * fc; fv += *a++ * fm; fv += *a++ * fy; fv += *a++ * fk;
  1839. if( fv < 0.0) y = 0;
  1840. else if((fv+0.5) > gx_max_color_value) y = gx_max_color_value;
  1841. else y = (gx_color_value)(fv+0.5);
  1842. }
  1843. if(c < m) {
  1844. if(c < y) { k = c; c = 0; mode = 0; }
  1845. else { k = y; y = 0; mode = 2; }
  1846. } else {
  1847. if(m < y) { k = m; m = 0; mode = 1; }
  1848. else { k = y; y = 0; mode = 2; }
  1849. }
  1850. }
  1851. /*
  1852. * truncate only the values that require it
  1853. */
  1854. if(c) c = stc_truncate(sd,0,c);
  1855. if(m) m = stc_truncate(sd,1,m);
  1856. if(y) y = stc_truncate(sd,2,y);
  1857. if(k) k = stc_truncate(sd,3,k);
  1858. /*
  1859. * make sure that truncation-white becomes white.
  1860. */
  1861. if((c|m|y) == 0) mode = 3;
  1862. /*
  1863. * check wether value-arrays can be bypassed
  1864. */
  1865. if(((sd->stc.dither->flags & STC_TYPE) == STC_BYTE) &&
  1866. ( sd->stc.dither->minmax[0] == 0.0 )) {
  1867. c = sd->stc.vals[0][c];
  1868. m = sd->stc.vals[1][m];
  1869. y = sd->stc.vals[2][y];
  1870. k = sd->stc.vals[3][k];
  1871. } else if(((sd->stc.dither->flags & STC_TYPE) == STC_LONG) &&
  1872. ( sd->stc.dither->minmax[0] == 0.0 ) &&
  1873. ( sd->stc.dither->minmax[1] <= 1023.0 )) {
  1874. c = ((long *)(sd->stc.vals[0]))[c];
  1875. m = ((long *)(sd->stc.vals[1]))[m];
  1876. y = ((long *)(sd->stc.vals[2]))[y];
  1877. k = ((long *)(sd->stc.vals[3]))[k];
  1878. } /* direct */
  1879. /*
  1880. * compute the long-representation of gx_color_index
  1881. */
  1882. switch(mode) {
  1883. case 0:
  1884. rv = (((gx_color_index) m)<<22)|
  1885. (((gx_color_index) y)<<12)|
  1886. (((gx_color_index) k)<< 2)|mode;
  1887. break;
  1888. case 1:
  1889. rv = (((gx_color_index) c)<<22)|
  1890. (((gx_color_index) y)<<12)|
  1891. (((gx_color_index) k)<< 2)|mode;
  1892. break;
  1893. case 2:
  1894. rv = (((gx_color_index) c)<<22)|
  1895. (((gx_color_index) m)<<12)|
  1896. (((gx_color_index) k)<< 2)|mode;
  1897. break;
  1898. default:
  1899. rv = (((gx_color_index) k)<< 2)|mode;
  1900. break;
  1901. }
  1902. /*
  1903. * We may need some swapping
  1904. */
  1905. #if !arch_is_big_endian
  1906. {
  1907. union { stc_pixel cv; byte bv[4]; } ui,uo;
  1908. ui.cv = rv;
  1909. uo.bv[0] = ui.bv[3];
  1910. uo.bv[1] = ui.bv[2];
  1911. uo.bv[2] = ui.bv[1];
  1912. uo.bv[3] = ui.bv[0];
  1913. rv = uo.cv;
  1914. }
  1915. #endif
  1916. return rv;
  1917. }
  1918. private int
  1919. stc_map_color_cmyk10(gx_device *pdev, gx_color_index color,
  1920. gx_color_value cv[3])
  1921. {
  1922. stcolor_device *sd = (stcolor_device *) pdev;
  1923. gx_color_value c,m,y;
  1924. /*
  1925. * We may need some swapping
  1926. */
  1927. #if !arch_is_big_endian
  1928. union { stc_pixel cv; byte bv[4]; } ui,uo;
  1929. ui.cv = color;
  1930. uo.bv[0] = ui.bv[3];
  1931. uo.bv[1] = ui.bv[2];
  1932. uo.bv[2] = ui.bv[1];
  1933. uo.bv[3] = ui.bv[0];
  1934. color = uo.cv;
  1935. #endif
  1936. c = stc_expand(sd,3,(color>>2)&0x3ff);
  1937. /* cast the 64 bit switch argument to work around broken HPUX 10 cc */
  1938. switch((int)(color & 3)) {
  1939. case 0:
  1940. m = stc_expand(sd,1,(color>>22) & 0x3ff);
  1941. y = stc_expand(sd,2,(color>>12) & 0x3ff);
  1942. break;
  1943. case 1:
  1944. m = c;
  1945. c = stc_expand(sd,0,(color>>22) & 0x3ff);
  1946. y = stc_expand(sd,2,(color>>12) & 0x3ff);
  1947. break;
  1948. case 2:
  1949. y = c;
  1950. c = stc_expand(sd,0,(color>>22) & 0x3ff);
  1951. m = stc_expand(sd,1,(color>>12) & 0x3ff);
  1952. break;
  1953. default:
  1954. m = c;
  1955. y = c;
  1956. break;
  1957. }
  1958. cv[0] = c;
  1959. cv[1] = m;
  1960. cv[2] = y;
  1961. return 0;
  1962. }
  1963. /***
  1964. *** Macros for parameter-handling
  1965. ***/
  1966. #define set_param_array(A, D, S)\
  1967. {A.data = D; A.size = S; A.persistent = false;}
  1968. #define stc_write_null(N) \
  1969. set_param_array(pfa,defext,countof(defext)) \
  1970. code = param_write_null(plist,N); \
  1971. if (code < 0) return code;
  1972. #define stc_write_xarray(I,Coding,Transfer) \
  1973. if(sd->stc.sizc[I] > 0) { \
  1974. set_param_array(pfa, sd->stc.extc[I],sd->stc.sizc[I]) \
  1975. code = param_write_float_array(plist,Coding,&pfa); \
  1976. } else { \
  1977. code = param_write_null(plist,Coding); \
  1978. } \
  1979. if ( code < 0 ) return code; \
  1980. \
  1981. if(sd->stc.sizv[I] > 0) \
  1982. set_param_array(pfa, sd->stc.extv[I],sd->stc.sizv[I]) \
  1983. else \
  1984. set_param_array(pfa,defext,countof(defext)) \
  1985. code = param_write_float_array(plist,Transfer,&pfa); \
  1986. if ( code < 0 ) return code;
  1987. #define stc_read_null(N) \
  1988. code = param_read_null(plist,N); \
  1989. if(code == gs_error_typecheck) \
  1990. code = param_read_float_array(plist,N,&pfa); \
  1991. if(code < 0) param_signal_error(plist,N,code); \
  1992. error = error > code ? code : error;
  1993. #define stc_read_xarray(I,Coding,Transfer) \
  1994. code = param_read_float_array(plist,Coding,&pfa); \
  1995. if((error == 0) && (code == 0)) { \
  1996. if(pfa.size > 1) { \
  1997. sd->stc.extc[I] = (float *) pfa.data; \
  1998. sd->stc.sizc[I] = pfa.size; \
  1999. } else { \
  2000. code = gs_error_rangecheck; \
  2001. } \
  2002. } else if(code < 0) { \
  2003. code = param_read_null(plist,Coding); \
  2004. if(code == 0) { \
  2005. sd->stc.extc[I] = NULL; \
  2006. sd->stc.sizc[I] = 0; \
  2007. } \
  2008. } \
  2009. if(code < 0) param_signal_error(plist,Coding,code); \
  2010. error = error > code ? code : error; \
  2011. code = param_read_float_array(plist,Transfer,&pfa); \
  2012. if((error == 0) && (code == 0)) { \
  2013. sd->stc.extv[I] = (float *) pfa.data; \
  2014. sd->stc.sizv[I] = pfa.size; \
  2015. } else if(code < 0) { \
  2016. code = param_read_null(plist,Transfer); \
  2017. if(code == 0) { \
  2018. sd->stc.extv[I] = defext; \
  2019. sd->stc.sizv[I] = countof(defext); \
  2020. } \
  2021. } \
  2022. if(code < 0) param_signal_error(plist,Transfer,code); \
  2023. error = error > code ? code : error;
  2024. /***
  2025. *** Get parameters == Make them accessable via PostScript
  2026. ***/
  2027. private int
  2028. stc_get_params(gx_device *pdev, gs_param_list *plist)
  2029. {
  2030. int code,nc;
  2031. gs_param_string ps;
  2032. gs_param_float_array pfa;
  2033. bool btmp;
  2034. stcolor_device *sd = (stcolor_device *) pdev;
  2035. code = gdev_prn_get_params(pdev, plist);
  2036. if ( code < 0 ) return code;
  2037. /*
  2038. * Export some readonly-Parameters, used by stcinfo.ps
  2039. */
  2040. param_string_from_string(ps,"1.91");
  2041. code = param_write_string(plist,"Version",&ps);
  2042. if ( code < 0 ) return code;
  2043. code = param_write_int(plist,"BitsPerComponent",&sd->stc.bits);
  2044. if ( code < 0 ) return code;
  2045. if(sd->stc.algorithms.size > 0) {
  2046. code = param_write_string_array(plist,"Algorithms",&sd->stc.algorithms);
  2047. } else {
  2048. code = param_write_null(plist,"Algorithms");
  2049. }
  2050. if ( code < 0 ) return code;
  2051. /*
  2052. * Export OutputCode
  2053. */
  2054. switch(sd->stc.flags & STCCOMP) {
  2055. case STCPLAIN: param_string_from_string(ps,"plain"); break;
  2056. case STCDELTA: param_string_from_string(ps,"deltarow"); break;
  2057. default: param_string_from_string(ps,"runlength"); break;
  2058. }
  2059. code = param_write_string(plist,"OutputCode",&ps);
  2060. if ( code < 0 ) return code;
  2061. /*
  2062. * Export Model
  2063. */
  2064. switch(sd->stc.flags & STCMODEL) {
  2065. case STCST800: param_string_from_string(ps,"st800"); break;
  2066. case STCSTCII: param_string_from_string(ps,"stcii"); break;
  2067. default: param_string_from_string(ps,"stc"); break;
  2068. }
  2069. code = param_write_string(plist,"Model",&ps);
  2070. if ( code < 0 ) return code;
  2071. /*
  2072. * Export the booleans
  2073. */
  2074. #define stc_write_flag(Mask,Name) \
  2075. btmp = sd->stc.flags & (Mask) ? true : false; \
  2076. code = param_write_bool(plist,Name,&btmp); \
  2077. if ( code < 0 ) return code;
  2078. stc_write_flag(STCUNIDIR,"Unidirectional")
  2079. stc_write_flag(STCUWEAVE,"Microweave")
  2080. btmp = sd->stc.flags & (STCUNIDIR|STCUWEAVE) ? false : true;
  2081. code = param_write_bool(plist,"Softweave",&btmp);
  2082. if ( code < 0 ) return code;
  2083. stc_write_flag(STCNWEAVE,"noWeave")
  2084. stc_write_flag(STCDFLAG0, "Flag0")
  2085. stc_write_flag(STCDFLAG1, "Flag1")
  2086. stc_write_flag(STCDFLAG2, "Flag2")
  2087. stc_write_flag(STCDFLAG3, "Flag3")
  2088. stc_write_flag(STCDFLAG4, "Flag4")
  2089. #undef stc_write_flag
  2090. # define stc_write_int(Mask,Name,Val) \
  2091. code = param_write_int(plist,Name,&Val); \
  2092. if ( code < 0 ) return code
  2093. stc_write_int(STCBAND, "escp_Band", sd->stc.escp_m);
  2094. stc_write_int(STCWIDTH, "escp_Width", sd->stc.escp_width);
  2095. stc_write_int(STCHEIGHT,"escp_Height",sd->stc.escp_height);
  2096. stc_write_int(STCTOP, "escp_Top", sd->stc.escp_top);
  2097. stc_write_int(STCBOTTOM,"escp_Bottom",sd->stc.escp_bottom);
  2098. # undef stc_write_int
  2099. code = param_write_string(plist,"escp_Init",&sd->stc.escp_init);
  2100. code = param_write_string(plist,"escp_Release",&sd->stc.escp_release);
  2101. if(sd->stc.dither != NULL) {
  2102. param_string_from_string(ps,sd->stc.dither->name);
  2103. code = param_write_string(plist,"Dithering",&ps);
  2104. } else {
  2105. code = param_write_null(plist,"Dithering");
  2106. }
  2107. if ( code < 0 ) return code;
  2108. nc = sd->color_info.num_components;
  2109. if(sd->stc.am != NULL) {
  2110. if( nc == 1) set_param_array(pfa, sd->stc.am, 3)
  2111. else if(nc == 3) set_param_array(pfa, sd->stc.am, 9)
  2112. else set_param_array(pfa, sd->stc.am,16)
  2113. code = param_write_float_array(plist,"ColorAdjustMatrix",&pfa);
  2114. } else {
  2115. code = param_write_null(plist,"ColorAdjustMatrix");
  2116. }
  2117. if ( code < 0 ) return code;
  2118. if(nc == 1) { /* DeviceGray */
  2119. stc_write_xarray(0,"Kcoding","Ktransfer");
  2120. stc_write_null("Rcoding"); stc_write_null("Rtransfer");
  2121. stc_write_null("Gcoding"); stc_write_null("Gtransfer");
  2122. stc_write_null("Bcoding"); stc_write_null("Btransfer");
  2123. stc_write_null("Ccoding"); stc_write_null("Ctransfer");
  2124. stc_write_null("Mcoding"); stc_write_null("Mtransfer");
  2125. stc_write_null("Ycoding"); stc_write_null("Ytransfer");
  2126. } else if(nc == 3) { /* DeviceRGB */
  2127. stc_write_xarray(0,"Rcoding","Rtransfer");
  2128. stc_write_xarray(1,"Gcoding","Gtransfer");
  2129. stc_write_xarray(2,"Bcoding","Btransfer");
  2130. stc_write_null("Ccoding"); stc_write_null("Ctransfer");
  2131. stc_write_null("Mcoding"); stc_write_null("Mtransfer");
  2132. stc_write_null("Ycoding"); stc_write_null("Ytransfer");
  2133. stc_write_null("Kcoding"); stc_write_null("Ktransfer");
  2134. } else { /* DeviceCMYK */
  2135. stc_write_xarray(0,"Ccoding","Ctransfer");
  2136. stc_write_xarray(1,"Mcoding","Mtransfer");
  2137. stc_write_xarray(2,"Ycoding","Ytransfer");
  2138. stc_write_xarray(3,"Kcoding","Ktransfer");
  2139. stc_write_null("Rcoding"); stc_write_null("Rtransfer");
  2140. stc_write_null("Gcoding"); stc_write_null("Gtransfer");
  2141. stc_write_null("Bcoding"); stc_write_null("Btransfer");
  2142. }
  2143. return code;
  2144. }
  2145. /***
  2146. *** put parameters == Store them in the device-structure
  2147. ***/
  2148. private int
  2149. stc_put_params(gx_device *pdev, gs_param_list *plist)
  2150. {
  2151. int code,error,i,l;
  2152. bool b1,b2,b3;
  2153. float fv,*fp;
  2154. gs_param_string ps;
  2155. gs_param_string_array psa;
  2156. gs_param_float_array pfa;
  2157. stcolor_device *sd = (stcolor_device *) pdev;
  2158. gx_device_color_info oldcolor;
  2159. stc_t oldstc;
  2160. /*
  2161. * save old Values
  2162. */
  2163. memcpy(&oldcolor,&sd->color_info,sizeof(oldcolor));
  2164. memcpy(&oldstc ,&sd->stc ,sizeof(oldstc ));
  2165. /*
  2166. * Arrrgh:
  2167. * With Version 3.4x and above my simple minded read-only Parameters
  2168. * do not work any more. So read them here for heavens sake.
  2169. */
  2170. code = param_read_string(plist,"Version",&ps);
  2171. code = param_read_int(plist,"BitsPerComponent",&i);
  2172. code = param_read_string_array(plist,"Algorithms",&psa);
  2173. /*
  2174. * Fetch Major-Parameters (Model, Dithering, BitsPerPixel/BitsPerComponent)
  2175. */
  2176. error = 0;
  2177. code = param_read_string(plist,"Model",&ps);
  2178. if(code == 0) { /* Analyze the Model-String */
  2179. /*
  2180. * Arrgh: I should have known, that internal strings are not zero-terminated.
  2181. */
  2182. for(l = ps.size; (l > 0) && (ps.data[l-1] == 0); --l);
  2183. # define stc_putcmp(Name) \
  2184. ((strlen(Name) != l) || (0 != strncmp(Name, (const char *)ps.data,l)))
  2185. sd->stc.flags &= ~STCMODEL;
  2186. if( !stc_putcmp("st800")) sd->stc.flags |= STCST800;
  2187. else if(!stc_putcmp("stcii")) sd->stc.flags |= STCSTCII;
  2188. } /* Analyze the Model-String */
  2189. if(code < 0) param_signal_error(plist,"Model",code);
  2190. error = error > code ? code : error;
  2191. /* If we're running for st800, #components must be 1 */
  2192. if(((sd->stc.flags & STCMODEL) == STCST800) &&
  2193. (( sd->color_info.num_components > 1) ||
  2194. ( sd->stc.dither == NULL) ||
  2195. ((sd->stc.dither->flags & 7) > 1))) {
  2196. sd->color_info.num_components = 1;
  2197. sd->stc.dither = NULL;
  2198. }
  2199. /* Weaving isn't a feature for the st800 */
  2200. if((sd->stc.flags & STCMODEL) == STCST800) {
  2201. sd->stc.flags &= ~STCUWEAVE;
  2202. sd->stc.flags |= STCNWEAVE;
  2203. } else if((sd->stc.flags & STCMODEL) == STCSTCII) { /* no SoftWeave */
  2204. sd->stc.flags |= STCNWEAVE;
  2205. }
  2206. code = param_read_string(plist,"Dithering",&ps);
  2207. if(code == 0) { /* lookup new value new value */
  2208. for(l = ps.size; (l > 0) && (ps.data[l-1] == 0); --l);
  2209. for(i = 0; stc_dither[i].name != NULL; ++i)
  2210. if(!stc_putcmp(stc_dither[i].name)) break;
  2211. } else if(sd->stc.dither != NULL) { /* compute index of given value */
  2212. i = sd->stc.dither - stc_dither;
  2213. } else { /* find matching value */
  2214. for(i = 0; stc_dither[i].name != NULL; ++i)
  2215. if((stc_dither[i].flags & 7) == sd->color_info.num_components) break;
  2216. } /* we've got an index */
  2217. if(stc_dither[i].name != NULL) { /* establish data */
  2218. /*
  2219. * Establish new dithering algorithm & color-model
  2220. */
  2221. sd->stc.dither = stc_dither+i;
  2222. sd->color_info.num_components = sd->stc.dither->flags & 7;
  2223. STC_TYPESWITCH(sd->stc.dither,stc_sizeofitem)
  2224. # undef stc_sizeofitem
  2225. if(((sd->stc.flags & STCMODEL) == STCST800) &&
  2226. ( sd->color_info.num_components > 1 ))
  2227. code = gs_error_rangecheck;
  2228. /*
  2229. * reset Parameters related to the color-model, if it changed
  2230. */
  2231. if(sd->color_info.num_components != oldcolor.num_components) {
  2232. for(i = 0; i < sd->color_info.num_components; ++i) {
  2233. sd->stc.extv[i] = (float *) defext;
  2234. sd->stc.sizv[i] = countof(defext);
  2235. sd->stc.extc[i] = NULL;
  2236. sd->stc.sizc[i] = 0;
  2237. }
  2238. sd->stc.am = NULL;
  2239. } else { /* guarantee, that extvals is present */
  2240. for(i = 0; i < sd->color_info.num_components; ++i) {
  2241. if(sd->stc.sizv[i] < 2) {
  2242. sd->stc.extv[i] = (float *) defext;
  2243. sd->stc.sizv[i] = countof(defext);
  2244. }
  2245. }
  2246. }
  2247. for(i = sd->color_info.num_components; i < 4; ++ i) { /* clear unused */
  2248. sd->stc.extv[i] = NULL;
  2249. sd->stc.sizv[i] = 0;
  2250. sd->stc.vals[i] = NULL;
  2251. sd->stc.extc[i] = NULL;
  2252. sd->stc.sizc[i] = 0;
  2253. sd->stc.code[i] = NULL;
  2254. } /* clear unused */
  2255. /*
  2256. * Guess default depth from range of values
  2257. */
  2258. if((sd->stc.dither != oldstc.dither)||(oldstc.vals[0] == NULL)) {
  2259. if((sd->stc.dither->flags & STC_CMYK10) != 0) {
  2260. sd->stc.flags |= STCCMYK10;
  2261. sd->stc.bits = 10;
  2262. sd->color_info.depth = 32;
  2263. } else {
  2264. sd->stc.flags &= ~STCCMYK10;
  2265. if((sd->stc.dither->flags & STC_FLOAT) != STC_FLOAT) {
  2266. fv = 2.0;
  2267. for(i = 1;(i < gx_color_value_bits) &&
  2268. (fv <= (sd->stc.dither->minmax[1]-sd->stc.dither->minmax[0]));
  2269. ++i) fv *= 2.0;
  2270. } else {
  2271. i = 8; /* arbitrary */
  2272. }
  2273. if((i*sd->color_info.num_components) > (sizeof(stc_pixel)*8)) {
  2274. sd->stc.bits = (sizeof(stc_pixel)*8) /
  2275. sd->color_info.num_components;
  2276. sd->color_info.depth = sd->stc.bits * sd->color_info.num_components;
  2277. } else {
  2278. sd->stc.bits = i;
  2279. sd->color_info.depth = sd->stc.bits * sd->color_info.num_components;
  2280. }
  2281. }
  2282. }
  2283. } else {
  2284. code = gs_error_rangecheck;
  2285. } /* verify new value */
  2286. if(code < 0) param_signal_error(plist,"Dithering",code);
  2287. error = error > code ? code : error;
  2288. /*
  2289. * now fetch the desired depth, if the algorithm allows it
  2290. */
  2291. /*
  2292. * Arrrgh: We get code == 0, even if nobody sets BitsPerPixel.
  2293. * The value is the old one, but this may cause trouble
  2294. * with CMYK10.
  2295. */
  2296. code = param_read_int(plist, "BitsPerPixel", &i);
  2297. if((error == 0) && (code == 0) &&
  2298. (((sd->stc.flags & STCCMYK10) == 0) || (i != sd->color_info.depth))) {
  2299. if((1 > i) || (i > (sizeof(stc_pixel)*8)))
  2300. code = gs_error_rangecheck;
  2301. else
  2302. sd->color_info.depth = i;
  2303. sd->stc.bits = i / sd->color_info.num_components;
  2304. if(1 > sd->stc.bits) code = gs_error_rangecheck;
  2305. if((sd->stc.dither->flags & STC_DIRECT) &&
  2306. (sd->stc.dither->flags & STC_CMYK10))
  2307. code = gs_error_rangecheck;
  2308. else
  2309. sd->stc.flags &= ~STCCMYK10;
  2310. }
  2311. if(code < 0) param_signal_error(plist,"BitsPerPixel",code);
  2312. error = error > code ? code : error;
  2313. /*
  2314. * Fetch OutputCode
  2315. */
  2316. code = param_read_string(plist,"OutputCode",&ps);
  2317. if(code == 0) { /* Analyze the OutputCode-String */
  2318. for(l = ps.size; (l > 0) && (ps.data[l-1] == 0); --l);
  2319. sd->stc.flags &= ~STCCOMP;
  2320. if(!stc_putcmp("plain")) sd->stc.flags |= STCPLAIN;
  2321. else if(!stc_putcmp("deltarow")) sd->stc.flags |= STCDELTA;
  2322. } /* Analyze the OutputCode-String */
  2323. if((sd->stc.flags & STCCOMP) == STCDELTA) {
  2324. sd->stc.flags |= STCUWEAVE;
  2325. sd->stc.flags &= ~STCNWEAVE;
  2326. }
  2327. if(code < 0) param_signal_error(plist,"OutputCode",code);
  2328. error = error > code ? code : error;
  2329. /*
  2330. * fetch the weave-mode (noWeave wins)
  2331. */
  2332. b1 = sd->stc.flags & STCUWEAVE ? true : false;
  2333. b2 = sd->stc.flags & STCNWEAVE ? true : false;
  2334. b3 = sd->stc.flags & (STCUWEAVE|STCNWEAVE) ? false : true;
  2335. code = param_read_bool(plist,"Microweave",&b1);
  2336. if(code < 0) {
  2337. param_signal_error(plist,"Microweave",code);
  2338. } else if(code == 0) {
  2339. if(b1) { b2 = false; b3 = false; }
  2340. }
  2341. error = error > code ? code : error;
  2342. code = param_read_bool(plist,"noWeave",&b2);
  2343. if(code < 0) {
  2344. param_signal_error(plist,"noWeave",code);
  2345. } else if (code == 0) {
  2346. if(b2) { b1 = false; b3 = false; }
  2347. }
  2348. error = error > code ? code : error;
  2349. code = param_read_bool(plist,"Softweave",&b3);
  2350. if(code < 0) {
  2351. param_signal_error(plist,"Softweave",code);
  2352. } else if (code == 0) {
  2353. if(b3) { b1 = false; b2 = false; }
  2354. }
  2355. error = error > code ? code : error;
  2356. if(b1) sd->stc.flags |= STCUWEAVE;
  2357. else sd->stc.flags &= ~STCUWEAVE;
  2358. if(b2) sd->stc.flags |= STCNWEAVE;
  2359. else sd->stc.flags &= ~STCNWEAVE;
  2360. /*
  2361. * Check the simple Flags
  2362. */
  2363. # define stc_read_flag(Mask,Name) \
  2364. code = param_read_bool(plist,Name,&b1); \
  2365. if(code < 0) { \
  2366. param_signal_error(plist,Name,code); \
  2367. } else if(code == 0) { \
  2368. if(b1 == true) sd->stc.flags |= Mask; \
  2369. else sd->stc.flags &= ~(Mask); \
  2370. } \
  2371. error = error > code ? code : error;
  2372. stc_read_flag(STCUNIDIR,"Unidirectional")
  2373. stc_read_flag(STCDFLAG0, "Flag0")
  2374. stc_read_flag(STCDFLAG1, "Flag1")
  2375. stc_read_flag(STCDFLAG2, "Flag2")
  2376. stc_read_flag(STCDFLAG3, "Flag3")
  2377. stc_read_flag(STCDFLAG4, "Flag4")
  2378. /*
  2379. * Now deal with the escp-Stuff
  2380. */
  2381. # define stc_read_int(Mask,Name,Val) \
  2382. code = param_read_int(plist,Name,&Val); \
  2383. if(code < 0) \
  2384. param_signal_error(plist,Name,code); \
  2385. else if(code == 0) \
  2386. sd->stc.flags |= Mask; \
  2387. error = error > code ? code : error
  2388. stc_read_int(STCBAND, "escp_Band", sd->stc.escp_m);
  2389. stc_read_int(STCWIDTH, "escp_Width", sd->stc.escp_width);
  2390. stc_read_int(STCHEIGHT,"escp_Height",sd->stc.escp_height);
  2391. stc_read_int(STCTOP, "escp_Top", sd->stc.escp_top);
  2392. stc_read_int(STCBOTTOM,"escp_Bottom",sd->stc.escp_bottom);
  2393. # undef stc_read_int
  2394. code = param_read_string(plist,"escp_Init",&sd->stc.escp_init);
  2395. if(code == 0) sd->stc.flags |= STCINIT;
  2396. error = error > code ? code : error;
  2397. code = param_read_string(plist,"escp_Release",&sd->stc.escp_release);
  2398. if(code == 0) sd->stc.flags |= STCRELEASE;
  2399. error = error > code ? code : error;
  2400. /*
  2401. * ColorAdjustMatrix must match the required size,
  2402. * setting it explicitly to null, erases old matrix
  2403. */
  2404. code = param_read_float_array(plist,"ColorAdjustMatrix",&pfa);
  2405. if((error == 0) && (code == 0)) {
  2406. if(((sd->color_info.num_components == 1) && (pfa.size == 3)) ||
  2407. ((sd->color_info.num_components == 3) && (pfa.size == 9)) ||
  2408. ((sd->color_info.num_components == 4) && (pfa.size == 16)))
  2409. sd->stc.am = (float *) pfa.data;
  2410. else
  2411. code = gs_error_rangecheck;
  2412. } else if(code < 0) {
  2413. code = param_read_null(plist,"ColorAdjustMatrix");
  2414. if(code == 0) sd->stc.am = NULL;
  2415. }
  2416. if(code < 0) param_signal_error(plist,"ColorAdjustMatrix",code);
  2417. error = error > code ? code : error;
  2418. /*
  2419. * Read the external array-Parameters
  2420. */
  2421. if(sd->color_info.num_components == 1) { /* DeviceGray */
  2422. stc_read_xarray(0,"Kcoding","Ktransfer");
  2423. stc_read_null("Rcoding"); stc_read_null("Rtransfer");
  2424. stc_read_null("Gcoding"); stc_read_null("Gtransfer");
  2425. stc_read_null("Bcoding"); stc_read_null("Btransfer");
  2426. stc_read_null("Ccoding"); stc_read_null("Ctransfer");
  2427. stc_read_null("Mcoding"); stc_read_null("Mtransfer");
  2428. stc_read_null("Ycoding"); stc_read_null("Ytransfer");
  2429. } else if(sd->color_info.num_components == 3) { /* DeviceRGB */
  2430. stc_read_xarray(0,"Rcoding","Rtransfer");
  2431. stc_read_xarray(1,"Gcoding","Gtransfer");
  2432. stc_read_xarray(2,"Bcoding","Btransfer");
  2433. stc_read_null("Ccoding"); stc_read_null("Ctransfer");
  2434. stc_read_null("Mcoding"); stc_read_null("Mtransfer");
  2435. stc_read_null("Ycoding"); stc_read_null("Ytransfer");
  2436. stc_read_null("Kcoding"); stc_read_null("Ktransfer");
  2437. } else { /* DeviceCMYK */
  2438. stc_read_xarray(0,"Ccoding","Ctransfer");
  2439. stc_read_xarray(1,"Mcoding","Mtransfer");
  2440. stc_read_xarray(2,"Ycoding","Ytransfer");
  2441. stc_read_xarray(3,"Kcoding","Ktransfer");
  2442. stc_read_null("Rcoding"); stc_read_null("Rtransfer");
  2443. stc_read_null("Gcoding"); stc_read_null("Gtransfer");
  2444. stc_read_null("Bcoding"); stc_read_null("Btransfer");
  2445. }
  2446. /*
  2447. * Update remaining color_info values
  2448. */
  2449. if(error == 0) {
  2450. /* compute #values from the component-bits */
  2451. sd->color_info.max_gray = sd->stc.bits < gx_color_value_bits ?
  2452. (1<<sd->stc.bits)-1 : gx_max_color_value;
  2453. /* An integer-algorithm might reduce the number of values */
  2454. if(((sd->stc.dither->flags & STC_TYPE) != STC_FLOAT) &&
  2455. ((sd->stc.dither->minmax[1]-sd->stc.dither->minmax[0]) <
  2456. sd->color_info.max_gray))
  2457. sd->color_info.max_gray = (gx_color_value)
  2458. (sd->stc.dither->minmax[1]-sd->stc.dither->minmax[0]+0.5);
  2459. sd->color_info.max_color = sd->color_info.num_components < 3 ? 0 :
  2460. sd->color_info.max_gray;
  2461. sd->color_info.dither_grays =
  2462. sd->color_info.max_gray < gx_max_color_value ?
  2463. sd->color_info.max_gray+1 : gx_max_color_value;
  2464. sd->color_info.dither_colors = sd->color_info.num_components < 3 ? 0 :
  2465. sd->color_info.dither_grays;
  2466. }
  2467. /*
  2468. * Call superclass-Update
  2469. */
  2470. code = gdev_prn_put_params(pdev, plist);
  2471. error = error > code ? code : error;
  2472. /*
  2473. * Arrrgh, writing BitsPerPixel is really *VERY* special:
  2474. * gdev_prn_put_params verifies, that the external value
  2475. * is written, if not, it raises a rangecheck-error.
  2476. * On the other hand ghostscript is quite unhappy with odd
  2477. * values, so we do the necessary rounding *AFTER* the
  2478. * "superclass-Update".
  2479. */
  2480. if(sd->color_info.depth == 3) sd->color_info.depth = 4;
  2481. else if(sd->color_info.depth > 4)
  2482. sd->color_info.depth = (sd->color_info.depth+7) & ~7;
  2483. /*
  2484. * Allocate the storage for the arrays in memory
  2485. */
  2486. if(error == 0) { /* Allocate new external-arrays */
  2487. for(i = 0; i < sd->color_info.num_components; ++i){ /* Active components */
  2488. int j;
  2489. if((sd->stc.extv[i] != oldstc.extv[i]) &&
  2490. (sd->stc.extv[i] != defext )) { /* Value-Arrays */
  2491. for(j = 0; j < i; ++j)
  2492. if((sd->stc.sizv[j] == sd->stc.sizv[i]) &&
  2493. (memcmp(sd->stc.extv[j],sd->stc.extv[i],
  2494. sd->stc.sizv[i]*sizeof(float)) == 0)) break;
  2495. if(j < i) {
  2496. sd->stc.extv[i] = sd->stc.extv[j];
  2497. } else {
  2498. fp = gs_malloc(sd->memory, sd->stc.sizv[i],sizeof(float),"stc_put_params");
  2499. if(fp != NULL)
  2500. memcpy(fp,sd->stc.extv[i],sd->stc.sizv[i]*sizeof(float));
  2501. else
  2502. code = gs_error_VMerror;
  2503. sd->stc.extv[i] = fp;
  2504. }
  2505. } /* Value-Arrays */
  2506. if((sd->stc.sizc[i] > 1) &&
  2507. (sd->stc.extc[i] != oldstc.extc[i])) { /* Code-Arrays */
  2508. for(j = 0; j < i; ++j)
  2509. if((sd->stc.sizc[j] == sd->stc.sizc[i]) &&
  2510. (memcmp(sd->stc.extc[j],sd->stc.extc[i],
  2511. sd->stc.sizc[i]*sizeof(float)) == 0)) break;
  2512. if(j < i) {
  2513. sd->stc.extc[i] = sd->stc.extc[j];
  2514. } else {
  2515. fp = gs_malloc(sd->memory, sd->stc.sizc[i],sizeof(float),"stc_put_params");
  2516. if(fp != NULL)
  2517. memcpy(fp,sd->stc.extc[i],sd->stc.sizc[i]*sizeof(float));
  2518. else
  2519. code = gs_error_VMerror;
  2520. sd->stc.extc[i] = fp;
  2521. }
  2522. } /* Code-Arrays */
  2523. } /* Active components */
  2524. if((sd->stc.am != NULL) && (sd->stc.am != oldstc.am)) {
  2525. if( sd->color_info.num_components == 1) i = 3;
  2526. else if(sd->color_info.num_components == 3) i = 9;
  2527. else i = 16;
  2528. fp = gs_malloc(sd->memory, i,sizeof(float),"stc_put_params");
  2529. if(fp != NULL) memcpy(fp,sd->stc.am,i*sizeof(float));
  2530. else code = gs_error_VMerror;
  2531. sd->stc.am = fp;
  2532. }
  2533. if(sd->stc.escp_init.data != oldstc.escp_init.data) {
  2534. byte *ip = NULL;
  2535. if(sd->stc.escp_init.size > 0) {
  2536. ip = gs_malloc(sd->memory, sd->stc.escp_init.size,1,"stcolor/init");
  2537. if(ip == NULL) {
  2538. code = gs_error_VMerror;
  2539. sd->stc.escp_init.size = 0;
  2540. } else {
  2541. memcpy(ip,sd->stc.escp_init.data,sd->stc.escp_init.size);
  2542. }
  2543. }
  2544. sd->stc.escp_init.data = ip;
  2545. sd->stc.escp_init.persistent = false;
  2546. }
  2547. if(sd->stc.escp_release.data != oldstc.escp_release.data) {
  2548. byte *ip = NULL;
  2549. if(sd->stc.escp_release.size > 0) {
  2550. ip = gs_malloc(sd->memory, sd->stc.escp_release.size,1,"stcolor/release");
  2551. if(ip == NULL) {
  2552. code = gs_error_VMerror;
  2553. sd->stc.escp_release.size = 0;
  2554. } else {
  2555. memcpy(ip,sd->stc.escp_release.data,sd->stc.escp_release.size);
  2556. }
  2557. }
  2558. sd->stc.escp_release.data = ip;
  2559. sd->stc.escp_release.persistent = false;
  2560. }
  2561. if(code < 0) { /* free newly allocated arrays */
  2562. if((sd->stc.am != NULL) && (sd->stc.am != oldstc.am)) {
  2563. if( sd->color_info.num_components == 1) i = 3;
  2564. else if(sd->color_info.num_components == 3) i = 9;
  2565. else i = 16;
  2566. gs_free(sd->memory, sd->stc.am,i,sizeof(float),"stc_put_params");
  2567. }
  2568. if((sd->stc.escp_init.data != NULL) &&
  2569. (sd->stc.escp_init.data != oldstc.escp_init.data))
  2570. gs_free(sd->memory, (byte *) sd->stc.escp_init.data,sd->stc.escp_init.size,1,
  2571. "stcolor/init");
  2572. if((sd->stc.escp_release.data != NULL) &&
  2573. (sd->stc.escp_release.data != oldstc.escp_release.data))
  2574. gs_free(sd->memory, (byte *) sd->stc.escp_release.data,sd->stc.escp_release.
  2575. size,1,"stcolor/release");
  2576. for(i = 0; i < sd->color_info.num_components; ++i) { /* components */
  2577. int j;
  2578. if((sd->stc.extc[i] != NULL) &&
  2579. (sd->stc.extc[i] != defext) &&
  2580. (sd->stc.extc[i] != oldstc.extc[i])) {
  2581. for(j = 0; j < i; ++j)
  2582. if(sd->stc.extc[i] == sd->stc.extc[j]) break;
  2583. if(i == j) gs_free(sd->memory, sd->stc.extc[i],sd->stc.sizc[i],sizeof(float),
  2584. "stc_put_params");
  2585. }
  2586. if((sd->stc.extv[i] != NULL) &&
  2587. (sd->stc.extv[i] != oldstc.extv[i]) &&
  2588. (sd->stc.extv[i] != defext)) {
  2589. for(j = 0; j < i; ++j)
  2590. if(sd->stc.extv[i] == sd->stc.extv[j]) break;
  2591. if(i == j) gs_free(sd->memory, sd->stc.extv[i],sd->stc.sizv[i],sizeof(float),
  2592. "stc_put_params");
  2593. }
  2594. } /* components */
  2595. } /* free newly allocated arrays */
  2596. } /* Allocate new arrays */
  2597. error = error > code ? code : error;
  2598. /*
  2599. * finally decide upon restore or release of old, unused data
  2600. */
  2601. if(error != 0) { /* Undo changes */
  2602. memcpy(&sd->color_info,&oldcolor,sizeof(oldcolor));
  2603. memcpy(&sd->stc ,&oldstc ,sizeof(oldstc ));
  2604. } else { /* undo / release */
  2605. if((oldstc.escp_init.data != NULL) &&
  2606. (oldstc.escp_init.data != sd->stc.escp_init.data)) {
  2607. gs_free(sd->memory, (byte *)oldstc.escp_init.data,
  2608. oldstc.escp_init.size,1,"stcolor/init");
  2609. }
  2610. if((oldstc.escp_release.data != NULL) &&
  2611. (oldstc.escp_release.data != sd->stc.escp_release.data)) {
  2612. gs_free(sd->memory, (byte *)oldstc.escp_release.data,
  2613. oldstc.escp_release.size,1,"stcolor/release");
  2614. }
  2615. if((oldstc.am != NULL) && (oldstc.am != sd->stc.am)) {
  2616. if( oldcolor.num_components == 1) i = 3;
  2617. else if(oldcolor.num_components == 3) i = 9;
  2618. else i = 16;
  2619. gs_free(sd->memory, oldstc.am,i,sizeof(float),"stc_put_params");
  2620. }
  2621. for(i = 0; i < 4; ++i) {
  2622. int j;
  2623. if((oldstc.extc[i] != NULL) &&
  2624. (oldstc.extc[i] != sd->stc.extc[i]) &&
  2625. (oldstc.dither != NULL) &&
  2626. (oldstc.extc[i] != defext)) {
  2627. for(j = 0; j < i; ++j) if(oldstc.extc[i] == oldstc.extc[j]) break;
  2628. if(i == j) gs_free(sd->memory, oldstc.extc[i],oldstc.sizc[i],sizeof(float),
  2629. "stc_put_params");
  2630. }
  2631. if((oldstc.extv[i] != NULL) &&
  2632. (oldstc.extv[i] != sd->stc.extv[i]) &&
  2633. (oldstc.extv[i] != defext)) {
  2634. for(j = 0; j < i; ++j) if(oldstc.extv[i] == oldstc.extv[j]) break;
  2635. if(i == j) gs_free(sd->memory, oldstc.extv[i],oldstc.sizv[i],sizeof(float),
  2636. "stc_put_params");
  2637. }
  2638. }
  2639. /*
  2640. * Close the device if colormodel changed or recomputation
  2641. * of internal arrays is required
  2642. */
  2643. if(sd->is_open) { /* we might need to close it */
  2644. bool doclose = false;
  2645. if((sd->color_info.num_components != oldcolor.num_components) ||
  2646. (sd->color_info.depth != oldcolor.depth ) ||
  2647. (sd->stc.bits != oldstc.bits ) ||
  2648. (sd->stc.dither != oldstc.dither ))
  2649. doclose = true;
  2650. for(i = 0; i < sd->color_info.num_components; ++i) {
  2651. if(sd->stc.extv[i] != oldstc.extv[i]) doclose = true;
  2652. if(sd->stc.extc[i] != oldstc.extc[i]) doclose = true;
  2653. }
  2654. if(doclose) {
  2655. stc_freedata(pdev->memory, &oldstc);
  2656. for(i = 0; i < 4; ++i) {
  2657. sd->stc.vals[i] = NULL;
  2658. sd->stc.code[i] = NULL;
  2659. }
  2660. gs_closedevice(pdev);
  2661. }
  2662. } /* we might need to close it */
  2663. }
  2664. return error;
  2665. }
  2666. /*
  2667. * 1Bit CMYK-Algorithm
  2668. */
  2669. private int
  2670. stc_gscmyk(stcolor_device *sdev,int npixel,byte *in,byte *buf,byte *out)
  2671. {
  2672. byte *ip = in;
  2673. int error = 0;
  2674. /* ============================================================= */
  2675. if(npixel > 0) { /* npixel > 0 -> scanline-processing */
  2676. /* ============================================================= */
  2677. int p;
  2678. /*
  2679. * simply split the two pixels rsiding in a byte
  2680. */
  2681. for(p = npixel; p > 0; --p) { /* loop over pixels */
  2682. byte tmp =*ip++;
  2683. *out++ = (tmp>>4) & 15;
  2684. if(--p <= 0) break;
  2685. *out++ = tmp & 15;
  2686. } /* loop over pixels */
  2687. /* ============================================================= */
  2688. } else { /* npixel <= 0 -> initialisation */
  2689. /* ============================================================= */
  2690. /* we didn't check for the white-calls above, so this may cause errors */
  2691. if(sdev->stc.dither->flags & STC_WHITE) error = -1;
  2692. /* if we're not setup for bytes, this is an error too */
  2693. if((sdev->stc.dither->flags & STC_TYPE) != STC_BYTE) error = -2;
  2694. /* This IS a direct-driver, so STC_DIRECT must be set! */
  2695. if((sdev->stc.dither->flags & STC_DIRECT) == 0) error = -3;
  2696. /* and cmyk-mode is the only supported mode */
  2697. if(sdev->color_info.num_components != 4) error = -4;
  2698. /* and we support only 4Bit-Depth here */
  2699. if(sdev->color_info.depth != 4) error = -5;
  2700. /* ============================================================= */
  2701. } /* scanline-processing or initialisation */
  2702. /* ============================================================= */
  2703. return error;
  2704. }
  2705. /*
  2706. * The following is an algorithm under test
  2707. */
  2708. private int
  2709. stc_hscmyk(stcolor_device *sdev,int npixel,byte *in,byte *buf,byte *out)
  2710. {
  2711. /* ============================================================= */
  2712. if(npixel < 0) { /* npixel <= 0 -> initialisation */
  2713. /* ============================================================= */
  2714. int i,i2do;
  2715. long *lp = (long *) buf;
  2716. /* CMYK-only algorithm */
  2717. if( sdev->color_info.num_components != 4) return -1;
  2718. /*
  2719. * check wether stcdither & TYPE are correct
  2720. */
  2721. if(( sdev->stc.dither == NULL) ||
  2722. ((sdev->stc.dither->flags & STC_TYPE) != STC_LONG)) return -2;
  2723. /*
  2724. * check wether the buffer-size is sufficiently large
  2725. */
  2726. if(((sdev->stc.dither->flags/STC_SCAN) < 1) ||
  2727. ( sdev->stc.dither->bufadd <
  2728. (1 + 2*sdev->color_info.num_components))) return -3;
  2729. /*
  2730. * must have STC_CMYK10, STC_DIRECT, but not STC_WHITE
  2731. */
  2732. if((sdev->stc.dither->flags & STC_CMYK10) == 0) return -4;
  2733. if((sdev->stc.dither->flags & STC_DIRECT) == 0) return -5;
  2734. if((sdev->stc.dither->flags & STC_WHITE ) != 0) return -6;
  2735. /*
  2736. * Must have values between 0-1023.0
  2737. */
  2738. if((sdev->stc.dither->minmax[0] != 0.0) ||
  2739. (sdev->stc.dither->minmax[1] != 1023.0)) return -7;
  2740. /*
  2741. * initialize buffer
  2742. */
  2743. i2do = 1 + 8 - 4 * npixel;
  2744. lp[0] = 0;
  2745. if(sdev->stc.flags & STCDFLAG0) {
  2746. for(i = 1; i < i2do; ++i) lp[i] = 0;
  2747. } else {
  2748. for(i = 1; i < i2do; ++i) lp[i] = (rand() % 381) - 190;
  2749. }
  2750. /* ============================================================= */
  2751. } else { /* npixel > 0 && in != NULL -> scanline-processing */
  2752. /* ============================================================= */
  2753. long errc[4],*errv;
  2754. int step = buf[0] ? -1 : 1;
  2755. stc_pixel *ip = (stc_pixel *) in;
  2756. buf[0] = ~ buf[0];
  2757. errv = (long *) buf + 5;
  2758. if(step < 0) {
  2759. ip += npixel-1;
  2760. out += npixel-1;
  2761. errv += 4*(npixel-1);
  2762. }
  2763. errc[0] = 0; errc[1] = 0; errc[2] = 0; errc[3] = 0;
  2764. while(npixel-- > 0) {
  2765. register stc_pixel ci,mode;
  2766. register long k,v,n;
  2767. register int pixel; /* internal pixel-value */
  2768. ci = *ip; ip += step;
  2769. mode = ci & 3;
  2770. k = (ci>>2) & 0x3ff;
  2771. pixel = 0;
  2772. v = k+errv[3]+((7*errc[3])>>4);
  2773. if(mode == 3) { /* only Black allowed to fire */
  2774. if(v > 511) {
  2775. v -= 1023;
  2776. pixel = BLACK;
  2777. }
  2778. errv[3-(step<<2)] += ((3*v+8)>>4); /* 3/16 */
  2779. errv[3] = ((5*v+errc[3]+8)>>4);/* 5/16 +1/16 (rest) */
  2780. errc[3] = v;
  2781. errv[0] = errv[0] < -190 ? -190 : errv[0] < 190 ? errv[0] : 190;
  2782. errv[1] = errv[1] < -190 ? -190 : errv[1] < 190 ? errv[1] : 190;
  2783. errv[2] = errv[2] < -190 ? -190 : errv[2] < 190 ? errv[2] : 190;
  2784. errc[0] = 0; errc[1] = 0; errc[2] = 0;
  2785. } else if(v > 511) { /* black known to fire */
  2786. v -= 1023;
  2787. pixel = BLACK;
  2788. errv[3-(step<<2)] += ((3*v+8)>>4); /* 3/16 */
  2789. errv[3] = ((5*v+errc[3]+8)>>4);/* 5/16 +1/16 (rest) */
  2790. errc[3] = v;
  2791. n = (ci>>12) & 0x3ff;
  2792. if(mode == 2) { v = k; }
  2793. else { v = n; n = (ci>>22) & 0x3ff; }
  2794. v += errv[2]+((7*errc[2])>>4)-1023;
  2795. if(v < -511) v = -511;
  2796. errv[2-(step<<2)] += ((3*v+8)>>4); /* 3/16 */
  2797. errv[2] = ((5*v+errc[2]+8)>>4);/* 5/16 +1/16 (rest) */
  2798. errc[2] = v;
  2799. if(mode == 1) { v = k; }
  2800. else { v = n; n = (ci>>22) & 0x3ff; }
  2801. v += errv[1]+((7*errc[1])>>4)-1023;
  2802. if(v < -511) v = -511;
  2803. errv[1-(step<<2)] += ((3*v+8)>>4); /* 3/16 */
  2804. errv[1] = ((5*v+errc[1]+8)>>4);/* 5/16 +1/16 (rest) */
  2805. errc[1] = v;
  2806. if(mode == 0) v = k;
  2807. else v = n;
  2808. v += errv[0]+((7*errc[0])>>4)-1023;
  2809. if(v < -511) v = -511;
  2810. errv[0-(step<<2)] += ((3*v+8)>>4); /* 3/16 */
  2811. errv[0] = ((5*v+errc[0]+8)>>4);/* 5/16 +1/16 (rest) */
  2812. errc[0] = v;
  2813. } else { /* Black does not fire initially */
  2814. long kv = v; /* Black computed after colors */
  2815. n = (ci>>12) & 0x3ff;
  2816. if(mode == 2) { v = k; }
  2817. else { v = n; n = (ci>>22) & 0x3ff; }
  2818. v += errv[2]+((7*errc[2])>>4);
  2819. if(v > 511) {
  2820. pixel |= YELLOW;
  2821. v -= 1023;
  2822. }
  2823. errv[2-(step<<2)] += ((3*v+8)>>4); /* 3/16 */
  2824. errv[2] = ((5*v+errc[2]+8)>>4);/* 5/16 +1/16 (rest) */
  2825. errc[2] = v;
  2826. if(mode == 1) { v = k; }
  2827. else { v = n; n = (ci>>22) & 0x3ff; }
  2828. v += errv[1]+((7*errc[1])>>4);
  2829. if(v > 511) {
  2830. pixel |= MAGENTA;
  2831. v -= 1023;
  2832. }
  2833. errv[1-(step<<2)] += ((3*v+8)>>4); /* 3/16 */
  2834. errv[1] = ((5*v+errc[1]+8)>>4);/* 5/16 +1/16 (rest) */
  2835. errc[1] = v;
  2836. if(mode == 0) v = k;
  2837. else v = n;
  2838. v += errv[0]+((7*errc[0])>>4);
  2839. if(v > 511) {
  2840. pixel |= CYAN;
  2841. v -= 1023;
  2842. }
  2843. errv[0-(step<<2)] += ((3*v+8)>>4); /* 3/16 */
  2844. errv[0] = ((5*v+errc[0]+8)>>4);/* 5/16 +1/16 (rest) */
  2845. errc[0] = v;
  2846. v = kv;
  2847. if(pixel == (CYAN|MAGENTA|YELLOW)) {
  2848. pixel = BLACK;
  2849. v = v > 511 ? v-1023 : -511;
  2850. }
  2851. errv[3-(step<<2)] += ((3*v+8)>>4); /* 3/16 */
  2852. errv[3] = ((5*v+errc[3]+8)>>4);/* 5/16 +1/16 (rest) */
  2853. errc[3] = v;
  2854. }
  2855. errv += step<<2;
  2856. *out = pixel; out += step;
  2857. } /* loop over pixels */
  2858. /* ============================================================= */
  2859. } /* initialisation, white or scanline-processing */
  2860. /* ============================================================= */
  2861. return 0;
  2862. }