/src/ghostpdl/base/gdevdcrd.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (C) 2001-2023 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., 39 Mesa Street, Suite 108A, San Francisco, |
13 | | CA 94129, USA, 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 | 0 | (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 |
41 | | bit_TransformPQR_proc(int index, double in, const gs_cie_wbsd * pwbsd, |
42 | | gs_cie_render * pcrd, float *out) |
43 | 0 | { |
44 | 0 | *out = DENT(in, dent_PQR); |
45 | 0 | return 0; |
46 | 0 | } |
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 |
52 | | bit_EncodeLMN_proc(double in, const gs_cie_render * pcrd) |
53 | 0 | { |
54 | 0 | return DENT(in, dent_LMN); |
55 | 0 | } |
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 |
68 | | bit_EncodeABC_proc(double in, const gs_cie_render * pcrd) |
69 | 0 | { |
70 | 0 | return pow(max(in, 0.0), 0.45); |
71 | 0 | } |
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 |
92 | | bit_rt_proc(byte in, const gs_cie_render *pcrd) |
93 | 0 | { |
94 | 0 | return frac_1 * in / 255; |
95 | 0 | } |
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 |
109 | | sample_device_crd_get_params(gx_device *pdev, gs_param_list *plist, |
110 | | const char *crd_param_name) |
111 | 469k | { |
112 | 469k | int ecode = 0; |
113 | | |
114 | 469k | if (param_requested(plist, "CRDName") > 0) { |
115 | 0 | gs_param_string cns; |
116 | 0 | int code; |
117 | |
|
118 | 0 | cns.data = (const byte *)crd_param_name; |
119 | 0 | cns.size = strlen(crd_param_name); |
120 | 0 | cns.persistent = true; |
121 | 0 | code = param_write_string(plist, "CRDName", &cns); |
122 | 0 | if (code < 0) |
123 | 0 | ecode = code; |
124 | 0 | } |
125 | 469k | if (param_requested(plist, crd_param_name) > 0) { |
126 | 0 | gs_cie_render *pcrd; |
127 | 0 | int code = gs_cie_render1_build(&pcrd, pdev->memory, |
128 | 0 | "sample_device_crd_get_params"); |
129 | 0 | if (code >= 0) { |
130 | 0 | gs_cie_transform_proc3 tpqr; |
131 | |
|
132 | 0 | tpqr = bit_TransformPQR; |
133 | 0 | tpqr.driver_name = pdev->dname; |
134 | 0 | code = gs_cie_render1_initialize(pdev->memory, pcrd, NULL, |
135 | 0 | &bit_WhitePoint, NULL /*BlackPoint*/, |
136 | 0 | NULL /*MatrixPQR*/, &bit_RangePQR, &tpqr, |
137 | 0 | NULL /*MatrixLMN*/, &bit_EncodeLMN, &bit_RangeLMN, |
138 | 0 | &bit_MatrixABC, &bit_EncodeABC, NULL /*RangeABC*/, |
139 | 0 | &bit_RenderTable); |
140 | 0 | if (code >= 0) { |
141 | 0 | code = param_write_cie_render1(plist, crd_param_name, pcrd, |
142 | 0 | pdev->memory); |
143 | 0 | } |
144 | 0 | rc_decrement(pcrd, "sample_device_crd_get_params"); /* release */ |
145 | 0 | } |
146 | 0 | if (code < 0) |
147 | 0 | ecode = code; |
148 | 0 | } |
149 | 469k | 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 | 0 | gs_cie_transform_proc my_proc = bit_TransformPQR_proc; |
155 | 0 | byte *my_addr = gs_alloc_string(pdev->memory, sizeof(my_proc), |
156 | 0 | "sd_crd_get_params(proc)"); |
157 | 0 | int code; |
158 | |
|
159 | 0 | if (my_addr == 0) |
160 | 0 | code = gs_note_error(gs_error_VMerror); |
161 | 0 | else { |
162 | 0 | gs_param_string as; |
163 | |
|
164 | 0 | memcpy(my_addr, &my_proc, sizeof(my_proc)); |
165 | 0 | as.data = my_addr; |
166 | 0 | as.size = sizeof(my_proc); |
167 | 0 | as.persistent = true; |
168 | 0 | code = param_write_string(plist, bit_TransformPQR.proc_name, &as); |
169 | 0 | } |
170 | 0 | if (code < 0) |
171 | 0 | ecode = code; |
172 | 0 | } |
173 | 469k | return ecode; |
174 | 469k | } |