123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- /* Copyright (C) 1989, 2000 Aladdin Enterprises. All rights reserved.
-
- This file is part of AFPL Ghostscript.
-
- AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author or
- distributor accepts any responsibility for the consequences of using it, or
- for whether it serves any particular purpose or works at all, unless he or
- she says so in writing. Refer to the Aladdin Free Public License (the
- "License") for full details.
-
- Every copy of AFPL Ghostscript must include a copy of the License, normally
- in a plain ASCII text file named PUBLIC. The License grants you the right
- to copy, modify and redistribute AFPL Ghostscript, but only under certain
- conditions described in the License. Among other things, the License
- requires that the copyright notice and this notice be preserved on all
- copies.
- */
- /*$Id: gzht.h,v 1.4 2000/10/22 03:15:26 lpd Exp $ */
- /* Internal procedures for halftones */
- /* Requires gxdevice.h, gxdcolor.h */
- #ifndef gzht_INCLUDED
- # define gzht_INCLUDED
- #include "gscsel.h"
- #include "gxht.h"
- #include "gxfmap.h"
- #include "gxdht.h"
- #include "gxhttile.h"
- /* Sort a sampled halftone order by sample value. */
- void gx_sort_ht_order(P2(gx_ht_bit *, uint));
- /* (Internal) procedures for constructing halftone orders. */
- int gx_ht_alloc_ht_order(P8(gx_ht_order * porder, uint width, uint height,
- uint num_levels, uint num_bits, uint strip_shift,
- const gx_ht_order_procs_t *procs,
- gs_memory_t * mem));
- int gx_ht_alloc_order(P6(gx_ht_order * porder, uint width, uint height,
- uint strip_shift, uint num_levels, gs_memory_t *mem));
- int gx_ht_alloc_threshold_order(P5(gx_ht_order * porder, uint width,
- uint height, uint num_levels,
- gs_memory_t * mem));
- int gx_ht_alloc_client_order(P6(gx_ht_order * porder, uint width, uint height,
- uint num_levels, uint num_bits, gs_memory_t * mem));
- void gx_ht_construct_spot_order(P1(gx_ht_order *));
- int gx_ht_construct_threshold_order(P2(gx_ht_order *, const byte *));
- void gx_ht_construct_bit(P3(gx_ht_bit * bit, int width, int bit_num));
- void gx_ht_construct_bits(P1(gx_ht_order *));
- /* Halftone enumeration structure */
- struct gs_screen_enum_s {
- gs_halftone halftone; /* supplied by client */
- gx_ht_order order;
- gs_matrix mat; /* for mapping device x,y to rotated cell */
- gs_matrix mat_inv; /* the inversion of mat */
- int x, y;
- int strip, shift;
- gs_state *pgs;
- };
- #define private_st_gs_screen_enum() /* in gshtscr.c */\
- gs_private_st_composite(st_gs_screen_enum, gs_screen_enum,\
- "gs_screen_enum", screen_enum_enum_ptrs, screen_enum_reloc_ptrs)
- /* order.levels, order.bits, pgs) */
- /* Prepare a device halftone for installation, but don't install it. */
- int gs_sethalftone_prepare(P3(gs_state *, gs_halftone *,
- gx_device_halftone *));
- /* Allocate and initialize a spot screen. */
- /* This is the first half of gs_screen_init_accurate/memory. */
- int gs_screen_order_alloc(P2(gx_ht_order *, gs_memory_t *));
- int gs_screen_order_init_memory(P5(gx_ht_order *, const gs_state *,
- gs_screen_halftone *, bool, gs_memory_t *));
- #define gs_screen_order_init(porder, pgs, phsp, accurate)\
- gs_screen_order_init_memory(porder, pgs, phsp, accurate, pgs->memory)
- /* Prepare to sample a spot screen. */
- /* This is the second half of gs_screen_init_accurate/memory. */
- int gs_screen_enum_init_memory(P5(gs_screen_enum *, const gx_ht_order *,
- gs_state *, const gs_screen_halftone *,
- gs_memory_t *));
- #define gs_screen_enum_init(penum, porder, pgs, phsp)\
- gs_screen_enum_init_memory(penum, porder, pgs, phsp, pgs->memory)
- /* Process an entire screen plane. */
- int gx_ht_process_screen_memory(P5(gs_screen_enum * penum, gs_state * pgs,
- gs_screen_halftone * phsp, bool accurate,
- gs_memory_t * mem));
- #define gx_ht_process_screen(penum, pgs, phsp, accurate)\
- gx_ht_process_screen_memory(penum, pgs, phsp, accurate, pgs->memory)
- /*
- * We don't want to remember all the values of the halftone screen,
- * because they would take up space proportional to P^3, where P is
- * the number of pixels in a cell. Instead, we pick some number N of
- * patterns to cache. Each cache slot covers a range of (P+1)/N
- * different gray levels: we "slide" the contents of the slot back and
- * forth within this range by incrementally adding and dropping 1-bits.
- * N>=0 (obviously); N<=P+1 (likewise); also, so that we can simplify things
- * by preallocating the bookkeeping information for the cache, we define
- * a constant max_cached_tiles which is an a priori maximum value for N.
- *
- * Note that the raster for each tile must be a multiple of bitmap_align_mod,
- * to satisfy the copy_mono device routine, even though a multiple of
- * sizeof(ht_mask_t) would otherwise be sufficient.
- */
- struct gx_ht_cache_s {
- /* The following are set when the cache is created. */
- byte *bits; /* the base of the bits */
- uint bits_size; /* the space available for bits */
- gx_ht_tile *ht_tiles; /* the base of the tiles */
- uint num_tiles; /* the number of tiles allocated */
- /* The following are reset each time the cache is initialized */
- /* for a new screen. */
- gx_ht_order order; /* the cached order vector */
- int num_cached; /* actual # of cached tiles */
- int levels_per_tile; /* # of levels per cached tile */
- int tiles_fit; /* -1 if not determined, 0 if no fit, */
- /* 1 if fit */
- gx_bitmap_id base_id; /* the base id, to which */
- /* we add the halftone level */
- gx_ht_tile *(*render_ht)(P2(gx_ht_cache *, int)); /* rendering procedure */
- };
- /* We don't mark from the tiles pointer, and we relocate the tiles en masse. */
- #define private_st_ht_tiles() /* in gxht.c */\
- gs_private_st_composite(st_ht_tiles, gx_ht_tile, "ht tiles",\
- ht_tiles_enum_ptrs, ht_tiles_reloc_ptrs)
- #define private_st_ht_cache() /* in gxht.c */\
- gs_private_st_ptrs_add2(st_ht_cache, gx_ht_cache, "ht cache",\
- ht_cache_enum_ptrs, ht_cache_reloc_ptrs,\
- st_ht_order, order, bits, ht_tiles)
- /* Compute a fractional color for dithering, the correctly rounded */
- /* quotient f * max_gx_color_value / maxv. */
- #define frac_color_(f, maxv)\
- (gx_color_value)(((f) * (0xffffL * 2) + maxv) / (maxv * 2))
- extern const gx_color_value *const fc_color_quo[8];
- #define fractional_color(f, maxv)\
- ((maxv) <= 7 ? fc_color_quo[maxv][f] : frac_color_(f, maxv))
- /* ------ Halftone cache procedures ------ */
- /* Allocate/free a halftone cache. */
- uint gx_ht_cache_default_tiles(P0());
- uint gx_ht_cache_default_bits(P0());
- gx_ht_cache *gx_ht_alloc_cache(P3(gs_memory_t *, uint, uint));
- void gx_ht_free_cache(P2(gs_memory_t *, gx_ht_cache *));
- /* Clear a halftone cache. */
- #define gx_ht_clear_cache(pcache)\
- ((pcache)->order.levels = 0, (pcache)->order.bit_data = 0,\
- (pcache)->ht_tiles[0].tiles.data = 0)
- /* Initialize a halftone cache with a given order. */
- void gx_ht_init_cache(P2(gx_ht_cache *, const gx_ht_order *));
- /* Make the cache order current, and return whether */
- /* there is room for all possible tiles in the cache. */
- bool gx_check_tile_cache(P1(const gs_imager_state *));
- /* Determine whether a given (width, y, height) might fit into a */
- /* single tile. If so, return the byte offset of the appropriate row */
- /* from the beginning of the tile, and set *ppx to the x phase offset */
- /* within the tile; if not, return -1. */
- int gx_check_tile_size(P6(const gs_imager_state * pis, int w, int y, int h,
- gs_color_select_t select, int *ppx));
- /* Make a given level current in a halftone cache. */
- #define gx_render_ht(pcache, b_level)\
- ((pcache)->render_ht(pcache, b_level))
- /* ------ Device halftone management ------ */
- /* Release a gx_ht_order by freeing its components. */
- /* (Don't free the gx_device_halftone itself.) */
- void gx_ht_order_release(P3(gx_ht_order * porder, gs_memory_t * mem, bool free_cache));
- /*
- * Install a device halftone in an imager state. Note that this does not
- * read or update the client halftone. There is a special check for pdht ==
- * pis->dev_ht, for the benefit of the band rendering code.
- */
- int gx_imager_dev_ht_install(P4(gs_imager_state * pis,
- const gx_device_halftone * pdht,
- gs_halftone_type type,
- const gx_device * dev));
- /*
- * Install a new halftone in the graphics state. Note that we copy the top
- * level of the gs_halftone and the gx_device_halftone, and take ownership
- * of any substructures.
- */
- int gx_ht_install(P3(gs_state *, const gs_halftone *,
- const gx_device_halftone *));
- /* Reestablish the effective transfer functions, taking into account */
- /* any overrides from halftone dictionaries. */
- /* Some compilers object to names longer than 31 characters.... */
- void gx_imager_set_effective_xfer(P1(gs_imager_state * pis));
- void gx_set_effective_transfer(P1(gs_state * pgs));
- #endif /* gzht_INCLUDED */
|