1 /* Copyright (C) 2001-2006 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, modified
8    or distributed except as expressly authorized under the terms of that
9    license.  Refer to licensing information at http://www.artifex.com/
10    or contact Artifex Software, Inc.,  7 Mt. Lassen Drive - Suite A-134,
11    San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
12 */
13 
14 /* $Id: gscpixel.c 8250 2007-09-25 13:31:24Z giles $ */
15 /* DevicePixel color space and operation definition */
16 #include "gx.h"
17 #include "gserrors.h"
18 #include "gsrefct.h"
19 #include "gxcspace.h"
20 #include "gscpixel.h"
21 #include "gxdevice.h"
22 #include "gxistate.h"
23 #include "gsovrc.h"
24 #include "gsstate.h"
25 #include "gzstate.h"
26 #include "stream.h"
27 
28 /* Define the DevicePixel color space type. */
29 static cs_proc_restrict_color(gx_restrict_DevicePixel);
30 static cs_proc_remap_concrete_color(gx_remap_concrete_DevicePixel);
31 static cs_proc_concretize_color(gx_concretize_DevicePixel);
32 static cs_proc_set_overprint(gx_set_overprint_DevicePixel);
33 static cs_proc_serialize(gx_serialize_DevicePixel);
34 static const gs_color_space_type gs_color_space_type_DevicePixel = {
35     gs_color_space_index_DevicePixel, true, false,
36     &st_base_color_space, gx_num_components_1,
37     gx_init_paint_1, gx_restrict_DevicePixel,
38     gx_same_concrete_space,
39     gx_concretize_DevicePixel, gx_remap_concrete_DevicePixel,
40     gx_default_remap_color, gx_no_install_cspace,
41     gx_set_overprint_DevicePixel,
42     NULL, gx_no_adjust_color_count,
43     gx_serialize_DevicePixel,
44     gx_cspace_is_linear_default
45 };
46 
47 /* Create a DevicePixel color space. */
48 int
gs_cspace_new_DevicePixel(gs_memory_t * mem,gs_color_space ** ppcs,int depth)49 gs_cspace_new_DevicePixel(gs_memory_t *mem, gs_color_space **ppcs, int depth)
50 {
51     gs_color_space *pcs;
52 
53     switch (depth) {
54 	case 1:
55 	case 2:
56 	case 4:
57 	case 8:
58 	case 16:
59 	case 24:
60 	case 32:
61 	    break;
62 	default:
63 	    return_error(gs_error_rangecheck);
64     }
65     pcs = gs_cspace_alloc(mem, &gs_color_space_type_DevicePixel);
66     if (pcs == NULL)
67 	return_error(gs_error_VMerror);
68     pcs->params.pixel.depth = depth;
69     *ppcs = pcs;
70     return 0;
71 }
72 
73 /* ------ Internal routines ------ */
74 
75 /* Force a DevicePixel color into legal range. */
76 static void
gx_restrict_DevicePixel(gs_client_color * pcc,const gs_color_space * pcs)77 gx_restrict_DevicePixel(gs_client_color * pcc, const gs_color_space * pcs)
78 {
79     /****** NOT ENOUGH BITS IN float OR frac ******/
80     floatp pixel = pcc->paint.values[0];
81     ulong max_value = (1L << pcs->params.pixel.depth) - 1;
82 
83     pcc->paint.values[0] = (pixel < 0 ? 0 : min(pixel, max_value));
84 }
85 
86 
87 /* Remap a DevicePixel color. */
88 
89 static int
gx_concretize_DevicePixel(const gs_client_color * pc,const gs_color_space * pcs,frac * pconc,const gs_imager_state * pis)90 gx_concretize_DevicePixel(const gs_client_color * pc, const gs_color_space * pcs,
91 			  frac * pconc, const gs_imager_state * pis)
92 {
93     /****** NOT ENOUGH BITS IN float OR frac ******/
94     pconc[0] = (frac) (ulong) pc->paint.values[0];
95     return 0;
96 }
97 
98 static int
gx_remap_concrete_DevicePixel(const frac * pconc,const gs_color_space * pcs,gx_device_color * pdc,const gs_imager_state * pis,gx_device * dev,gs_color_select_t select)99 gx_remap_concrete_DevicePixel(const frac * pconc, const gs_color_space * pcs,
100 	gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev,
101 			      gs_color_select_t select)
102 {
103     color_set_pure(pdc, pconc[0] & ((1 << dev->color_info.depth) - 1));
104     return 0;
105 }
106 
107 /* DevicePixel disables overprint */
108 static int
gx_set_overprint_DevicePixel(const gs_color_space * pcs,gs_state * pgs)109 gx_set_overprint_DevicePixel(const gs_color_space * pcs, gs_state * pgs)
110 {
111     gs_overprint_params_t   params;
112 
113     params.retain_any_comps = false;
114     pgs->effective_overprint_mode = 0;
115     return gs_state_update_overprint(pgs, &params);
116 }
117 
118 
119 /* ---------------- Serialization. -------------------------------- */
120 
121 static int
gx_serialize_DevicePixel(const gs_color_space * pcs,stream * s)122 gx_serialize_DevicePixel(const gs_color_space * pcs, stream * s)
123 {
124     const gs_device_pixel_params * p = &pcs->params.pixel;
125     uint n;
126     int code = gx_serialize_cspace_type(pcs, s);
127 
128     if (code < 0)
129 	return code;
130     return sputs(s, (const byte *)&p->depth, sizeof(p->depth), &n);
131 }
132