Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
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
};