1 /* Copyright (C) 1989, 1992, 1993, 1994, 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: gscolor1.c,v 1.11 2004/08/04 19:36:12 stefan Exp $ */
18 /* Level 1 extended color operators for Ghostscript library */
19 #include "gx.h"
20 #include "gserrors.h"
21 #include "gsstruct.h"
22 #include "gsutil.h" /* for gs_next_ids */
23 #include "gsccolor.h"
24 #include "gxcspace.h"
25 #include "gxdcconv.h"
26 #include "gxdevice.h" /* for gx_color_index */
27 #include "gxcmap.h"
28 #include "gzstate.h"
29 #include "gscolor1.h"
30 #include "gscolor2.h"
31 #include "gxhttype.h"
32 #include "gzht.h"
33
34 /* Imports from gscolor.c */
35 void load_transfer_map(gs_state *, gx_transfer_map *, floatp);
36
37 /* Imported from gsht.c */
38 void gx_set_effective_transfer(gs_state *);
39
40 /* Force a parameter into the range [0.0..1.0]. */
41 #define FORCE_UNIT(p) (p < 0.0 ? 0.0 : p > 1.0 ? 1.0 : p)
42
43 /* setcmykcolor */
44 int
gs_setcmykcolor(gs_state * pgs,floatp c,floatp m,floatp y,floatp k)45 gs_setcmykcolor(gs_state * pgs, floatp c, floatp m, floatp y, floatp k)
46 {
47 gs_color_space cs;
48 int code;
49
50 gs_cspace_init_DeviceCMYK(pgs->memory, &cs);
51 if ((code = gs_setcolorspace(pgs, &cs)) >= 0) {
52 gs_client_color * pcc = pgs->ccolor;
53
54 cs_adjust_color_count(pgs, -1); /* not strictly necessary */
55 pcc->paint.values[0] = FORCE_UNIT(c);
56 pcc->paint.values[1] = FORCE_UNIT(m);
57 pcc->paint.values[2] = FORCE_UNIT(y);
58 pcc->paint.values[3] = FORCE_UNIT(k);
59 pcc->pattern = 0; /* for GC */
60 gx_unset_dev_color(pgs);
61 }
62 return code;
63 }
64
65
66 /* setblackgeneration */
67 /* Remap=0 is used by the interpreter. */
68 int
gs_setblackgeneration(gs_state * pgs,gs_mapping_proc proc)69 gs_setblackgeneration(gs_state * pgs, gs_mapping_proc proc)
70 {
71 return gs_setblackgeneration_remap(pgs, proc, true);
72 }
73 int
gs_setblackgeneration_remap(gs_state * pgs,gs_mapping_proc proc,bool remap)74 gs_setblackgeneration_remap(gs_state * pgs, gs_mapping_proc proc, bool remap)
75 {
76 rc_unshare_struct(pgs->black_generation, gx_transfer_map,
77 &st_transfer_map, pgs->memory,
78 return_error(gs_error_VMerror),
79 "gs_setblackgeneration");
80 pgs->black_generation->proc = proc;
81 pgs->black_generation->id = gs_next_ids(pgs->memory, 1);
82 if (remap) {
83 load_transfer_map(pgs, pgs->black_generation, 0.0);
84 gx_unset_dev_color(pgs);
85 }
86 return 0;
87 }
88
89 /* currentblackgeneration */
90 gs_mapping_proc
gs_currentblackgeneration(const gs_state * pgs)91 gs_currentblackgeneration(const gs_state * pgs)
92 {
93 return pgs->black_generation->proc;
94 }
95
96 /* setundercolorremoval */
97 /* Remap=0 is used by the interpreter. */
98 int
gs_setundercolorremoval(gs_state * pgs,gs_mapping_proc proc)99 gs_setundercolorremoval(gs_state * pgs, gs_mapping_proc proc)
100 {
101 return gs_setundercolorremoval_remap(pgs, proc, true);
102 }
103 int
gs_setundercolorremoval_remap(gs_state * pgs,gs_mapping_proc proc,bool remap)104 gs_setundercolorremoval_remap(gs_state * pgs, gs_mapping_proc proc, bool remap)
105 {
106 rc_unshare_struct(pgs->undercolor_removal, gx_transfer_map,
107 &st_transfer_map, pgs->memory,
108 return_error(gs_error_VMerror),
109 "gs_setundercolorremoval");
110 pgs->undercolor_removal->proc = proc;
111 pgs->undercolor_removal->id = gs_next_ids(pgs->memory, 1);
112 if (remap) {
113 load_transfer_map(pgs, pgs->undercolor_removal, -1.0);
114 gx_unset_dev_color(pgs);
115 }
116 return 0;
117 }
118
119 /* currentundercolorremoval */
120 gs_mapping_proc
gs_currentundercolorremoval(const gs_state * pgs)121 gs_currentundercolorremoval(const gs_state * pgs)
122 {
123 return pgs->undercolor_removal->proc;
124 }
125
126 /* setcolortransfer */
127 /* Remap=0 is used by the interpreter. */
128 int
gs_setcolortransfer_remap(gs_state * pgs,gs_mapping_proc red_proc,gs_mapping_proc green_proc,gs_mapping_proc blue_proc,gs_mapping_proc gray_proc,bool remap)129 gs_setcolortransfer_remap(gs_state * pgs, gs_mapping_proc red_proc,
130 gs_mapping_proc green_proc,
131 gs_mapping_proc blue_proc,
132 gs_mapping_proc gray_proc, bool remap)
133 {
134 gx_transfer *ptran = &pgs->set_transfer;
135 gx_transfer old;
136 gs_id new_ids = gs_next_ids(pgs->memory, 4);
137 gx_device * dev = pgs->device;
138
139 old = *ptran;
140 rc_unshare_struct(ptran->gray, gx_transfer_map, &st_transfer_map,
141 pgs->memory, goto fgray, "gs_setcolortransfer");
142 rc_unshare_struct(ptran->red, gx_transfer_map, &st_transfer_map,
143 pgs->memory, goto fred, "gs_setcolortransfer");
144 rc_unshare_struct(ptran->green, gx_transfer_map, &st_transfer_map,
145 pgs->memory, goto fgreen, "gs_setcolortransfer");
146 rc_unshare_struct(ptran->blue, gx_transfer_map, &st_transfer_map,
147 pgs->memory, goto fblue, "gs_setcolortransfer");
148 ptran->gray->proc = gray_proc;
149 ptran->gray->id = new_ids;
150 ptran->red->proc = red_proc;
151 ptran->red->id = new_ids + 1;
152 ptran->green->proc = green_proc;
153 ptran->green->id = new_ids + 2;
154 ptran->blue->proc = blue_proc;
155 ptran->blue->id = new_ids + 3;
156 ptran->red_component_num =
157 gs_color_name_component_number(dev, "Red", 3, ht_type_colorscreen);
158 ptran->green_component_num =
159 gs_color_name_component_number(dev, "Green", 5, ht_type_colorscreen);
160 ptran->blue_component_num =
161 gs_color_name_component_number(dev, "Blue", 4, ht_type_colorscreen);
162 ptran->gray_component_num =
163 gs_color_name_component_number(dev, "Gray", 4, ht_type_colorscreen);
164 if (remap) {
165 load_transfer_map(pgs, ptran->red, 0.0);
166 load_transfer_map(pgs, ptran->green, 0.0);
167 load_transfer_map(pgs, ptran->blue, 0.0);
168 load_transfer_map(pgs, ptran->gray, 0.0);
169 gx_set_effective_transfer(pgs);
170 gx_unset_dev_color(pgs);
171 } else
172 gx_set_effective_transfer(pgs);
173 return 0;
174 fblue:
175 rc_assign(ptran->green, old.green, "setcolortransfer");
176 fgreen:
177 rc_assign(ptran->red, old.red, "setcolortransfer");
178 fred:
179 rc_assign(ptran->gray, old.gray, "setcolortransfer");
180 fgray:
181 return_error(gs_error_VMerror);
182 }
183 int
gs_setcolortransfer(gs_state * pgs,gs_mapping_proc red_proc,gs_mapping_proc green_proc,gs_mapping_proc blue_proc,gs_mapping_proc gray_proc)184 gs_setcolortransfer(gs_state * pgs, gs_mapping_proc red_proc,
185 gs_mapping_proc green_proc, gs_mapping_proc blue_proc,
186 gs_mapping_proc gray_proc)
187 {
188 return gs_setcolortransfer_remap(pgs, red_proc, green_proc,
189 blue_proc, gray_proc, true);
190 }
191
192 /* currentcolortransfer */
193 void
gs_currentcolortransfer(const gs_state * pgs,gs_mapping_proc procs[4])194 gs_currentcolortransfer(const gs_state * pgs, gs_mapping_proc procs[4])
195 {
196 const gx_transfer *ptran = &pgs->set_transfer;
197
198 procs[0] = ptran->red->proc;
199 procs[1] = ptran->green->proc;
200 procs[2] = ptran->blue->proc;
201 procs[3] = ptran->gray->proc;
202 }
203