xref: /plan9/sys/src/cmd/gs/src/gxht.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises.  All rights reserved.
2 
3   This software is provided AS-IS with no warranty, either express or
4   implied.
5 
6   This software is distributed under license and may not be copied,
7   modified or distributed except as expressly authorized under the terms
8   of the license contained in the file LICENSE in this distribution.
9 
10   For more information about licensing, please refer to
11   http://www.ghostscript.com/licensing/. For information on
12   commercial licensing, go to http://www.artifex.com/licensing/ or
13   contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14   San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15 */
16 
17 /*$Id: gxht.c,v 1.17 2005/05/23 22:33:22 dan Exp $ */
18 /* Halftone rendering for imaging library */
19 #include "memory_.h"
20 #include "gx.h"
21 #include "gserrors.h"
22 #include "gsstruct.h"
23 #include "gsbitops.h"
24 #include "gsutil.h"		/* for gs_next_ids */
25 #include "gxdcolor.h"
26 #include "gxfixed.h"
27 #include "gxdevice.h"		/* for gzht.h */
28 #include "gxistate.h"
29 #include "gzht.h"
30 #include "gsserial.h"
31 
32 /* Define the sizes of the halftone cache. */
33 #define max_cached_tiles_HUGE 5000	/* not used */
34 #define max_ht_bits_HUGE 1000000	/* not used */
35 #define max_cached_tiles_LARGE 577
36 #define max_ht_bits_LARGE 100000
37 #define max_cached_tiles_SMALL 25
38 #define max_ht_bits_SMALL 1000
39 
40 /* Define the binary halftone device color type. */
41 /* The type descriptor must be public for Pattern types. */
42 gs_public_st_composite(st_dc_ht_binary, gx_device_color, "dc_ht_binary",
43 		       dc_ht_binary_enum_ptrs, dc_ht_binary_reloc_ptrs);
44 private dev_color_proc_save_dc(gx_dc_ht_binary_save_dc);
45 private dev_color_proc_get_dev_halftone(gx_dc_ht_binary_get_dev_halftone);
46 private dev_color_proc_load(gx_dc_ht_binary_load);
47 private dev_color_proc_fill_rectangle(gx_dc_ht_binary_fill_rectangle);
48 private dev_color_proc_fill_masked(gx_dc_ht_binary_fill_masked);
49 private dev_color_proc_equal(gx_dc_ht_binary_equal);
50 private dev_color_proc_write(gx_dc_ht_binary_write);
51 private dev_color_proc_read(gx_dc_ht_binary_read);
52 const gx_device_color_type_t
53       gx_dc_type_data_ht_binary =
54 {&st_dc_ht_binary,
55  gx_dc_ht_binary_save_dc, gx_dc_ht_binary_get_dev_halftone,
56  gx_dc_ht_get_phase,
57  gx_dc_ht_binary_load, gx_dc_ht_binary_fill_rectangle,
58  gx_dc_ht_binary_fill_masked, gx_dc_ht_binary_equal,
59  gx_dc_ht_binary_write, gx_dc_ht_binary_read,
60  gx_dc_ht_binary_get_nonzero_comps
61 };
62 
63 #undef gx_dc_type_ht_binary
64 const gx_device_color_type_t *const gx_dc_type_ht_binary =
65 &gx_dc_type_data_ht_binary;
66 
67 #define gx_dc_type_ht_binary (&gx_dc_type_data_ht_binary)
68 /* GC procedures */
69 private
70 ENUM_PTRS_WITH(dc_ht_binary_enum_ptrs, gx_device_color *cptr) return 0;
71 ENUM_PTR(0, gx_device_color, colors.binary.b_ht);
72 case 1:
73 {
74     gx_ht_tile *tile = cptr->colors.binary.b_tile;
75 
76     ENUM_RETURN(tile ? tile - tile->index : 0);
77 }
78 ENUM_PTRS_END
RELOC_PTRS_WITH(dc_ht_binary_reloc_ptrs,gx_device_color * cptr)79 private RELOC_PTRS_WITH(dc_ht_binary_reloc_ptrs, gx_device_color *cptr)
80 {
81     gx_ht_tile *tile = cptr->colors.binary.b_tile;
82     uint index = tile ? tile->index : 0;
83 
84     RELOC_PTR(gx_device_color, colors.binary.b_ht);
85     RELOC_TYPED_OFFSET_PTR(gx_device_color, colors.binary.b_tile, index);
86 }
87 RELOC_PTRS_END
88 #undef cptr
89 
90 /* Other GC procedures */
91 private_st_ht_tiles();
92 private
ENUM_PTRS_BEGIN_PROC(ht_tiles_enum_ptrs)93 ENUM_PTRS_BEGIN_PROC(ht_tiles_enum_ptrs)
94 {
95     return 0;
96 }
97 ENUM_PTRS_END_PROC
RELOC_PTRS_BEGIN(ht_tiles_reloc_ptrs)98 private RELOC_PTRS_BEGIN(ht_tiles_reloc_ptrs)
99 {
100     /* Reset the bitmap pointers in the tiles. */
101     /* We know the first tile points to the base of the bits. */
102     gx_ht_tile *ht_tiles = vptr;
103     byte *bits = ht_tiles->tiles.data;
104     uint diff;
105 
106     if (bits == 0)
107 	return;
108     RELOC_VAR(bits);
109     if (size == size_of(gx_ht_tile)) {	/* only 1 tile */
110 	ht_tiles->tiles.data = bits;
111 	return;
112     }
113     diff = ht_tiles[1].tiles.data - ht_tiles[0].tiles.data;
114     for (; size; ht_tiles++, size -= size_of(gx_ht_tile), bits += diff) {
115 	ht_tiles->tiles.data = bits;
116     }
117 }
118 RELOC_PTRS_END
119 private_st_ht_cache();
120 
121 /* Return the default sizes of the halftone cache. */
122 uint
gx_ht_cache_default_tiles(void)123 gx_ht_cache_default_tiles(void)
124 {
125 #if arch_small_memory
126     return max_cached_tiles_SMALL;
127 #else
128     return (gs_debug_c('.') ? max_cached_tiles_SMALL :
129 	    max_cached_tiles_LARGE);
130 #endif
131 }
132 uint
gx_ht_cache_default_bits(void)133 gx_ht_cache_default_bits(void)
134 {
135 #if arch_small_memory
136     return max_ht_bits_SMALL;
137 #else
138     return (gs_debug_c('.') ? max_ht_bits_SMALL :
139 	    max_ht_bits_LARGE);
140 #endif
141 }
142 
143 /* Allocate a halftone cache. */
144 gx_ht_cache *
gx_ht_alloc_cache(gs_memory_t * mem,uint max_tiles,uint max_bits)145 gx_ht_alloc_cache(gs_memory_t * mem, uint max_tiles, uint max_bits)
146 {
147     gx_ht_cache *pcache =
148     gs_alloc_struct(mem, gx_ht_cache, &st_ht_cache,
149 		    "alloc_ht_cache(struct)");
150     byte *tbits =
151 	gs_alloc_bytes(mem, max_bits, "alloc_ht_cache(bits)");
152     gx_ht_tile *ht_tiles =
153 	gs_alloc_struct_array(mem, max_tiles, gx_ht_tile, &st_ht_tiles,
154 			      "alloc_ht_cache(ht_tiles)");
155 
156     if (pcache == 0 || tbits == 0 || ht_tiles == 0) {
157 	gs_free_object(mem, ht_tiles, "alloc_ht_cache(ht_tiles)");
158 	gs_free_object(mem, tbits, "alloc_ht_cache(bits)");
159 	gs_free_object(mem, pcache, "alloc_ht_cache(struct)");
160 	return 0;
161     }
162     pcache->bits = tbits;
163     pcache->bits_size = max_bits;
164     pcache->ht_tiles = ht_tiles;
165     pcache->num_tiles = max_tiles;
166     pcache->order.cache = pcache;
167     pcache->order.transfer = 0;
168     gx_ht_clear_cache(pcache);
169     return pcache;
170 }
171 
172 /* Free a halftone cache. */
173 void
gx_ht_free_cache(gs_memory_t * mem,gx_ht_cache * pcache)174 gx_ht_free_cache(gs_memory_t * mem, gx_ht_cache * pcache)
175 {
176     gs_free_object(mem, pcache->ht_tiles, "free_ht_cache(ht_tiles)");
177     gs_free_object(mem, pcache->bits, "free_ht_cache(bits)");
178     gs_free_object(mem, pcache, "free_ht_cache(struct)");
179 }
180 
181 /* Check whether the tile cache corresponds to the current order */
182 bool
gx_check_tile_cache_current(const gs_imager_state * pis)183 gx_check_tile_cache_current(const gs_imager_state * pis)
184 {
185     /* TO_DO_DEVICEN - this routine is no longer used - delete. */
186     return false;
187 }
188 
189 /* Make the cache order current, and return whether */
190 /* there is room for all possible tiles in the cache. */
191 bool
gx_check_tile_cache(const gs_imager_state * pis)192 gx_check_tile_cache(const gs_imager_state * pis)
193 {
194     /* TO_DO_DEVICEN - this routine is no longer used - delete. */
195     return false;
196 }
197 
198 /*
199  * Determine whether a given (width, y, height) might fit into a single
200  * (non-strip) tile. If so, return the byte offset of the appropriate row
201  * from the beginning of the tile, and set *ppx to the x phase offset
202  * within the tile; if not, return -1.
203  *
204  * This routine cannot be supported in the DeviceN code.
205  */
206 int
gx_check_tile_size(const gs_imager_state * pis,int w,int y,int h,gs_color_select_t select,int * ppx)207 gx_check_tile_size(const gs_imager_state * pis, int w, int y, int h,
208 		   gs_color_select_t select, int *ppx)
209 {
210     /* TO_DO_DEVICEN - this routine is no longer used - delete. */
211     return -1;
212 }
213 
214 /* Render a given level into a halftone cache. */
215 private int render_ht(gx_ht_tile *, int, const gx_ht_order *,
216 		      gx_bitmap_id);
217 private gx_ht_tile *
gx_render_ht_default(gx_ht_cache * pcache,int b_level)218 gx_render_ht_default(gx_ht_cache * pcache, int b_level)
219 {
220     const gx_ht_order *porder = &pcache->order;
221     int level = porder->levels[b_level];
222     gx_ht_tile *bt = &pcache->ht_tiles[level / pcache->levels_per_tile];
223 
224     if (bt->level != level) {
225 	int code = render_ht(bt, level, porder, pcache->base_id + b_level);
226 
227 	if (code < 0)
228 	    return 0;
229     }
230     return bt;
231 }
232 /* Faster code if num_tiles == 1. */
233 private gx_ht_tile *
gx_render_ht_1_tile(gx_ht_cache * pcache,int b_level)234 gx_render_ht_1_tile(gx_ht_cache * pcache, int b_level)
235 {
236     const gx_ht_order *porder = &pcache->order;
237     int level = porder->levels[b_level];
238     gx_ht_tile *bt = &pcache->ht_tiles[0];
239 
240     if (bt->level != level) {
241 	int code = render_ht(bt, level, porder, pcache->base_id + b_level);
242 
243 	if (code < 0)
244 	    return 0;
245     }
246     return bt;
247 }
248 /* Faster code if levels_per_tile == 1. */
249 private gx_ht_tile *
gx_render_ht_1_level(gx_ht_cache * pcache,int b_level)250 gx_render_ht_1_level(gx_ht_cache * pcache, int b_level)
251 {
252     const gx_ht_order *porder = &pcache->order;
253     int level = porder->levels[b_level];
254     gx_ht_tile *bt = &pcache->ht_tiles[level];
255 
256     if (bt->level != level) {
257 	int code = render_ht(bt, level, porder, pcache->base_id + b_level);
258 
259 	if (code < 0)
260 	    return 0;
261     }
262     return bt;
263 }
264 
265 /* save information about the operand binary halftone color */
266 private void
gx_dc_ht_binary_save_dc(const gx_device_color * pdevc,gx_device_color_saved * psdc)267 gx_dc_ht_binary_save_dc(const gx_device_color * pdevc,
268                         gx_device_color_saved * psdc)
269 {
270     psdc->type = pdevc->type;
271     psdc->colors.binary.b_color[0] = pdevc->colors.binary.color[0];
272     psdc->colors.binary.b_color[1] = pdevc->colors.binary.color[1];
273     psdc->colors.binary.b_level = pdevc->colors.binary.b_level;
274     psdc->colors.binary.b_index = pdevc->colors.binary.b_index;
275     psdc->phase = pdevc->phase;
276 }
277 
278 /* get the halftone used for a binary halftone color */
279 private const gx_device_halftone *
gx_dc_ht_binary_get_dev_halftone(const gx_device_color * pdevc)280 gx_dc_ht_binary_get_dev_halftone(const gx_device_color * pdevc)
281 {
282     return pdevc->colors.binary.b_ht;
283 }
284 
285 /* Load the device color into the halftone cache if needed. */
286 private int
gx_dc_ht_binary_load(gx_device_color * pdevc,const gs_imager_state * pis,gx_device * dev,gs_color_select_t select)287 gx_dc_ht_binary_load(gx_device_color * pdevc, const gs_imager_state * pis,
288 		     gx_device * dev, gs_color_select_t select)
289 {
290     int component_index = pdevc->colors.binary.b_index;
291     const gx_ht_order *porder =
292 	(component_index < 0 ?
293 	 &pdevc->colors.binary.b_ht->order :
294 	 &pdevc->colors.binary.b_ht->components[component_index].corder);
295     gx_ht_cache *pcache = porder->cache;
296 
297     if (pcache->order.bit_data != porder->bit_data)
298 	gx_ht_init_cache(pis->memory, pcache, porder);
299     /*
300      * We do not load the cache now.  Instead we wait until we are ready
301      * to actually render the color.  This allows multiple colors to be
302      * loaded without cache conflicts.  (Cache conflicts can occur when
303      * if two device colors use the same cache elements.  This can occur
304      * when the tile size is large enough that we do not have a separate
305      * tile for each half tone level.)  See gx_dc_ht_binary_load_cache.
306      */
307     pdevc->colors.binary.b_tile = NULL;
308     return 0;
309 }
310 
311 /*
312  * Load the half tone tile in the halftone cache.
313  */
314 private int
gx_dc_ht_binary_load_cache(const gx_device_color * pdevc)315 gx_dc_ht_binary_load_cache(const gx_device_color * pdevc)
316 {
317     int component_index = pdevc->colors.binary.b_index;
318     const gx_ht_order *porder =
319 	 &pdevc->colors.binary.b_ht->components[component_index].corder;
320     gx_ht_cache *pcache = porder->cache;
321     int b_level = pdevc->colors.binary.b_level;
322     int level = porder->levels[b_level];
323     gx_ht_tile *bt = &pcache->ht_tiles[level / pcache->levels_per_tile];
324 
325     if (bt->level != level) {
326 	int code = render_ht(bt, level, porder, pcache->base_id + b_level);
327 
328 	if (code < 0)
329 	    return_error(gs_error_Fatal);
330     }
331     ((gx_device_color *)pdevc)->colors.binary.b_tile = bt;
332     return 0;
333 }
334 
335 /* Fill a rectangle with a binary halftone. */
336 /* Note that we treat this as "texture" for RasterOp. */
337 private int
gx_dc_ht_binary_fill_rectangle(const gx_device_color * pdevc,int x,int y,int w,int h,gx_device * dev,gs_logical_operation_t lop,const gx_rop_source_t * source)338 gx_dc_ht_binary_fill_rectangle(const gx_device_color * pdevc, int x, int y,
339 		  int w, int h, gx_device * dev, gs_logical_operation_t lop,
340 			       const gx_rop_source_t * source)
341 {
342     gx_rop_source_t no_source;
343 
344     /* Load the halftone cache for the color */
345     gx_dc_ht_binary_load_cache(pdevc);
346     /*
347      * Observation of H-P devices and documentation yields confusing
348      * evidence about whether white pixels in halftones are always
349      * opaque.  It appears that for black-and-white devices, these
350      * pixels are *not* opaque.
351      */
352     if (dev->color_info.depth > 1)
353 	lop &= ~lop_T_transparent;
354     if (source == NULL && lop_no_S_is_T(lop))
355 	return (*dev_proc(dev, strip_tile_rectangle)) (dev,
356 					&pdevc->colors.binary.b_tile->tiles,
357 				  x, y, w, h, pdevc->colors.binary.color[0],
358 					      pdevc->colors.binary.color[1],
359 					    pdevc->phase.x, pdevc->phase.y);
360     /* Adjust the logical operation per transparent colors. */
361     if (pdevc->colors.binary.color[0] == gx_no_color_index)
362 	lop = rop3_use_D_when_T_0(lop);
363     if (pdevc->colors.binary.color[1] == gx_no_color_index)
364 	lop = rop3_use_D_when_T_1(lop);
365     if (source == NULL)
366 	set_rop_no_source(source, no_source, dev);
367     return (*dev_proc(dev, strip_copy_rop)) (dev, source->sdata,
368 			       source->sourcex, source->sraster, source->id,
369 			     (source->use_scolors ? source->scolors : NULL),
370 					&pdevc->colors.binary.b_tile->tiles,
371 					     pdevc->colors.binary.color,
372 				 x, y, w, h, pdevc->phase.x, pdevc->phase.y,
373 					     lop);
374 }
375 
376 private int
gx_dc_ht_binary_fill_masked(const gx_device_color * pdevc,const byte * data,int data_x,int raster,gx_bitmap_id id,int x,int y,int w,int h,gx_device * dev,gs_logical_operation_t lop,bool invert)377 gx_dc_ht_binary_fill_masked(const gx_device_color * pdevc, const byte * data,
378 	int data_x, int raster, gx_bitmap_id id, int x, int y, int w, int h,
379 		   gx_device * dev, gs_logical_operation_t lop, bool invert)
380 {
381     /*
382      * Load the halftone cache for the color.  We do not do it earlier
383      * because for small halftone caches, each cache tile may be used for
384      * for more than one halftone level.  This can cause conflicts if more
385      * than one device color has been set and they use the same cache
386      * entry.
387      */
388     int code = gx_dc_ht_binary_load_cache(pdevc);
389 
390     if (code < 0)
391 	return code;
392     return gx_dc_default_fill_masked(pdevc, data, data_x, raster, id,
393 		    			x, y, w, h, dev, lop, invert);
394 }
395 
396 /* Compare two binary halftones for equality. */
397 private bool
gx_dc_ht_binary_equal(const gx_device_color * pdevc1,const gx_device_color * pdevc2)398 gx_dc_ht_binary_equal(const gx_device_color * pdevc1,
399 		      const gx_device_color * pdevc2)
400 {
401     return pdevc2->type == pdevc1->type &&
402 	pdevc1->phase.x == pdevc2->phase.x &&
403 	pdevc1->phase.y == pdevc2->phase.y &&
404 	gx_dc_binary_color0(pdevc1) == gx_dc_binary_color0(pdevc2) &&
405 	gx_dc_binary_color1(pdevc1) == gx_dc_binary_color1(pdevc2) &&
406 	pdevc1->colors.binary.b_level == pdevc2->colors.binary.b_level;
407 }
408 
409 
410 /*
411  * Flags to indicate the pieces of a binary halftone that are included
412  * in its string representation. The first byte of the string holds this
413  * set of flags.
414  *
415  * The binary halftone tile is never transmitted as part of the string
416  * representation, so there is also no flag bit for it.
417  */
418 private const int   dc_ht_binary_has_color0 = 0x01;
419 private const int   dc_ht_binary_has_color1 = 0x02;
420 private const int   dc_ht_binary_has_level = 0x04;
421 private const int   dc_ht_binary_has_index = 0x08;
422 
423 
424 /*
425  * Serialize a binany halftone device color.
426  *
427  * Operands:
428  *
429  *  pdevc       pointer to device color to be serialized
430  *
431  *  psdc        pointer ot saved version of last serialized color (for
432  *              this band)
433  *
434  *  dev         pointer to the current device, used to retrieve process
435  *              color model information
436  *
437  *  pdata       pointer to buffer in which to write the data
438  *
439  *  psize       pointer to a location that, on entry, contains the size of
440  *              the buffer pointed to by pdata; on return, the size of
441  *              the data required or actually used will be written here.
442  *
443  * Returns:
444  *  1, with *psize set to 0, if *psdc and *pdevc represent the same color
445  *
446  *  0, with *psize set to the amount of data written, if everything OK
447  *
448  *  gs_error_rangecheck, with *psize set to the size of buffer required,
449  *  if *psize was not large enough
450  *
451  *  < 0, != gs_error_rangecheck, in the event of some other error; in this
452  *  case *psize is not changed.
453  */
454 private int
gx_dc_ht_binary_write(const gx_device_color * pdevc,const gx_device_color_saved * psdc0,const gx_device * dev,byte * pdata,uint * psize)455 gx_dc_ht_binary_write(
456     const gx_device_color *         pdevc,
457     const gx_device_color_saved *   psdc0,
458     const gx_device *               dev,
459     byte *                          pdata,
460     uint *                          psize )
461 {
462     int                             req_size = 1;   /* flag bits */
463     int                             flag_bits = 0;
464     uint                            tmp_size;
465     byte *                          pdata0 = pdata;
466     const gx_device_color_saved *   psdc = psdc0;
467     int                             code;
468 
469     /* check if operand and saved colors are the same type */
470     if (psdc != 0 && psdc->type != pdevc->type)
471         psdc = 0;
472 
473     /* check for the information that must be transmitted */
474     if ( psdc == 0                                                      ||
475          pdevc->colors.binary.color[0] != psdc->colors.binary.b_color[0]  ) {
476         flag_bits |= dc_ht_binary_has_color0;
477         tmp_size = 0;
478         (void)gx_dc_write_color( pdevc->colors.binary.color[0],
479                                  dev,
480                                  pdata,
481                                  &tmp_size );
482         req_size += tmp_size;
483     }
484     if ( psdc == 0                                                      ||
485          pdevc->colors.binary.color[1] != psdc->colors.binary.b_color[1]  ) {
486         flag_bits |= dc_ht_binary_has_color1;
487         tmp_size = 0;
488         (void)gx_dc_write_color( pdevc->colors.binary.color[1],
489                                  dev,
490                                  pdata,
491                                  &tmp_size );
492         req_size += tmp_size;
493     }
494 
495     if ( psdc == 0                                                  ||
496          pdevc->colors.binary.b_level != psdc->colors.binary.b_level  ) {
497         flag_bits |= dc_ht_binary_has_level;
498         req_size += enc_u_sizew(pdevc->colors.binary.b_level);
499     }
500 
501     if ( psdc == 0                                                  ||
502          pdevc->colors.binary.b_index != psdc->colors.binary.b_index  ) {
503         flag_bits |= dc_ht_binary_has_index;
504         req_size += 1;
505     }
506 
507     /* check if there is anything to be done */
508     if (flag_bits == 0) {
509         *psize = 0;
510         return 1;
511     }
512 
513     /* check if sufficient space has been provided */
514     if (req_size > *psize) {
515         *psize = req_size;
516         return gs_error_rangecheck;
517     }
518 
519     /* write out the flag byte */
520     *pdata++ = (byte)flag_bits;
521 
522     /* write out such other parts of the device color as are required */
523     if ((flag_bits & dc_ht_binary_has_color0) != 0) {
524         tmp_size = req_size - (pdata - pdata0);
525         code = gx_dc_write_color( pdevc->colors.binary.color[0],
526                                   dev,
527                                   pdata,
528                                   &tmp_size );
529         if (code < 0)
530             return code;
531         pdata += tmp_size;
532     }
533     if ((flag_bits & dc_ht_binary_has_color1) != 0) {
534         tmp_size = req_size - (pdata - pdata0);
535         code = gx_dc_write_color( pdevc->colors.binary.color[1],
536                                   dev,
537                                   pdata,
538                                   &tmp_size );
539         if (code < 0)
540             return code;
541         pdata += tmp_size;
542     }
543     if ((flag_bits & dc_ht_binary_has_level) != 0)
544         enc_u_putw(pdevc->colors.binary.b_level, pdata);
545     if ((flag_bits & dc_ht_binary_has_index) != 0)
546         *pdata++ = pdevc->colors.binary.b_index;
547 
548     *psize = pdata - pdata0;
549     return 0;
550 }
551 
552 /*
553  * Reconstruct a binary halftone device color from its serial representation.
554  *
555  * Operands:
556  *
557  *  pdevc       pointer to the location in which to write the
558  *              reconstructed device color
559  *
560  *  pis         pointer to the current imager state (to access the
561  *              current halftone)
562  *
563  *  prior_devc  pointer to the current device color (this is provided
564  *              separately because the device color is not part of the
565  *              imager state)
566  *
567  *  dev         pointer to the current device, used to retrieve process
568  *              color model information
569  *
570  *  pdata       pointer to the buffer to be read
571  *
572  *  size        size of the buffer to be read; this should be large
573  *              enough to hold the entire color description
574  *
575  *  mem         pointer to the memory to be used for allocations
576  *              (ignored here)
577  *
578  * Returns:
579  *
580  *  # of bytes read if everthing OK, < 0 in the event of an error
581  */
582 private int
gx_dc_ht_binary_read(gx_device_color * pdevc,const gs_imager_state * pis,const gx_device_color * prior_devc,const gx_device * dev,const byte * pdata,uint size,gs_memory_t * mem)583 gx_dc_ht_binary_read(
584     gx_device_color *       pdevc,
585     const gs_imager_state * pis,
586     const gx_device_color * prior_devc,
587     const gx_device *       dev,        /* ignored */
588     const byte *            pdata,
589     uint                    size,
590     gs_memory_t *           mem )       /* ignored */
591 {
592     gx_device_color         devc;
593     const byte *            pdata0 = pdata;
594     int                     code, flag_bits;
595 
596     /* if prior information is available, use it */
597     if (prior_devc != 0 && prior_devc->type == gx_dc_type_ht_binary)
598         devc = *prior_devc;
599     else
600         memset(&devc, 0, sizeof(devc));   /* clear pointers */
601     devc.type = gx_dc_type_ht_binary;
602 
603     /* the halftone is always taken from the imager state */
604     devc.colors.binary.b_ht = pis->dev_ht;
605 
606     /* cache is not porvided until the device color is used */
607     devc.colors.binary.b_tile = 0;
608 
609     /* verify the minimum amount of information */
610     if (size == 0)
611         return_error(gs_error_rangecheck);
612     size --;
613     flag_bits = *pdata++;
614 
615     /* read the other information provided */
616     if ((flag_bits & dc_ht_binary_has_color0) != 0) {
617         code = gx_dc_read_color( &devc.colors.binary.color[0],
618                                  dev,
619                                  pdata,
620                                  size );
621         if (code < 0)
622             return code;
623         size -= code;
624         pdata += code;
625     }
626     if ((flag_bits & dc_ht_binary_has_color1) != 0) {
627         code = gx_dc_read_color( &devc.colors.binary.color[1],
628                                  dev,
629                                  pdata,
630                                  size );
631         if (code < 0)
632             return code;
633         size -= code;
634         pdata += code;
635     }
636     if ((flag_bits & dc_ht_binary_has_level) != 0) {
637         const byte *    pdata_start = pdata;
638 
639         if (size < 1)
640             return_error(gs_error_rangecheck);
641         enc_u_getw(devc.colors.binary.b_level, pdata);
642         size -= pdata - pdata_start;
643     }
644     if ((flag_bits & dc_ht_binary_has_index) != 0) {
645         if (size == 0)
646             return_error(gs_error_rangecheck);
647 	--size;
648         devc.colors.binary.b_index = *pdata++;
649     }
650 
651     /* set the phase as required (select value is arbitrary) */
652     /* set the phase as required (select value is arbitrary) */
653     color_set_phase_mod( &devc,
654                          pis->screen_phase[0].x,
655                          pis->screen_phase[0].y,
656                          pis->dev_ht->lcm_width,
657                          pis->dev_ht->lcm_height );
658 
659     /* everything looks good */
660     *pdevc = devc;
661     return pdata - pdata0;
662 }
663 
664 
665 /*
666  * Get the nonzero components of a binary halftone. This is used to
667  * distinguish components that are given zero intensity due to halftoning
668  * from those for which the original color intensity was in fact zero.
669  *
670  * Since this device color type involves only a single halftone component,
671  * we can reasonably assume that b_level != 0. Hence, we need to check
672  * for components with identical intensities in color[0] and color[1].
673  */
674 int
gx_dc_ht_binary_get_nonzero_comps(const gx_device_color * pdevc,const gx_device * dev,gx_color_index * pcomp_bits)675 gx_dc_ht_binary_get_nonzero_comps(
676     const gx_device_color * pdevc,
677     const gx_device *       dev,
678     gx_color_index *        pcomp_bits )
679 {
680     int                     code;
681     gx_color_value          cvals_0[GX_DEVICE_COLOR_MAX_COMPONENTS],
682                             cvals_1[GX_DEVICE_COLOR_MAX_COMPONENTS];
683 
684     if ( (code = dev_proc(dev, decode_color)( (gx_device *)dev,
685                                               pdevc->colors.binary.color[0],
686                                               cvals_0 )) >= 0 &&
687          (code = dev_proc(dev, decode_color)( (gx_device *)dev,
688                                               pdevc->colors.binary.color[1],
689                                               cvals_1 )) >= 0   ) {
690         int     i, ncomps = dev->color_info.num_components;
691         int     mask = 0x1, comp_bits = 0;
692 
693         for (i = 0; i < ncomps; i++, mask <<= 1) {
694             if (cvals_0[i] != 0 || cvals_1[i] != 0)
695                 comp_bits |= mask;
696         }
697         *pcomp_bits = comp_bits;
698         code = 0;
699     }
700 
701     return code;
702 }
703 
704 
705 /* Initialize the tile cache for a given screen. */
706 /* Cache as many different levels as will fit. */
707 void
gx_ht_init_cache(const gs_memory_t * mem,gx_ht_cache * pcache,const gx_ht_order * porder)708 gx_ht_init_cache(const gs_memory_t *mem, gx_ht_cache * pcache, const gx_ht_order * porder)
709 {
710     uint width = porder->width;
711     uint height = porder->height;
712     uint size = width * height + 1;
713     int width_unit =
714     (width <= ht_mask_bits / 2 ? ht_mask_bits / width * width :
715      width);
716     int height_unit = height;
717     uint raster = porder->raster;
718     uint tile_bytes = raster * height;
719     uint shift = porder->shift;
720     int num_cached;
721     int i;
722     byte *tbits = pcache->bits;
723 
724     /* Non-monotonic halftones may have more bits than size. */
725     if (porder->num_bits >= size)
726 	size = porder->num_bits + 1;
727     /* Make sure num_cached is within bounds */
728     num_cached = pcache->bits_size / tile_bytes;
729     if (num_cached > size)
730 	num_cached = size;
731     if (num_cached > pcache->num_tiles)
732 	num_cached = pcache->num_tiles;
733     if (num_cached == size &&
734 	tile_bytes * num_cached <= pcache->bits_size / 2
735 	) {
736 	/*
737 	 * We can afford to replicate every tile in the cache,
738 	 * which will reduce breakage when tiling.  Since
739 	 * horizontal breakage is more expensive than vertical,
740 	 * and since wide shallow fills are more common than
741 	 * narrow deep fills, we replicate the tile horizontally.
742 	 * We do have to be careful not to replicate the tile
743 	 * to an absurdly large size, however.
744 	 */
745 	uint rep_raster =
746 	((pcache->bits_size / num_cached) / height) &
747 	~(align_bitmap_mod - 1);
748 	uint rep_count = rep_raster * 8 / width;
749 
750 	/*
751 	 * There's no real value in replicating the tile
752 	 * beyond the point where the byte width of the replicated
753 	 * tile is a multiple of a long.
754 	 */
755 	if (rep_count > sizeof(ulong) * 8)
756 	    rep_count = sizeof(ulong) * 8;
757 	width_unit = width * rep_count;
758 	raster = bitmap_raster(width_unit);
759 	tile_bytes = raster * height;
760     }
761     pcache->base_id = gs_next_ids(mem, porder->num_levels + 1);
762     pcache->order = *porder;
763     /* The transfer function is irrelevant, and might become dangling. */
764     pcache->order.transfer = 0;
765     pcache->num_cached = num_cached;
766     pcache->levels_per_tile = (size + num_cached - 1) / num_cached;
767     pcache->tiles_fit = -1;
768     memset(tbits, 0, pcache->bits_size);
769     for (i = 0; i < num_cached; i++, tbits += tile_bytes) {
770 	register gx_ht_tile *bt = &pcache->ht_tiles[i];
771 
772 	bt->level = 0;
773 	bt->index = i;
774 	bt->tiles.data = tbits;
775 	bt->tiles.raster = raster;
776 	bt->tiles.size.x = width_unit;
777 	bt->tiles.size.y = height_unit;
778 	bt->tiles.rep_width = width;
779 	bt->tiles.rep_height = height;
780 	bt->tiles.shift = bt->tiles.rep_shift = shift;
781     }
782     pcache->render_ht =
783 	(pcache->num_tiles == 1 ? gx_render_ht_1_tile :
784 	 pcache->levels_per_tile == 1 ? gx_render_ht_1_level :
785 	 gx_render_ht_default);
786 }
787 
788 /*
789  * Compute and save the rendering of a given gray level
790  * with the current halftone.  The cache holds multiple tiles,
791  * where each tile covers a range of possible levels.
792  * We adjust the tile whose range includes the desired level incrementally;
793  * this saves a lot of time for the average image, where gray levels
794  * don't change abruptly.  Note that the "level" is the number of bits,
795  * not the index in the levels vector.
796  */
797 private int
render_ht(gx_ht_tile * pbt,int level,const gx_ht_order * porder,gx_bitmap_id new_id)798 render_ht(gx_ht_tile * pbt, int level /* [1..num_bits-1] */ ,
799 	  const gx_ht_order * porder, gx_bitmap_id new_id)
800 {
801     byte *data = pbt->tiles.data;
802     int code;
803 
804     if_debug7('H', "[H]Halftone cache slot 0x%lx: old=%d, new=%d, w=%d(%d), h=%d(%d):\n",
805 	      (ulong) data, pbt->level, level,
806 	      pbt->tiles.size.x, porder->width,
807 	      pbt->tiles.size.y, porder->num_bits / porder->width);
808 #ifdef DEBUG
809     if (level < 0 || level > porder->num_bits) {
810 	lprintf3("Error in render_ht: level=%d, old level=%d, num_bits=%d\n",
811 		 level, pbt->level, porder->num_bits);
812 	return_error(gs_error_Fatal);
813     }
814 #endif
815     code = porder->procs->render(pbt, level, porder);
816     if (code < 0)
817 	return code;
818     pbt->level = level;
819     pbt->tiles.id = new_id;
820     /*
821      * Check whether we want to replicate the tile in the cache.
822      * Since we only do this when all the renderings will fit
823      * in the cache, we only do it once per level, and it doesn't
824      * have to be very efficient.
825      */
826 	/****** TEST IS WRONG if width > rep_width but tile.raster ==
827 	 ****** order raster.
828 	 ******/
829     if (pbt->tiles.raster > porder->raster)
830 	bits_replicate_horizontally(data, pbt->tiles.rep_width,
831 				    pbt->tiles.rep_height, porder->raster,
832 				    pbt->tiles.size.x, pbt->tiles.raster);
833     if (pbt->tiles.size.y > pbt->tiles.rep_height &&
834 	pbt->tiles.shift == 0
835 	)
836 	bits_replicate_vertically(data, pbt->tiles.rep_height,
837 				  pbt->tiles.raster, pbt->tiles.size.y);
838 #ifdef DEBUG
839     if (gs_debug_c('H')) {
840 	const byte *p = pbt->tiles.data;
841 	int wb = pbt->tiles.raster;
842 	const byte *ptr = p + wb * pbt->tiles.size.y;
843 
844 	while (p < ptr) {
845 	    dprintf8(" %d%d%d%d%d%d%d%d",
846 		     *p >> 7, (*p >> 6) & 1, (*p >> 5) & 1,
847 		     (*p >> 4) & 1, (*p >> 3) & 1, (*p >> 2) & 1,
848 		     (*p >> 1) & 1, *p & 1);
849 	    if ((++p - data) % wb == 0)
850 		dputc('\n');
851 	}
852     }
853 #endif
854     return 0;
855 }
856