diff options
Diffstat (limited to 'gs/base/gdevdcrd.c')
-rw-r--r-- | gs/base/gdevdcrd.c | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/gs/base/gdevdcrd.c b/gs/base/gdevdcrd.c new file mode 100644 index 000000000..f15749acb --- /dev/null +++ b/gs/base/gdevdcrd.c @@ -0,0 +1,172 @@ +/* Copyright (C) 2001-2006 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, modified + or distributed except as expressly authorized under the terms of that + license. Refer to licensing information at http://www.artifex.com/ + or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, + San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information. +*/ +/* $Id$ */ +/* Create a sample device CRD */ +#include "math_.h" +#include "memory_.h" +#include "string_.h" +#include "gx.h" +#include "gserrors.h" +#include "gsparam.h" +#include "gscspace.h" /* for gscie.h */ +#include "gscrd.h" +#include "gscrdp.h" +#include "gxdevcli.h" +#include "gdevdcrd.h" + +/* + * The parameters in this driver CRD are the default PostScript values, + * except for the optional 'dented' procedures. + */ +#define DENT(v, f)\ + (v <= 0.5 ? v * f : (v - 0.5) * (1 - (0.5 * f)) / 0.5 + 0.5 * f) +static const gs_vector3 bit_WhitePoint = {(float)0.9505, 1, (float)1.0890}; +static const gs_range3 bit_RangePQR = { + {{0, (float)0.9505}, {0, 1}, {0, (float)1.0890}} +}; +static const float dent_PQR = 1.0; +static int +bit_TransformPQR_proc(int index, floatp in, const gs_cie_wbsd * pwbsd, + gs_cie_render * pcrd, float *out) +{ + *out = DENT(in, dent_PQR); + return 0; +} +static const gs_cie_transform_proc3 bit_TransformPQR = { + bit_TransformPQR_proc, "bitTPQRDefault", {0, 0}, 0 +}; +static const float dent_LMN = 1.0; +static float +bit_EncodeLMN_proc(floatp in, const gs_cie_render * pcrd) +{ + return DENT(in, dent_LMN); +} +static const gs_cie_render_proc3 bit_EncodeLMN = { /* dummy */ + {bit_EncodeLMN_proc, bit_EncodeLMN_proc, bit_EncodeLMN_proc} +}; +static const gs_range3 bit_RangeLMN = { + {{0, (float)0.9505}, {0, 1}, {0, (float)1.0890}} +}; +static const gs_matrix3 bit_MatrixABC = { + {(float) 3.24063, (float)-0.96893, (float) 0.05571}, + {(float)-1.53721, (float) 1.87576, (float)-0.20402}, + {(float)-0.49863, (float) 0.04152, (float) 1.05700} +}; +static float +bit_EncodeABC_proc(floatp in, const gs_cie_render * pcrd) +{ + return pow(max(in, 0.0), 0.45); +} +static const gs_cie_render_proc3 bit_EncodeABC = { + {bit_EncodeABC_proc, bit_EncodeABC_proc, bit_EncodeABC_proc} +}; +/* These RenderTables are no-ops. */ +static const byte bit_rtt0[2*2*3] = { + /*0,0,0*/ 0,0,0, + /*0,0,1*/ 0,0,255, + /*0,1,0*/ 0,255,0, + /*0,1,1*/ 0,255,255 +}; +static const byte bit_rtt1[2*2*3] = { + /*1,0,0*/ 255,0,0, + /*1,0,1*/ 255,0,255, + /*1,1,0*/ 255,255,0, + /*1,1,1*/ 255,255,255 +}; +static const gs_const_string bit_rt_data[2] = { + {bit_rtt0, 2*2*3}, {bit_rtt1, 2*2*3} +}; +static frac +bit_rt_proc(byte in, const gs_cie_render *pcrd) +{ + return frac_1 * in / 255; +} +static const gs_cie_render_table_t bit_RenderTable = { /* dummy */ + {3, {2, 2, 2}, 3, bit_rt_data}, + {{bit_rt_proc, bit_rt_proc, bit_rt_proc}} +}; + +/* + * Implement get_params for a sample device CRD. A useful convention, + * for devices that can provide more than one CRD, is to have a settable + * parameter CRDName, which gives the name of the CRD in use. This sample + * code provides a constant CRDName: making it settable is left as an + * exercise to the reader. + */ +int +sample_device_crd_get_params(gx_device *pdev, gs_param_list *plist, + const char *crd_param_name) +{ + int ecode = 0; + + if (param_requested(plist, "CRDName") > 0) { + gs_param_string cns; + int code; + + cns.data = (const byte *)crd_param_name; + cns.size = strlen(crd_param_name); + cns.persistent = true; + code = param_write_string(plist, "CRDName", &cns); + if (code < 0) + ecode = code; + } + if (param_requested(plist, crd_param_name) > 0) { + gs_cie_render *pcrd; + int code = gs_cie_render1_build(&pcrd, pdev->memory, + "sample_device_crd_get_params"); + if (code >= 0) { + gs_cie_transform_proc3 tpqr; + + tpqr = bit_TransformPQR; + tpqr.driver_name = pdev->dname; + code = gs_cie_render1_initialize(pdev->memory, pcrd, NULL, + &bit_WhitePoint, NULL /*BlackPoint*/, + NULL /*MatrixPQR*/, &bit_RangePQR, &tpqr, + NULL /*MatrixLMN*/, &bit_EncodeLMN, &bit_RangeLMN, + &bit_MatrixABC, &bit_EncodeABC, NULL /*RangeABC*/, + &bit_RenderTable); + if (code >= 0) { + code = param_write_cie_render1(plist, crd_param_name, pcrd, + pdev->memory); + } + rc_decrement(pcrd, "sample_device_crd_get_params"); /* release */ + } + if (code < 0) + ecode = code; + } + if (param_requested(plist, bit_TransformPQR.proc_name) > 0) { + /* + * We definitely do not recommend the following use of a static + * to hold the address: this is a shortcut. + */ + gs_cie_transform_proc my_proc = bit_TransformPQR_proc; + byte *my_addr = gs_alloc_string(pdev->memory, sizeof(my_proc), + "sd_crd_get_params(proc)"); + int code; + + if (my_addr == 0) + code = gs_note_error(gs_error_VMerror); + else { + gs_param_string as; + + memcpy(my_addr, &my_proc, sizeof(my_proc)); + as.data = my_addr; + as.size = sizeof(my_proc); + as.persistent = true; + code = param_write_string(plist, bit_TransformPQR.proc_name, &as); + } + if (code < 0) + ecode = code; + } + return ecode; +} |