1 /* Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael,
13 CA 94903, U.S.A., +1(415)492-9861, for further information.
14 */
15
16 /* Create a sample device CRD */
17 #include "math_.h"
18 #include "memory_.h"
19 #include "string_.h"
20 #include "gx.h"
21 #include "gserrors.h"
22 #include "gsparam.h"
23 #include "gscspace.h" /* for gscie.h */
24 #include "gscrd.h"
25 #include "gscrdp.h"
26 #include "gxdevcli.h"
27 #include "gdevdcrd.h"
28
29 /*
30 * The parameters in this driver CRD are the default PostScript values,
31 * except for the optional 'dented' procedures.
32 */
33 #define DENT(v, f)\
34 (v <= 0.5 ? v * f : (v - 0.5) * (1 - (0.5 * f)) / 0.5 + 0.5 * f)
35 static const gs_vector3 bit_WhitePoint = {(float)0.9505, 1, (float)1.0890};
36 static const gs_range3 bit_RangePQR = {
37 {{0, (float)0.9505}, {0, 1}, {0, (float)1.0890}}
38 };
39 static const float dent_PQR = 1.0;
40 static int
bit_TransformPQR_proc(int index,floatp in,const gs_cie_wbsd * pwbsd,gs_cie_render * pcrd,float * out)41 bit_TransformPQR_proc(int index, floatp in, const gs_cie_wbsd * pwbsd,
42 gs_cie_render * pcrd, float *out)
43 {
44 *out = DENT(in, dent_PQR);
45 return 0;
46 }
47 static const gs_cie_transform_proc3 bit_TransformPQR = {
48 bit_TransformPQR_proc, "bitTPQRDefault", {0, 0}, 0
49 };
50 static const float dent_LMN = 1.0;
51 static float
bit_EncodeLMN_proc(floatp in,const gs_cie_render * pcrd)52 bit_EncodeLMN_proc(floatp in, const gs_cie_render * pcrd)
53 {
54 return DENT(in, dent_LMN);
55 }
56 static const gs_cie_render_proc3 bit_EncodeLMN = { /* dummy */
57 {bit_EncodeLMN_proc, bit_EncodeLMN_proc, bit_EncodeLMN_proc}
58 };
59 static const gs_range3 bit_RangeLMN = {
60 {{0, (float)0.9505}, {0, 1}, {0, (float)1.0890}}
61 };
62 static const gs_matrix3 bit_MatrixABC = {
63 {(float) 3.24063, (float)-0.96893, (float) 0.05571},
64 {(float)-1.53721, (float) 1.87576, (float)-0.20402},
65 {(float)-0.49863, (float) 0.04152, (float) 1.05700}
66 };
67 static float
bit_EncodeABC_proc(floatp in,const gs_cie_render * pcrd)68 bit_EncodeABC_proc(floatp in, const gs_cie_render * pcrd)
69 {
70 return pow(max(in, 0.0), 0.45);
71 }
72 static const gs_cie_render_proc3 bit_EncodeABC = {
73 {bit_EncodeABC_proc, bit_EncodeABC_proc, bit_EncodeABC_proc}
74 };
75 /* These RenderTables are no-ops. */
76 static const byte bit_rtt0[2*2*3] = {
77 /*0,0,0*/ 0,0,0,
78 /*0,0,1*/ 0,0,255,
79 /*0,1,0*/ 0,255,0,
80 /*0,1,1*/ 0,255,255
81 };
82 static const byte bit_rtt1[2*2*3] = {
83 /*1,0,0*/ 255,0,0,
84 /*1,0,1*/ 255,0,255,
85 /*1,1,0*/ 255,255,0,
86 /*1,1,1*/ 255,255,255
87 };
88 static const gs_const_string bit_rt_data[2] = {
89 {bit_rtt0, 2*2*3}, {bit_rtt1, 2*2*3}
90 };
91 static frac
bit_rt_proc(byte in,const gs_cie_render * pcrd)92 bit_rt_proc(byte in, const gs_cie_render *pcrd)
93 {
94 return frac_1 * in / 255;
95 }
96 static const gs_cie_render_table_t bit_RenderTable = { /* dummy */
97 {3, {2, 2, 2}, 3, bit_rt_data},
98 {{bit_rt_proc, bit_rt_proc, bit_rt_proc}}
99 };
100
101 /*
102 * Implement get_params for a sample device CRD. A useful convention,
103 * for devices that can provide more than one CRD, is to have a settable
104 * parameter CRDName, which gives the name of the CRD in use. This sample
105 * code provides a constant CRDName: making it settable is left as an
106 * exercise to the reader.
107 */
108 int
sample_device_crd_get_params(gx_device * pdev,gs_param_list * plist,const char * crd_param_name)109 sample_device_crd_get_params(gx_device *pdev, gs_param_list *plist,
110 const char *crd_param_name)
111 {
112 int ecode = 0;
113
114 if (param_requested(plist, "CRDName") > 0) {
115 gs_param_string cns;
116 int code;
117
118 cns.data = (const byte *)crd_param_name;
119 cns.size = strlen(crd_param_name);
120 cns.persistent = true;
121 code = param_write_string(plist, "CRDName", &cns);
122 if (code < 0)
123 ecode = code;
124 }
125 if (param_requested(plist, crd_param_name) > 0) {
126 gs_cie_render *pcrd;
127 int code = gs_cie_render1_build(&pcrd, pdev->memory,
128 "sample_device_crd_get_params");
129 if (code >= 0) {
130 gs_cie_transform_proc3 tpqr;
131
132 tpqr = bit_TransformPQR;
133 tpqr.driver_name = pdev->dname;
134 code = gs_cie_render1_initialize(pdev->memory, pcrd, NULL,
135 &bit_WhitePoint, NULL /*BlackPoint*/,
136 NULL /*MatrixPQR*/, &bit_RangePQR, &tpqr,
137 NULL /*MatrixLMN*/, &bit_EncodeLMN, &bit_RangeLMN,
138 &bit_MatrixABC, &bit_EncodeABC, NULL /*RangeABC*/,
139 &bit_RenderTable);
140 if (code >= 0) {
141 code = param_write_cie_render1(plist, crd_param_name, pcrd,
142 pdev->memory);
143 }
144 rc_decrement(pcrd, "sample_device_crd_get_params"); /* release */
145 }
146 if (code < 0)
147 ecode = code;
148 }
149 if (param_requested(plist, bit_TransformPQR.proc_name) > 0) {
150 /*
151 * We definitely do not recommend the following use of a static
152 * to hold the address: this is a shortcut.
153 */
154 gs_cie_transform_proc my_proc = bit_TransformPQR_proc;
155 byte *my_addr = gs_alloc_string(pdev->memory, sizeof(my_proc),
156 "sd_crd_get_params(proc)");
157 int code;
158
159 if (my_addr == 0)
160 code = gs_note_error(gs_error_VMerror);
161 else {
162 gs_param_string as;
163
164 memcpy(my_addr, &my_proc, sizeof(my_proc));
165 as.data = my_addr;
166 as.size = sizeof(my_proc);
167 as.persistent = true;
168 code = param_write_string(plist, bit_TransformPQR.proc_name, &as);
169 }
170 if (code < 0)
171 ecode = code;
172 }
173 return ecode;
174 }
175