1 /* Copyright (C) 2001-2019 Artifex Software, Inc.
2 All Rights Reserved.
3
4 This software is provided AS-IS with no warranty, either express or
5 implied.
6
7 This software is distributed under license and may not be copied,
8 modified or distributed except as expressly authorized under the terms
9 of the license contained in the file LICENSE in this distribution.
10
11 Refer to licensing information at http://www.artifex.com or contact
12 Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato,
13 CA 94945, U.S.A., +1(415)492-9861, for further information.
14 */
15
16
17 /* Color space substitution "operators" */
18 #include "gx.h"
19 #include "gserrors.h"
20 #include "gscssub.h"
21 #include "gxcspace.h" /* for st_color_space */
22 #include "gxdevcli.h"
23 #include "gzstate.h"
24
25 /* .setsubstitutecolorspace */
26 /* Note that, to support PDF, ICCBased color spaces may be used to substitute
27 * for the Device* color spaces (previously, only CIEBased color spaces could
28 * be used for this purpose). */
29 int
gs_setsubstitutecolorspace(gs_gstate * pgs,gs_color_space_index csi,const gs_color_space * pcs)30 gs_setsubstitutecolorspace(gs_gstate *pgs, gs_color_space_index csi,
31 const gs_color_space *pcs)
32 {
33 int index = (int)csi;
34 static const uint masks[3] = {
35 (1 << gs_color_space_index_DeviceGray) |
36 (1 << gs_color_space_index_CIEA),
37 (1 << gs_color_space_index_DeviceRGB) |
38 (1 << gs_color_space_index_CIEABC) |
39 (1 << gs_color_space_index_CIEDEF),
40 (1 << gs_color_space_index_DeviceCMYK) |
41 (1 << gs_color_space_index_CIEDEFG)
42 };
43 const gs_color_space *pcs_old;
44
45 if (index < 0 || index > 2)
46 return_error(gs_error_rangecheck);
47 if (pcs) {
48 if (gs_color_space_get_index(pcs) == gs_color_space_index_CIEICC) {
49 static const byte dev_ncomps[3] = {1, 3, 4};
50
51 if (dev_ncomps[index] != cs_num_components(pcs))
52 return_error(gs_error_rangecheck);
53 } else if (!masks[index] && (1 << gs_color_space_get_index(pcs)))
54 return_error(gs_error_rangecheck);
55 }
56 pcs_old = pgs->device_color_spaces.indexed[index];
57 if (pcs_old == 0 && (pcs == 0 || gs_color_space_get_index(pcs) == csi))
58 return 0;
59 rc_assign(pgs->device_color_space.indexed[index],
60 (pcs ? pcs :
61 pgs->shared->device_color_spaces.indexed[index]),
62 "gs_setsubstitutecolorspace");
63 return 0;
64 }
65
66 /* Possibly-substituted color space accessors. */
67 const gs_color_space *
gs_current_DeviceGray_space(const gs_gstate * pgs)68 gs_current_DeviceGray_space(const gs_gstate *pgs)
69 {
70 const gs_color_space *pcs;
71
72 return (!pgs->device->UseCIEColor ||
73 (pcs = pgs->device_color_spaces.named.Gray) == 0 ?
74 pgs->shared->device_color_spaces.named.Gray : pcs);
75 }
76 const gs_color_space *
gs_current_DeviceRGB_space(const gs_gstate * pgs)77 gs_current_DeviceRGB_space(const gs_gstate *pgs)
78 {
79 const gs_color_space *pcs;
80
81 return (!pgs->device->UseCIEColor ||
82 (pcs = pgs->device_color_spaces.named.RGB) == 0 ?
83 pgs->shared->device_color_spaces.named.RGB : pcs);
84 }
85 const gs_color_space *
gs_current_DeviceCMYK_space(const gs_gstate * pgs)86 gs_current_DeviceCMYK_space(const gs_gstate *pgs)
87 {
88 const gs_color_space *pcs;
89
90 return (!pgs->device->UseCIEColor ||
91 (pcs = pgs->device_color_spaces.named.CMYK) == 0 ?
92 pgs->shared->device_color_spaces.named.CMYK : pcs);
93 }
94
95 /* .currentsubstitutecolorspace */
96 const gs_color_space *
gs_currentsubstitutecolorspace(const gs_gstate * pgs,gs_color_space_index csi)97 gs_currentsubstitutecolorspace(const gs_gstate *pgs, gs_color_space_index csi)
98 {
99 switch (csi) {
100 case gs_color_space_index_DeviceGray:
101 return gs_current_DeviceGray_space(pgs);
102 case gs_color_space_index_DeviceRGB:
103 return gs_current_DeviceRGB_space(pgs);
104 case gs_color_space_index_DeviceCMYK:
105 return gs_current_DeviceCMYK_space(pgs);
106 default:
107 return 0;
108 }
109 }
110