2 |
- |
1 |
/* Copyright (C) 2001 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: zicc.c,v 1.7 2004/08/04 19:36:13 stefan Exp $ */
|
|
|
18 |
/* ICCBased color operators */
|
|
|
19 |
|
|
|
20 |
#include "math_.h"
|
|
|
21 |
#include "memory_.h"
|
|
|
22 |
#include "ghost.h"
|
|
|
23 |
#include "oper.h"
|
|
|
24 |
#include "gsstruct.h"
|
|
|
25 |
#include "gxcspace.h" /* gscolor2.h requires gscspace.h */
|
|
|
26 |
#include "stream.h"
|
|
|
27 |
#include "files.h"
|
|
|
28 |
#include "gscolor2.h"
|
|
|
29 |
#include "gsicc.h"
|
|
|
30 |
#include "estack.h"
|
|
|
31 |
#include "idict.h"
|
|
|
32 |
#include "idparam.h"
|
|
|
33 |
#include "igstate.h"
|
|
|
34 |
#include "icie.h"
|
|
|
35 |
#include "ialloc.h"
|
|
|
36 |
|
|
|
37 |
/*
|
|
|
38 |
* <dict> .seticcspace -
|
|
|
39 |
*
|
|
|
40 |
* Create an ICCBased color space and set it to be the current color space.
|
|
|
41 |
*
|
|
|
42 |
* The PostScript structure of an ICCBased color space is that same as that
|
|
|
43 |
* for a CIEBased* color space:
|
|
|
44 |
*
|
|
|
45 |
* [ /ICCBased <dictionary> ]
|
|
|
46 |
*
|
|
|
47 |
* As is the for other .setcie*space operators, the operand dictionary rather
|
|
|
48 |
* than the complete color space array is on the stack when this operator
|
|
|
49 |
* is inovked.
|
|
|
50 |
*
|
|
|
51 |
* At the time this procedure is called, the alternative color space for
|
|
|
52 |
* the ICCBased color space is expected to be the current color space,
|
|
|
53 |
* whether that space was explicitly specified or implied by the number
|
|
|
54 |
* of components in the ICCBased color space dictionary. This is consistent
|
|
|
55 |
* with the handling of alternative spaces in Separation, DeviceN, and
|
|
|
56 |
* Indexed color spaces. Unlike the "zset*space" routines for those spaces,
|
|
|
57 |
* however, the current code does not attempt to build the color space
|
|
|
58 |
* "in place" in the graphic state.
|
|
|
59 |
*
|
|
|
60 |
* The procedure that invokes this operator will already have checked that
|
|
|
61 |
* the operand is a dictionary, is readable, and defines the key /N
|
|
|
62 |
* (number of components).
|
|
|
63 |
*/
|
|
|
64 |
private int
|
|
|
65 |
zseticcspace(i_ctx_t * i_ctx_p)
|
|
|
66 |
{
|
|
|
67 |
os_ptr op = osp;
|
|
|
68 |
int edepth = ref_stack_count(&e_stack);
|
|
|
69 |
int code;
|
|
|
70 |
gs_color_space * pcs;
|
|
|
71 |
const gs_color_space * palt_cs;
|
|
|
72 |
ref * pnval;
|
|
|
73 |
ref * pstrmval;
|
|
|
74 |
stream * s;
|
|
|
75 |
int i, ncomps;
|
|
|
76 |
gs_cie_icc * picc_info;
|
|
|
77 |
float range_buff[8];
|
|
|
78 |
static const float dflt_range[8] = { 0, 1, 0, 1, 0, 1, 0, 1 };
|
|
|
79 |
|
|
|
80 |
dict_find_string(op, "N", &pnval);
|
|
|
81 |
ncomps = pnval->value.intval;
|
|
|
82 |
|
|
|
83 |
/* verify the DataSource entry */
|
|
|
84 |
if (dict_find_string(op, "DataSource", &pstrmval) <= 0)
|
|
|
85 |
return_error(e_undefined);
|
|
|
86 |
check_read_file(s, pstrmval);
|
|
|
87 |
|
|
|
88 |
/*
|
|
|
89 |
* Verify that the current color space can be a alternative color space.
|
|
|
90 |
* The check for ICCBased color space is a hack to avoid introducing yet
|
|
|
91 |
* another category indicator into the gs_color_space_type structur.
|
|
|
92 |
*/
|
|
|
93 |
palt_cs = gs_currentcolorspace(igs);
|
|
|
94 |
if ( !palt_cs->type->can_be_alt_space ||
|
|
|
95 |
gs_color_space_get_index(palt_cs) == gs_color_space_index_CIEICC )
|
|
|
96 |
return_error(e_rangecheck);
|
|
|
97 |
|
|
|
98 |
/*
|
|
|
99 |
* Fetch and verify the Range array.
|
|
|
100 |
*
|
|
|
101 |
* The PDF documentation is unclear as to the purpose of this array.
|
|
|
102 |
* Essentially all that is stated is that "These values must match the
|
|
|
103 |
* information in the ICC profile" (PDF Reference, 2nd ed., p. 174).
|
|
|
104 |
* If that is the case, why not use the information in the profile?
|
|
|
105 |
* The only reason we can think of is range specification is intended
|
|
|
106 |
* to be used to limit the range of values passed to the alternate
|
|
|
107 |
* color space (the range may be smaller than the native range of values
|
|
|
108 |
* provided by that color space).
|
|
|
109 |
*
|
|
|
110 |
* Because the icclib code will perform normalization based on color
|
|
|
111 |
* space, we use the range values only to restrict the set of input
|
|
|
112 |
* values; they are not used for normalization.
|
|
|
113 |
*/
|
|
|
114 |
code = dict_floats_param( imemory,
|
|
|
115 |
op,
|
|
|
116 |
"Range",
|
|
|
117 |
2 * ncomps,
|
|
|
118 |
range_buff,
|
|
|
119 |
dflt_range );
|
|
|
120 |
for (i = 0; i < 2 * ncomps && range_buff[i + 1] >= range_buff[i]; i += 2)
|
|
|
121 |
;
|
|
|
122 |
if (i != 2 * ncomps)
|
|
|
123 |
return_error(e_rangecheck);
|
|
|
124 |
|
|
|
125 |
/* build the color space object */
|
|
|
126 |
code = gs_cspace_build_CIEICC(&pcs, NULL, gs_state_memory(igs));
|
|
|
127 |
if (code < 0)
|
|
|
128 |
return code;
|
|
|
129 |
picc_info = pcs->params.icc.picc_info;
|
|
|
130 |
picc_info->num_components = ncomps;
|
|
|
131 |
picc_info->instrp = s;
|
|
|
132 |
picc_info->file_id = (s->read_id | s->write_id);
|
|
|
133 |
for (i = 0; i < ncomps; i++) {
|
|
|
134 |
picc_info->Range.ranges[i].rmin = range_buff[2 * i];
|
|
|
135 |
picc_info->Range.ranges[i].rmax = range_buff[2 * i + 1];
|
|
|
136 |
|
|
|
137 |
}
|
|
|
138 |
|
|
|
139 |
/* record the current space as the alternative color space */
|
|
|
140 |
memmove( &pcs->params.icc.alt_space,
|
|
|
141 |
palt_cs,
|
|
|
142 |
sizeof(pcs->params.icc.alt_space) );
|
|
|
143 |
/*
|
|
|
144 |
* Increment reference counts for current cspace since it is the
|
|
|
145 |
* alternate color space for the ICC space.
|
|
|
146 |
*/
|
|
|
147 |
gx_increment_cspace_count(palt_cs);
|
|
|
148 |
|
|
|
149 |
code = gx_load_icc_profile(picc_info);
|
|
|
150 |
if (code < 0)
|
|
|
151 |
return code;
|
|
|
152 |
|
|
|
153 |
code = cie_cache_joint(i_ctx_p, &istate->colorrendering.procs,
|
|
|
154 |
(gs_cie_common *)picc_info, igs);
|
|
|
155 |
if (code < 0)
|
|
|
156 |
return code;
|
|
|
157 |
|
|
|
158 |
return cie_set_finish( i_ctx_p,
|
|
|
159 |
pcs,
|
|
|
160 |
&istate->colorspace.procs.cie,
|
|
|
161 |
edepth,
|
|
|
162 |
code );
|
|
|
163 |
}
|
|
|
164 |
|
|
|
165 |
|
|
|
166 |
const op_def zicc_ll3_op_defs[] = {
|
|
|
167 |
op_def_begin_ll3(),
|
|
|
168 |
{ "1.seticcspace", zseticcspace },
|
|
|
169 |
op_def_end(0)
|
|
|
170 |
};
|