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