gdevcd8.c 90 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865
  1. /*
  2. Copyright (C) 1996-1998 <Uli Wortmann uliw@erdw.ethz.ch>
  3. Portions Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 U.S.A.
  15. This program may also be distributed as part of Aladdin Ghostscript,
  16. under the terms of the Aladdin Free Public License (the "License").
  17. Every copy of Aladdin Ghostscript must include a copy of the
  18. License, normally in a plain ASCII text file named PUBLIC. The
  19. License grants you the right to copy, modify and redistribute
  20. Aladdin Ghostscript, but only under certain conditions described in
  21. the License. Among other things, the License requires that the
  22. copyright notice and this notice be preserved on all copies.
  23. */
  24. /*$Id: gdevcd8.c,v 1.1 2000/03/09 08:40:40 lpd Exp $*/
  25. /*
  26. A printer driver for the HP670, HP690, HP850, HP855
  27. HP870, HP890, HP1100 and HP1600 color printers.
  28. To be used with the Ghostscript printing system.
  29. Please report all problems to uliw@erdw.ethz.ch
  30. CREDITS: Much of the driver is based on ideas derived
  31. from the cdj550 driver of George Cameron.
  32. The support for the hp670, hp690, hp890
  33. and hp1600 was added by Martin Gerbershagen.
  34. */
  35. /* Note: Depending on how you transfered the files,
  36. you might need to remove some CR-codes used on intel-based machines:
  37. simply type: unzip -a hp850.zip
  38. to compile with gs5.x, simply add
  39. DEVICE_DEVS4=cdj850.dev cdj670.dev cdj890.dev cdj1600.dev
  40. to your makefile.
  41. BTW, it is always a good idea to read Make.htm found in the
  42. gs-distrib before attempting to recompile.....
  43. */
  44. /* 1999-01-07 edited by L. Peter Deutsch <ghost@aladdin.com> to eliminate
  45. non-const statics and otherwise bring up to date with Ghostscript coding
  46. style guidelines. */
  47. /* 01.06.98 Version 1.3 Due to the most welcome contribution
  48. of Martin Gerbershagen (ger@ulm.temic.de),
  49. support for the hp670, hp690 and hp890
  50. and hp1600 has been added. Martin has also
  51. resolved all known bugs.
  52. Problems : Dark colors are still pale.
  53. The driver no longer needs special switches to be invoked
  54. except -sDEVICE=cdj850, or -sDEVICE=CDJ890, or sDEVICE=CDJ670
  55. or -sDEVICE=CDJ1600
  56. The hp690 is supported through the hp670 device, the hp855, hp870
  57. and the hp1100 through the hp850 device.
  58. The driver implements the following switches:
  59. -dPapertype= 0 plain paper [default]
  60. 1 bond paper
  61. 2 special paper
  62. 3 glossy film
  63. 4 transparency film
  64. Note, currently the lookuptables are not suited
  65. for printing on special paper or transperencies.
  66. Please revert to the gamma functions in this case.
  67. -dQuality= -1 draft
  68. 0 normal [default]
  69. 1 presentation
  70. -dRetStatus= 0 C-RET off
  71. 1 C-RET on [default]
  72. -dMasterGamma= 3.0 [default = 1.0]
  73. __Note__: To take advantage of the calibrated color-transfer
  74. functions, be sure not to have any Gamma-Statements
  75. left! If you need to (i.e. overhead sheets),
  76. you still can use the gamma-functions, but they will
  77. override the built-in calibration. To use gamma in the
  78. traditional way, set MasterGamma to any value greater
  79. 1.0 and less 10.0. To adjust individual gamma-values,
  80. you have to additionally set MasterGamma to a value
  81. greater 1.0 and less 10.0
  82. With the next release, gamma functions will be dropped.
  83. When using the driver, be aware that printing in 600dpi involves
  84. processing of large amounts of data (> 188MB !). Therefore, the
  85. driver is not what you would expect to be a fast driver ;-)
  86. This is no problem when printing a full sized color page (because
  87. printing itself is slow), but it's really annoying if yoy print only
  88. text pages. Maybe I can optimize the code for text-only pages in a
  89. later release. Right now, it is recommended to use the highest
  90. possible optimisation level your compiler offers....
  91. For the time beeing, use the cdj550 device with -sBitsPerPixel=3
  92. for fast proof-prints. If you simply want to print 600dpi b/w data,
  93. use the cdj550 device with -sBitsPerPixel=8 (or 1).
  94. Since the printer itself is slow, it may help to set the
  95. process-priority of the gs-process to regular or even less. On a
  96. 486/100MHZ this is still sufficient to maintain a continuos
  97. data-flow.
  98. Note to OS/2 users: Simply put the gs-window into the background,
  99. or minimize it. Also make sure, that print01.sys is invoked without
  100. the /irq switch (great speed improvement under warp4).
  101. The printer default settings compensate for dot-gain by a
  102. calibrated color-transfer function. If this appears to be to light
  103. for your business-graphs, or for overhead-sheets, feel free to set
  104. -dMasterGamma=1.7.
  105. Furthermore, you may tweak the gammavalues independently by setting
  106. -dGammaValC, -dGammaValM, -dGammaValY or -dGammaValK (if not set,
  107. the values default to MasterGamma). This will only work, when
  108. -dMasterGamma is set to a value greater than 1.0.
  109. If you want to learn more about gamma, see:
  110. http://www.erdw.ethz.ch/~bonk/ftp/misc/gammafaq.pdf
  111. http://www.erdw.ethz.ch/~bonk/ftp/misc/colorfaq.pdf
  112. Further information, bugs, tips etc, can be found
  113. at my website.
  114. Have fun!
  115. Uli
  116. uliw@erdw.ethz.ch
  117. http://www.erdw.ethz.ch/~bonk/bonk.html
  118. */
  119. /* 25.08.97 Version 1.2. Resolved all but one of the
  120. known bugs, introduced a couple
  121. of perfomance improvements. Complete
  122. new color-transfer-function handling.
  123. (see gamma). */
  124. /* 04.05.97 Version 1.1. For added features, */
  125. /* resolved bugs and so forth, please see */
  126. /* http://bonk.ethz.ch */
  127. /* 11.11.96. Initial release of the driver */
  128. #include "math_.h"
  129. #include <stdlib.h> /* for rand() */
  130. #include <assert.h>
  131. #include "gdevprn.h"
  132. #include "gdevpcl.h"
  133. #include "gsparam.h"
  134. /* Conversion stuff. */
  135. #include "gxlum.h"
  136. #define P1(x) x
  137. #define P2(x,y) x,y
  138. #define P3(x,y,z) x,y,z
  139. #define P4(x,y,z,a) x,y,z,a
  140. #define P5(x,y,z,a,b) x,y,z,a,b
  141. #define P6(x,y,z,a,b,c) x,y,z,a,b,c
  142. #define P7(x,y,z,a,b,c,d) x,y,z,a,b,c,d
  143. #define P8(x,y,z,a,b,c,d,e) x,y,z,a,b,c,d,e
  144. #define P9(x,y,z,a,b,c,d,e,f) x,y,z,a,b,c,d,e,f
  145. #define P10(x,y,z,a,b,c,d,e,f,g) x,y,z,a,b,c,d,e,f,g
  146. #define P11(x,y,z,a,b,c,d,e,f,g,h) x,y,z,a,b,c,d,e,f,g,h
  147. #define P12(x,y,z,a,b,c,d,e,f,g,h,i) x,y,z,a,b,c,d,e,f,g,h,i
  148. /* this holds the initialisation data of the hp850 */
  149. typedef struct hp850_cmyk_init_s {
  150. byte a[26];
  151. } hp850_cmyk_init_t;
  152. private const hp850_cmyk_init_t hp850_cmyk_init =
  153. {
  154. {
  155. 0x02, /* format */
  156. 0x04, /* number of components */
  157. /* black */
  158. 0x01, /* MSB x resolution */
  159. 0x2c, /* LSB x resolution */
  160. 0x01, /* MSB y resolution */
  161. 0x2c, /* LSB y resolution */
  162. 0x00, /* MSB intensity levels */
  163. 0x02, /* LSB intensity levels */
  164. /* cyan */
  165. 0x01, /* MSB x resolution */
  166. 0x2c, /* LSB x resolution */
  167. 0x01, /* MSB y resolution */
  168. 0x2c, /* LSB y resolution */
  169. 0x00, /* MSB intensity levels */
  170. 0x02, /* LSB intensity levels */
  171. /* magenta */
  172. 0x01, /* MSB x resolution */
  173. 0x2c, /* LSB x resolution */
  174. 0x01, /* MSB y resolution */
  175. 0x2c, /* LSB y resolution */
  176. 0x00, /* MSB intensity levels */
  177. 0x02, /* LSB intensity levels */
  178. /* yellow */
  179. 0x01, /* MSB x resolution */
  180. 0x2c, /* LSB x resolution */
  181. 0x01, /* MSB y resolution */
  182. 0x2c, /* LSB y resolution */
  183. 0x00, /* MSB intensity levels */
  184. 0x02 /* LSB intensity levels */
  185. }
  186. };
  187. /* this holds the color lookuptable data of the hp850 */
  188. typedef struct {
  189. byte c[256]; /* Lookuptable for cyan */
  190. byte m[256]; /* dito for magenta */
  191. byte y[256]; /* dito for yellow */
  192. byte k[256]; /* dito for black */
  193. int correct[256]; /* potential undercolor black correction */
  194. } Gamma;
  195. private const Gamma gammat850 =
  196. {
  197. /* Lookup values for cyan */
  198. {0, 0, 0, 2, 2, 2, 3, 3, 3, 5, 5, 5, 7, 7, 6, 7, 7, 6, 7, 7, 7, 8, 8,
  199. 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 11, 11, 12, 12, 12,
  200. 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 16, 16, 15, 16, 16, 17, 17,
  201. 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 20, 20, 20, 21, 21, 21, 22,
  202. 22, 23, 23, 23, 23, 23, 24, 24, 25, 25, 26, 26, 26, 26, 26, 27, 27,
  203. 27, 27, 28, 28, 29, 28, 28, 29, 29, 30, 30, 31, 31, 32, 32, 33, 34,
  204. 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, 40, 40, 41, 41, 42, 42, 42,
  205. 43, 43, 43, 44, 45, 45, 46, 46, 47, 47, 48, 48, 49, 50, 50, 51, 51,
  206. 52, 52, 53, 54, 54, 54, 55, 55, 56, 57, 58, 58, 59, 60, 60, 61, 62,
  207. 62, 63, 65, 65, 66, 67, 67, 68, 69, 69, 70, 72, 73, 73, 74, 75, 75,
  208. 76, 77, 79, 79, 80, 81, 82, 83, 83, 84, 86, 87, 88, 88, 89, 90, 91,
  209. 92, 93, 94, 95, 96, 97, 97, 99, 100, 101, 102, 103, 104, 105, 106,
  210. 108, 109, 110, 111, 112, 114, 115, 117, 119, 120, 122, 124, 125, 127,
  211. 129, 131, 132, 135, 136, 138, 140, 142, 144, 146, 147, 150, 152, 154,
  212. 157, 159, 162, 164, 166, 168, 171, 174, 176, 180, 182, 187, 192, 197,
  213. 204, 215, 255},
  214. /* Lookup values for magenta */
  215. {0, 0, 0, 1, 1, 1, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 7,
  216. 7, 8, 8, 8, 9, 9, 10, 10, 9, 10, 10, 10, 11, 11, 11, 11, 11, 12, 12,
  217. 12, 13, 13, 13, 14, 14, 15, 15, 15, 16, 16, 16, 16, 16, 17, 17, 17,
  218. 17, 17, 18, 18, 19, 19, 19, 19, 19, 20, 20, 20, 21, 21, 22, 22, 22,
  219. 23, 23, 24, 24, 25, 25, 25, 26, 26, 27, 27, 28, 29, 29, 29, 29, 30,
  220. 30, 31, 30, 31, 31, 32, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36,
  221. 36, 37, 37, 38, 38, 39, 39, 40, 40, 41, 41, 42, 42, 43, 43, 44, 44,
  222. 45, 45, 46, 46, 47, 48, 48, 49, 49, 50, 50, 51, 51, 52, 53, 53, 54,
  223. 54, 55, 55, 56, 57, 57, 58, 58, 59, 60, 60, 61, 61, 62, 63, 64, 65,
  224. 66, 66, 67, 68, 68, 70, 71, 71, 72, 73, 73, 74, 76, 77, 77, 78, 79,
  225. 79, 80, 81, 82, 83, 84, 85, 86, 87, 87, 88, 89, 90, 91, 91, 92, 93,
  226. 94, 95, 96, 97, 98, 99, 100, 100, 101, 102, 103, 105, 106, 107, 108,
  227. 109, 112, 113, 114, 115, 116, 118, 119, 121, 123, 124, 125, 128, 129,
  228. 130, 133, 134, 135, 138, 139, 142, 144, 145, 148, 150, 152, 154, 157,
  229. 159, 162, 164, 168, 169, 170, 172, 175, 177, 179, 182, 185, 189, 193,
  230. 198, 204, 215, 255},
  231. /* Lookup values for yellow */
  232. {0, 0, 0, 2, 2, 2, 3, 3, 3, 5, 5, 5, 7, 7, 6, 7, 7, 6, 7, 7, 7, 8, 8,
  233. 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11,
  234. 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 17, 17, 18, 18,
  235. 18, 19, 18, 19, 19, 19, 20, 20, 21, 21, 21, 22, 22, 22, 22, 22, 23,
  236. 23, 24, 24, 25, 25, 25, 26, 27, 28, 28, 29, 29, 29, 30, 30, 30, 30,
  237. 31, 31, 32, 32, 33, 33, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37,
  238. 38, 38, 39, 39, 40, 40, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 45,
  239. 45, 46, 46, 47, 48, 48, 49, 49, 50, 50, 51, 51, 52, 53, 53, 54, 54,
  240. 55, 55, 56, 57, 58, 59, 59, 60, 61, 61, 62, 62, 63, 64, 65, 66, 67,
  241. 67, 68, 69, 69, 70, 71, 72, 73, 74, 74, 75, 76, 77, 77, 78, 79, 79,
  242. 80, 81, 82, 83, 84, 85, 86, 87, 87, 88, 89, 90, 91, 91, 93, 94, 95,
  243. 96, 97, 98, 100, 101, 102, 102, 103, 104, 106, 107, 108, 109, 110,
  244. 111, 113, 114, 115, 116, 117, 118, 119, 121, 123, 124, 126, 128, 130,
  245. 131, 134, 135, 137, 139, 140, 143, 145, 146, 148, 150, 152, 154, 156,
  246. 158, 160, 163, 166, 167, 169, 171, 173, 176, 178, 181, 184, 188, 192,
  247. 198, 204, 215, 255},
  248. /* Lookup values for black */
  249. {0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 2, 4, 3, 3, 3, 3, 3, 4, 4,
  250. 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 9, 9, 8,
  251. 8, 8, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13,
  252. 12, 12, 12, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 16, 16,
  253. 16, 17, 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 20, 20, 20, 21, 21,
  254. 21, 21, 22, 22, 22, 22, 23, 22, 23, 23, 24, 24, 24, 24, 25, 25, 26,
  255. 26, 26, 26, 27, 27, 28, 28, 28, 28, 29, 29, 30, 30, 31, 31, 31, 32,
  256. 32, 33, 33, 34, 34, 35, 36, 36, 36, 37, 37, 37, 38, 38, 40, 40, 40,
  257. 41, 41, 42, 43, 43, 43, 43, 44, 45, 45, 46, 47, 47, 48, 49, 49, 50,
  258. 52, 52, 53, 54, 54, 56, 56, 57, 58, 59, 60, 60, 61, 62, 63, 63, 64,
  259. 65, 66, 67, 68, 69, 70, 71, 72, 72, 73, 75, 75, 76, 77, 78, 80, 81,
  260. 82, 82, 83, 84, 85, 86, 88, 89, 90, 91, 94, 95, 96, 98, 99, 100, 101,
  261. 103, 105, 106, 107, 110, 111, 112, 115, 116, 118, 120, 121, 124, 126,
  262. 127, 131, 133, 134, 138, 140, 141, 146, 148, 151, 154, 156, 160, 163,
  263. 166, 169, 174, 177, 182, 187, 194, 203, 215, 255}
  264. };
  265. private const Gamma gammat890 =
  266. {
  267. /* Lookup values for cyan */
  268. {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
  269. 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  270. 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
  271. 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
  272. 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
  273. 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
  274. 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
  275. 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
  276. 126, 127,
  277. 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
  278. 142, 143,
  279. 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157,
  280. 158, 159,
  281. 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173,
  282. 174, 175,
  283. 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189,
  284. 190, 191,
  285. 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205,
  286. 206, 207,
  287. 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221,
  288. 222, 223,
  289. 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237,
  290. 238, 239,
  291. 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253,
  292. 254, 255},
  293. /* Lookup values for magenta */
  294. {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
  295. 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  296. 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
  297. 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
  298. 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
  299. 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
  300. 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
  301. 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
  302. 126, 127,
  303. 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
  304. 142, 143,
  305. 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157,
  306. 158, 159,
  307. 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173,
  308. 174, 175,
  309. 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189,
  310. 190, 191,
  311. 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205,
  312. 206, 207,
  313. 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221,
  314. 222, 223,
  315. 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237,
  316. 238, 239,
  317. 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253,
  318. 254, 255},
  319. /* Lookup values for yellow */
  320. {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
  321. 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  322. 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
  323. 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
  324. 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
  325. 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
  326. 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
  327. 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
  328. 126, 127,
  329. 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
  330. 142, 143,
  331. 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157,
  332. 158, 159,
  333. 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173,
  334. 174, 175,
  335. 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189,
  336. 190, 191,
  337. 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205,
  338. 206, 207,
  339. 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221,
  340. 222, 223,
  341. 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237,
  342. 238, 239,
  343. 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253,
  344. 254, 255},
  345. /* Lookup values for black */
  346. {0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 2, 4, 3, 3, 3, 3, 3, 4, 4,
  347. 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 9, 9, 8,
  348. 8, 8, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13,
  349. 12, 12, 12, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 16, 16,
  350. 16, 17, 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 20, 20, 20, 21, 21,
  351. 21, 21, 22, 22, 22, 22, 23, 22, 23, 23, 24, 24, 24, 24, 25, 25, 26,
  352. 26, 26, 26, 27, 27, 28, 28, 28, 28, 29, 29, 30, 30, 31, 31, 31, 32,
  353. 32, 33, 33, 34, 34, 35, 36, 36, 36, 37, 37, 37, 38, 38, 40, 40, 40,
  354. 41, 41, 42, 43, 43, 43, 43, 44, 45, 45, 46, 47, 47, 48, 49, 49, 50,
  355. 52, 52, 53, 54, 54, 56, 56, 57, 58, 59, 60, 60, 61, 62, 63, 63, 64,
  356. 65, 66, 67, 68, 69, 70, 71, 72, 72, 73, 75, 75, 76, 77, 78, 80, 81,
  357. 82, 82, 83, 84, 85, 86, 88, 89, 90, 91, 94, 95, 96, 98, 99, 100, 101,
  358. 103, 105, 106, 107, 110, 111, 112, 115, 116, 118, 120, 121, 124, 126,
  359. 127, 131, 133, 134, 138, 140, 141, 146, 148, 151, 154, 156, 160, 163,
  360. 166, 169, 174, 177, 182, 187, 194, 203, 215, 255}
  361. };
  362. private const Gamma * const gammat[] =
  363. {
  364. &gammat850, /* CDJ670 */
  365. &gammat850, /* CDJ850 */
  366. &gammat890, /* CDJ890 */
  367. &gammat850 /* CDJ1600 */
  368. };
  369. private int
  370. rescale_byte_wise1x1(P4(int bytecount, const byte * inbytea,
  371. const byte * inbyteb, byte * outbyte));
  372. private int
  373. rescale_byte_wise2x1(P4(int bytecount, const byte * inbytea,
  374. const byte * inbyteb, byte * outbyte));
  375. private int
  376. rescale_byte_wise1x2(P4(int bytecount, const byte * inbytea,
  377. const byte * inbyteb, byte * outbyte));
  378. private int
  379. rescale_byte_wise2x2(P4(int bytecount, const byte * inbytea,
  380. const byte * inbyteb, byte * outbyte));
  381. private int (* const rescale_color_plane[2][2]) (P4(int, const byte *, const byte *, byte *)) = {
  382. {
  383. rescale_byte_wise1x1, rescale_byte_wise1x2
  384. },
  385. {
  386. rescale_byte_wise2x1, rescale_byte_wise2x2
  387. }
  388. };
  389. /*
  390. * Drivers stuff.
  391. *
  392. */
  393. #define DESKJET_PRINT_LIMIT 0.04 /* 'real' top margin? */
  394. /* Margins are left, bottom, right, top. */
  395. #define DESKJET_MARGINS_LETTER 0.25, 0.50, 0.25, 0.167
  396. #define DESKJET_MARGINS_A4 0.13, 0.46, 0.13, 0.04
  397. /* Define bits-per-pixel - default is 32-bit cmyk-mode */
  398. #ifndef BITSPERPIXEL
  399. # define BITSPERPIXEL 32
  400. #endif
  401. #define DOFFSET (dev_t_margin(pdev) - DESKJET_PRINT_LIMIT) /* Print position */
  402. #define W sizeof(word)
  403. #define I sizeof(int)
  404. /* paper types */
  405. typedef enum {
  406. PLAIN_PAPER, BOND_PAPER, SPECIAL_PAPER, GLOSSY_FILM, TRANSPARENCY_FILM
  407. } cdj_paper_type_t;
  408. /* quality */
  409. typedef enum {
  410. DRAFT = -1, NORMAL = 0, PRESENTATION = 1
  411. } cdj_quality_t;
  412. /* Printer types */
  413. typedef enum {
  414. DJ670C, DJ850C, DJ890C, DJ1600C
  415. } cdj_printer_type_t;
  416. /* No. of ink jets (used to minimise head movements) */
  417. #define HEAD_ROWS_MONO 50
  418. #define HEAD_ROWS_COLOUR 16
  419. /* Colour mapping procedures */
  420. private dev_proc_map_cmyk_color(gdev_cmyk_map_cmyk_color);
  421. private dev_proc_map_rgb_color(gdev_cmyk_map_rgb_color);
  422. private dev_proc_map_color_rgb(gdev_cmyk_map_color_rgb);
  423. private dev_proc_map_rgb_color(gdev_pcl_map_rgb_color);
  424. private dev_proc_map_color_rgb(gdev_pcl_map_color_rgb);
  425. /* Print-page, parameters and miscellaneous procedures */
  426. private dev_proc_open_device(hp_colour_open);
  427. private dev_proc_get_params(cdj850_get_params);
  428. private dev_proc_put_params(cdj850_put_params);
  429. private dev_proc_print_page(cdj850_print_page);
  430. /* The device descriptors */
  431. /* The basic structure for all printers. Note the presence of the cmyk, depth
  432. and correct fields even if some are not used by all printers. */
  433. #define prn_colour_device_body(dtype, procs, dname, w10, h10, xdpi, ydpi, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_page, cmyk, correct)\
  434. prn_device_body(dtype, procs, dname, w10, h10, xdpi, ydpi, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_page), cmyk, depth /* default */, correct
  435. #define gx_prn_colour_device_common \
  436. gx_prn_device_common; \
  437. int cmyk; /* 0: not CMYK-capable, > 0: printing CMYK, */ \
  438. /* < 0 : CMYK-capable, not printing CMYK */ \
  439. uint default_depth; /* Used only for CMYK-capable printers now. */ \
  440. uint correction
  441. /* some definitions needed later */
  442. struct error_val_field {
  443. int c; /* Current value of Cyan error during dithering */
  444. int m; /* Current value of Magenta error during dithering */
  445. int y; /* Current value of Yellow error during dithering */
  446. int k; /* Current value of Black error during dithering */
  447. };
  448. /* this structure holds all the pointers to the different values
  449. in all those data fields */
  450. /*
  451. * The principal data pointers are stored as pairs of values, with
  452. * the selection being made by the 'scan' variable. The function of the
  453. * scan variable is overloaded, as it controls both the alternating
  454. * raster scan direction used in the Floyd-Steinberg dithering and also
  455. * the buffer alternation required for line-difference compression.
  456. *
  457. * Thus, the number of pointers required is as follows:
  458. */
  459. struct ptr_arrays {
  460. byte *data[4]; /* 4 600dpi data, scan direction and alternating buffers */
  461. byte *data_c[4]; /* 4 300dpi data, as above, */
  462. byte *plane_data[4][4]; /*4 b/w-planes, scan direction and alternating buffers */
  463. byte *plane_data_c[4][8]; /* as above, but for 8 planes */
  464. byte *out_data; /* output buffer for the b/w data, one 600dpi plane */
  465. byte *test_data[4]; /* holds a copy of the last plane */
  466. int *errors[2]; /* 2 b/w dithering erros (scan direction only) */
  467. int *errors_c[2]; /* 2 color dithering errors (scan direction only) */
  468. word *storage; /* pointer to the beginning of the b/w-buffer */
  469. word *storage_start; /* used for debugging */
  470. word *storage_end; /* used for debugging */
  471. word *storage_size; /* used for debugging */
  472. };
  473. /* Some miscellaneous variables */
  474. struct misc_struct {
  475. int line_size; /* size of scan_line */
  476. int line_size_c; /* size of rescaled scan_line */
  477. int line_size_words; /* size of scan_line in words */
  478. int paper_size; /* size of paper */
  479. int num_comps; /* number of color components (1 - 4) */
  480. int bits_per_pixel; /* bits per pixel 1,4,8,16,24,32 */
  481. int storage_bpp; /* = bits_per_pixel */
  482. int expanded_bpp; /* = bits_per_pixel */
  483. int plane_size; /* size of b/w bit plane */
  484. int plane_size_c; /* size of color bit plane */
  485. int databuff_size; /* size of databuffer for b/w data */
  486. int databuff_size_c; /* size of databuffer for color data */
  487. int errbuff_size; /* size of error buffer b/w -data */
  488. int errbuff_size_c; /* size of error buffer color -data */
  489. int outbuff_size; /* size of output buffer for b/w data */
  490. int scan; /* scan-line variable [0,1] */
  491. int cscan; /* dito for the color-planes */
  492. int is_two_pass; /* checks if b/w data has already been printed */
  493. int zero_row_count; /* How many empty lines */
  494. uint storage_size_words; /* size of storage in words for b/w data */
  495. uint storage_size_words_c; /* size of storage in words for c-data */
  496. int is_color_data; /* indicates whether there is color data */
  497. };
  498. /* function pointer typedefs for device driver struct */
  499. typedef void (*StartRasterMode) (P3(gx_device_printer * pdev, int paper_size,
  500. FILE * prn_stream));
  501. typedef void (*PrintNonBlankLines) (P6(gx_device_printer * pdev,
  502. struct ptr_arrays *data_ptrs,
  503. struct misc_struct *misc_vars,
  504. struct error_val_field *error_values,
  505. const Gamma *gamma,
  506. FILE * prn_stream));
  507. typedef void (*TerminatePage) (P2(gx_device_printer * pdev, FILE * prn_stream));
  508. typedef struct gx_device_cdj850_s {
  509. gx_device_common;
  510. gx_prn_colour_device_common;
  511. int /*cdj_quality_t*/ quality; /* -1 draft, 0 normal, 1 best */
  512. int /*cdj_paper_type_t*/ papertype; /* papertype [0,4] */
  513. int intensities; /* intensity values per pixel [2,4] */
  514. int xscal; /* boolean to indicate x scaling by 2 */
  515. int yscal; /* boolean to indicate y scaling by 2 */
  516. int /*cdj_printer_type_t*/ ptype; /* printer type, one of DJ670C, DJ850C, DJ890C, DJ1600C */
  517. int compression; /* compression level */
  518. float mastergamma; /* Gammavalue applied to all colors */
  519. float gammavalc; /* range to which gamma-correction is
  520. applied to bw values */
  521. float gammavalm; /* amount of gamma correction for bw */
  522. float gammavaly; /* range to which gamma-correction i
  523. applied to color values */
  524. float gammavalk; /* amount of gamma correction for color */
  525. float blackcorrect; /* amount of gamma correction for color */
  526. StartRasterMode start_raster_mode; /* output function to start raster mode */
  527. PrintNonBlankLines print_non_blank_lines; /* output function to print a non blank line */
  528. TerminatePage terminate_page; /* page termination output function */
  529. } gx_device_cdj850;
  530. typedef struct {
  531. gx_device_common;
  532. gx_prn_colour_device_common;
  533. } gx_device_colour_prn;
  534. /* Use the cprn_device macro to access generic fields (like cmyk,
  535. default_depth and correction), and specific macros for specific
  536. devices. */
  537. #define cprn_device ((gx_device_colour_prn*) pdev)
  538. #define cdj850 ((gx_device_cdj850 *)pdev)
  539. #define prn_cmyk_colour_device(dtype, procs, dev_name, x_dpi, y_dpi, bpp, print_page, correct)\
  540. prn_colour_device_body(dtype, procs, dev_name,\
  541. DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS, x_dpi, y_dpi, 0, 0, 0, 0,\
  542. ((bpp == 1 || bpp == 4) ? 1 : 4), bpp,\
  543. (bpp > 8 ? 255 : 1), (1 << (bpp >> 2)) - 1, /* max_gray, max_color */\
  544. (bpp > 8 ? 5 : 2), (bpp > 8 ? 5 : bpp > 1 ? 2 : 0),\
  545. print_page, 1 /* cmyk */, correct)
  546. #define prn_cmy_colour_device(dtype, procs, dev_name, x_dpi, y_dpi, bpp, print_page, correct)\
  547. prn_colour_device_body(dtype, procs, dev_name,\
  548. DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS, x_dpi, y_dpi, 0, 0, 0, 0,\
  549. ((bpp == 1 || bpp == 4) ? 1 : 3), bpp,\
  550. (bpp > 8 ? 255 : 1), (bpp > 8 ? 255 : 1), /* max_gray, max_color */\
  551. (bpp > 8 ? 5 : 2), (bpp > 8 ? 5 : bpp > 1 ? 2 : 0),\
  552. print_page, -1 /* cmyk */, correct)
  553. #define cdj_850_device(procs, dev_name, x_dpi, y_dpi, bpp, print_page, correction, quality, papertype, intensities,ptype,compression,mastergamma,gammavalc,gammavalm,gammavaly,gammavalk,blackcorrect,start_raster_mode,print_non_blank_line,terminate_page)\
  554. { prn_cmyk_colour_device(gx_device_cdj850, procs, dev_name, x_dpi, y_dpi, bpp, print_page, correction),\
  555. quality,\
  556. papertype,\
  557. intensities,\
  558. 0, 0, /* xscal, yscal */\
  559. ptype,\
  560. compression,\
  561. mastergamma,\
  562. gammavalc,\
  563. gammavalm,\
  564. gammavaly,\
  565. gammavalk,\
  566. blackcorrect,\
  567. start_raster_mode,\
  568. print_non_blank_line,\
  569. terminate_page\
  570. }
  571. #define cdj_1600_device(procs, dev_name, x_dpi, y_dpi, bpp, print_page, correction, quality, papertype, intensities,ptype,compression,mastergamma,gammavalc,gammavalm,gammavaly,gammavalk,blackcorrect,start_raster_mode,print_non_blank_line,terminate_page)\
  572. { prn_cmy_colour_device(gx_device_cdj850, procs, dev_name, x_dpi, y_dpi, bpp, print_page, correction),\
  573. quality,\
  574. papertype,\
  575. intensities,\
  576. 0, 0, /* xscal, yscal */\
  577. ptype,\
  578. compression,\
  579. mastergamma,\
  580. gammavalc,\
  581. gammavalm,\
  582. gammavaly,\
  583. gammavalk,\
  584. blackcorrect,\
  585. start_raster_mode,\
  586. print_non_blank_line,\
  587. terminate_page\
  588. }
  589. #define cmyk_colour_procs(proc_colour_open, proc_get_params, proc_put_params, \
  590. map_rgb_color, map_color_rgb, map_cmyk_color) {\
  591. proc_colour_open,\
  592. gx_default_get_initial_matrix,\
  593. gx_default_sync_output,\
  594. gdev_prn_output_page,\
  595. gdev_prn_close,\
  596. map_rgb_color,\
  597. map_color_rgb,\
  598. NULL /* fill_rectangle */,\
  599. NULL /* tile_rectangle */,\
  600. NULL /* copy_mono */,\
  601. NULL /* copy_color */,\
  602. NULL /* draw_line */,\
  603. gx_default_get_bits,\
  604. proc_get_params,\
  605. proc_put_params,\
  606. map_cmyk_color\
  607. }
  608. private void
  609. cdj850_start_raster_mode(P3(gx_device_printer * pdev,
  610. int papersize, FILE * prn_stream));
  611. private void
  612. cdj850_print_non_blank_lines(P6(gx_device_printer * pdev,
  613. struct ptr_arrays *data_ptrs,
  614. struct misc_struct *misc_vars,
  615. struct error_val_field *error_values,
  616. const Gamma *gamma,
  617. FILE * prn_stream));
  618. private void
  619. cdj850_terminate_page(P2(gx_device_printer * pdev, FILE * prn_stream));
  620. private void
  621. cdj1600_start_raster_mode(P3(gx_device_printer * pdev,
  622. int papersize, FILE * prn_stream));
  623. private void
  624. cdj1600_print_non_blank_lines(P6(gx_device_printer * pdev,
  625. struct ptr_arrays *data_ptrs,
  626. struct misc_struct *misc_vars,
  627. struct error_val_field *error_values,
  628. const Gamma *gamma,
  629. FILE * prn_stream));
  630. private void
  631. cdj1600_terminate_page(P2(gx_device_printer * pdev, FILE * prn_stream));
  632. private const gx_device_procs cdj670_procs =
  633. cmyk_colour_procs(hp_colour_open, cdj850_get_params, cdj850_put_params,
  634. NULL, gdev_cmyk_map_color_rgb, gdev_cmyk_map_cmyk_color);
  635. private const gx_device_procs cdj850_procs =
  636. cmyk_colour_procs(hp_colour_open, cdj850_get_params, cdj850_put_params,
  637. NULL, gdev_cmyk_map_color_rgb, gdev_cmyk_map_cmyk_color);
  638. private const gx_device_procs cdj890_procs =
  639. cmyk_colour_procs(hp_colour_open, cdj850_get_params, cdj850_put_params,
  640. NULL, gdev_cmyk_map_color_rgb, gdev_cmyk_map_cmyk_color);
  641. private const gx_device_procs cdj1600_procs =
  642. cmyk_colour_procs(hp_colour_open, cdj850_get_params, cdj850_put_params,
  643. gdev_pcl_map_rgb_color, gdev_pcl_map_color_rgb, NULL);
  644. const gx_device_cdj850 gs_cdj670_device =
  645. cdj_850_device(cdj670_procs, "cdj670", 600, 600, 32, cdj850_print_page, 0,
  646. PRESENTATION, PLAIN_PAPER, 2, DJ670C, 9,
  647. 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
  648. cdj850_start_raster_mode, cdj850_print_non_blank_lines,
  649. cdj850_terminate_page);
  650. const gx_device_cdj850 gs_cdj850_device =
  651. cdj_850_device(cdj850_procs, "cdj850", 600, 600, 32, cdj850_print_page, 0,
  652. PRESENTATION, PLAIN_PAPER, 4, DJ850C, 9,
  653. 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
  654. cdj850_start_raster_mode, cdj850_print_non_blank_lines,
  655. cdj850_terminate_page);
  656. const gx_device_cdj850 gs_cdj890_device =
  657. cdj_850_device(cdj890_procs, "cdj890", 600, 600, 32, cdj850_print_page, 0,
  658. PRESENTATION, PLAIN_PAPER, 4, DJ890C, 9,
  659. 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
  660. cdj850_start_raster_mode, cdj850_print_non_blank_lines,
  661. cdj850_terminate_page);
  662. const gx_device_cdj850 gs_cdj1600_device =
  663. cdj_1600_device(cdj1600_procs, "cdj1600", 300, 300, 24, cdj850_print_page, 0,
  664. PRESENTATION, PLAIN_PAPER, 2, DJ1600C, 3,
  665. 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
  666. cdj1600_start_raster_mode, cdj1600_print_non_blank_lines,
  667. cdj1600_terminate_page);
  668. /* Forward references */
  669. private int cdj_put_param_int(P6(gs_param_list *, gs_param_name,
  670. int *, int, int, int));
  671. private int cdj_put_param_float(P6(gs_param_list *, gs_param_name, float
  672. *, float, float, int));
  673. private int cdj_put_param_bpp(P5(gx_device *, gs_param_list *, int, int, int));
  674. private int cdj_set_bpp(P3(gx_device *, int, int));
  675. /* Open the printer and set up the margins. */
  676. private int
  677. hp_colour_open(gx_device * pdev)
  678. { /* Change the margins if necessary. */
  679. static const float dj_a4[4] = {
  680. DESKJET_MARGINS_A4
  681. };
  682. static const float dj_letter[4] = {
  683. DESKJET_MARGINS_LETTER
  684. };
  685. /* margins for DJ1600C from manual */
  686. static const float m_cdj1600[4] = {
  687. 0.25, 0.5, 0.25, 0.5
  688. };
  689. const float *m = (float *)0;
  690. /* Set up colour params if put_params has not already done so */
  691. if (pdev->color_info.num_components == 0) {
  692. int code = cdj_set_bpp(pdev, pdev->color_info.depth,
  693. pdev->color_info.num_components);
  694. if (code < 0)
  695. return code;
  696. }
  697. /* assign printer type and set resolution dependent on printer type */
  698. switch (cdj850->ptype) {
  699. case DJ670C:
  700. if (cdj850->papertype <= SPECIAL_PAPER) { /* paper */
  701. if (cdj850->quality == DRAFT) {
  702. gx_device_set_resolution(pdev, 300.0, 300.0);
  703. cdj850->xscal = 0;
  704. cdj850->yscal = 0;
  705. } else if (cdj850->quality == NORMAL) {
  706. gx_device_set_resolution(pdev, 600.0, 300.0);
  707. cdj850->xscal = 1;
  708. cdj850->yscal = 0;
  709. } else { /* quality == PRESENTATION */
  710. gx_device_set_resolution(pdev, 600.0, 600.0);
  711. cdj850->xscal = 1;
  712. cdj850->yscal = 1;
  713. }
  714. } else { /* film */
  715. gx_device_set_resolution(pdev, 600.0, 300.0);
  716. cdj850->xscal = 0;
  717. cdj850->yscal = 0;
  718. }
  719. m = (gdev_pcl_paper_size(pdev) == PAPER_SIZE_A4 ? dj_a4 : dj_letter);
  720. break;
  721. case DJ850C:
  722. case DJ890C:
  723. if (cdj850->quality == DRAFT) {
  724. gx_device_set_resolution(pdev, 300.0, 300.0);
  725. cdj850->xscal = 0;
  726. cdj850->yscal = 0;
  727. cdj850->intensities = 2;
  728. } else if (cdj850->quality == NORMAL) {
  729. gx_device_set_resolution(pdev, 600.0, 300.0);
  730. cdj850->xscal = 1;
  731. cdj850->yscal = 0;
  732. /* only 3 intensities for normal paper */
  733. if (cdj850->papertype <= PLAIN_PAPER) {
  734. cdj850->intensities = 3;
  735. } /* else cdj850->intensities = 4 from initialization */
  736. } else { /* quality == PRESENTATION */
  737. gx_device_set_resolution(pdev, 600.0, 600.0);
  738. cdj850->xscal = 1;
  739. cdj850->yscal = 1;
  740. /* intensities = 4 from initialization */
  741. }
  742. m = (gdev_pcl_paper_size(pdev) == PAPER_SIZE_A4 ? dj_a4 : dj_letter);
  743. break;
  744. case DJ1600C:
  745. gx_device_set_resolution(pdev, 300.0, 300.0);
  746. m = m_cdj1600;
  747. break;
  748. default:
  749. assert(0);
  750. }
  751. gx_device_set_margins(pdev, m, true);
  752. return gdev_prn_open(pdev);
  753. }
  754. /* Added parameters for DeskJet 850C */
  755. private int
  756. cdj850_get_params(gx_device * pdev, gs_param_list * plist)
  757. {
  758. int code = gdev_prn_get_params(pdev, plist);
  759. if (code < 0 ||
  760. (code = param_write_int(plist, "Quality", &cdj850->quality)) < 0 ||
  761. (code = param_write_int(plist, "Papertype", &cdj850->papertype)) < 0 ||
  762. (code = param_write_float(plist, "MasterGamma", &cdj850->gammavalc))
  763. < 0 ||
  764. (code = param_write_float(plist, "GammaValC", &cdj850->gammavalc)) <
  765. 0 ||
  766. (code = param_write_float(plist, "GammaValM", &cdj850->gammavalm)) <
  767. 0 ||
  768. (code = param_write_float(plist, "GammaValY", &cdj850->gammavaly)) <
  769. 0 ||
  770. (code = param_write_float(plist, "GammaValK", &cdj850->gammavalk)) <
  771. 0 ||
  772. (code = param_write_float(plist, "BlackCorrect",
  773. &cdj850->blackcorrect)) < 0
  774. )
  775. return code;
  776. return code;
  777. }
  778. private int
  779. cdj850_put_params(gx_device * pdev, gs_param_list * plist)
  780. {
  781. int quality = cdj850->quality;
  782. int papertype = cdj850->papertype;
  783. float mastergamma = cdj850->mastergamma;
  784. float gammavalc = cdj850->gammavalc;
  785. float gammavalm = cdj850->gammavalm;
  786. float gammavaly = cdj850->gammavaly;
  787. float gammavalk = cdj850->gammavalk;
  788. float blackcorrect = cdj850->blackcorrect;
  789. int bpp = 0;
  790. int code = 0;
  791. code = cdj_put_param_int(plist, "BitsPerPixel", &bpp, 1, 32, code);
  792. code = cdj_put_param_int(plist, "Quality", &quality, 0, 2, code);
  793. code = cdj_put_param_int(plist, "Papertype", &papertype, 0, 4, code);
  794. code = cdj_put_param_float(plist, "MasterGamma", &mastergamma, 0.1, 9.0, code);
  795. code = cdj_put_param_float(plist, "GammaValC", &gammavalc, 0.0, 9.0, code);
  796. code = cdj_put_param_float(plist, "GammaValM", &gammavalm, 0.0, 9.0, code);
  797. code = cdj_put_param_float(plist, "GammaValY", &gammavaly, 0.0, 9.0, code);
  798. code = cdj_put_param_float(plist, "GammaValK", &gammavalk, 0.0, 9.0, code);
  799. code = cdj_put_param_float(plist, "BlackCorrect", &blackcorrect, 0.0,
  800. 9.0, code);
  801. if (code < 0)
  802. return code;
  803. code = cdj_put_param_bpp(pdev, plist, bpp, bpp, 0);
  804. if (code < 0)
  805. return code;
  806. cdj850->quality = quality;
  807. cdj850->papertype = papertype;
  808. cdj850->mastergamma = mastergamma;
  809. cdj850->gammavalc = gammavalc;
  810. cdj850->gammavalm = gammavalm;
  811. cdj850->gammavaly = gammavaly;
  812. cdj850->gammavalk = gammavalk;
  813. cdj850->blackcorrect = blackcorrect;
  814. return 0;
  815. }
  816. /* ------ Internal routines ------ */
  817. /* The DeskJet850C can compress (mode 9) */
  818. /* Some convenient shorthand .. */
  819. #define x_dpi (pdev->x_pixels_per_inch)
  820. #define y_dpi (pdev->y_pixels_per_inch)
  821. /* To calculate buffer size as next greater multiple of both parameter and W */
  822. #define calc_buffsize(a, b) (((((a) + ((b) * W) - 1) / ((b) * W))) * W)
  823. /* internal functions */
  824. private void
  825. FSDlinebw(P7(int scan, int plane_size,
  826. struct error_val_field *error_values,
  827. byte * kP,
  828. int n, int *ep, byte * dp));
  829. private void
  830. FSDlinec2(P9(int scan, int plane_size,
  831. struct error_val_field *error_values,
  832. byte * cPa, byte * mPa, byte * yPa, int n,
  833. byte * dp, int *ep));
  834. private void
  835. FSDlinec3(P12(int scan, int plane_size,
  836. struct error_val_field *error_values,
  837. byte * cPa, byte * mPa, byte * yPa,
  838. byte * cPb, byte * mPb, byte * yPb,
  839. int n, byte * dp, int *ep));
  840. private void
  841. FSDlinec4(P12(int scan, int plane_size,
  842. struct error_val_field *error_values,
  843. byte * cPa, byte * mPa, byte * yPa,
  844. byte * cPb, byte * mPb, byte * yPb,
  845. int n, byte * dp, int *ep));
  846. private void
  847. init_error_buffer(struct misc_struct *misc_vars,
  848. struct ptr_arrays *data_ptrs);
  849. private void
  850. do_floyd_steinberg(P8(int scan, int cscan, int plane_size,
  851. int plane_size_c, int n,
  852. struct ptr_arrays *data_ptrs,
  853. gx_device_printer * pdev,
  854. struct error_val_field *error_values));
  855. private int
  856. do_gcr(P7(int bytecount, byte * inbyte, const byte * kvalues,
  857. const byte * cvalues, const byte * mvalues,
  858. const byte * yvalues, const int *kcorrect));
  859. /* UNUSED
  860. *private int
  861. *test_scan (P4(int size,
  862. * byte * current,
  863. * byte * last,
  864. * byte * control));
  865. *private void
  866. *save_color_data(P3(int size,
  867. * byte * current,
  868. * byte * saved));
  869. *
  870. */
  871. private void
  872. send_scan_lines(P6(gx_device_printer * pdev,
  873. struct ptr_arrays *data_ptrs,
  874. struct misc_struct *misc_vars,
  875. struct error_val_field *error_values,
  876. const Gamma *gamma,
  877. FILE * prn_stream));
  878. private void
  879. do_gamma(P3(float mastergamma, float gammaval, byte * values));
  880. private void
  881. do_black_correction(P2(float kvalue, int *kcorrect));
  882. private void
  883. init_data_structure(P3(gx_device_printer * pdev,
  884. struct ptr_arrays *data_ptrs,
  885. struct misc_struct *misc_vars));
  886. private void
  887. calculate_memory_size(P2(gx_device_printer * pdev,
  888. struct misc_struct *misc_vars));
  889. private void
  890. assign_dpi(int dpi, byte * msb)
  891. {
  892. if (dpi == 600) {
  893. msb[0] = 0x02;
  894. msb[1] = 0x58;
  895. } else {
  896. msb[0] = 0x01;
  897. msb[1] = 0x2c;
  898. }
  899. }
  900. private void
  901. cdj850_terminate_page(gx_device_printer * pdev, FILE * prn_stream)
  902. {
  903. fputs("0M", prn_stream); /* Reset compression */
  904. fputs("\033*rC\033E", prn_stream); /* End Graphics, Reset */
  905. fputs("\033&l0H", prn_stream); /* eject page */
  906. }
  907. /* Here comes the hp850 output routine -------------------- */
  908. private int
  909. cdj850_print_page(gx_device_printer * pdev, FILE * prn_stream)
  910. {
  911. struct error_val_field error_values;
  912. struct ptr_arrays data_ptrs;
  913. struct misc_struct misc_vars;
  914. Gamma gamma;
  915. /* make a local writable copy of the Gamma tables */
  916. memcpy(&gamma, gammat[cdj850->ptype], sizeof(Gamma));
  917. /* if mastergamma, don't use the built in functions */
  918. if (cdj850->mastergamma > 1.0) {
  919. /* prepare the bw lookup table */
  920. do_gamma(cdj850->mastergamma, cdj850->gammavalk, gamma.k);
  921. /* prepare the color lookup table */
  922. do_gamma(cdj850->mastergamma, cdj850->gammavalc, gamma.c);
  923. do_gamma(cdj850->mastergamma, cdj850->gammavalm, gamma.m);
  924. do_gamma(cdj850->mastergamma, cdj850->gammavaly, gamma.y);
  925. }
  926. /* prepare the black correction table for the unbunt mask */
  927. do_black_correction(cdj850->blackcorrect, gamma.correct);
  928. /* Calculate the needed memory */
  929. calculate_memory_size(pdev, &misc_vars);
  930. /* and allocate the memory */
  931. /* Since we need 600 and 300 dpi, we set up several buffers:
  932. storage contains the data as copied from gs, as well as the
  933. plane-data and the out_row buffer.
  934. storagec will contain the rescaled color data. It also contains the
  935. plane_data for the color-planes - these are needed by the
  936. compression routine, but would be overwritten by the
  937. b/w-dithering. The color planes allow for overwriting the
  938. color-data by the error-data. Since we might use the
  939. 2bpp feature of the hp850 someday, it is sized like storage.
  940. storagee contains the errors from b/w fs-ditherng */
  941. data_ptrs.storage = (ulong *) gs_malloc(pdev->memory, misc_vars.storage_size_words, W,
  942. "cdj850_print_page");
  943. /* if we can't allocate working area */
  944. if (data_ptrs.storage == 0) {
  945. return_error(gs_error_VMerror);
  946. }
  947. /* Initialise the needed pointers */
  948. init_data_structure(pdev, &data_ptrs, &misc_vars);
  949. /* Start Raster mode */
  950. (*cdj850->start_raster_mode) (pdev, misc_vars.paper_size, prn_stream);
  951. /* Send each scan line in turn */
  952. send_scan_lines(pdev, &data_ptrs, &misc_vars,
  953. &error_values, &gamma, prn_stream);
  954. /* terminate page and eject paper */
  955. (*cdj850->terminate_page) (pdev, prn_stream);
  956. /* Free Memory */
  957. gs_free(pdev->memory, (char *)data_ptrs.storage, misc_vars.storage_size_words, W,
  958. "hp850_print_page");
  959. return 0;
  960. }
  961. #define odd(i) ((i & 01) != 0)
  962. private int
  963. GetScanLine(gx_device_printer * pdev, int *lnum,
  964. struct ptr_arrays *data_ptrs,
  965. struct misc_struct *misc_vars,
  966. word rmask)
  967. {
  968. word *data_words = (word *) data_ptrs->data[misc_vars->scan];
  969. register word *end_data = data_words + misc_vars->line_size_words;
  970. ++(*lnum);
  971. gdev_prn_copy_scan_lines(pdev, *lnum, (byte *) data_words, misc_vars->line_size);
  972. misc_vars->scan = 1 - misc_vars->scan; /* toggle scan direction */
  973. misc_vars->is_two_pass = odd(*lnum); /* color output for odd lines */
  974. /* Mask off 1-bits beyond the line width. */
  975. end_data[-1] &= rmask;
  976. /* Remove trailing 0s. */
  977. while (end_data > data_words && end_data[-1] == 0)
  978. end_data--;
  979. return end_data - data_words;
  980. }
  981. /* Send the scan lines to the printer */
  982. private void
  983. send_scan_lines(gx_device_printer * pdev,
  984. struct ptr_arrays *data_ptrs,
  985. struct misc_struct *misc_vars,
  986. struct error_val_field *error_values,
  987. const Gamma *gamma,
  988. FILE * prn_stream)
  989. {
  990. int lnum, lend, llen;
  991. int num_blank_lines = 0;
  992. word rmask =
  993. ~(word) 0 << ((-pdev->width * misc_vars->storage_bpp) & (W * 8 - 1));
  994. lend = pdev->height - (dev_t_margin(pdev) + dev_b_margin(pdev)) * y_dpi;
  995. error_values->c = error_values->m = error_values->y =
  996. error_values->k = 0;
  997. /* init the error buffer */
  998. init_error_buffer(misc_vars, data_ptrs);
  999. misc_vars->zero_row_count = 0;
  1000. lnum = -1;
  1001. llen = GetScanLine(pdev, &lnum, data_ptrs, misc_vars, rmask);
  1002. while (lnum < lend) {
  1003. num_blank_lines = 0;
  1004. while (lnum < lend && llen == 0) {
  1005. ++num_blank_lines;
  1006. llen = GetScanLine(pdev, &lnum, data_ptrs, misc_vars, rmask);
  1007. }
  1008. if (lnum >= lend) {
  1009. break;
  1010. }
  1011. /* Skip blank lines if any */
  1012. if (num_blank_lines > 0) {
  1013. fprintf(prn_stream, "%dy", num_blank_lines / (cdj850->yscal + 1));
  1014. memset(data_ptrs->plane_data[0][0], 0,
  1015. (misc_vars->plane_size * 2 * misc_vars->num_comps));
  1016. memset(data_ptrs->plane_data_c[0][0], 0,
  1017. (misc_vars->plane_size_c * 2 * misc_vars->num_comps));
  1018. }
  1019. /* all blank lines printed, now for the non-blank lines */
  1020. if (cdj850->yscal && odd(lnum)) {
  1021. /* output a blank black plane for odd lines */
  1022. putc('v', prn_stream);
  1023. }
  1024. /* now output all non blank lines */
  1025. while (lnum < lend && llen != 0) {
  1026. misc_vars->is_color_data = 0; /* maybe we have color ? */
  1027. (*cdj850->print_non_blank_lines) (pdev, data_ptrs, misc_vars,
  1028. error_values, gamma, prn_stream);
  1029. llen = GetScanLine(pdev, &lnum, data_ptrs, misc_vars, rmask);
  1030. }
  1031. if (cdj850->yscal && odd(lnum)) { /* output empty line for odd lines */
  1032. (*cdj850->print_non_blank_lines) (pdev, data_ptrs, misc_vars,
  1033. error_values, gamma, prn_stream);
  1034. }
  1035. /* the current line is empty => run the next iteration */
  1036. }
  1037. }
  1038. /* print_line compresses (mode 9) and outputs one plane */
  1039. private void
  1040. print_c9plane(FILE * prn_stream, char plane_code, int plane_size,
  1041. const byte * curr, const byte * prev, byte * out_data)
  1042. {
  1043. /* Compress the output data */
  1044. int out_count = gdev_pcl_mode9compress(plane_size, curr, prev, out_data);
  1045. /* and output the data */
  1046. if (out_count > 0) {
  1047. fprintf(prn_stream, "%d%c", out_count, plane_code);
  1048. fwrite(out_data, sizeof(byte), out_count, prn_stream);
  1049. } else {
  1050. putc(plane_code, prn_stream);
  1051. }
  1052. }
  1053. /* Printing non-blank lines */
  1054. private void
  1055. cdj850_print_non_blank_lines(gx_device_printer * pdev,
  1056. struct ptr_arrays *data_ptrs,
  1057. struct misc_struct *misc_vars,
  1058. struct error_val_field *error_values,
  1059. const Gamma *gamma,
  1060. FILE * prn_stream)
  1061. {
  1062. static const char *const plane_code[2] =
  1063. {"wvvv", "vvvv"};
  1064. int i;
  1065. byte *kP = data_ptrs->plane_data[misc_vars->scan + 2][3];
  1066. byte *dp = data_ptrs->data[misc_vars->scan + 2];
  1067. int *ep = data_ptrs->errors[misc_vars->scan];
  1068. /* we need cmyk color separation befor all the rest, since
  1069. black may be contained in the color fields. This needs to
  1070. be done on all pixel-rows, since even unused color-bytes
  1071. might generate black */
  1072. misc_vars->is_color_data =
  1073. do_gcr(misc_vars->databuff_size, data_ptrs->data[misc_vars->scan],
  1074. gamma->k, gamma->c, gamma->m, gamma->y, gamma->correct);
  1075. /* dithering the black-plane */
  1076. FSDlinebw(misc_vars->scan, misc_vars->plane_size,
  1077. error_values, kP, misc_vars->num_comps, ep, dp);
  1078. /* output the black plane */
  1079. print_c9plane(prn_stream, 'v', misc_vars->plane_size,
  1080. data_ptrs->plane_data[misc_vars->scan][3],
  1081. data_ptrs->plane_data[1 - misc_vars->scan][3],
  1082. data_ptrs->out_data);
  1083. /* since color resolution is only half of the b/w-resolution,
  1084. we only output every second row */
  1085. if (!cdj850->yscal || misc_vars->is_two_pass) {
  1086. int plane_size_c = (*rescale_color_plane[cdj850->xscal][cdj850->yscal])
  1087. (misc_vars->databuff_size,
  1088. data_ptrs->data[misc_vars->scan],
  1089. data_ptrs->data[1 - misc_vars->scan],
  1090. data_ptrs->data_c[misc_vars->cscan]) / misc_vars->storage_bpp;
  1091. /* dither the color planes */
  1092. do_floyd_steinberg(misc_vars->scan, misc_vars->cscan,
  1093. misc_vars->plane_size, plane_size_c,
  1094. misc_vars->num_comps, data_ptrs, pdev, error_values);
  1095. /* Transfer raster graphics in the order C, M, Y, that is
  1096. planes 2,1,0 */
  1097. for (i = misc_vars->num_comps - 2; i >= 0; i--) {
  1098. /* output the lower color planes */
  1099. print_c9plane(prn_stream, plane_code[cdj850->intensities > 2][i],
  1100. plane_size_c,
  1101. data_ptrs->plane_data_c[misc_vars->cscan][i],
  1102. data_ptrs->plane_data_c[1 - misc_vars->cscan][i],
  1103. data_ptrs->out_data);
  1104. /* output the upper color planes */
  1105. if (cdj850->intensities > 2) {
  1106. print_c9plane(prn_stream, plane_code[0][i], plane_size_c,
  1107. data_ptrs->plane_data_c[misc_vars->cscan][i + 4],
  1108. data_ptrs->plane_data_c[1 -
  1109. misc_vars->cscan][i
  1110. + 4],
  1111. data_ptrs->out_data);
  1112. } /* end cdj850->intensities > 2 */
  1113. } /* End For i = num_comps */
  1114. misc_vars->cscan = 1 - misc_vars->cscan;
  1115. } /* End of is_two_pass */
  1116. return;
  1117. }
  1118. /* moved that code into his own subroutine, otherwise things get
  1119. somewhat clumsy */
  1120. private void
  1121. do_floyd_steinberg(int scan, int cscan, int plane_size,
  1122. int plane_size_c, int n,
  1123. struct ptr_arrays *data_ptrs,
  1124. gx_device_printer * pdev,
  1125. struct error_val_field *error_values)
  1126. {
  1127. /* the color pointers */
  1128. byte *cPa, *mPa, *yPa, *cPb, *mPb, *yPb;
  1129. byte *dpc;
  1130. int *epc;
  1131. /* the b/w pointers */
  1132. byte *kP, *dp;
  1133. int *ep;
  1134. /* the color pointers, lower byte */
  1135. cPa = data_ptrs->plane_data_c[cscan + 2][2];
  1136. mPa = data_ptrs->plane_data_c[cscan + 2][1];
  1137. yPa = data_ptrs->plane_data_c[cscan + 2][0];
  1138. /* upper byte */
  1139. cPb = data_ptrs->plane_data_c[cscan + 2][6];
  1140. mPb = data_ptrs->plane_data_c[cscan + 2][5];
  1141. yPb = data_ptrs->plane_data_c[cscan + 2][4];
  1142. /* data and error */
  1143. dpc = data_ptrs->data_c[cscan + 2];
  1144. epc = data_ptrs->errors_c[cscan];
  1145. /* the b/w pointers */
  1146. kP = data_ptrs->plane_data[scan + 2][3];
  1147. dp = data_ptrs->data[scan + 2];
  1148. ep = data_ptrs->errors[scan];
  1149. switch (cdj850->intensities) {
  1150. case 2:
  1151. FSDlinec2(cscan, plane_size_c, error_values,
  1152. cPa, mPa, yPa, n, dpc, epc);
  1153. break;
  1154. case 3:
  1155. FSDlinec3(cscan, plane_size_c, error_values,
  1156. cPa, mPa, yPa, cPb, mPb, yPb, n, dpc, epc);
  1157. break;
  1158. case 4:
  1159. FSDlinec4(cscan, plane_size_c, error_values,
  1160. cPa, mPa, yPa, cPb, mPb, yPb, n, dpc, epc);
  1161. break;
  1162. default:
  1163. assert(0);
  1164. }
  1165. return;
  1166. }
  1167. /* here we do our own gamma-correction */
  1168. private void
  1169. do_gamma(float mastergamma, float gammaval, byte values[256])
  1170. {
  1171. int i;
  1172. float gamma;
  1173. if (gammaval > 0.0) {
  1174. gamma = gammaval;
  1175. } else {
  1176. gamma = mastergamma;
  1177. }
  1178. for (i = 0; i < 256; i++) {
  1179. values[i] = (byte) (255.0 *
  1180. (1.0 - pow(((double)(255.0 - (float)i) / 255.0),
  1181. (double)(1.0 / gamma))));
  1182. }
  1183. return;
  1184. }
  1185. /* here we calculate a lookup-table which is used to compensate the
  1186. relativ loss of color due to undercolor-removal */
  1187. private void
  1188. do_black_correction(float kvalue, int kcorrect[256])
  1189. {
  1190. int i;
  1191. for (i = 0; i < 256; i++) {
  1192. kcorrect[i] = (int)
  1193. (100.0 * kvalue * (
  1194. pow(10.0,
  1195. pow((i / 255.0), 3.0)
  1196. )
  1197. - 1.0
  1198. )
  1199. );
  1200. }
  1201. return;
  1202. }
  1203. /* For Better Performance we use a macro here */
  1204. #define DOUCR(col1, col2, col3, col4)\
  1205. {\
  1206. /* determine how far we are from the grey axis. This is */\
  1207. /* traditionally done by computing MAX(CMY)-MIN(CMY). */\
  1208. /* However, if two colors are very similar, we could */\
  1209. /* as either CMYRGB and K. Therefore we calculate the */\
  1210. /* the distance col1-col2 and col2-col3, and use the */\
  1211. /* smaller one. */\
  1212. a = *col1 - *col2;\
  1213. b = *col2 - *col3;\
  1214. if (a >= b) {\
  1215. grey_distance = 1.0 - (b/255.0);\
  1216. } else {\
  1217. grey_distance = 1.0 - (a/255.0);\
  1218. }\
  1219. ucr = (byte) (*col3 * grey_distance); \
  1220. *col4 = *col4 + ucr; /* add removed black to black */\
  1221. /* remove only as much color as black is surviving the */\
  1222. /* gamma correction */\
  1223. ucr = *(kvalues + ucr);\
  1224. *col1 = *col1 - ucr ;\
  1225. *col2 = *col2 - ucr ;\
  1226. *col3 = *col3 - ucr ;\
  1227. }
  1228. /* For Better Performance we use a macro here */
  1229. #define DOGCR(col1, col2, col3, col4)\
  1230. {\
  1231. ucr = (int) *col3;\
  1232. *col1 -= ucr ;\
  1233. *col2 -= ucr ;\
  1234. *col3 -= ucr ;\
  1235. *col4 += ucr; /* add removed black to black */\
  1236. kadd = ucr + *(kcorrect + ucr);\
  1237. uca_fac = 1.0 + (kadd/255.0);\
  1238. *col1 *= uca_fac;\
  1239. *col2 *= uca_fac;\
  1240. }
  1241. /* Since resolution can be different on different planes, we need to
  1242. do real color separation, here we try a real grey component
  1243. replacement */
  1244. private int
  1245. do_gcr(int bytecount, byte * inbyte, const byte kvalues[256],
  1246. const byte cvalues[256], const byte mvalues[256],
  1247. const byte yvalues[256], const int kcorrect[256])
  1248. {
  1249. int i, ucr, kadd, is_color = 0;
  1250. byte *black, *cyan, *magenta, *yellow;
  1251. float uca_fac;
  1252. /* Grey component replacement */
  1253. for (i = 0; i < bytecount; i += 4) {
  1254. black = inbyte++; /* Assign to black the current address of inbyte */
  1255. cyan = inbyte++;
  1256. magenta = inbyte++;
  1257. yellow = inbyte++;
  1258. if (*magenta + *yellow + *cyan > 0) { /* if any color at all */
  1259. is_color = 1;
  1260. if ((*cyan >= *magenta)
  1261. && (*magenta >= *yellow)
  1262. && (*yellow > 0)) { /* if any grey component */
  1263. DOGCR(cyan, magenta, yellow, black);
  1264. } else if ((*cyan >= *yellow)
  1265. && (*yellow >= *magenta)
  1266. && (*magenta > 0)) {
  1267. DOGCR(cyan, yellow, magenta, black);
  1268. } else if ((*yellow >= *magenta)
  1269. && (*magenta >= *cyan)
  1270. && (*cyan > 0)) {
  1271. DOGCR(yellow, magenta, cyan, black);
  1272. } else if ((*yellow >= *cyan)
  1273. && (*cyan >= *magenta)
  1274. && (*magenta > 0)) {
  1275. DOGCR(yellow, cyan, magenta, black);
  1276. } else if ((*magenta >= *yellow)
  1277. && (*yellow >= *cyan)
  1278. && (*cyan > 0)) {
  1279. DOGCR(magenta, yellow, cyan, black);
  1280. } else if ((*magenta >= *cyan)
  1281. && (*cyan >= *yellow)
  1282. && (*yellow > 0)) {
  1283. DOGCR(magenta, cyan, yellow, black);
  1284. } else { /* do gamma only if no black */
  1285. }
  1286. *cyan = *(cvalues + *cyan);
  1287. *magenta = *(mvalues + *magenta);
  1288. *yellow = *(yvalues + *yellow);
  1289. } /* end of if c+m+y > 0 */
  1290. *black = *(kvalues + *black);
  1291. } /* end of for bytecount */
  1292. return is_color;
  1293. }
  1294. /* Since resolution can be different on different planes, we need to
  1295. rescale the data byte by byte */
  1296. private int
  1297. rescale_byte_wise2x2(int bytecount, const byte * inbytea, const byte * inbyteb,
  1298. byte * outbyte)
  1299. {
  1300. register int i, j;
  1301. int max = bytecount / 2;
  1302. for (i = 0; i < max; i += 4) {
  1303. j = 2 * i;
  1304. /* cyan */
  1305. outbyte[i + 1] = (inbytea[j + 1] + inbytea[j + 5] + inbyteb[j + 1] +
  1306. inbyteb[j + 5]) / 4;
  1307. /* magenta */
  1308. outbyte[i + 2] = (inbytea[j + 2] + inbytea[j + 6] + inbyteb[j + 2] +
  1309. inbyteb[j + 6]) / 4;
  1310. /* yellow */
  1311. outbyte[i + 3] = (inbytea[j + 3] + inbytea[j + 7] + inbyteb[j + 3] +
  1312. inbyteb[j + 7]) / 4;
  1313. }
  1314. return max;
  1315. }
  1316. /* Since resolution can be different on different planes, we need to
  1317. rescale the data byte by byte */
  1318. private int
  1319. rescale_byte_wise2x1(int bytecount, const byte * inbytea, const byte * inbyteb,
  1320. byte * outbyte)
  1321. {
  1322. register int i, j;
  1323. int max = bytecount / 2;
  1324. for (i = 0; i < max; i += 4) {
  1325. j = 2 * i;
  1326. /* cyan */
  1327. outbyte[i + 1] = (inbytea[j + 1] + inbytea[j + 5]) / 2;
  1328. /* magenta */
  1329. outbyte[i + 2] = (inbytea[j + 2] + inbytea[j + 6]) / 2;
  1330. /* yellow */
  1331. outbyte[i + 3] = (inbytea[j + 3] + inbytea[j + 7]) / 2;
  1332. }
  1333. return max;
  1334. }
  1335. /* Since resolution can be different on different planes, we need to
  1336. rescale the data byte by byte */
  1337. private int
  1338. rescale_byte_wise1x2(int bytecount, const byte * inbytea, const byte * inbyteb,
  1339. byte * outbyte)
  1340. {
  1341. register int i;
  1342. for (i = 0; i < bytecount; i += 4) {
  1343. /* cyan */
  1344. outbyte[i + 1] = (inbytea[i + 1] + inbyteb[i + 1]) / 2;
  1345. /* magenta */
  1346. outbyte[i + 2] = (inbytea[i + 2] + inbyteb[i + 2]) / 2;
  1347. /* yellow */
  1348. outbyte[i + 3] = (inbytea[i + 3] + inbyteb[i + 3]) / 2;
  1349. }
  1350. return bytecount;
  1351. }
  1352. /* Since resolution can be different on different planes, we need to
  1353. rescale the data byte by byte */
  1354. private int
  1355. rescale_byte_wise1x1(int bytecount, const byte * inbytea, const byte * inbyteb,
  1356. byte * outbyte)
  1357. {
  1358. register int i;
  1359. for (i = 0; i < bytecount; i += 4) {
  1360. /* cyan */
  1361. outbyte[i + 1] = inbytea[i + 1];
  1362. /* magenta */
  1363. outbyte[i + 2] = inbytea[i + 2];
  1364. /* yellow */
  1365. outbyte[i + 3] = inbytea[i + 3];
  1366. }
  1367. return bytecount;
  1368. }
  1369. /* MACROS FOR DITHERING (we use macros for compact source and faster code) */
  1370. /* Floyd-Steinberg dithering. Often results in a dramatic improvement in
  1371. * subjective image quality, but can also produce dramatic increases in
  1372. * amount of printer data generated and actual printing time!! Mode 9 2D
  1373. * compression is still useful for fairly flat colour or blank areas but its
  1374. * compression is much less effective in areas where the dithering has
  1375. * effectively randomised the dot distribution. */
  1376. #define RSHIFT ((I * 8) - 16)
  1377. #define SHIFT ((I * 8) - 13)
  1378. #define MAXVALUE (255 << SHIFT)
  1379. #define RANDOM (((rand() << RSHIFT) % (MAXVALUE / 2)) - MAXVALUE /4);
  1380. #define MINVALUE 0
  1381. #define C 8
  1382. #define THRESHOLD (128 << SHIFT)
  1383. /* --- needed for the hp850 -- */
  1384. #define SHIFTS ((I * 8) - 14)
  1385. #define SHIFTM ((I * 8) - 13)
  1386. #define SHIFTL ((I * 8) - 12)
  1387. #define MAXVALUES (160 << SHIFTM)
  1388. #define MAXVALUEM (226 << SHIFTM)
  1389. #define MAXVALUEL (255 << SHIFTM)
  1390. #define THRESHOLDS (128 << SHIFTM)
  1391. #define THRESHOLDM (192 << SHIFTM)
  1392. #define THRESHOLDL (226 << SHIFTM)
  1393. /* --------------------------- */
  1394. /* initialise the error_buffer */
  1395. private void
  1396. init_error_buffer(struct misc_struct *misc_vars,
  1397. struct ptr_arrays *data_ptrs)
  1398. {
  1399. int i;
  1400. int *ep;
  1401. int *epc;
  1402. ep = data_ptrs->errors[0];
  1403. epc = data_ptrs->errors_c[0];
  1404. if (misc_vars->bits_per_pixel > 4) { /* Randomly seed initial error
  1405. buffer */
  1406. /* Otherwise, the first dithered rows would look rather uniform */
  1407. for (i = 0; i < misc_vars->databuff_size; i++) { /* 600dpi planes */
  1408. *ep++ = RANDOM;
  1409. }
  1410. /* Now for the 2 * 300dpi color planes */
  1411. for (i = 0; i < misc_vars->databuff_size_c; i++) {
  1412. *epc++ = RANDOM;
  1413. }
  1414. }
  1415. return;
  1416. }
  1417. #define FSdither(inP, out, errP, Err, Bit, Offset, Element)\
  1418. {\
  1419. oldErr = Err;\
  1420. Err = (*(errP + Element)\
  1421. + ((Err * 7 + C) >> 4)\
  1422. + ((int)*(inP + Element) << SHIFT));\
  1423. if (Err > THRESHOLD) {\
  1424. out |= Bit;\
  1425. Err -= MAXVALUE;\
  1426. }\
  1427. *(errP + (Element + Offset)) += ((Err * 3 + C) >> 4);\
  1428. *(errP + Element) = ((Err * 5 + oldErr + C) >> 4);\
  1429. }
  1430. /* The hp850c has 600dpi black and 300 dpi color. Therefore, we need
  1431. an adapted dither algorythm */
  1432. private void
  1433. FSDlinebw(int scan, int plane_size,
  1434. struct error_val_field *error_values,
  1435. byte * kP, int n, int *ep, byte * dp)
  1436. {
  1437. if (scan == 0) { /* going_up */
  1438. byte k, bitmask; /* k = outbyte byte, whereas bitmask defines the
  1439. bit to be set within k */
  1440. int oldErr, i;
  1441. for (i = 0; i < plane_size; i++) {
  1442. bitmask = 0x80;
  1443. for (k = 0; bitmask != 0; bitmask >>= 1) {
  1444. /* dp points to the first word of the input data which is in
  1445. kcmy-format */
  1446. /* k points to the beginning of the first outbut byte, which
  1447. is filled up, bit by bit while looping over bytemask */
  1448. /* ep points to the first word of the error-plane which
  1449. contains the errors kcmy format */
  1450. /* err_values->k tempararily holds the error-value */
  1451. /* bitmask selects the bit to be set in the outbyte */
  1452. /* n gives the offset for the byte selection within
  1453. words. With simple cmyk-printing, this should be 4 */
  1454. /* 0 points to the active color within the input-word, i.e. 0
  1455. = black, 1 = cyan, 2 = yellow, 3 = magenta */
  1456. FSdither(dp, k, ep, error_values->k, bitmask, -n, 0);
  1457. dp += n, ep += n; /* increment the input and error pointer one
  1458. word (=4 byte) further, in order to
  1459. convert the next word into an bit */
  1460. }
  1461. *kP++ = k; /* fill the output-plane byte with the computet byte
  1462. and increment the output plane pointer one byte */
  1463. }
  1464. } else { /* going_down */
  1465. byte k, bitmask;
  1466. int oldErr, i;
  1467. for (i = 0; i < plane_size; i++) {
  1468. bitmask = 0x01;
  1469. for (k = 0; bitmask != 0; bitmask <<= 1) {
  1470. dp -= n, ep -= n;
  1471. FSdither(dp, k, ep, error_values->k, bitmask, n, 0);
  1472. }
  1473. *--kP = k;
  1474. }
  1475. }
  1476. return;
  1477. }
  1478. /* Since bw has already been dithered for the hp850c, we need
  1479. an adapted dither algorythm */
  1480. private void
  1481. FSDlinec2(int scan, int plane_size,
  1482. struct error_val_field *error_values,
  1483. byte * cPa, byte * mPa, byte * yPa, int n,
  1484. byte * dp, int *ep)
  1485. {
  1486. if (scan == 0) { /* going_up */
  1487. int oldErr, i;
  1488. byte ca, ya, ma, bitmask;
  1489. for (i = 0; i < plane_size; i++) {
  1490. bitmask = 0x80;
  1491. ca = ya = ma = 0;
  1492. for (ca = 0; bitmask != 0; bitmask >>= 1) {
  1493. FSdither(dp, ca, ep, error_values->c, bitmask, -n, n - 3);
  1494. FSdither(dp, ma, ep, error_values->m, bitmask, -n, n - 2);
  1495. FSdither(dp, ya, ep, error_values->y, bitmask, -n, n - 1);
  1496. dp += n, ep += n;
  1497. }
  1498. *cPa++ = ca;
  1499. *mPa++ = ma;
  1500. *yPa++ = ya;
  1501. }
  1502. } else { /* going_down */
  1503. byte ca, ya, ma, bitmask;
  1504. int oldErr, i;
  1505. for (i = 0; i < plane_size; i++) {
  1506. bitmask = 0x01;
  1507. ca = ya = ma = 0;
  1508. for (ca = 0; bitmask != 0; bitmask <<= 1) {
  1509. dp -= n, ep -= n;
  1510. FSdither(dp, ya, ep, error_values->y, bitmask, n, n - 1);
  1511. FSdither(dp, ma, ep, error_values->m, bitmask, n, n - 2);
  1512. FSdither(dp, ca, ep, error_values->c, bitmask, n, n - 3);
  1513. }
  1514. *--yPa = ya;
  1515. *--mPa = ma;
  1516. *--cPa = ca;
  1517. }
  1518. }
  1519. return;
  1520. }
  1521. /* while printing on paper, we only use 3 -intensities */
  1522. #define FSdither8503(inP, outa, outb, errP, Err, Bit, Offset, Element)\
  1523. {\
  1524. oldErr = Err;\
  1525. Err = (*(errP + Element)\
  1526. + ((Err * 7 + C) >> 4)\
  1527. + ((int) *(inP + Element) << SHIFT));\
  1528. if ((Err > THRESHOLDS) && (Err <= THRESHOLDM)) {\
  1529. outa |= Bit;\
  1530. Err -= MAXVALUES;\
  1531. }\
  1532. if (Err > THRESHOLDM) {\
  1533. outb |= Bit;\
  1534. Err -= MAXVALUEM;\
  1535. }\
  1536. *(errP + (Element + Offset)) += ((Err * 3 + C) >> 4);\
  1537. *(errP + Element) = ((Err * 5 + oldErr + C) >> 4);\
  1538. }
  1539. /* On ordinary paper, we'll only use 3 intensities with the hp850 */
  1540. private void
  1541. FSDlinec3(int scan, int plane_size,
  1542. struct error_val_field *error_values,
  1543. byte * cPa, byte * mPa, byte * yPa,
  1544. byte * cPb, byte * mPb, byte * yPb,
  1545. int n, byte * dp, int *ep)
  1546. {
  1547. if (scan == 0) { /* going_up */
  1548. byte ca, ya, ma, cb, yb, mb, bitmask;
  1549. int oldErr, i;
  1550. for (i = 0; i < plane_size; i++) {
  1551. bitmask = 0x80;
  1552. ca = ya = ma = cb = yb = mb = 0;
  1553. for (ca = 0; bitmask != 0; bitmask >>= 1) {
  1554. FSdither8503(dp, ca, cb, ep, error_values->c, bitmask, -n, n
  1555. - 3);
  1556. FSdither8503(dp, ma, mb, ep, error_values->m, bitmask, -n, n
  1557. - 2);
  1558. FSdither8503(dp, ya, yb, ep, error_values->y, bitmask, -n, n
  1559. - 1);
  1560. dp += n, ep += n;
  1561. }
  1562. *cPa++ = ca;
  1563. *mPa++ = ma;
  1564. *yPa++ = ya;
  1565. *cPb++ = cb;
  1566. *mPb++ = mb;
  1567. *yPb++ = yb;
  1568. }
  1569. } else { /* going_down */
  1570. byte ca, ya, ma, cb, yb, mb, bitmask;
  1571. int oldErr, i;
  1572. for (i = 0; i < plane_size; i++) {
  1573. bitmask = 0x01;
  1574. ca = ya = ma = cb = yb = mb = 0;
  1575. for (ca = 0; bitmask != 0; bitmask <<= 1) {
  1576. dp -= n, ep -= n;
  1577. FSdither8503(dp, ya, yb, ep, error_values->y, bitmask, n, n
  1578. - 1);
  1579. FSdither8503(dp, ma, mb, ep, error_values->m, bitmask, n, n
  1580. - 2);
  1581. FSdither8503(dp, ca, cb, ep, error_values->c, bitmask, n, n
  1582. - 3);
  1583. }
  1584. *--yPa = ya;
  1585. *--mPa = ma;
  1586. *--cPa = ca;
  1587. *--yPb = yb;
  1588. *--mPb = mb;
  1589. *--cPb = cb;
  1590. }
  1591. }
  1592. return;
  1593. }
  1594. /* the hp850 knows about 4 different color intensities per color */
  1595. #define FSdither8504(inP, outa, outb, errP, Err, Bit, Offset, Element)\
  1596. {\
  1597. oldErr = Err;\
  1598. Err = (*(errP + Element)\
  1599. + ((Err * 7 + C) >> 4)\
  1600. + ((int) *(inP + Element) << SHIFT));\
  1601. if ((Err > THRESHOLDS) && (Err <= THRESHOLDM)) {\
  1602. outa |= Bit;\
  1603. Err -= MAXVALUES;\
  1604. }\
  1605. if ((Err > THRESHOLDM) && (Err <= THRESHOLDL)) {\
  1606. outb |= Bit;\
  1607. Err -= MAXVALUEM;\
  1608. }\
  1609. if (Err > THRESHOLDL) {\
  1610. outa |= Bit;\
  1611. outb |= Bit;\
  1612. Err -= MAXVALUEL;\
  1613. }\
  1614. *(errP + (Element + Offset)) += ((Err * 3 + C) >> 4);\
  1615. *(errP + Element) = ((Err * 5 + oldErr + C) >> 4);\
  1616. }
  1617. /* The hp850c knows about 4 intensity levels per color. Once more, we need
  1618. an adapted dither algorythm */
  1619. private void
  1620. FSDlinec4(int scan, int plane_size,
  1621. struct error_val_field *error_values,
  1622. byte * cPa, byte * mPa, byte * yPa,
  1623. byte * cPb, byte * mPb, byte * yPb,
  1624. int n, byte * dp, int *ep)
  1625. {
  1626. if (scan == 0) { /* going_up */
  1627. byte ca, ya, ma, cb, yb, mb, bitmask;
  1628. int oldErr, i;
  1629. for (i = 0; i < plane_size; i++) {
  1630. bitmask = 0x80;
  1631. ca = ya = ma = cb = yb = mb = 0;
  1632. for (ca = 0; bitmask != 0; bitmask >>= 1) {
  1633. FSdither8504(dp, ca, cb, ep, error_values->c, bitmask, -n, n
  1634. - 3);
  1635. FSdither8504(dp, ma, mb, ep, error_values->m, bitmask, -n, n
  1636. - 2);
  1637. FSdither8504(dp, ya, yb, ep, error_values->y, bitmask, -n, n
  1638. - 1);
  1639. dp += n, ep += n;
  1640. }
  1641. *cPa++ = ca;
  1642. *mPa++ = ma;
  1643. *yPa++ = ya;
  1644. *cPb++ = cb;
  1645. *mPb++ = mb;
  1646. *yPb++ = yb;
  1647. }
  1648. } else { /* going_down */
  1649. byte ca, ya, ma, cb, yb, mb, bitmask;
  1650. int oldErr, i;
  1651. for (i = 0; i < plane_size; i++) {
  1652. bitmask = 0x01;
  1653. ca = ya = ma = cb = yb = mb = 0;
  1654. for (ca = 0; bitmask != 0; bitmask <<= 1) {
  1655. dp -= n, ep -= n;
  1656. FSdither8504(dp, ya, yb, ep, error_values->y, bitmask, n, n
  1657. - 1);
  1658. FSdither8504(dp, ma, mb, ep, error_values->m, bitmask, n, n
  1659. - 2);
  1660. FSdither8504(dp, ca, cb, ep, error_values->c, bitmask, n, n
  1661. - 3);
  1662. }
  1663. *--yPa = ya;
  1664. *--mPa = ma;
  1665. *--cPa = ca;
  1666. *--yPb = yb;
  1667. *--mPb = mb;
  1668. *--cPb = cb;
  1669. }
  1670. }
  1671. return;
  1672. }
  1673. /* calculate the needed memory */
  1674. private void
  1675. calculate_memory_size(gx_device_printer * pdev,
  1676. struct misc_struct *misc_vars)
  1677. {
  1678. int xfac = cdj850->xscal ? 2 : 1;
  1679. misc_vars->line_size = gdev_prn_raster(pdev);
  1680. misc_vars->line_size_c = misc_vars->line_size / xfac;
  1681. misc_vars->line_size_words = (misc_vars->line_size + W - 1) / W;
  1682. misc_vars->paper_size = gdev_pcl_paper_size((gx_device *) pdev);
  1683. misc_vars->num_comps = pdev->color_info.num_components;
  1684. misc_vars->bits_per_pixel = pdev->color_info.depth;
  1685. misc_vars->storage_bpp = misc_vars->num_comps * 8;
  1686. misc_vars->expanded_bpp = misc_vars->num_comps * 8;
  1687. misc_vars->errbuff_size = 0;
  1688. misc_vars->errbuff_size_c = 0;
  1689. misc_vars->plane_size = calc_buffsize(misc_vars->line_size, misc_vars->storage_bpp);
  1690. /* plane_size_c is dependedend on the bits used for
  1691. dithering. Currently 2 bits are sufficient */
  1692. misc_vars->plane_size_c = 2 * misc_vars->plane_size / xfac;
  1693. /* 4n extra values for line ends */
  1694. /* might be wrong, see gdevcdj.c */
  1695. misc_vars->errbuff_size =
  1696. calc_buffsize((misc_vars->plane_size * misc_vars->expanded_bpp +
  1697. misc_vars->num_comps * 4) * I, 1);
  1698. /* 4n extra values for line ends */
  1699. misc_vars->errbuff_size_c =
  1700. calc_buffsize((misc_vars->plane_size_c / 2 * misc_vars->expanded_bpp
  1701. + misc_vars->num_comps * 4) * I, 1);
  1702. misc_vars->databuff_size =
  1703. misc_vars->plane_size * misc_vars->storage_bpp;
  1704. misc_vars->databuff_size_c =
  1705. misc_vars->plane_size_c / 2 * misc_vars->storage_bpp;
  1706. misc_vars->outbuff_size = misc_vars->plane_size * 4;
  1707. misc_vars->storage_size_words = (((misc_vars->plane_size)
  1708. * 2
  1709. * misc_vars->num_comps)
  1710. + misc_vars->databuff_size
  1711. + misc_vars->errbuff_size
  1712. + misc_vars->outbuff_size
  1713. + ((misc_vars->plane_size_c)
  1714. * 2
  1715. * misc_vars->num_comps)
  1716. + misc_vars->databuff_size_c
  1717. + misc_vars->errbuff_size_c
  1718. + (4 * misc_vars->plane_size_c))
  1719. / W;
  1720. return;
  1721. }
  1722. /* Initialise the needed pointers */
  1723. private void
  1724. init_data_structure(gx_device_printer * pdev,
  1725. struct ptr_arrays *data_ptrs,
  1726. struct misc_struct *misc_vars)
  1727. {
  1728. int i;
  1729. byte *p = (byte *) data_ptrs->storage;
  1730. misc_vars->scan = 0;
  1731. misc_vars->cscan = 0;
  1732. misc_vars->is_two_pass = 1;
  1733. /* the b/w pointer */
  1734. data_ptrs->data[0] = data_ptrs->data[1] = data_ptrs->data[2] = p;
  1735. data_ptrs->data[3] = p + misc_vars->databuff_size;
  1736. /* Note: The output data will overwrite part of the input-data */
  1737. if (misc_vars->bits_per_pixel > 1) {
  1738. p += misc_vars->databuff_size;
  1739. }
  1740. if (misc_vars->bits_per_pixel > 4) {
  1741. data_ptrs->errors[0] = (int *)p + misc_vars->num_comps * 2;
  1742. data_ptrs->errors[1] = data_ptrs->errors[0] + misc_vars->databuff_size;
  1743. p += misc_vars->errbuff_size;
  1744. }
  1745. for (i = 0; i < misc_vars->num_comps; i++) {
  1746. data_ptrs->plane_data[0][i] = data_ptrs->plane_data[2][i] = p;
  1747. p += misc_vars->plane_size;
  1748. }
  1749. for (i = 0; i < misc_vars->num_comps; i++) {
  1750. data_ptrs->plane_data[1][i] = p;
  1751. data_ptrs->plane_data[3][i] = p + misc_vars->plane_size;
  1752. p += misc_vars->plane_size;
  1753. }
  1754. data_ptrs->out_data = p;
  1755. p += misc_vars->outbuff_size;
  1756. /* ---------------------------------------------------------
  1757. now for the color pointers
  1758. --------------------------------------------------------- */
  1759. data_ptrs->data_c[0] = data_ptrs->data_c[1] = data_ptrs->data_c[2] = p;
  1760. data_ptrs->data_c[3] = p + misc_vars->databuff_size_c;
  1761. /* Note: The output data will overwrite part of the input-data */
  1762. if (misc_vars->bits_per_pixel > 1) {
  1763. p += misc_vars->databuff_size_c;
  1764. }
  1765. if (misc_vars->bits_per_pixel > 4) {
  1766. data_ptrs->errors_c[0] = (int *)p + misc_vars->num_comps * 2;
  1767. data_ptrs->errors_c[1] = data_ptrs->errors_c[0] + misc_vars->databuff_size_c;
  1768. p += misc_vars->errbuff_size_c;
  1769. }
  1770. /* pointer for the lower bits of the output data */
  1771. for (i = 0; i < misc_vars->num_comps; i++) {
  1772. data_ptrs->plane_data_c[0][i] = data_ptrs->plane_data_c[2][i] = p;
  1773. p += misc_vars->plane_size_c / 2;
  1774. }
  1775. for (i = 0; i < misc_vars->num_comps; i++) {
  1776. data_ptrs->plane_data_c[1][i] = p;
  1777. data_ptrs->plane_data_c[3][i] = p + misc_vars->plane_size_c / 2;
  1778. p += misc_vars->plane_size_c / 2;
  1779. }
  1780. /* pointer for the upper bits of the output data */
  1781. for (i = 0; i < misc_vars->num_comps; i++) {
  1782. data_ptrs->plane_data_c[0][i + 4] = data_ptrs->plane_data_c[2][i +
  1783. 4] = p;
  1784. p += misc_vars->plane_size_c / 2;
  1785. }
  1786. for (i = 0; i < misc_vars->num_comps; i++) {
  1787. data_ptrs->plane_data_c[1][i + 4] = p;
  1788. data_ptrs->plane_data_c[3][i + 4] = p + misc_vars->plane_size_c / 2;
  1789. p += misc_vars->plane_size_c / 2;
  1790. }
  1791. for (i = 0; i < misc_vars->num_comps; i++) {
  1792. data_ptrs->test_data[i] = p;
  1793. p += misc_vars->plane_size_c / 2;
  1794. }
  1795. /* Clear temp storage */
  1796. memset(data_ptrs->storage, 0, misc_vars->storage_size_words * W);
  1797. return;
  1798. } /* end init_data_structure */
  1799. /* Configure the printer and start Raster mode */
  1800. private void
  1801. cdj850_start_raster_mode(gx_device_printer * pdev, int paper_size,
  1802. FILE * prn_stream)
  1803. {
  1804. int xres, yres; /* x,y resolution for color planes */
  1805. hp850_cmyk_init_t init;
  1806. init = hp850_cmyk_init;
  1807. init.a[13] = cdj850->intensities; /* Intensity levels cyan */
  1808. init.a[19] = cdj850->intensities; /* Intensity levels magenta */
  1809. init.a[25] = cdj850->intensities; /* Intensity levels yellow */
  1810. /* black plane resolution */
  1811. assign_dpi(cdj850->x_pixels_per_inch, init.a + 2);
  1812. assign_dpi(cdj850->y_pixels_per_inch, init.a + 4);
  1813. /* color plane resolution */
  1814. xres = cdj850->x_pixels_per_inch / (cdj850->xscal + 1);
  1815. yres = cdj850->y_pixels_per_inch / (cdj850->yscal + 1);
  1816. /* cyan */
  1817. assign_dpi(xres, init.a + 8);
  1818. assign_dpi(yres, init.a + 10);
  1819. /* magenta */
  1820. assign_dpi(xres, init.a + 14);
  1821. assign_dpi(yres, init.a + 16);
  1822. /* yellow */
  1823. assign_dpi(xres, init.a + 20);
  1824. assign_dpi(yres, init.a + 22);
  1825. fputs("\033*rbC", prn_stream); /* End raster graphics */
  1826. fputs("\033E", prn_stream); /* Reset */
  1827. /* Page size, orientation, top margin & perforation skip */
  1828. fprintf(prn_stream, "\033&l%daolE", paper_size);
  1829. /* Print Quality, -1 = draft, 0 = normal, 1 = presentation */
  1830. fprintf(prn_stream, "\033*o%dM", cdj850->quality);
  1831. /* Media Type,0 = plain paper, 1 = bond paper, 2 = special
  1832. paper, 3 = glossy film, 4 = transparency film */
  1833. fprintf(prn_stream, "\033&l%dM", cdj850->papertype);
  1834. /* Move to top left of printed area */
  1835. fprintf(prn_stream, "\033*p%dY", (int)(600 * DOFFSET));
  1836. /* This will start and configure the raster-mode */
  1837. fprintf(prn_stream, "\033*g%dW", (int)sizeof(init.a)); /* The new configure
  1838. raster data comand */
  1839. fwrite(init.a, sizeof(byte), sizeof(init.a),
  1840. prn_stream); /* Transmit config
  1841. data */
  1842. /* From now on, all escape commands start with \033*b, so we
  1843. * combine them (if the printer supports this). */
  1844. fputs("\033*b", prn_stream);
  1845. /* Set compression if the mode has been defined. */
  1846. if (cdj850->compression)
  1847. fprintf(prn_stream, "%dm", cdj850->compression);
  1848. return;
  1849. } /* end configure raster-mode */
  1850. private int
  1851. cdj_put_param_int(gs_param_list * plist, gs_param_name pname, int *pvalue,
  1852. int minval, int maxval, int ecode)
  1853. {
  1854. int code, value;
  1855. switch (code = param_read_int(plist, pname, &value)) {
  1856. default:
  1857. return code;
  1858. case 1:
  1859. return ecode;
  1860. case 0:
  1861. if (value < minval || value > maxval)
  1862. param_signal_error(plist, pname, gs_error_rangecheck);
  1863. *pvalue = value;
  1864. return (ecode < 0 ? ecode : 1);
  1865. }
  1866. }
  1867. private int
  1868. cdj_put_param_float(gs_param_list * plist, gs_param_name pname, float *pvalue,
  1869. float minval, float maxval, int ecode)
  1870. {
  1871. int code;
  1872. float value;
  1873. switch (code = param_read_float(plist, pname, &value)) {
  1874. default:
  1875. return code;
  1876. case 1:
  1877. return ecode;
  1878. case 0:
  1879. if (value < minval || value > maxval)
  1880. param_signal_error(plist, pname, gs_error_rangecheck);
  1881. *pvalue = value;
  1882. return (ecode < 0 ? ecode : 1);
  1883. }
  1884. }
  1885. private int
  1886. cdj_set_bpp(gx_device * pdev, int bpp, int ccomps)
  1887. {
  1888. gx_device_color_info *ci = &pdev->color_info;
  1889. if (ccomps && bpp == 0) {
  1890. if (cprn_device->cmyk) {
  1891. switch (ccomps) {
  1892. default:
  1893. return gs_error_rangecheck;
  1894. /*NOTREACHED */
  1895. break;
  1896. case 1:
  1897. bpp = 1;
  1898. break;
  1899. case 3:
  1900. bpp = 24;
  1901. break;
  1902. case 4:
  1903. switch (ci->depth) {
  1904. case 8:
  1905. case 16:
  1906. case 24:
  1907. case 32:
  1908. break;
  1909. default:
  1910. bpp = cprn_device->default_depth;
  1911. break;
  1912. }
  1913. break;
  1914. }
  1915. }
  1916. }
  1917. if (bpp == 0) {
  1918. bpp = ci->depth; /* Use the current setting. */
  1919. }
  1920. if (cprn_device->cmyk < 0) {
  1921. /* Reset procedures because we may have been in another mode. */
  1922. dev_proc(pdev, map_cmyk_color) = gdev_cmyk_map_cmyk_color;
  1923. dev_proc(pdev, map_rgb_color) = NULL;
  1924. dev_proc(pdev, map_color_rgb) = gdev_cmyk_map_color_rgb;
  1925. if (pdev->is_open)
  1926. gs_closedevice(pdev);
  1927. }
  1928. /* Check for valid bpp values */
  1929. switch (bpp) {
  1930. case 16:
  1931. case 32:
  1932. if (cprn_device->cmyk && ccomps && ccomps != 4)
  1933. goto bppe;
  1934. break;
  1935. case 24:
  1936. if (!cprn_device->cmyk || ccomps == 0 || ccomps == 4) {
  1937. break;
  1938. } else if (ccomps == 1) {
  1939. goto bppe;
  1940. } else {
  1941. /* 3 components 24 bpp printing for CMYK device. */
  1942. cprn_device->cmyk = -1;
  1943. }
  1944. break;
  1945. case 8:
  1946. if (cprn_device->cmyk) {
  1947. if (ccomps) {
  1948. if (ccomps == 3) {
  1949. cprn_device->cmyk = -1;
  1950. bpp = 3;
  1951. } else if (ccomps != 1 && ccomps != 4) {
  1952. goto bppe;
  1953. }
  1954. }
  1955. if (ccomps != 1)
  1956. break;
  1957. } else {
  1958. break;
  1959. }
  1960. case 1:
  1961. if (ccomps != 1)
  1962. goto bppe;
  1963. if (cprn_device->cmyk && bpp != pdev->color_info.depth) {
  1964. dev_proc(pdev, map_cmyk_color) = NULL;
  1965. dev_proc(pdev, map_rgb_color) = gdev_cmyk_map_rgb_color;
  1966. if (pdev->is_open) {
  1967. gs_closedevice(pdev);
  1968. }
  1969. }
  1970. break;
  1971. case 3:
  1972. if (!cprn_device->cmyk) {
  1973. break;
  1974. }
  1975. default:
  1976. bppe:return gs_error_rangecheck;
  1977. }
  1978. if (cprn_device->cmyk == -1) {
  1979. dev_proc(pdev, map_cmyk_color) = NULL;
  1980. dev_proc(pdev, map_rgb_color) = gdev_pcl_map_rgb_color;
  1981. dev_proc(pdev, map_color_rgb) = gdev_pcl_map_color_rgb;
  1982. if (pdev->is_open) {
  1983. gs_closedevice(pdev);
  1984. }
  1985. }
  1986. switch (ccomps) {
  1987. case 0:
  1988. break;
  1989. case 1:
  1990. if (bpp != 1 && bpp != 8)
  1991. goto cce;
  1992. break;
  1993. case 4:
  1994. if (cprn_device->cmyk) {
  1995. if (bpp >= 8)
  1996. break;
  1997. }
  1998. case 3:
  1999. if (bpp == 1 || bpp == 3 || bpp == 8 || bpp == 16
  2000. || bpp == 24 || bpp == 32) {
  2001. break;
  2002. }
  2003. cce: default:
  2004. return gs_error_rangecheck;
  2005. }
  2006. if (cprn_device->cmyk) {
  2007. if (cprn_device->cmyk > 0) {
  2008. ci->num_components = ccomps ? ccomps : (bpp < 8 ? 1 : 4);
  2009. } else {
  2010. ci->num_components = ccomps ? ccomps : (bpp < 8 ? 1 : 3);
  2011. }
  2012. if (bpp != 1 && ci->num_components == 1) { /* We do dithered grays. */
  2013. bpp = bpp < 8 ? 8 : bpp;
  2014. }
  2015. ci->max_color = (1 << (bpp >> 2)) - 1;
  2016. ci->max_gray = (bpp >= 8 ? 255 : 1);
  2017. if (ci->num_components == 1) {
  2018. ci->dither_grays = (bpp >= 8 ? 5 : 2);
  2019. ci->dither_colors = (bpp >= 8 ? 5 : bpp > 1 ? 2 : 0);
  2020. } else {
  2021. ci->dither_grays = (bpp > 8 ? 5 : 2);
  2022. ci->dither_colors = (bpp > 8 ? 5 : bpp > 1 ? 2 : 0);
  2023. }
  2024. } else {
  2025. ci->num_components = (bpp == 1 || bpp == 8 ? 1 : 3);
  2026. ci->max_color = (bpp >= 8 ? 255 : bpp > 1 ? 1 : 0);
  2027. ci->max_gray = (bpp >= 8 ? 255 : 1);
  2028. ci->dither_grays = (bpp >= 8 ? 5 : 2);
  2029. ci->dither_colors = (bpp >= 8 ? 5 : bpp > 1 ? 2 : 0);
  2030. }
  2031. ci->depth = ((bpp > 1) && (bpp < 8) ? 8 : bpp);
  2032. return 0;
  2033. }
  2034. /*
  2035. * Map a CMYK color to a color index. We just use depth / 4 bits per color
  2036. * to produce the color index.
  2037. *
  2038. * Important note: CMYK values are stored in the order K, C, M, Y because of
  2039. * the way the HP drivers work.
  2040. *
  2041. */
  2042. #define gx_color_value_to_bits(cv, b) \
  2043. ((cv) >> (gx_color_value_bits - (b)))
  2044. #define gx_bits_to_color_value(cv, b) \
  2045. ((cv) << (gx_color_value_bits - (b)))
  2046. #define gx_cmyk_value_bits(c, m, y, k, b) \
  2047. ((gx_color_value_to_bits((k), (b)) << (3 * (b))) | \
  2048. (gx_color_value_to_bits((c), (b)) << (2 * (b))) | \
  2049. (gx_color_value_to_bits((m), (b)) << (b)) | \
  2050. (gx_color_value_to_bits((y), (b))))
  2051. #define gx_value_cmyk_bits(v, c, m, y, k, b) \
  2052. (k) = gx_bits_to_color_value(((v) >> (3 * (b))) & ((1 << (b)) - 1), (b)), \
  2053. (c) = gx_bits_to_color_value(((v) >> (2 * (b))) & ((1 << (b)) - 1), (b)), \
  2054. (m) = gx_bits_to_color_value(((v) >> (b)) & ((1 << (b)) - 1), (b)), \
  2055. (y) = gx_bits_to_color_value((v) & ((1 << (b)) - 1), (b))
  2056. private gx_color_index
  2057. gdev_cmyk_map_cmyk_color(gx_device * pdev,
  2058. gx_color_value *cmyk)
  2059. {
  2060. gx_color_value cyan=cmyk[0], magenta=cmyk[1], yellow=cmyk[3], black=cmyk[4];
  2061. gx_color_index color;
  2062. switch (pdev->color_info.depth) {
  2063. case 1:
  2064. color = (cyan | magenta | yellow | black) > gx_max_color_value / 2 ?
  2065. (gx_color_index) 1 : (gx_color_index) 0;
  2066. break;
  2067. default:{
  2068. int nbits = pdev->color_info.depth;
  2069. if (cyan == magenta && magenta == yellow) {
  2070. /* Convert CMYK to gray -- Red Book 6.2.2 */
  2071. float bpart = ((float)cyan) * (lum_red_weight / 100.) +
  2072. ((float)magenta) * (lum_green_weight / 100.) +
  2073. ((float)yellow) * (lum_blue_weight / 100.) +
  2074. (float)black;
  2075. cyan = magenta = yellow = (gx_color_index) 0;
  2076. black = (gx_color_index) (bpart > gx_max_color_value ?
  2077. gx_max_color_value : bpart);
  2078. }
  2079. color = gx_cmyk_value_bits(cyan, magenta, yellow, black,
  2080. nbits >> 2);
  2081. }
  2082. }
  2083. return color;
  2084. }
  2085. /* Mapping of RGB colors to gray values. */
  2086. private gx_color_index
  2087. gdev_cmyk_map_rgb_color(gx_device * pdev, gx_color_value rgb[3])
  2088. {
  2089. gx_color_value r=rgb[0], g=rgb[1], b=rgb[2];
  2090. if (gx_color_value_to_byte(r & g & b) == 0xff) {
  2091. return (gx_color_index) 0; /* White */
  2092. } else {
  2093. gx_color_value c = gx_max_color_value - r;
  2094. gx_color_value m = gx_max_color_value - g;
  2095. gx_color_value y = gx_max_color_value - b;
  2096. switch (pdev->color_info.depth) {
  2097. case 1:
  2098. return (c | m | y) > gx_max_color_value / 2 ?
  2099. (gx_color_index) 1 : (gx_color_index) 0;
  2100. /*NOTREACHED */
  2101. break;
  2102. case 8:
  2103. return ((ulong) c * lum_red_weight * 10
  2104. + (ulong) m * lum_green_weight * 10
  2105. + (ulong) y * lum_blue_weight * 10)
  2106. >> (gx_color_value_bits + 2);
  2107. /*NOTREACHED */
  2108. break;
  2109. }
  2110. }
  2111. return (gx_color_index) 0; /* This should never happen. */
  2112. }
  2113. /* Mapping of CMYK colors. */
  2114. private int
  2115. gdev_cmyk_map_color_rgb(gx_device * pdev, gx_color_index color,
  2116. gx_color_value prgb[3])
  2117. {
  2118. switch (pdev->color_info.depth) {
  2119. case 1:
  2120. prgb[0] = prgb[1] = prgb[2] = gx_max_color_value * (1 - color);
  2121. break;
  2122. case 8:
  2123. if (pdev->color_info.num_components == 1) {
  2124. gx_color_value value = (gx_color_value) color ^ 0xff;
  2125. prgb[0] = prgb[1] = prgb[2] = (value << 8) + value;
  2126. break;
  2127. }
  2128. default:{
  2129. unsigned long bcyan, bmagenta, byellow, black;
  2130. int nbits = pdev->color_info.depth;
  2131. gx_value_cmyk_bits(color, bcyan, bmagenta, byellow, black,
  2132. nbits >> 2);
  2133. #ifdef USE_ADOBE_CMYK_RGB
  2134. /* R = 1.0 - min(1.0, C + K), etc. */
  2135. bcyan += black, bmagenta += black, byellow += black;
  2136. prgb[0] = (bcyan > gx_max_color_value ? (gx_color_value) 0 :
  2137. gx_max_color_value - bcyan);
  2138. prgb[1] = (bmagenta > gx_max_color_value ? (gx_color_value) 0 :
  2139. gx_max_color_value - bmagenta);
  2140. prgb[2] = (byellow > gx_max_color_value ? (gx_color_value) 0 :
  2141. gx_max_color_value - byellow);
  2142. #else
  2143. /* R = (1.0 - C) * (1.0 - K), etc. */
  2144. prgb[0] = (gx_color_value)
  2145. ((ulong) (gx_max_color_value - bcyan) *
  2146. (gx_max_color_value - black) / gx_max_color_value);
  2147. prgb[1] = (gx_color_value)
  2148. ((ulong) (gx_max_color_value - bmagenta) *
  2149. (gx_max_color_value - black) / gx_max_color_value);
  2150. prgb[2] = (gx_color_value)
  2151. ((ulong) (gx_max_color_value - byellow) *
  2152. (gx_max_color_value - black) / gx_max_color_value);
  2153. #endif
  2154. }
  2155. }
  2156. return 0;
  2157. }
  2158. private gx_color_index
  2159. gdev_pcl_map_rgb_color(gx_device * pdev, gx_color_value *rgb)
  2160. {
  2161. gx_color_value r=rgb[0], g=rgb[1], b=rgb[2];
  2162. if (gx_color_value_to_byte(r & g & b) == 0xff)
  2163. return (gx_color_index) 0; /* white */
  2164. else {
  2165. gx_color_value c = gx_max_color_value - r;
  2166. gx_color_value m = gx_max_color_value - g;
  2167. gx_color_value y = gx_max_color_value - b;
  2168. switch (pdev->color_info.depth) {
  2169. case 1:
  2170. return ((c | m | y) > gx_max_color_value / 2 ?
  2171. (gx_color_index) 1 : (gx_color_index) 0);
  2172. case 8:
  2173. if (pdev->color_info.num_components >= 3)
  2174. #define gx_color_value_to_1bit(cv) ((cv) >> (gx_color_value_bits - 1))
  2175. return (gx_color_value_to_1bit(c) +
  2176. (gx_color_value_to_1bit(m) << 1) +
  2177. (gx_color_value_to_1bit(y) << 2));
  2178. else
  2179. #define red_weight 306
  2180. #define green_weight 601
  2181. #define blue_weight 117
  2182. return ((((ulong) c * red_weight +
  2183. (ulong) m * green_weight +
  2184. (ulong) y * blue_weight)
  2185. >> (gx_color_value_bits + 2)));
  2186. case 16:
  2187. #define gx_color_value_to_5bits(cv) ((cv) >> (gx_color_value_bits - 5))
  2188. #define gx_color_value_to_6bits(cv) ((cv) >> (gx_color_value_bits - 6))
  2189. return (gx_color_value_to_5bits(y) +
  2190. (gx_color_value_to_6bits(m) << 5) +
  2191. (gx_color_value_to_5bits(c) << 11));
  2192. case 24:
  2193. return (gx_color_value_to_byte(y) +
  2194. (gx_color_value_to_byte(m) << 8) +
  2195. ((ulong) gx_color_value_to_byte(c) << 16));
  2196. case 32:
  2197. {
  2198. return ((c == m && c == y) ? ((ulong)
  2199. gx_color_value_to_byte(c) << 24)
  2200. : (gx_color_value_to_byte(y) +
  2201. (gx_color_value_to_byte(m) << 8) +
  2202. ((ulong) gx_color_value_to_byte(c) << 16)));
  2203. }
  2204. }
  2205. }
  2206. return (gx_color_index) 0; /* This never happens */
  2207. }
  2208. /* Map a color index to a r-g-b color. */
  2209. private int
  2210. gdev_pcl_map_color_rgb(gx_device * pdev, gx_color_index color,
  2211. gx_color_value prgb[3])
  2212. {
  2213. /* For the moment, we simply ignore any black correction */
  2214. switch (pdev->color_info.depth) {
  2215. case 1:
  2216. prgb[0] = prgb[1] = prgb[2] = -((gx_color_value) color ^ 1);
  2217. break;
  2218. case 8:
  2219. if (pdev->color_info.num_components >= 3) {
  2220. gx_color_value c = (gx_color_value) color ^ 7;
  2221. prgb[0] = -(c & 1);
  2222. prgb[1] = -((c >> 1) & 1);
  2223. prgb[2] = -(c >> 2);
  2224. } else {
  2225. gx_color_value value = (gx_color_value) color ^ 0xff;
  2226. prgb[0] = prgb[1] = prgb[2] = (value << 8) + value;
  2227. }
  2228. break;
  2229. case 16:
  2230. {
  2231. gx_color_value c = (gx_color_value) color ^ 0xffff;
  2232. ushort value = c >> 11;
  2233. prgb[0] = ((value << 11) + (value << 6) + (value << 1) +
  2234. (value >> 4)) >> (16 - gx_color_value_bits);
  2235. value = (c >> 6) & 0x3f;
  2236. prgb[1] = ((value << 10) + (value << 4) + (value >> 2))
  2237. >> (16 - gx_color_value_bits);
  2238. value = c & 0x1f;
  2239. prgb[2] = ((value << 11) + (value << 6) + (value << 1) +
  2240. (value >> 4)) >> (16 - gx_color_value_bits);
  2241. }
  2242. break;
  2243. case 24:
  2244. {
  2245. gx_color_value c = (gx_color_value) color ^ 0xffffff;
  2246. prgb[0] = gx_color_value_from_byte(c >> 16);
  2247. prgb[1] = gx_color_value_from_byte((c >> 8) & 0xff);
  2248. prgb[2] = gx_color_value_from_byte(c & 0xff);
  2249. }
  2250. break;
  2251. case 32:
  2252. #define gx_maxcol gx_color_value_from_byte(gx_color_value_to_byte(gx_max_color_value))
  2253. {
  2254. gx_color_value w = gx_maxcol - gx_color_value_from_byte(color >> 24);
  2255. prgb[0] = w - gx_color_value_from_byte((color >> 16) & 0xff);
  2256. prgb[1] = w - gx_color_value_from_byte((color >> 8) & 0xff);
  2257. prgb[2] = w - gx_color_value_from_byte(color & 0xff);
  2258. }
  2259. break;
  2260. }
  2261. return 0;
  2262. }
  2263. /* new_bpp == save_bpp or new_bpp == 0 means don't change bpp.
  2264. ccomps == 0 means don't change number of color comps.
  2265. If new_bpp != 0, it must be the value of the BitsPerPixel element of
  2266. the plist; real_bpp may differ from new_bpp.
  2267. */
  2268. private int
  2269. cdj_put_param_bpp(gx_device * pdev, gs_param_list * plist, int new_bpp,
  2270. int real_bpp, int ccomps)
  2271. {
  2272. if (new_bpp == 0 && ccomps == 0)
  2273. return gdev_prn_put_params(pdev, plist);
  2274. else {
  2275. gx_device_color_info save_info;
  2276. int save_bpp;
  2277. int code;
  2278. save_info = pdev->color_info;
  2279. save_bpp = save_info.depth;
  2280. #define save_ccomps save_info.num_components
  2281. if (save_bpp == 8 && save_ccomps == 3 && !cprn_device->cmyk)
  2282. save_bpp = 3;
  2283. code = cdj_set_bpp(pdev, real_bpp, ccomps);
  2284. if (code < 0) {
  2285. param_signal_error(plist, "BitsPerPixel", code);
  2286. param_signal_error(plist, "ProcessColorModel", code);
  2287. return code;
  2288. }
  2289. pdev->color_info.depth = new_bpp; /* cdj_set_bpp maps 3/6 to 8 */
  2290. code = gdev_prn_put_params(pdev, plist);
  2291. if (code < 0) {
  2292. cdj_set_bpp(pdev, save_bpp, save_ccomps);
  2293. return code;
  2294. }
  2295. cdj_set_bpp(pdev, real_bpp, ccomps); /* reset depth if needed */
  2296. if ((cdj850->color_info.depth != save_bpp ||
  2297. (ccomps != 0 && ccomps != save_ccomps))
  2298. && pdev->is_open)
  2299. return gs_closedevice(pdev);
  2300. return 0;
  2301. #undef save_ccomps
  2302. }
  2303. }
  2304. /* the following code was in the original driver but is unused
  2305. * private int
  2306. * x_mul_div (int a, int b, int c)
  2307. * {
  2308. * int result;
  2309. *
  2310. * result = (int) ((a * b) / c) ;
  2311. * return result;
  2312. * }
  2313. *
  2314. * private void
  2315. * save_color_data(int size,
  2316. * byte * current,
  2317. * byte * saved)
  2318. * {
  2319. * int i;
  2320. * for (i=0;i<size;i++){
  2321. * *saved++ = *current++;
  2322. * }
  2323. * return;
  2324. * }
  2325. *
  2326. * private int
  2327. * test_scan (int size,
  2328. * byte * current,
  2329. * byte * last,
  2330. * byte * control)
  2331. * {
  2332. * int error = 0;
  2333. * int i;
  2334. *
  2335. * for (i=0;i<size;i++){
  2336. * if (*control != *last){
  2337. * error = 1;
  2338. * }
  2339. * *control = *current;
  2340. *
  2341. * control++;
  2342. * last++;
  2343. * current++;
  2344. * }
  2345. * return error;
  2346. * }
  2347. *
  2348. * * Transform from cmy into hsv
  2349. * private void
  2350. * cmy2hsv(int *c, int *m, int *y, int *h, int *s, int *v)
  2351. * {
  2352. * int hue;
  2353. * int r, g, b;
  2354. * int r1, g1, b1;
  2355. * int maxValue, minValue, diff;
  2356. *
  2357. * r = 255 - *c;
  2358. * g = 255 - *m;
  2359. * b = 255 - *y;
  2360. *
  2361. * maxValue = max(r, max(g,b));
  2362. * minValue = min(r,min(g,b));
  2363. * diff = maxValue - minValue;
  2364. * *v = maxValue;
  2365. *
  2366. * if (maxValue != 0)
  2367. * *s = x_mul_div(diff,255,maxValue);
  2368. * else
  2369. * *s = 0;
  2370. *
  2371. * if (*s == 0)
  2372. * {
  2373. * hue = 0;
  2374. * }
  2375. * else
  2376. * {
  2377. * r1 = x_mul_div(maxValue - r,255,diff);
  2378. * g1 = x_mul_div(maxValue - g,255,diff);
  2379. * b1 = x_mul_div(maxValue - b,255,diff);
  2380. *
  2381. * if (r == maxValue)
  2382. * hue = b1 - g1;
  2383. * else if (g == maxValue)
  2384. * hue = 510 + r1 - b1;
  2385. * else
  2386. * hue = 1020 + g1 - r1;
  2387. *
  2388. * if (hue < 0)
  2389. * hue += 1530;
  2390. * }
  2391. *
  2392. * *h = (hue + 3) / 6;
  2393. *
  2394. * return;
  2395. * }
  2396. * end of unused code */
  2397. /************************ the routines for the cdj1600 printer ***************/
  2398. /* Configure the printer and start Raster mode */
  2399. private void
  2400. cdj1600_start_raster_mode(gx_device_printer * pdev, int paper_size,
  2401. FILE * prn_stream)
  2402. {
  2403. uint raster_width = pdev->width -
  2404. pdev->x_pixels_per_inch * (dev_l_margin(pdev) + dev_r_margin(pdev));
  2405. /* switch to PCL control language */
  2406. fputs("\033%-12345X@PJL enter language = PCL\n", prn_stream);
  2407. fputs("\033*rbC", prn_stream); /* End raster graphics */
  2408. fputs("\033E", prn_stream); /* Reset */
  2409. /* resolution */
  2410. fprintf(prn_stream, "\033*t%dR", (int)cdj850->x_pixels_per_inch);
  2411. /* Page size, orientation, top margin & perforation skip */
  2412. fprintf(prn_stream, "\033&l%daolE", paper_size);
  2413. /* no negative motion */
  2414. fputs("\033&a1N", prn_stream);
  2415. /* Print Quality, -1 = draft, 0 = normal, 1 = presentation */
  2416. fprintf(prn_stream, "\033*o%dQ", cdj850->quality);
  2417. /* Media Type,0 = plain paper, 1 = bond paper, 2 = special
  2418. paper, 3 = glossy film, 4 = transparency film */
  2419. fprintf(prn_stream, "\033&l%dM", cdj850->papertype);
  2420. /* Move to top left of printed area */
  2421. fprintf(prn_stream, "\033*p%dY", (int)(300.0 * DOFFSET));
  2422. /* raster width and number of planes */
  2423. fprintf(prn_stream, "\033*r%ds-%du0A",
  2424. raster_width, pdev->color_info.num_components);
  2425. /* start raster graphics */
  2426. fputs("\033*r1A", prn_stream);
  2427. /* From now on, all escape commands start with \033*b, so we
  2428. * combine them (if the printer supports this). */
  2429. fputs("\033*b", prn_stream);
  2430. /* Set compression if the mode has been defined. */
  2431. if (cdj850->compression)
  2432. fprintf(prn_stream, "%dm", cdj850->compression);
  2433. return;
  2434. } /* end configure raster-mode */
  2435. /* print_plane compresses (mode 3) and outputs one plane */
  2436. private void
  2437. print_c3plane(FILE * prn_stream, char plane_code, int plane_size,
  2438. const byte * curr, byte * prev, byte * out_data)
  2439. {
  2440. /* Compress the output data */
  2441. int out_count = gdev_pcl_mode3compress(plane_size, curr, prev, out_data);
  2442. /* and output the data */
  2443. if (out_count > 0) {
  2444. fprintf(prn_stream, "%d%c", out_count, plane_code);
  2445. fwrite(out_data, sizeof(byte), out_count, prn_stream);
  2446. } else {
  2447. putc(plane_code, prn_stream);
  2448. }
  2449. }
  2450. private int
  2451. copy_color_data(byte * dest, const byte * src, int n)
  2452. {
  2453. /* copy word by word */
  2454. register int i = n / 4;
  2455. register word *d = (word *) dest;
  2456. register const word *s = (const word *)src;
  2457. while (i-- > 0) {
  2458. *d++ = *s++;
  2459. }
  2460. return n;
  2461. }
  2462. /* Printing non-blank lines */
  2463. private void
  2464. cdj1600_print_non_blank_lines(gx_device_printer * pdev,
  2465. struct ptr_arrays *data_ptrs,
  2466. struct misc_struct *misc_vars,
  2467. struct error_val_field *error_values,
  2468. const Gamma *gamma,
  2469. FILE * prn_stream)
  2470. {
  2471. int i, plane_size_c;
  2472. /* copy data to data_c in order to make do_floyd_steinberg work */
  2473. plane_size_c = copy_color_data
  2474. (data_ptrs->data_c[misc_vars->cscan],
  2475. data_ptrs->data[misc_vars->scan],
  2476. misc_vars->databuff_size) / misc_vars->storage_bpp;
  2477. /* dither the color planes */
  2478. do_floyd_steinberg(misc_vars->scan, misc_vars->cscan,
  2479. misc_vars->plane_size, plane_size_c,
  2480. misc_vars->num_comps, data_ptrs, pdev, error_values);
  2481. /* Transfer raster graphics in the order C, M, Y, that is
  2482. planes 2,1,0 */
  2483. for (i = misc_vars->num_comps - 1; i >= 0; i--) {
  2484. /* output the lower color planes */
  2485. print_c3plane(prn_stream, "wvv"[i], plane_size_c,
  2486. data_ptrs->plane_data_c[misc_vars->cscan][i],
  2487. data_ptrs->plane_data_c[1 - misc_vars->cscan][i],
  2488. data_ptrs->out_data);
  2489. } /* End For i = num_comps */
  2490. misc_vars->cscan = 1 - misc_vars->cscan;
  2491. }
  2492. private void
  2493. cdj1600_terminate_page(gx_device_printer * pdev, FILE * prn_stream)
  2494. {
  2495. cdj850_terminate_page(pdev, prn_stream);
  2496. fputs("\033%-12345X", prn_stream);
  2497. }