xref: /plan9/sys/src/cmd/gs/src/gxfmap.h (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 1992, 1995, 1996, 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: gxfmap.h,v 1.6 2002/06/16 08:45:43 lpd Exp $ */
18 /* Fraction map representation for Ghostscript */
19 
20 #ifndef gxfmap_INCLUDED
21 #  define gxfmap_INCLUDED
22 
23 #include "gsrefct.h"
24 #include "gsstype.h"
25 #include "gxfrac.h"
26 #include "gxtmap.h"
27 
28 /*
29  * Define a cached map from fracs to fracs.  Level 1 uses this only
30  * for the transfer function; level 2 also uses it for black generation
31  * and undercolor removal.  Note that reference counting macros must
32  * be used to allocate, free, and assign references to gx_transfer_maps.
33  *
34  * NOTE: proc and closure are redundant.  Eventually closure will replace
35  * proc.  For now, things are in an uneasy intermediate state where
36  * proc = 0 means use closure.
37  */
38 /* log2... must not be greater than frac_bits, and must be least 8. */
39 #define log2_transfer_map_size 8
40 #define transfer_map_size (1 << log2_transfer_map_size)
41 /*typedef struct gx_transfer_map_s gx_transfer_map; *//* in gxtmap.h */
42 struct gx_transfer_map_s {
43     rc_header rc;
44     gs_mapping_proc proc;	/* typedef is in gxtmap.h */
45     gs_mapping_closure_t closure;	/* SEE ABOVE */
46     /* The id changes whenever the map or function changes. */
47     gs_id id;
48     frac values[transfer_map_size];
49 };
50 
51 extern_st(st_transfer_map);
52 #define public_st_transfer_map() /* in gscolor.c */\
53   gs_public_st_composite(st_transfer_map, gx_transfer_map, "gx_transfer_map",\
54     transfer_map_enum_ptrs, transfer_map_reloc_ptrs)
55 
56 /* Set a transfer map to the identity map. */
57 void gx_set_identity_transfer(gx_transfer_map *);
58 
59 /*
60  * Map a color fraction through a transfer map.  If the map is small,
61  * we interpolate; if it is large, we don't, and save a lot of time.
62  */
63 #define FRAC_MAP_INTERPOLATE (log2_transfer_map_size <= 8)
64 #if FRAC_MAP_INTERPOLATE
65 
66 frac gx_color_frac_map(frac, const frac *);		/* in gxcmap.c */
67 
68 #  define gx_map_color_frac(pgs,cf,m)\
69      (pgs->m->proc == gs_identity_transfer ? cf :\
70       gx_color_frac_map(cf, &pgs->m->values[0]))
71 
72 #else /* !FRAC_MAP_INTERPOLATE */
73 
74 /* Do the lookup in-line. */
75 #  define gx_map_color_frac(pgs,cf,m)\
76      (pgs->m->values[frac2bits(cf, log2_transfer_map_size)])
77 
78 #endif /* (!)FRAC_MAP_INTERPOLATE */
79 
80 /* Map a color fraction expressed as a byte through a transfer map. */
81 /* (We don't use this anywhere right now.) */
82 /****************
83 #if log2_transfer_map_size <= 8
84 #  define byte_to_tmx(b) ((b) >> (8 - log2_transfer_map_size))
85 #else
86 #  define byte_to_tmx(b)\
87 	(((b) << (log2_transfer_map_size - 8)) +\
88 	 ((b) >> (16 - log2_transfer_map_size)))
89 #endif
90 #define gx_map_color_frac_byte(pgs,b,m)\
91  (pgs->m->values[byte_to_tmx(b)])
92  ****************/
93 
94 /* Map a floating point value through a transfer map. */
95 #define gx_map_color_float(pmap,v)\
96   ((pmap)->values[(int)((v) * transfer_map_size + 0.5)] / frac_1_float)
97 
98 /* Define a mapping procedure that just looks up the value in the cache. */
99 /* (It is equivalent to gx_map_color_float with the arguments swapped.) */
100 float gs_mapped_transfer(floatp, const gx_transfer_map *);
101 
102 /* Define an identity mapping procedure. */
103 /* Don't store this directly in proc/closure.proc: */
104 /* use gx_set_identity_transfer. */
105 float gs_identity_transfer(floatp, const gx_transfer_map *);
106 
107 #endif /* gxfmap_INCLUDED */
108