gxdcolor.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758
  1. /* Copyright (C) 1996, 2000 Aladdin Enterprises. All rights reserved.
  2. This software is provided AS-IS with no warranty, either express or
  3. implied.
  4. This software is distributed under license and may not be copied,
  5. modified or distributed except as expressly authorized under the terms
  6. of the license contained in the file LICENSE in this distribution.
  7. For more information about licensing, please refer to
  8. http://www.ghostscript.com/licensing/. For information on
  9. commercial licensing, go to http://www.artifex.com/licensing/ or
  10. contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  11. San Rafael, CA 94903, U.S.A., +1(415)492-9861.
  12. */
  13. /*$Id: gxdcolor.c,v 1.13 2005/06/20 08:59:23 igor Exp $ */
  14. /* Pure and null device color implementation */
  15. #include "gx.h"
  16. #include "memory_.h"
  17. #include "gserrors.h"
  18. #include "gsbittab.h"
  19. #include "gxdcolor.h"
  20. #include "gxdevice.h"
  21. #include "gxdevcli.h"
  22. /* Define the standard device color types. */
  23. /* 'none' means the color is not defined. */
  24. private dev_color_proc_save_dc(gx_dc_no_save_dc);
  25. private dev_color_proc_get_dev_halftone(gx_dc_no_get_dev_halftone);
  26. private dev_color_proc_load(gx_dc_no_load);
  27. private dev_color_proc_fill_rectangle(gx_dc_no_fill_rectangle);
  28. private dev_color_proc_fill_masked(gx_dc_no_fill_masked);
  29. private dev_color_proc_equal(gx_dc_no_equal);
  30. private dev_color_proc_write(gx_dc_no_write);
  31. private dev_color_proc_read(gx_dc_no_read);
  32. private dev_color_proc_get_nonzero_comps(gx_dc_no_get_nonzero_comps);
  33. const gx_device_color_type_t gx_dc_type_data_none = {
  34. &st_bytes,
  35. gx_dc_no_save_dc, gx_dc_no_get_dev_halftone, gx_dc_no_get_phase,
  36. gx_dc_no_load, gx_dc_no_fill_rectangle, gx_dc_no_fill_masked,
  37. gx_dc_no_equal, gx_dc_no_write, gx_dc_no_read, gx_dc_no_get_nonzero_comps
  38. };
  39. #undef gx_dc_type_none
  40. const gx_device_color_type_t *const gx_dc_type_none = &gx_dc_type_data_none;
  41. #define gx_dc_type_none (&gx_dc_type_data_none)
  42. /* 'null' means the color has no effect when used for drawing. */
  43. private dev_color_proc_load(gx_dc_null_load);
  44. private dev_color_proc_fill_rectangle(gx_dc_null_fill_rectangle);
  45. private dev_color_proc_fill_masked(gx_dc_null_fill_masked);
  46. private dev_color_proc_equal(gx_dc_null_equal);
  47. private dev_color_proc_read(gx_dc_null_read);
  48. const gx_device_color_type_t gx_dc_type_data_null = {
  49. &st_bytes,
  50. gx_dc_no_save_dc, gx_dc_no_get_dev_halftone, gx_dc_no_get_phase,
  51. gx_dc_null_load, gx_dc_null_fill_rectangle, gx_dc_null_fill_masked,
  52. gx_dc_null_equal, gx_dc_no_write, gx_dc_null_read, gx_dc_no_get_nonzero_comps
  53. };
  54. #undef gx_dc_type_null
  55. const gx_device_color_type_t *const gx_dc_type_null = &gx_dc_type_data_null;
  56. #define gx_dc_type_null (&gx_dc_type_data_null)
  57. private dev_color_proc_save_dc(gx_dc_pure_save_dc);
  58. private dev_color_proc_load(gx_dc_pure_load);
  59. private dev_color_proc_fill_rectangle(gx_dc_pure_fill_rectangle);
  60. private dev_color_proc_fill_masked(gx_dc_pure_fill_masked);
  61. private dev_color_proc_equal(gx_dc_pure_equal);
  62. private dev_color_proc_write(gx_dc_pure_write);
  63. private dev_color_proc_read(gx_dc_pure_read);
  64. const gx_device_color_type_t gx_dc_type_data_pure = {
  65. &st_bytes,
  66. gx_dc_pure_save_dc, gx_dc_no_get_dev_halftone, gx_dc_no_get_phase,
  67. gx_dc_pure_load, gx_dc_pure_fill_rectangle, gx_dc_pure_fill_masked,
  68. gx_dc_pure_equal, gx_dc_pure_write, gx_dc_pure_read,
  69. gx_dc_pure_get_nonzero_comps
  70. };
  71. #undef gx_dc_type_pure
  72. const gx_device_color_type_t *const gx_dc_type_pure = &gx_dc_type_data_pure;
  73. #define gx_dc_type_pure (&gx_dc_type_data_pure)
  74. /*
  75. * Get the black and white pixel values of a device.
  76. */
  77. gx_color_index
  78. gx_device_black(gx_device *dev)
  79. {
  80. if (dev->cached_colors.black == gx_no_color_index) {
  81. const gx_cm_color_map_procs * cm_procs = dev_proc(dev, get_color_mapping_procs)(dev);
  82. int i, ncomps = dev->color_info.num_components;
  83. frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
  84. gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
  85. /* Get color components for black (gray = 0) */
  86. cm_procs->map_gray(dev, frac_0, cm_comps);
  87. for (i = 0; i < ncomps; i++)
  88. cv[i] = frac2cv(cm_comps[i]);
  89. dev->cached_colors.black = dev_proc(dev, encode_color)(dev, cv);
  90. }
  91. return dev->cached_colors.black;
  92. }
  93. gx_color_index
  94. gx_device_white(gx_device *dev)
  95. {
  96. if (dev->cached_colors.white == gx_no_color_index) {
  97. const gx_cm_color_map_procs * cm_procs = dev_proc(dev, get_color_mapping_procs)(dev);
  98. int i, ncomps = dev->color_info.num_components;
  99. frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
  100. gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
  101. /* Get color components for white (gray = 1) */
  102. cm_procs->map_gray(dev, frac_1, cm_comps);
  103. for (i = 0; i < ncomps; i++)
  104. cv[i] = frac2cv(cm_comps[i]);
  105. dev->cached_colors.white = dev_proc(dev, encode_color)(dev, cv);
  106. }
  107. return dev->cached_colors.white;
  108. }
  109. /* Clear the color cache. */
  110. void
  111. gx_device_decache_colors(gx_device *dev)
  112. {
  113. dev->cached_colors.black = dev->cached_colors.white = gx_no_color_index;
  114. }
  115. /* Set a null RasterOp source. */
  116. private const gx_rop_source_t gx_rop_no_source_0 = {gx_rop_no_source_body(0)};
  117. private const gx_rop_source_t gx_rop_no_source_1 = {gx_rop_no_source_body(1)};
  118. void
  119. gx_set_rop_no_source(const gx_rop_source_t **psource,
  120. gx_rop_source_t *pno_source, gx_device *dev)
  121. {
  122. gx_color_index black;
  123. top:
  124. black = dev->cached_colors.black;
  125. if (black == 0)
  126. *psource = &gx_rop_no_source_0;
  127. else if (black == 1)
  128. *psource = &gx_rop_no_source_1;
  129. else if (black == gx_no_color_index) { /* cache not loaded */
  130. discard(gx_device_black(dev));
  131. goto top;
  132. } else {
  133. *pno_source = gx_rop_no_source_0;
  134. gx_rop_source_set_color(pno_source, black);
  135. *psource = pno_source;
  136. }
  137. }
  138. /*
  139. * Test device colors for equality. Testing for equality is done
  140. * for determining when cache values, etc. can be used. Thus these
  141. * routines should err toward false responses if there is any question
  142. * about the equality of the two device colors.
  143. */
  144. bool
  145. gx_device_color_equal(const gx_device_color *pdevc1,
  146. const gx_device_color *pdevc2)
  147. {
  148. return pdevc1->type->equal(pdevc1, pdevc2);
  149. }
  150. /*
  151. * Return a device color type index. This index is used by the command
  152. * list processor to identify a device color type, as the type pointer
  153. * itself is meaningful only within a single address space.
  154. *
  155. * Currently, we ignore the pattern device colors as they cannot be
  156. * passed through the command list.
  157. *
  158. * Returns gs_error_unknownerror for an unrecognized type.
  159. */
  160. private const gx_device_color_type_t * dc_color_type_table[] = {
  161. gx_dc_type_none, /* unset device color */
  162. gx_dc_type_null, /* blank (transparent) device color */
  163. gx_dc_type_pure, /* pure device color */
  164. /* gx_dc_type_pattern, */ /* patterns - not used in command list */
  165. gx_dc_type_ht_binary, /* binary halftone device colors */
  166. gx_dc_type_ht_colored, /* general halftone device colors */
  167. gx_dc_type_wts /* well-tempered screen device colors */
  168. };
  169. int
  170. gx_get_dc_type_index(const gx_device_color * pdevc)
  171. {
  172. const gx_device_color_type_t * type = pdevc->type;
  173. int num_types, i;
  174. num_types = sizeof(dc_color_type_table) / sizeof(dc_color_type_table[0]);
  175. for (i = 0; i < num_types && type != dc_color_type_table[i]; i++)
  176. ;
  177. return i < num_types ? i : gs_error_unknownerror;
  178. }
  179. /* map a device color type index into the associated method vector */
  180. const gx_device_color_type_t *
  181. gx_get_dc_type_from_index(int i)
  182. {
  183. if ( i >= 0 &&
  184. i < sizeof(dc_color_type_table) / sizeof(dc_color_type_table[0]) )
  185. return dc_color_type_table[i];
  186. else
  187. return 0;
  188. }
  189. /* ------ Canonical get_phase methods ------ */
  190. bool
  191. gx_dc_no_get_phase(const gx_device_color * pdevc, gs_int_point * pphase)
  192. {
  193. return false;
  194. }
  195. bool
  196. gx_dc_ht_get_phase(const gx_device_color * pdevc, gs_int_point * pphase)
  197. {
  198. *pphase = pdevc->phase;
  199. return true;
  200. }
  201. /* ------ Undefined color ------ */
  202. private void
  203. gx_dc_no_save_dc(const gx_device_color * pdevc, gx_device_color_saved * psdc)
  204. {
  205. psdc->type = pdevc->type;
  206. }
  207. private const gx_device_halftone *
  208. gx_dc_no_get_dev_halftone(const gx_device_color * pdevc)
  209. {
  210. return 0;
  211. }
  212. private int
  213. gx_dc_no_load(gx_device_color *pdevc, const gs_imager_state *ignore_pis,
  214. gx_device *ignore_dev, gs_color_select_t ignore_select)
  215. {
  216. return 0;
  217. }
  218. private int
  219. gx_dc_no_fill_rectangle(const gx_device_color *pdevc, int x, int y,
  220. int w, int h, gx_device *dev,
  221. gs_logical_operation_t lop,
  222. const gx_rop_source_t *source)
  223. {
  224. gx_device_color filler;
  225. if (w <= 0 || h <= 0)
  226. return 0;
  227. if (lop_uses_T(lop))
  228. return_error(gs_error_Fatal);
  229. set_nonclient_dev_color(&filler, 0); /* any valid value for dev will do */
  230. return gx_dc_pure_fill_rectangle(&filler, x, y, w, h, dev, lop, source);
  231. }
  232. private int
  233. gx_dc_no_fill_masked(const gx_device_color *pdevc, const byte *data,
  234. int data_x, int raster, gx_bitmap_id id,
  235. int x, int y, int w, int h, gx_device *dev,
  236. gs_logical_operation_t lop, bool invert)
  237. {
  238. if (w <= 0 || h <= 0)
  239. return 0;
  240. return_error(gs_error_Fatal);
  241. }
  242. private bool
  243. gx_dc_no_equal(const gx_device_color *pdevc1, const gx_device_color *pdevc2)
  244. {
  245. return false;
  246. }
  247. private int
  248. gx_dc_no_write(
  249. const gx_device_color * pdevc, /* ignored */
  250. const gx_device_color_saved * psdc, /* ignored */
  251. const gx_device * dev, /* ignored */
  252. byte * data, /* ignored */
  253. uint * psize )
  254. {
  255. *psize = 0;
  256. return psdc != 0 && psdc->type == pdevc->type ? 1 : 0;
  257. }
  258. private int
  259. gx_dc_no_read(
  260. gx_device_color * pdevc,
  261. const gs_imager_state * pis, /* ignored */
  262. const gx_device_color * prior_devc, /* ignored */
  263. const gx_device * dev, /* ignored */
  264. const byte * pdata, /* ignored */
  265. uint size, /* ignored */
  266. gs_memory_t * mem ) /* ignored */
  267. {
  268. pdevc->type = gx_dc_type_none;
  269. return 0;
  270. }
  271. private int
  272. gx_dc_no_get_nonzero_comps(
  273. const gx_device_color * pdevc_ignored,
  274. const gx_device * dev_ignored,
  275. gx_color_index * pcomp_bits_ignored )
  276. {
  277. return 0;
  278. }
  279. /* ------ Null color ------ */
  280. private int
  281. gx_dc_null_load(gx_device_color *pdevc, const gs_imager_state *ignore_pis,
  282. gx_device *ignore_dev, gs_color_select_t ignore_select)
  283. {
  284. return 0;
  285. }
  286. private int
  287. gx_dc_null_fill_rectangle(const gx_device_color * pdevc, int x, int y,
  288. int w, int h, gx_device * dev,
  289. gs_logical_operation_t lop,
  290. const gx_rop_source_t * source)
  291. {
  292. return 0;
  293. }
  294. private int
  295. gx_dc_null_fill_masked(const gx_device_color * pdevc, const byte * data,
  296. int data_x, int raster, gx_bitmap_id id,
  297. int x, int y, int w, int h, gx_device * dev,
  298. gs_logical_operation_t lop, bool invert)
  299. {
  300. return 0;
  301. }
  302. private bool
  303. gx_dc_null_equal(const gx_device_color * pdevc1, const gx_device_color * pdevc2)
  304. {
  305. return pdevc2->type == pdevc1->type;
  306. }
  307. private int
  308. gx_dc_null_read(
  309. gx_device_color * pdevc,
  310. const gs_imager_state * pis, /* ignored */
  311. const gx_device_color * prior_devc, /* ignored */
  312. const gx_device * dev, /* ignored */
  313. const byte * pdata, /* ignored */
  314. uint size, /* ignored */
  315. gs_memory_t * mem ) /* ignored */
  316. {
  317. pdevc->type = gx_dc_type_null;
  318. return 0;
  319. }
  320. /* ------ Pure color ------ */
  321. private void
  322. gx_dc_pure_save_dc(const gx_device_color * pdevc, gx_device_color_saved * psdc)
  323. {
  324. psdc->type = pdevc->type;
  325. psdc->colors.pure = pdevc->colors.pure;
  326. }
  327. private int
  328. gx_dc_pure_load(gx_device_color * pdevc, const gs_imager_state * ignore_pis,
  329. gx_device * ignore_dev, gs_color_select_t ignore_select)
  330. {
  331. return 0;
  332. }
  333. /* Fill a rectangle with a pure color. */
  334. /* Note that we treat this as "texture" for RasterOp. */
  335. private int
  336. gx_dc_pure_fill_rectangle(const gx_device_color * pdevc, int x, int y,
  337. int w, int h, gx_device * dev, gs_logical_operation_t lop,
  338. const gx_rop_source_t * source)
  339. {
  340. if (source == NULL && lop_no_S_is_T(lop))
  341. return (*dev_proc(dev, fill_rectangle)) (dev, x, y, w, h,
  342. pdevc->colors.pure);
  343. {
  344. gx_color_index colors[2];
  345. gx_rop_source_t no_source;
  346. colors[0] = colors[1] = pdevc->colors.pure;
  347. if (source == NULL)
  348. set_rop_no_source(source, no_source, dev);
  349. return (*dev_proc(dev, strip_copy_rop))
  350. (dev, source->sdata, source->sourcex, source->sraster,
  351. source->id, (source->use_scolors ? source->scolors : NULL),
  352. NULL /*arbitrary */ , colors, x, y, w, h, 0, 0, lop);
  353. }
  354. }
  355. /* Fill a mask with a pure color. */
  356. /* Note that there is no source in this case: the mask is the source. */
  357. private int
  358. gx_dc_pure_fill_masked(const gx_device_color * pdevc, const byte * data,
  359. int data_x, int raster, gx_bitmap_id id, int x, int y, int w, int h,
  360. gx_device * dev, gs_logical_operation_t lop, bool invert)
  361. {
  362. if (lop_no_S_is_T(lop)) {
  363. gx_color_index color0, color1;
  364. if (invert)
  365. color0 = pdevc->colors.pure, color1 = gx_no_color_index;
  366. else
  367. color1 = pdevc->colors.pure, color0 = gx_no_color_index;
  368. return (*dev_proc(dev, copy_mono))
  369. (dev, data, data_x, raster, id, x, y, w, h, color0, color1);
  370. } {
  371. gx_color_index scolors[2];
  372. gx_color_index tcolors[2];
  373. scolors[0] = gx_device_black(dev);
  374. scolors[1] = gx_device_white(dev);
  375. tcolors[0] = tcolors[1] = pdevc->colors.pure;
  376. return (*dev_proc(dev, strip_copy_rop))
  377. (dev, data, data_x, raster, id, scolors,
  378. NULL, tcolors, x, y, w, h, 0, 0,
  379. (invert ? rop3_invert_S(lop) : lop) | lop_S_transparent);
  380. }
  381. }
  382. private bool
  383. gx_dc_pure_equal(const gx_device_color * pdevc1, const gx_device_color * pdevc2)
  384. {
  385. return pdevc2->type == pdevc1->type &&
  386. gx_dc_pure_color(pdevc1) == gx_dc_pure_color(pdevc2);
  387. }
  388. /*
  389. * Serialize a pure color.
  390. *
  391. * Operands:
  392. *
  393. * pdevc pointer to device color to be serialized
  394. *
  395. * psdc pointer ot saved version of last serialized color (for
  396. * this band); this is ignored
  397. *
  398. * dev pointer to the current device, used to retrieve process
  399. * color model information
  400. *
  401. * pdata pointer to buffer in which to write the data
  402. *
  403. * psize pointer to a location that, on entry, contains the size of
  404. * the buffer pointed to by pdata; on return, the size of
  405. * the data required or actually used will be written here.
  406. *
  407. * Returns:
  408. *
  409. * 1, with *psize set to 0, if *pdevc and *psdc represent the same color
  410. *
  411. * 0, with *psize set to the amount of data written, if everything OK
  412. *
  413. * gs_error_rangecheck, with *psize set to the size of buffer required,
  414. * if *psize was not large enough
  415. *
  416. * < 0, != gs_error_rangecheck, in the event of some other error; in this
  417. * case *psize is not changed.
  418. */
  419. private int
  420. gx_dc_pure_write(
  421. const gx_device_color * pdevc,
  422. const gx_device_color_saved * psdc, /* ignored */
  423. const gx_device * dev,
  424. byte * pdata,
  425. uint * psize )
  426. {
  427. if ( psdc != 0 &&
  428. psdc->type == pdevc->type &&
  429. psdc->colors.pure == pdevc->colors.pure ) {
  430. *psize = 0;
  431. return 1;
  432. } else
  433. return gx_dc_write_color(pdevc->colors.pure, dev, pdata, psize);
  434. }
  435. /*
  436. * Reconstruct a pure device color from its serial representation.
  437. *
  438. * Operands:
  439. *
  440. * pdevc pointer to the location in which to write the
  441. * reconstructed device color
  442. *
  443. * pis pointer to the current imager state (ignored here)
  444. *
  445. * prior_devc pointer to the current device color (this is provided
  446. * separately because the device color is not part of the
  447. * imager state; it is ignored here)
  448. *
  449. * dev pointer to the current device, used to retrieve process
  450. * color model information
  451. *
  452. * pdata pointer to the buffer to be read
  453. *
  454. * size size of the buffer to be read; this should be large
  455. * enough to hold the entire color description
  456. *
  457. * mem pointer to the memory to be used for allocations
  458. * (ignored here)
  459. *
  460. * Returns:
  461. *
  462. * # of bytes read if everthing OK, < 0 in the event of an error
  463. */
  464. private int
  465. gx_dc_pure_read(
  466. gx_device_color * pdevc,
  467. const gs_imager_state * pis, /* ignored */
  468. const gx_device_color * prior_devc, /* ignored */
  469. const gx_device * dev,
  470. const byte * pdata,
  471. uint size,
  472. gs_memory_t * mem ) /* ignored */
  473. {
  474. pdevc->type = gx_dc_type_pure;
  475. return gx_dc_read_color(&pdevc->colors.pure, dev, pdata, size);
  476. }
  477. int
  478. gx_dc_pure_get_nonzero_comps(
  479. const gx_device_color * pdevc,
  480. const gx_device * dev,
  481. gx_color_index * pcomp_bits )
  482. {
  483. int code;
  484. gx_color_value cvals[GX_DEVICE_COLOR_MAX_COMPONENTS];
  485. code = dev_proc(dev, decode_color)( (gx_device *)dev,
  486. pdevc->colors.pure,
  487. cvals );
  488. if (code >= 0) {
  489. int i, ncomps = dev->color_info.num_components;
  490. gx_color_index mask = 0x1, comp_bits = 0;
  491. for (i = 0; i < ncomps; i++, mask <<= 1) {
  492. if (cvals[i] != 0)
  493. comp_bits |= mask;
  494. }
  495. *pcomp_bits = comp_bits;
  496. code = 0;
  497. }
  498. return code;
  499. }
  500. /* ------ Halftone color initialization ------ */
  501. void
  502. gx_complete_halftone(gx_device_color *pdevc, int num_comps, gx_device_halftone *pdht)
  503. {
  504. int i, mask = 0;
  505. pdevc->type = gx_dc_type_ht_colored;
  506. pdevc->colors.colored.c_ht = pdht;
  507. pdevc->colors.colored.num_components = num_comps;
  508. pdevc->colors.colored.alpha = max_ushort;
  509. for (i = 0; i < num_comps; i++)
  510. mask |= ((pdevc->colors.colored.c_level[i] != 0 ? 1 : 0) << i);
  511. pdevc->colors.colored.plane_mask = mask;
  512. }
  513. /* ------ Default implementations ------ */
  514. /* Fill a mask with a color by parsing the mask into rectangles. */
  515. int
  516. gx_dc_default_fill_masked(const gx_device_color * pdevc, const byte * data,
  517. int data_x, int raster, gx_bitmap_id id, int x, int y, int w, int h,
  518. gx_device * dev, gs_logical_operation_t lop, bool invert)
  519. {
  520. int lbit = data_x & 7;
  521. const byte *row = data + (data_x >> 3);
  522. uint one = (invert ? 0 : 0xff);
  523. uint zero = one ^ 0xff;
  524. int iy;
  525. for (iy = 0; iy < h; ++iy, row += raster) {
  526. const byte *p = row;
  527. int bit = lbit;
  528. int left = w;
  529. int l0;
  530. while (left) {
  531. int run, code;
  532. /* Skip a run of zeros. */
  533. run = byte_bit_run_length[bit][*p ^ one];
  534. if (run) {
  535. if (run < 8) {
  536. if (run >= left)
  537. break; /* end of row while skipping */
  538. bit += run, left -= run;
  539. } else if ((run -= 8) >= left)
  540. break; /* end of row while skipping */
  541. else {
  542. left -= run;
  543. ++p;
  544. while (left > 8 && *p == zero)
  545. left -= 8, ++p;
  546. run = byte_bit_run_length_0[*p ^ one];
  547. if (run >= left) /* run < 8 unless very last byte */
  548. break; /* end of row while skipping */
  549. else
  550. bit = run & 7, left -= run;
  551. }
  552. }
  553. l0 = left;
  554. /* Scan a run of ones, and then paint it. */
  555. run = byte_bit_run_length[bit][*p ^ zero];
  556. if (run < 8) {
  557. if (run >= left)
  558. left = 0;
  559. else
  560. bit += run, left -= run;
  561. } else if ((run -= 8) >= left)
  562. left = 0;
  563. else {
  564. left -= run;
  565. ++p;
  566. while (left > 8 && *p == one)
  567. left -= 8, ++p;
  568. run = byte_bit_run_length_0[*p ^ zero];
  569. if (run >= left) /* run < 8 unless very last byte */
  570. left = 0;
  571. else
  572. bit = run & 7, left -= run;
  573. }
  574. code = gx_device_color_fill_rectangle(pdevc,
  575. x + w - l0, y + iy, l0 - left, 1, dev, lop, NULL);
  576. if (code < 0)
  577. return code;
  578. }
  579. }
  580. return 0;
  581. }
  582. /* ------ Serialization identification support ------ */
  583. /*
  584. * Utility to write a color index. Currently, a very simple mechanism
  585. * is used, much simpler than that used by other command-list writers. This
  586. * should be sufficient for most situations.
  587. *
  588. * Operands:
  589. *
  590. * color color to be serialized.
  591. *
  592. * dev pointer to the current device, used to retrieve process
  593. * color model information
  594. *
  595. * pdata pointer to buffer in which to write the data
  596. *
  597. * psize pointer to a location that, on entry, contains the size of
  598. * the buffer pointed to by pdata; on return, the size of
  599. * the data required or actually used will be written here.
  600. *
  601. * Returns:
  602. *
  603. * 0, with *psize set to the amount of data written, if everything OK
  604. *
  605. * gs_error_rangecheck, with *psize set to the size of buffer required,
  606. * if *psize was not large enough
  607. *
  608. * < 0, != gs_error_rangecheck, in the event of some other error; in this
  609. * case *psize is not changed.
  610. */
  611. int
  612. gx_dc_write_color(
  613. gx_color_index color,
  614. const gx_device * dev,
  615. byte * pdata,
  616. uint * psize )
  617. {
  618. int depth = dev->color_info.depth;
  619. int num_bytes = (depth + 8) >> 3; /* NB: +8, not +7 */
  620. /* gx_no_color_index is encoded as a single byte */
  621. if (color == gx_no_color_index)
  622. num_bytes = 1;
  623. /* check for adequate space */
  624. if (*psize < num_bytes) {
  625. *psize = num_bytes;
  626. return gs_error_rangecheck;
  627. }
  628. *psize = num_bytes;
  629. /* gx_no_color_index is a single byte of 0xff */
  630. if (color == gx_no_color_index) {
  631. *psize = 1;
  632. *pdata = 0xff;
  633. } else {
  634. if (depth < 8 * arch_sizeof_color_index)
  635. color &= ((gx_color_index)1 << depth) - 1;
  636. while (--num_bytes >= 0) {
  637. pdata[num_bytes] = color & 0xff;
  638. color >>= 8;
  639. }
  640. }
  641. return 0;
  642. }
  643. /*
  644. * Utility to reconstruct device color from its serial representation.
  645. *
  646. * Operands:
  647. *
  648. * pcolor pointer to the location in which to write the
  649. * reconstucted color
  650. *
  651. * dev pointer to the current device, used to retrieve process
  652. * color model information
  653. *
  654. * pdata pointer to the buffer to be read
  655. *
  656. * size size of the buffer to be read; this is expected to be
  657. * large enough for the full color
  658. *
  659. * Returns: # of bytes read, or < 0 in the event of an error
  660. */
  661. int
  662. gx_dc_read_color(
  663. gx_color_index * pcolor,
  664. const gx_device * dev,
  665. const byte * pdata,
  666. int size )
  667. {
  668. gx_color_index color = 0;
  669. int depth = dev->color_info.depth;
  670. int i, num_bytes = (depth + 8) >> 3; /* NB: +8, not +7 */
  671. /* check that enough data has been provided */
  672. if (size < 1 || (pdata[0] != 0xff && size < num_bytes))
  673. return gs_error_rangecheck;
  674. /* check of gx_no_color_index */
  675. if (pdata[0] == 0xff) {
  676. *pcolor = gx_no_color_index;
  677. return 1;
  678. }
  679. /* num_bytes > arch_sizeof_color_index, discard first byte */
  680. for (i = (num_bytes >= arch_sizeof_color_index ? 1 : 0); i < num_bytes; i++)
  681. color = (color << 8) | pdata[i];
  682. *pcolor = color;
  683. return num_bytes;
  684. }