Coverage Report

Created: 2025-06-10 06:58

/src/ghostpdl/base/gsdparam.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2025 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
/* Default device parameters for Ghostscript library */
17
#include "memory_.h"    /* for memcpy */
18
#include "string_.h"    /* for strlen */
19
#include "gx.h"
20
#include "gserrors.h"
21
#include "gsdevice.h"   /* for prototypes */
22
#include "gsparam.h"
23
#include "gsparamx.h"   /* for param_put_enum */
24
#include "gxdevice.h"
25
#include "gxdevsop.h"
26
#include "gxfixed.h"
27
#include "gsicc_manage.h"
28
#include "gdevnup.h"    /* to install N-up subclass device */
29
#include "gp_utf8.h"
30
31
extern gx_device_nup gs_nup_device;
32
33
/* Define whether we accept PageSize as a synonym for MediaSize. */
34
/* This is for backward compatibility only. */
35
#define PAGESIZE_IS_MEDIASIZE
36
37
459k
#define BLACKTHRESHOLDL 90
38
459k
#define BLACKTHRESHOLDC 3
39
40
/* Names corresponding to gs_overprint_control_t enum */
41
static const char *const overprint_control_names[] = {
42
    gs_overprint_control_names, 0
43
};
44
45
/* ================ Getting parameters ================ */
46
47
/* Forward references */
48
static bool param_HWColorMap(gx_device *, byte *);
49
50
/* Get the device parameters. */
51
int
52
gs_get_device_or_hw_params(gx_device * orig_dev, gs_param_list * plist,
53
                           bool is_hardware)
54
305k
{
55
    /*
56
     * We must be prepared to copy the device if it is the read-only
57
     * prototype.
58
     */
59
305k
    gx_device *dev;
60
305k
    int code = 0;
61
62
305k
    if (orig_dev->memory)
63
305k
        dev = orig_dev;
64
0
    else {
65
0
        code = gs_copydevice(&dev, orig_dev, plist->memory);
66
0
        if (code < 0)
67
0
            return code;
68
0
    }
69
305k
    fill_dev_proc(dev, get_params, gx_default_get_params);
70
305k
    fill_dev_proc(dev, get_page_device, gx_default_get_page_device);
71
305k
    fill_dev_proc(dev, get_alpha_bits, gx_default_get_alpha_bits);
72
305k
    if (is_hardware) {
73
0
        if (dev_proc(dev, get_hardware_params) != NULL)
74
0
            code = (*dev_proc(dev, get_hardware_params)) (dev, plist);
75
305k
    } else {
76
305k
        if (dev_proc(dev, get_params) != NULL)
77
305k
            code = (*dev_proc(dev, get_params)) (dev, plist);
78
305k
    }
79
305k
    if (dev != orig_dev)
80
0
        gx_device_retain(dev, false);  /* frees the copy */
81
305k
    return code;
82
305k
}
83
84
static int
85
get_dev_icccolorants_utf8(gs_memory_t *mem, cmm_dev_profile_t *dev_profile, char **putf8)
86
0
{
87
0
    char *colorants = gsicc_get_dev_icccolorants(dev_profile);
88
0
    char *utf8;
89
0
    unsigned char *s;
90
0
    unsigned short *unicode, *u;
91
0
    size_t len;
92
93
0
    if (colorants == NULL)
94
0
    {
95
0
        *putf8 = NULL;
96
0
        return 0;
97
0
    }
98
99
0
    len = strlen(colorants);
100
101
    /* Convert our 8 bit raw bytes into 16 bit raw. */
102
0
    unicode = (unsigned short *)gs_alloc_bytes(mem, (len+1)*sizeof(unsigned short), "get_dev_icccolorants_utf8");
103
0
    if (unicode == NULL)
104
0
        return_error(gs_error_VMerror);
105
106
0
    u = unicode;
107
0
    s = (unsigned char *)colorants;
108
0
    while ((*u++ = *s++) != 0);
109
110
    /* Now utf-8 encode that. */
111
0
    len = gp_uint16_to_utf8(NULL, unicode);
112
0
    utf8 = (char *)gs_alloc_bytes(mem, len, "get_dev_icccolorants_utf8");
113
0
    if (utf8 == NULL) {
114
0
        gs_free_object(mem, unicode, "get_dev_icccolorants_utf8");
115
0
        return_error(gs_error_VMerror);
116
0
    }
117
0
    gp_uint16_to_utf8(utf8, unicode);
118
119
0
    gs_free_object(mem, unicode, "get_dev_icccolorants_utf8");
120
0
    *putf8 = utf8;
121
122
0
    return 0;
123
0
}
124
125
126
int gx_default_get_param(gx_device *dev, char *Param, void *list)
127
41.4k
{
128
41.4k
    gs_param_list * plist = (gs_param_list *)list;
129
41.4k
    int k, colors = dev->color_info.num_components;
130
41.4k
    gs_param_string profile_array[NUM_DEVICE_PROFILES];
131
41.4k
    gs_param_string postren_profile, blend_profile;
132
41.4k
    gs_param_string proof_profile, link_profile, icc_colorants;
133
41.4k
    gsicc_rendering_intents_t profile_intents[NUM_DEVICE_PROFILES];
134
41.4k
    gsicc_blackptcomp_t blackptcomps[NUM_DEVICE_PROFILES];
135
41.4k
    gsicc_blackpreserve_t blackpreserve[NUM_DEVICE_PROFILES];
136
41.4k
    int color_accuracy = MAX_COLOR_ACCURACY;
137
41.4k
    int depth = dev->color_info.depth;
138
41.4k
    cmm_dev_profile_t *dev_profile;
139
41.4k
    char null_str[1]={'\0'};
140
41.4k
#define set_param_array(a, d, s)\
141
41.4k
  (a.data = d, a.size = s, a.persistent = false);
142
41.4k
    bool devicegraytok = true;  /* Default if device profile stuct not set */
143
41.4k
    bool graydetection = false;
144
41.4k
    bool usefastcolor = false;  /* set for unmanaged color */
145
41.4k
    bool blacktext = false;
146
41.4k
    bool blackvector = false;
147
41.4k
    float blackthresholdL = BLACKTHRESHOLDL;
148
41.4k
    float blackthresholdC = BLACKTHRESHOLDC;
149
    /* By default overprinting only valid with cmyk devices */
150
41.4k
    gs_overprint_control_t overprint_control = gs_overprint_control_enable;
151
41.4k
    bool prebandthreshold = true, temp_bool = false;
152
153
41.4k
    if(strcmp(Param, "OutputDevice") == 0){
154
0
        gs_param_string dns;
155
0
        param_string_from_string(dns, dev->dname);
156
0
        return param_write_name(plist, "OutputDevice", &dns);
157
0
    }
158
41.4k
#ifdef PAGESIZE_IS_MEDIASIZE
159
41.4k
    if (strcmp(Param, "PageSize") == 0) {
160
20.6k
        gs_param_float_array msa;
161
20.6k
        set_param_array(msa, dev->MediaSize, 2);
162
20.6k
        return param_write_float_array(plist, "PageSize", &msa);
163
20.6k
    }
164
20.8k
#endif
165
20.8k
    if (strcmp(Param, "ProcessColorModel") == 0) {
166
0
        const char *cms = get_process_color_model_name(dev);
167
168
        /* We might have an uninitialized device with */
169
        /* color_info.num_components = 0.... */
170
0
        if ((cms != NULL) && (*cms != '\0')) {
171
0
            gs_param_string pcms;
172
0
            param_string_from_string(pcms, cms);
173
0
            return param_write_name(plist, "ProcessColorModel", &pcms);
174
0
        }
175
0
    }
176
20.8k
    if (strcmp(Param, "HWResolution") == 0) {
177
0
        gs_param_float_array hwra;
178
0
        set_param_array(hwra, dev->HWResolution, 2);
179
0
        return param_write_float_array(plist, "HWResolution", &hwra);
180
0
    }
181
20.8k
    if (strcmp(Param, "ImagingBBox") == 0) {
182
0
        gs_param_float_array ibba;
183
0
        set_param_array(ibba, dev->ImagingBBox, 4);
184
0
        if (dev->ImagingBBox_set)
185
0
            return param_write_float_array(plist, "ImagingBBox", &ibba);
186
0
        else
187
0
            return param_write_null(plist, "ImagingBBox");
188
0
    }
189
20.8k
    if (strcmp(Param, "Margins") == 0) {
190
0
        gs_param_float_array ma;
191
0
        set_param_array(ma, dev->Margins, 2);
192
0
        return param_write_float_array(plist, "Margins", &ma);
193
0
    }
194
20.8k
    if (strcmp(Param, "MaxSeparations") == 0) {
195
0
        int max_sep = dev->color_info.max_components;
196
0
        return param_write_int(plist, "MaxSeparations", &max_sep);
197
0
    }
198
20.8k
    if (strcmp(Param, "NumCopies") == 0) {
199
0
        if (dev->NumCopies_set < 0 || (*dev_proc(dev, get_page_device))(dev) == 0) {
200
0
            return_error(gs_error_undefined);
201
0
        } else {
202
0
            if (dev->NumCopies_set)
203
0
                return param_write_int(plist, "NumCopies", &dev->NumCopies);
204
0
            else
205
0
                return param_write_null(plist, "NumCopies");
206
0
        }
207
0
    }
208
20.8k
    if (strcmp(Param, "SeparationColorNames") == 0) {
209
0
        gs_param_string_array scna;
210
0
        set_param_array(scna, NULL, 0);
211
0
        return param_write_name_array(plist, "SeparationColorNames", &scna);
212
0
    }
213
20.8k
    if (strcmp(Param, "Separations") == 0) {
214
0
        bool seprs = false;
215
0
        return param_write_bool(plist, "Separations", &seprs);
216
0
    }
217
20.8k
    if (strcmp(Param, "UseCIEColor") == 0) {
218
0
        return param_write_bool(plist, "UseCIEColor", &dev->UseCIEColor);
219
0
    }
220
221
    /* Non-standard parameters */
222
20.8k
    if (strcmp(Param, "HWSize") == 0) {
223
0
        int HWSize[2];
224
0
        gs_param_int_array hwsa;
225
226
0
        HWSize[0] = dev->width;
227
0
        HWSize[1] = dev->height;
228
0
        set_param_array(hwsa, HWSize, 2);
229
0
        return param_write_int_array(plist, "HWSize", &hwsa);
230
0
    }
231
20.8k
    if (strcmp(Param, ".HWMargins") == 0) {
232
0
        gs_param_float_array hwma;
233
0
        set_param_array(hwma, dev->HWMargins, 4);
234
0
        return param_write_float_array(plist, ".HWMargins", &hwma);
235
0
    }
236
20.8k
    if (strcmp(Param, ".MediaSize") == 0) {
237
0
        gs_param_float_array msa;
238
0
        set_param_array(msa, dev->MediaSize, 2);
239
0
        return param_write_float_array(plist, ".MediaSize", &msa);
240
0
    }
241
20.8k
    if (strcmp(Param, "Name") == 0) {
242
0
        gs_param_string dns;
243
0
        param_string_from_string(dns, dev->dname);
244
0
        return param_write_string(plist, "Name", &dns);
245
0
    }
246
20.8k
    if (strcmp(Param, "Colors") == 0) {
247
0
        int colors = dev->color_info.num_components;
248
0
        return param_write_int(plist, "Colors", &colors);
249
0
    }
250
20.8k
    if (strcmp(Param, "BitsPerPixel") == 0) {
251
0
        return param_write_int(plist, "BitsPerPixel", &depth);
252
0
    }
253
20.8k
    if (strcmp(Param, "GrayValues") == 0) {
254
0
        int GrayValues = dev->color_info.max_gray + 1;
255
0
        return param_write_int(plist, "GrayValues", &GrayValues);
256
0
    }
257
20.8k
    if (strcmp(Param, "PageCount") == 0) {
258
0
        return param_write_long(plist, "PageCount", &dev->PageCount);
259
0
    }
260
20.8k
    if (strcmp(Param, ".IgnoreNumCopies") == 0) {
261
0
        return param_write_bool(plist, ".IgnoreNumCopies", &dev->IgnoreNumCopies);
262
0
    }
263
20.8k
    if (strcmp(Param, "TextAlphaBits") == 0) {
264
0
        return param_write_int(plist, "TextAlphaBits",
265
0
                                &dev->color_info.anti_alias.text_bits);
266
0
    }
267
20.8k
    if (strcmp(Param, "GraphicsAlphaBits") == 0) {
268
0
        return param_write_int(plist, "GraphicsAlphaBits",
269
0
                                &dev->color_info.anti_alias.graphics_bits);
270
0
    }
271
20.8k
    if (strcmp(Param, "AntidropoutDownscaler") == 0) {
272
0
        return param_write_bool(plist, "AntidropoutDownscaler",
273
0
                                &dev->color_info.use_antidropout_downscaler);
274
0
    }
275
20.8k
    if (strcmp(Param, ".LockSafetyParams") == 0) {
276
0
        return param_write_bool(plist, ".LockSafetyParams", &dev->LockSafetyParams);
277
0
    }
278
20.8k
    if (strcmp(Param, "MaxPatternBitmap") == 0) {
279
0
        return param_write_size_t(plist, "MaxPatternBitmap", &dev->MaxPatternBitmap);
280
0
    }
281
20.8k
    if (strcmp(Param, "PageUsesTransparency") == 0) {
282
0
        return param_write_bool(plist, "PageUsesTransparency", &dev->page_uses_transparency);
283
0
    }
284
20.8k
    if (strcmp(Param, "PageUsesOverprint") == 0) {
285
0
        return param_write_bool(plist, "PageUsesOverprint", &dev->page_uses_overprint);
286
0
    }
287
20.8k
    if (strcmp(Param, "MaxBitmap") == 0) {
288
0
        return param_write_size_t(plist, "MaxBitmap", &(dev->space_params.MaxBitmap));
289
0
    }
290
20.8k
    if (strcmp(Param, "BandBufferSpace") == 0) {
291
0
        return param_write_size_t(plist, "BandBufferSpace", &dev->space_params.band.BandBufferSpace);
292
0
    }
293
20.8k
    if (strcmp(Param, "BandHeight") == 0) {
294
0
        return param_write_int(plist, "BandHeight", &dev->space_params.band.BandHeight);
295
0
    }
296
20.8k
    if (strcmp(Param, "BandWidth") == 0) {
297
0
        return param_write_int(plist, "BandWidth", &dev->space_params.band.BandWidth);
298
0
    }
299
20.8k
    if (strcmp(Param, "BufferSpace") == 0) {
300
0
        return param_write_size_t(plist, "BufferSpace", &dev->space_params.BufferSpace);
301
0
    }
302
20.8k
    if (strcmp(Param, "InterpolateControl") == 0) {
303
0
        int interpolate_control = dev->interpolate_control;
304
0
        return param_write_int(plist, "InterpolateControl", &interpolate_control);
305
0
    }
306
20.8k
    if (strcmp(Param, "LeadingEdge") == 0) {
307
0
        if (dev->LeadingEdge & LEADINGEDGE_SET_MASK) {
308
0
            int leadingedge = dev->LeadingEdge & LEADINGEDGE_MASK;
309
0
            return param_write_int(plist, "LeadingEdge", &leadingedge);
310
0
        } else
311
0
            return param_write_null(plist, "LeadingEdge");
312
0
    }
313
314
20.8k
    if (dev->color_info.num_components > 1) {
315
20.5k
        int RGBValues = dev->color_info.max_color + 1;
316
20.5k
        long ColorValues = (depth >= 32 ? -1 : 1L << depth); /* value can only be 32 bits */
317
318
20.5k
        if (strcmp(Param, "RedValues") == 0) {
319
0
            return param_write_int(plist, "RedValues", &RGBValues);
320
0
        }
321
20.5k
        if (strcmp(Param, "GreenValues") == 0) {
322
0
            return param_write_int(plist, "GreenValues", &RGBValues);
323
0
        }
324
20.5k
        if (strcmp(Param, "BlueValues") == 0) {
325
0
            return param_write_int(plist, "BlueValues", &RGBValues);
326
0
        }
327
20.5k
        if (strcmp(Param, "ColorValues") == 0) {
328
0
            return param_write_long(plist, "ColorValues", &ColorValues);
329
0
        }
330
20.5k
    }
331
20.8k
    if (strcmp(Param, "HWColorMap") == 0) {
332
0
        byte palette[3 << 8];
333
334
0
        if (param_HWColorMap(dev, palette)) {
335
0
            gs_param_string hwcms;
336
337
0
            hwcms.data = palette, hwcms.size = colors << depth,
338
0
                hwcms.persistent = false;
339
0
            return param_write_string(plist, "HWColorMap", &hwcms);
340
0
        }
341
0
    }
342
343
    /* ICC profiles */
344
    /* Check if the device profile is null.  If it is, then we need to
345
       go ahead and get it set up at this time.  If the proc is not
346
       set up yet then we are not going to do anything yet */
347
    /* Although device methods should not be NULL, they are not completely filled in until
348
     * gx_device_fill_in_procs is called, and its possible for us to get here before this
349
     * happens, so we *must* make sure the method is not NULL before we use it.
350
     */
351
20.8k
    if (dev_proc(dev, get_profile) != NULL) {
352
20.8k
        int code;
353
20.8k
        code = dev_proc(dev, get_profile)(dev,  &dev_profile);
354
20.8k
        if (code < 0)
355
0
            return code;
356
20.8k
        if (dev_profile == NULL) {
357
0
            code = gsicc_init_device_profile_struct(dev, NULL, 0);
358
0
            if (code < 0)
359
0
                return code;
360
0
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
361
0
            if (code < 0)
362
0
                return code;
363
0
        }
364
104k
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
365
83.5k
            if (dev_profile->device_profile[k] == NULL
366
83.5k
                || dev_profile->device_profile[k]->name == NULL) {
367
62.6k
                param_string_from_string(profile_array[k], null_str);
368
62.6k
                profile_intents[k] = gsRINOTSPECIFIED;
369
62.6k
                blackptcomps[k] = gsBPNOTSPECIFIED;
370
62.6k
                blackpreserve[k] = gsBKPRESNOTSPECIFIED;
371
62.6k
            } else {
372
20.8k
                param_string_from_transient_string(profile_array[k],
373
20.8k
                    dev_profile->device_profile[k]->name);
374
20.8k
                profile_intents[k] = dev_profile->rendercond[k].rendering_intent;
375
20.8k
                blackptcomps[k] = dev_profile->rendercond[k].black_point_comp;
376
20.8k
                blackpreserve[k] = dev_profile->rendercond[k].preserve_black;
377
20.8k
            }
378
83.5k
        }
379
20.8k
        if (dev_profile->blend_profile == NULL) {
380
20.8k
            param_string_from_string(blend_profile, null_str);
381
20.8k
        } else {
382
0
            param_string_from_transient_string(blend_profile,
383
0
                dev_profile->blend_profile->name);
384
0
        }
385
20.8k
        if (dev_profile->postren_profile == NULL) {
386
20.8k
            param_string_from_string(postren_profile, null_str);
387
20.8k
        } else {
388
0
            param_string_from_transient_string(postren_profile,
389
0
                dev_profile->postren_profile->name);
390
0
        }
391
20.8k
        if (dev_profile->proof_profile == NULL) {
392
20.8k
            param_string_from_string(proof_profile, null_str);
393
20.8k
        } else {
394
0
            param_string_from_transient_string(proof_profile,
395
0
                                     dev_profile->proof_profile->name);
396
0
        }
397
20.8k
        if (dev_profile->link_profile == NULL) {
398
20.8k
            param_string_from_string(link_profile, null_str);
399
20.8k
        } else {
400
0
            param_string_from_transient_string(link_profile,
401
0
                                     dev_profile->link_profile->name);
402
0
        }
403
20.8k
        devicegraytok = dev_profile->devicegraytok;
404
20.8k
        graydetection = dev_profile->graydetection;
405
20.8k
        usefastcolor = dev_profile->usefastcolor;
406
20.8k
        blacktext = dev_profile->blacktext;
407
20.8k
        blackvector = dev_profile->blackvector;
408
20.8k
        blackthresholdC = dev_profile->blackthresholdC;
409
20.8k
        blackthresholdL = dev_profile->blackthresholdL;
410
20.8k
        overprint_control = dev_profile->overprint_control;
411
20.8k
        prebandthreshold = dev_profile->prebandthreshold;
412
        /* With respect to Output profiles that have non-standard colorants,
413
           we rely upon the default profile to give us the colorants if they do
414
           exist. */
415
20.8k
        if (dev_profile->spotnames == NULL) {
416
20.8k
            param_string_from_string(icc_colorants, null_str);
417
20.8k
        } else {
418
0
            char *colorant_names;
419
420
0
            code = get_dev_icccolorants_utf8(dev->memory, dev_profile, &colorant_names);
421
0
            if (code < 0)
422
0
                return code;
423
0
            if (colorant_names != NULL) {
424
0
                param_string_from_transient_string(icc_colorants, colorant_names);
425
0
                gs_free_object(dev->memory, colorant_names, "gx_default_get_param");
426
0
            } else {
427
0
                param_string_from_string(icc_colorants, null_str);
428
0
            }
429
0
        }
430
20.8k
    } else {
431
0
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
432
0
            param_string_from_string(profile_array[k], null_str);
433
0
            profile_intents[k] = gsRINOTSPECIFIED;
434
0
            blackptcomps[k] = gsBPNOTSPECIFIED;
435
0
            blackpreserve[k] = gsBKPRESNOTSPECIFIED;
436
0
        }
437
0
        param_string_from_string(blend_profile, null_str);
438
0
        param_string_from_string(postren_profile, null_str);
439
0
        param_string_from_string(proof_profile, null_str);
440
0
        param_string_from_string(link_profile, null_str);
441
0
        param_string_from_string(icc_colorants, null_str);
442
0
    }
443
20.8k
    if (strcmp(Param, "DeviceGrayToK") == 0) {
444
0
        return param_write_bool(plist, "DeviceGrayToK", &devicegraytok);
445
0
    }
446
20.8k
    if (strcmp(Param, "GrayDetection") == 0) {
447
0
        return param_write_bool(plist, "GrayDetection", &graydetection);
448
0
    }
449
20.8k
    if (strcmp(Param, "UseFastColor") == 0) {
450
0
        return param_write_bool(plist, "UseFastColor", &usefastcolor);
451
0
    }
452
20.8k
    if (strcmp(Param, "BlackText") == 0) {
453
0
        return param_write_bool(plist, "BlackText", &blacktext);
454
0
    }
455
20.8k
    if (strcmp(Param, "BlackVector") == 0) {
456
0
        return param_write_bool(plist, "BlackVector", &blackvector);
457
0
    }
458
20.8k
    if (strcmp(Param, "BlackThresholdL") == 0) {
459
0
        return param_write_float(plist, "BlackThresholdL", &blackthresholdL);
460
0
    }
461
20.8k
    if (strcmp(Param, "BlackThresholdC") == 0) {
462
0
        return param_write_float(plist, "BlackThresholdC", &blackthresholdC);
463
0
    }
464
20.8k
    if (strcmp(Param, "Overprint") == 0) {
465
0
        gs_param_string opc_name;
466
0
        const char *s = overprint_control_names[(int)overprint_control];
467
468
0
        param_string_from_string(opc_name, s);
469
0
        return param_write_name(plist, "Overprint", &opc_name);
470
0
    }
471
20.8k
    if (strcmp(Param, "PreBandThreshold") == 0) {
472
0
        return param_write_bool(plist, "PreBandThreshold", &prebandthreshold);
473
0
    }
474
20.8k
    if (strcmp(Param, "PostRenderProfile") == 0) {
475
0
        return param_write_string(plist, "PostRenderProfile", &(postren_profile));
476
0
    }
477
20.8k
    if (strcmp(Param, "BlendColorProfile") == 0) {
478
0
        return param_write_string(plist, "BlendColorProfile", &(blend_profile));
479
0
    }
480
20.8k
    if (strcmp(Param, "ProofProfile") == 0) {
481
0
        return param_write_string(plist,"ProofProfile", &(proof_profile));
482
0
    }
483
20.8k
    if (strcmp(Param, "DeviceLinkProfile") == 0) {
484
0
        return param_write_string(plist,"DeviceLinkProfile", &(link_profile));
485
0
    }
486
20.8k
    if (strcmp(Param, "ICCOutputColors") == 0) {
487
0
        return param_write_string(plist,"ICCOutputColors", &(icc_colorants));
488
0
    }
489
20.8k
    if (strcmp(Param, "OutputICCProfile") == 0) {
490
0
        return param_write_string(plist,"OutputICCProfile", &(profile_array[0]));
491
0
    }
492
20.8k
    if (strcmp(Param, "VectorICCProfile") == 0) {
493
0
        return param_write_string(plist,"VectorICCProfile", &(profile_array[1]));
494
0
    }
495
20.8k
    if (strcmp(Param, "ImageICCProfile") == 0) {
496
0
        return param_write_string(plist,"ImageICCProfile", &(profile_array[2]));
497
0
    }
498
20.8k
    if (strcmp(Param, "TextICCProfile") == 0) {
499
0
        return param_write_string(plist,"TextICCProfile", &(profile_array[3]));
500
0
    }
501
20.8k
    if (strcmp(Param, "ColorAccuracy") == 0) {
502
0
        return param_write_int(plist, "ColorAccuracy", (const int *)(&(color_accuracy)));
503
0
    }
504
20.8k
    if (strcmp(Param, "RenderIntent") == 0) {
505
0
        return param_write_int(plist,"RenderIntent", (const int *) (&(profile_intents[0])));
506
0
    }
507
20.8k
    if (strcmp(Param, "VectorIntent") == 0) {
508
0
        return param_write_int(plist,"VectorIntent", (const int *) &(profile_intents[1]));
509
0
    }
510
20.8k
    if (strcmp(Param, "ImageIntent") == 0) {
511
0
        return param_write_int(plist,"ImageIntent", (const int *) &(profile_intents[2]));
512
0
    }
513
20.8k
    if (strcmp(Param, "TextIntent") == 0) {
514
0
        return param_write_int(plist,"TextIntent", (const int *) &(profile_intents[3]));
515
0
    }
516
20.8k
    if (strcmp(Param, "BlackPtComp") == 0) {
517
0
        return param_write_int(plist,"BlackPtComp", (const int *) (&(blackptcomps[0])));
518
0
    }
519
20.8k
    if (strcmp(Param, "VectorBlackPt") == 0) {
520
0
        return param_write_int(plist,"VectorBlackPt", (const int *) &(blackptcomps[1]));
521
0
    }
522
20.8k
    if (strcmp(Param, "ImageBlackPt") == 0) {
523
0
        return param_write_int(plist,"ImageBlackPt", (const int *) &(blackptcomps[2]));
524
0
    }
525
20.8k
    if (strcmp(Param, "TextBlackPt") == 0) {
526
0
        return param_write_int(plist,"TextBlackPt", (const int *) &(blackptcomps[3]));
527
0
    }
528
20.8k
    if (strcmp(Param, "KPreserve") == 0) {
529
0
        return param_write_int(plist,"KPreserve", (const int *) (&(blackpreserve[0])));
530
0
    }
531
20.8k
    if (strcmp(Param, "VectorKPreserve") == 0) {
532
0
        return param_write_int(plist,"VectorKPreserve", (const int *) &(blackpreserve[1]));
533
0
    }
534
20.8k
    if (strcmp(Param, "ImageKPreserve") == 0) {
535
0
        return param_write_int(plist,"ImageKPreserve", (const int *) &(blackpreserve[2]));
536
0
    }
537
20.8k
    if (strcmp(Param, "TextKPreserve") == 0) {
538
0
        return param_write_int(plist,"TextKPreserve", (const int *) &(blackpreserve[3]));
539
0
    }
540
20.8k
    if (strcmp(Param, "FirstPage") == 0) {
541
0
        return param_write_int(plist, "FirstPage", &dev->FirstPage);
542
0
    }
543
20.8k
    if (strcmp(Param, "LastPage") == 0) {
544
0
        return param_write_int(plist, "LastPage", &dev->LastPage);
545
0
    }
546
20.8k
    if (strcmp(Param, "DisablePageHandler") == 0) {
547
0
        temp_bool = dev->DisablePageHandler;
548
0
        return param_write_bool(plist, "DisablePageHandler", &temp_bool);
549
0
    }
550
20.8k
    if (strcmp(Param, "NupControl") == 0){
551
0
        gs_param_string nupcontrol;
552
553
0
        if (dev->NupControl) {
554
0
            gdev_nupcontrol *p = (gdev_nupcontrol *)dev->NupControl;
555
0
            param_string_from_string(nupcontrol, p->nupcontrol_str);
556
0
        }
557
0
        else
558
0
            param_string_from_string(nupcontrol, null_str);
559
0
        return param_write_string(plist, "NupControl", &nupcontrol);
560
0
    }
561
20.8k
    if (strcmp(Param, "PageList") == 0){
562
0
        gs_param_string pagelist;
563
0
        if (dev->PageList) {
564
0
            gdev_pagelist *p = (gdev_pagelist *)dev->PageList;
565
0
            param_string_from_string(pagelist, p->Pages);
566
0
        }
567
0
        else
568
0
            param_string_from_string(pagelist, null_str);
569
0
        return param_write_string(plist, "PageList", &pagelist);
570
0
    }
571
20.8k
    if (strcmp(Param, "FILTERIMAGE") == 0) {
572
0
        temp_bool = dev->ObjectFilter & FILTERIMAGE;
573
0
        return param_write_bool(plist, "FILTERIMAGE", &temp_bool);
574
0
    }
575
20.8k
    if (strcmp(Param, "FILTERTEXT") == 0) {
576
0
        temp_bool = dev->ObjectFilter & FILTERTEXT;
577
0
        return param_write_bool(plist, "FILTERTEXT", &temp_bool);
578
0
    }
579
20.8k
    if (strcmp(Param, "FILTERVECTOR") == 0) {
580
0
        temp_bool = dev->ObjectFilter & FILTERVECTOR;
581
0
        return param_write_bool(plist, "FILTERVECTOR", &temp_bool);
582
0
    }
583
584
20.8k
    return_error(gs_error_undefined);
585
20.8k
}
586
587
/* Get standard parameters. */
588
int
589
gx_default_get_params(gx_device * dev, gs_param_list * plist)
590
305k
{
591
305k
    int code;
592
593
    /* Standard page device parameters: */
594
595
305k
    bool seprs = false;
596
305k
    gs_param_string dns, pcms, profile_array[NUM_DEVICE_PROFILES];
597
305k
    gs_param_string blend_profile, postren_profile, pagelist, nuplist;
598
305k
    gs_param_string proof_profile, link_profile, icc_colorants;
599
305k
    gsicc_rendering_intents_t profile_intents[NUM_DEVICE_PROFILES];
600
305k
    gsicc_blackptcomp_t blackptcomps[NUM_DEVICE_PROFILES];
601
305k
    gsicc_blackpreserve_t blackpreserve[NUM_DEVICE_PROFILES];
602
305k
    bool devicegraytok = true;  /* Default if device profile stuct not set */
603
305k
    bool graydetection = false;
604
305k
    bool usefastcolor = false;  /* set for unmanaged color */
605
305k
    bool blacktext = false;
606
305k
    bool blackvector = false;
607
305k
    float blackthresholdL = BLACKTHRESHOLDL;
608
305k
    float blackthresholdC = BLACKTHRESHOLDC;
609
    /* By default, only overprint if the device supports it */
610
305k
    gs_overprint_control_t overprint_control = gs_overprint_control_enable;
611
305k
    bool prebandthreshold = true, temp_bool;
612
305k
    int k;
613
305k
    int color_accuracy = MAX_COLOR_ACCURACY;
614
305k
    gs_param_float_array msa, ibba, hwra, ma;
615
305k
    gs_param_string_array scna;
616
305k
    char null_str[1]={'\0'};
617
618
305k
#define set_param_array(a, d, s)\
619
2.14M
  (a.data = d, a.size = s, a.persistent = false);
620
621
    /* Non-standard parameters: */
622
305k
    int colors = dev->color_info.num_components;
623
305k
    int mns = dev->color_info.max_components;
624
305k
    int depth = dev->color_info.depth;
625
305k
    int GrayValues = dev->color_info.max_gray + 1;
626
305k
    int HWSize[2];
627
305k
    gs_param_int_array hwsa;
628
305k
    gs_param_float_array hwma;
629
305k
    cmm_dev_profile_t *dev_profile;
630
305k
    char *colorant_names = NULL;
631
632
    /* Fill in page device parameters. */
633
634
305k
    param_string_from_string(dns, dev->dname);
635
305k
    {
636
305k
        const char *cms = get_process_color_model_name(dev);
637
638
        /* We might have an uninitialized device with */
639
        /* color_info.num_components = 0.... */
640
305k
        if ((cms != NULL) && (*cms != '\0'))
641
305k
            param_string_from_string(pcms, cms);
642
0
        else
643
0
            pcms.data = 0;
644
305k
    }
645
646
305k
    set_param_array(hwra, dev->HWResolution, 2);
647
305k
    set_param_array(msa, dev->MediaSize, 2);
648
305k
    set_param_array(ibba, dev->ImagingBBox, 4);
649
305k
    set_param_array(ma, dev->Margins, 2);
650
305k
    set_param_array(scna, NULL, 0);
651
652
    /* Fill in non-standard parameters. */
653
305k
    HWSize[0] = dev->width;
654
305k
    HWSize[1] = dev->height;
655
305k
    set_param_array(hwsa, HWSize, 2);
656
305k
    set_param_array(hwma, dev->HWMargins, 4);
657
    /* Check if the device profile is null.  If it is, then we need to
658
       go ahead and get it set up at this time.  If the proc is not
659
       set up yet then we are not going to do anything yet */
660
    /* Although device methods should not be NULL, they are not completely filled in until
661
     * gx_device_fill_in_procs is called, and its possible for us to get here before this
662
     * happens, so we *must* make sure the method is not NULL before we use it.
663
     */
664
305k
    if (dev_proc(dev, get_profile) != NULL) {
665
285k
        code = dev_proc(dev, get_profile)(dev,  &dev_profile);
666
285k
        if (code < 0)
667
0
            return code;
668
669
285k
        if (dev_profile == NULL) {
670
0
            code = gsicc_init_device_profile_struct(dev, NULL, 0);
671
0
            if (code < 0)
672
0
                return code;
673
0
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
674
0
            if (code < 0)
675
0
                return code;
676
0
        }
677
        /* It is possible that the current device profile name is NULL if we
678
           have a pdf14 device in line with a transparency group that is in a
679
           color space specified from a source defined ICC profile. Check for
680
           that here to avoid any access violations.  Bug 692558 */
681
1.42M
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
682
1.14M
            if (dev_profile->device_profile[k] == NULL
683
1.14M
                || dev_profile->device_profile[k]->name == NULL) {
684
855k
                param_string_from_string(profile_array[k], null_str);
685
855k
                profile_intents[k] = gsRINOTSPECIFIED;
686
855k
                blackptcomps[k] = gsBPNOTSPECIFIED;
687
855k
                blackpreserve[k] = gsBKPRESNOTSPECIFIED;
688
855k
            } else {
689
285k
                param_string_from_transient_string(profile_array[k],
690
285k
                    dev_profile->device_profile[k]->name);
691
285k
                profile_intents[k] = dev_profile->rendercond[k].rendering_intent;
692
285k
                blackptcomps[k] = dev_profile->rendercond[k].black_point_comp;
693
285k
                blackpreserve[k] = dev_profile->rendercond[k].preserve_black;
694
285k
            }
695
1.14M
        }
696
        /* The proof, link and post render profile */
697
285k
        if (dev_profile->proof_profile == NULL) {
698
285k
            param_string_from_string(proof_profile, null_str);
699
285k
        } else {
700
0
            param_string_from_transient_string(proof_profile,
701
0
                                     dev_profile->proof_profile->name);
702
0
        }
703
285k
        if (dev_profile->link_profile == NULL) {
704
285k
            param_string_from_string(link_profile, null_str);
705
285k
        } else {
706
0
            param_string_from_transient_string(link_profile,
707
0
                                     dev_profile->link_profile->name);
708
0
        }
709
285k
        if (dev_profile->postren_profile == NULL) {
710
285k
            param_string_from_string(postren_profile, null_str);
711
285k
        } else {
712
0
            param_string_from_transient_string(postren_profile,
713
0
                dev_profile->postren_profile->name);
714
0
        }
715
285k
        if (dev_profile->blend_profile == NULL) {
716
285k
            param_string_from_string(blend_profile, null_str);
717
285k
        } else {
718
0
            param_string_from_transient_string(blend_profile,
719
0
                dev_profile->blend_profile->name);
720
0
        }
721
285k
        devicegraytok = dev_profile->devicegraytok;
722
285k
        graydetection = dev_profile->graydetection;
723
285k
        usefastcolor = dev_profile->usefastcolor;
724
285k
        blacktext = dev_profile->blacktext;
725
285k
        blackvector = dev_profile->blackvector;
726
285k
        blackthresholdC = dev_profile->blackthresholdC;
727
285k
        blackthresholdL = dev_profile->blackthresholdL;
728
285k
        overprint_control = dev_profile->overprint_control;
729
285k
        prebandthreshold = dev_profile->prebandthreshold;
730
        /* With respect to Output profiles that have non-standard colorants,
731
           we rely upon the default profile to give us the colorants if they do
732
           exist. */
733
285k
        if (dev_profile->spotnames == NULL) {
734
285k
            param_string_from_string(icc_colorants, null_str);
735
285k
        } else {
736
0
            code = get_dev_icccolorants_utf8(dev->memory, dev_profile, &colorant_names);
737
0
            if (code < 0)
738
0
                return code;
739
0
            if (colorant_names != NULL) {
740
0
                param_string_from_transient_string(icc_colorants, colorant_names);
741
0
            } else {
742
0
                param_string_from_string(icc_colorants, null_str);
743
0
            }
744
0
        }
745
285k
    } else {
746
103k
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
747
82.4k
            param_string_from_string(profile_array[k], null_str);
748
82.4k
            profile_intents[k] = gsRINOTSPECIFIED;
749
82.4k
            blackptcomps[k] = gsBPNOTSPECIFIED;
750
82.4k
            blackpreserve[k] = gsBKPRESNOTSPECIFIED;
751
82.4k
        }
752
20.6k
        param_string_from_string(proof_profile, null_str);
753
20.6k
        param_string_from_string(link_profile, null_str);
754
20.6k
        param_string_from_string(icc_colorants, null_str);
755
20.6k
        param_string_from_string(postren_profile, null_str);
756
20.6k
        param_string_from_string(blend_profile, null_str);
757
20.6k
    }
758
    /* Transmit the values. */
759
    /* Standard parameters */
760
305k
    if (
761
305k
        (code = param_write_name(plist, "OutputDevice", &dns)) < 0 ||
762
305k
#ifdef PAGESIZE_IS_MEDIASIZE
763
305k
        (code = param_write_float_array(plist, "PageSize", &msa)) < 0 ||
764
305k
#endif
765
305k
        (code = (pcms.data == 0 ? 0 :
766
305k
                 param_write_name(plist, "ProcessColorModel", &pcms))) < 0 ||
767
305k
        (code = param_write_float_array(plist, "HWResolution", &hwra)) < 0 ||
768
305k
        (code = (dev->ImagingBBox_set ?
769
0
                 param_write_float_array(plist, "ImagingBBox", &ibba) :
770
305k
                 param_write_null(plist, "ImagingBBox"))) < 0 ||
771
305k
        (code = param_write_float_array(plist, "Margins", &ma)) < 0 ||
772
305k
        (code = param_write_int(plist, "MaxSeparations", &mns)) < 0 ||
773
305k
        (code = (dev->NumCopies_set < 0 ||
774
305k
                 (*dev_proc(dev, get_page_device))(dev) == 0 ? 0:
775
305k
                 dev->NumCopies_set ?
776
0
                 param_write_int(plist, "NumCopies", &dev->NumCopies) :
777
305k
                 param_write_null(plist, "NumCopies"))) < 0 ||
778
305k
        (code = param_write_name_array(plist, "SeparationColorNames", &scna)) < 0 ||
779
305k
        (code = param_write_bool(plist, "Separations", &seprs)) < 0 ||
780
305k
        (code = param_write_bool(plist, "UseCIEColor", &dev->UseCIEColor)) < 0 ||
781
        /* Non-standard parameters */
782
        /* Note:  if change is made in NUM_DEVICE_PROFILES we need to name
783
           that profile here for the device parameter on the command line */
784
305k
        (code = param_write_bool(plist, "DeviceGrayToK", &devicegraytok)) < 0 ||
785
305k
        (code = param_write_bool(plist, "GrayDetection", &graydetection)) < 0 ||
786
305k
        (code = param_write_bool(plist, "UseFastColor", &usefastcolor)) < 0 ||
787
305k
        (code = param_write_bool(plist, "BlackText", &blacktext)) < 0 ||
788
305k
        (code = param_write_bool(plist, "BlackVector", &blackvector)) < 0 ||
789
305k
        (code = param_write_float(plist, "BlackThresholdL", &blackthresholdL)) < 0 ||
790
305k
        (code = param_write_float(plist, "BlackThresholdC", &blackthresholdC)) < 0 ||
791
305k
        (code = param_write_bool(plist, "PreBandThreshold", &prebandthreshold)) < 0 ||
792
305k
        (code = param_write_string(plist,"OutputICCProfile", &(profile_array[0]))) < 0 ||
793
305k
        (code = param_write_string(plist,"VectorICCProfile", &(profile_array[1]))) < 0 ||
794
305k
        (code = param_write_string(plist,"ImageICCProfile", &(profile_array[2]))) < 0 ||
795
305k
        (code = param_write_string(plist,"TextICCProfile", &(profile_array[3]))) < 0 ||
796
305k
        (code = param_write_string(plist,"ProofProfile", &(proof_profile))) < 0 ||
797
305k
        (code = param_write_string(plist, "PostRenderProfile", &(postren_profile))) < 0 ||
798
305k
        (code = param_write_string(plist, "BlendColorProfile", &(blend_profile))) < 0 ||
799
305k
        (code = param_write_string(plist,"DeviceLinkProfile", &(link_profile))) < 0 ||
800
305k
        (code = param_write_string(plist,"ICCOutputColors", &(icc_colorants))) < 0 ||
801
305k
        (code = param_write_int(plist, "RenderIntent", (const int *)(&(profile_intents[0])))) < 0 ||
802
305k
        (code = param_write_int(plist, "ColorAccuracy", (const int *)(&(color_accuracy)))) < 0 ||
803
305k
        (code = param_write_int(plist,"VectorIntent", (const int *) &(profile_intents[1]))) < 0 ||
804
305k
        (code = param_write_int(plist,"ImageIntent", (const int *) &(profile_intents[2]))) < 0 ||
805
305k
        (code = param_write_int(plist,"TextIntent", (const int *) &(profile_intents[3]))) < 0 ||
806
305k
        (code = param_write_int(plist,"BlackPtComp", (const int *) (&(blackptcomps[0])))) < 0 ||
807
305k
        (code = param_write_int(plist,"VectorBlackPt", (const int *) &(blackptcomps[1]))) < 0 ||
808
305k
        (code = param_write_int(plist,"ImageBlackPt", (const int *) &(blackptcomps[2]))) < 0 ||
809
305k
        (code = param_write_int(plist,"TextBlackPt", (const int *) &(blackptcomps[3]))) < 0 ||
810
305k
        (code = param_write_int(plist,"KPreserve", (const int *) (&(blackpreserve[0])))) < 0 ||
811
305k
        (code = param_write_int(plist,"VectorKPreserve", (const int *) &(blackpreserve[1]))) < 0 ||
812
305k
        (code = param_write_int(plist,"ImageKPreserve", (const int *) &(blackpreserve[2]))) < 0 ||
813
305k
        (code = param_write_int(plist,"TextKPreserve", (const int *) &(blackpreserve[3]))) < 0 ||
814
305k
        (code = param_write_int_array(plist, "HWSize", &hwsa)) < 0 ||
815
305k
        (code = param_write_float_array(plist, ".HWMargins", &hwma)) < 0 ||
816
305k
        (code = param_write_float_array(plist, ".MediaSize", &msa)) < 0 ||
817
305k
        (code = param_write_string(plist, "Name", &dns)) < 0 ||
818
305k
        (code = param_write_int(plist, "Colors", &colors)) < 0 ||
819
305k
        (code = param_write_int(plist, "BitsPerPixel", &depth)) < 0 ||
820
305k
        (code = param_write_int(plist, "GrayValues", &GrayValues)) < 0 ||
821
305k
        (code = param_write_long(plist, "PageCount", &dev->PageCount)) < 0 ||
822
305k
        (code = param_write_bool(plist, ".IgnoreNumCopies", &dev->IgnoreNumCopies)) < 0 ||
823
305k
        (code = param_write_int(plist, "TextAlphaBits",
824
305k
                                &dev->color_info.anti_alias.text_bits)) < 0 ||
825
305k
        (code = param_write_int(plist, "GraphicsAlphaBits",
826
305k
                                &dev->color_info.anti_alias.graphics_bits)) < 0 ||
827
305k
        (code = param_write_bool(plist, "AntidropoutDownscaler",
828
305k
                                &dev->color_info.use_antidropout_downscaler)) < 0 ||
829
305k
        (code = param_write_bool(plist, ".LockSafetyParams", &dev->LockSafetyParams)) < 0 ||
830
305k
        (code = param_write_size_t(plist, "MaxPatternBitmap", &dev->MaxPatternBitmap)) < 0 ||
831
305k
        (code = param_write_bool(plist, "PageUsesTransparency", &dev->page_uses_transparency)) < 0 ||
832
305k
        (code = param_write_bool(plist, "PageUsesOverprint", &dev->page_uses_overprint)) < 0 ||
833
305k
        (code = param_write_size_t(plist, "MaxBitmap", &(dev->space_params.MaxBitmap))) < 0 ||
834
305k
        (code = param_write_size_t(plist, "BandBufferSpace", &dev->space_params.band.BandBufferSpace)) < 0 ||
835
305k
        (code = param_write_int(plist, "BandHeight", &dev->space_params.band.BandHeight)) < 0 ||
836
305k
        (code = param_write_int(plist, "BandWidth", &dev->space_params.band.BandWidth)) < 0 ||
837
305k
        (code = param_write_size_t(plist, "BufferSpace", &dev->space_params.BufferSpace)) < 0 ||
838
305k
        (code = param_write_int(plist, "InterpolateControl", &dev->interpolate_control)) < 0
839
305k
        )
840
0
    {
841
0
        gs_free_object(dev->memory, colorant_names, "gx_default_get_param");
842
0
        return code;
843
0
    }
844
305k
    gs_free_object(dev->memory, colorant_names, "gx_default_get_param");
845
305k
    {
846
305k
        gs_param_string opc_name;
847
305k
        const char *s = overprint_control_names[(int)overprint_control];
848
849
305k
        param_string_from_string(opc_name, s);
850
305k
        param_write_name(plist, "Overprint", &opc_name);
851
305k
    }
852
    /* If LeadingEdge was set explicitly, report it here. */
853
305k
    if (dev->LeadingEdge & LEADINGEDGE_SET_MASK) {
854
0
        int leadingedge = dev->LeadingEdge & LEADINGEDGE_MASK;
855
0
        code = param_write_int(plist, "LeadingEdge", &leadingedge);
856
0
    } else
857
305k
        code = param_write_null(plist, "LeadingEdge");
858
305k
    if (code < 0)
859
0
        return code;
860
861
305k
    if ((code = param_write_int(plist, "FirstPage", &dev->FirstPage)) < 0)
862
0
        return code;
863
305k
    if ((code = param_write_int(plist, "LastPage", &dev->LastPage)) < 0)
864
0
        return code;
865
866
305k
    temp_bool = dev->DisablePageHandler;
867
305k
    if ((code = param_write_bool(plist, "DisablePageHandler", &temp_bool)) < 0)
868
0
        return code;
869
870
305k
    if (dev->NupControl) {
871
0
        gdev_nupcontrol *p = (gdev_nupcontrol *)dev->NupControl;
872
0
        param_string_from_string(nuplist, p->nupcontrol_str);
873
305k
    } else {
874
305k
        param_string_from_string(nuplist, null_str);
875
305k
    }
876
305k
    if ((code = param_write_string(plist, "NupControl", &nuplist)) < 0)
877
0
        return code;
878
879
305k
    if (dev->PageList) {
880
0
        gdev_pagelist *p = (gdev_pagelist *)dev->PageList;
881
0
        param_string_from_transient_string(pagelist, p->Pages);
882
305k
    } else {
883
305k
        param_string_from_string(pagelist, null_str);
884
305k
    }
885
305k
    if ((code = param_write_string(plist, "PageList", &pagelist)) < 0)
886
0
        return code;
887
888
305k
    temp_bool = dev->ObjectFilter & FILTERIMAGE;
889
305k
    if ((code = param_write_bool(plist, "FILTERIMAGE", &temp_bool)) < 0)
890
0
        return code;
891
305k
    temp_bool = dev->ObjectFilter & FILTERTEXT;
892
305k
    if ((code = param_write_bool(plist, "FILTERTEXT", &temp_bool)) < 0)
893
0
        return code;
894
305k
    temp_bool = dev->ObjectFilter & FILTERVECTOR;
895
305k
    if ((code = param_write_bool(plist, "FILTERVECTOR", &temp_bool)) < 0)
896
0
        return code;
897
898
    /* Fill in color information. */
899
900
305k
    if (colors > 1) {
901
305k
        int RGBValues = dev->color_info.max_color + 1;
902
305k
        long ColorValues = (depth >= 32 ? -1 : 1L << depth); /* value can only be 32 bits */
903
904
305k
        if ((code = param_write_int(plist, "RedValues", &RGBValues)) < 0 ||
905
305k
            (code = param_write_int(plist, "GreenValues", &RGBValues)) < 0 ||
906
305k
            (code = param_write_int(plist, "BlueValues", &RGBValues)) < 0 ||
907
305k
            (code = param_write_long(plist, "ColorValues", &ColorValues)) < 0
908
305k
            )
909
0
            return code;
910
305k
    }
911
305k
    if (param_requested(plist, "HWColorMap")) {
912
30.9k
        byte palette[3 << 8];
913
914
30.9k
        if (param_HWColorMap(dev, palette)) {
915
0
            gs_param_string hwcms;
916
917
0
            hwcms.data = palette, hwcms.size = colors << depth,
918
0
                hwcms.persistent = false;
919
0
            if ((code = param_write_string(plist, "HWColorMap", &hwcms)) < 0)
920
0
                return code;
921
0
        }
922
30.9k
    }
923
924
305k
    return 0;
925
305k
}
926
927
/* Get the color map for a device.  Return true if there is one. */
928
static bool
929
param_HWColorMap(gx_device * dev, byte * palette /* 3 << 8 */ )
930
30.9k
{
931
30.9k
    int depth = dev->color_info.depth;
932
30.9k
    int colors = dev->color_info.num_components;
933
934
30.9k
    if (depth <= 8 && colors <= 3) {
935
0
        byte *p = palette;
936
0
        gx_color_value rgb[3];
937
0
        gx_color_index i;
938
939
0
        fill_dev_proc(dev, map_color_rgb, gx_default_map_color_rgb);
940
0
        for (i = 0; (i >> depth) == 0; i++) {
941
0
            int j;
942
943
0
            if ((*dev_proc(dev, map_color_rgb)) (dev, i, rgb) < 0)
944
0
                return false;
945
0
            for (j = 0; j < colors; j++)
946
0
                *p++ = gx_color_value_to_byte(rgb[j]);
947
0
        }
948
0
        return true;
949
0
    }
950
30.9k
    return false;
951
30.9k
}
952
953
/* Get hardware-detected parameters. Default action is no hardware params. */
954
int
955
gx_default_get_hardware_params(gx_device * dev, gs_param_list * plist)
956
0
{
957
0
    return 0;
958
0
}
959
960
/* ---------------- Input and output media ---------------- */
961
962
/* Finish defining input or output media. */
963
static int
964
finish_media(gs_param_list * mlist, gs_param_name key, const char *media_type)
965
0
{
966
0
    int code = 0;
967
968
0
    if (media_type != 0) {
969
0
        gs_param_string as;
970
971
0
        param_string_from_string(as, media_type);
972
0
        code = param_write_string(mlist, key, &as);
973
0
    }
974
0
    return code;
975
0
}
976
977
/* Define input media. */
978
979
const gdev_input_media_t gdev_input_media_default =
980
{
981
    gdev_input_media_default_values
982
};
983
984
int
985
gdev_begin_input_media(gs_param_list * mlist, gs_param_dict * pdict,
986
                       int count)
987
0
{
988
0
    pdict->size = count;
989
0
    return param_begin_write_dict(mlist, "InputAttributes", pdict, true);
990
0
}
991
992
int
993
gdev_write_input_media(int index, gs_param_dict * pdict,
994
                       const gdev_input_media_t * pim)
995
0
{
996
0
    char key[25];
997
0
    gs_param_dict mdict;
998
0
    int code;
999
0
    gs_param_string as;
1000
1001
0
    gs_snprintf(key, sizeof(key), "%d", index);
1002
0
    mdict.size = 4;
1003
0
    code = param_begin_write_dict(pdict->list, key, &mdict, false);
1004
0
    if (code < 0)
1005
0
        return code;
1006
0
    if ((pim->PageSize[0] != 0 && pim->PageSize[1] != 0) ||
1007
0
        (pim->PageSize[2] != 0 && pim->PageSize[3] != 0)
1008
0
        ) {
1009
0
        gs_param_float_array psa;
1010
1011
0
        psa.data = pim->PageSize;
1012
0
        psa.size =
1013
0
            (pim->PageSize[0] == pim->PageSize[2] &&
1014
0
             pim->PageSize[1] == pim->PageSize[3] ? 2 : 4);
1015
0
        psa.persistent = false;
1016
0
        code = param_write_float_array(mdict.list, "PageSize",
1017
0
                                       &psa);
1018
0
        if (code < 0)
1019
0
            return code;
1020
0
    }
1021
0
    if (pim->MediaColor != 0) {
1022
0
        param_string_from_string(as, pim->MediaColor);
1023
0
        code = param_write_string(mdict.list, "MediaColor",
1024
0
                                  &as);
1025
0
        if (code < 0)
1026
0
            return code;
1027
0
    }
1028
0
    if (pim->MediaWeight != 0) {
1029
        /*
1030
         * We do the following silly thing in order to avoid
1031
         * having to work around the 'const' in the arg list.
1032
         */
1033
0
        float weight = pim->MediaWeight;
1034
1035
0
        code = param_write_float(mdict.list, "MediaWeight",
1036
0
                                 &weight);
1037
0
        if (code < 0)
1038
0
            return code;
1039
0
    }
1040
0
    code = finish_media(mdict.list, "MediaType", pim->MediaType);
1041
0
    if (code < 0)
1042
0
        return code;
1043
0
    return param_end_write_dict(pdict->list, key, &mdict);
1044
0
}
1045
1046
int
1047
gdev_write_input_page_size(int index, gs_param_dict * pdict,
1048
                           double width_points, double height_points)
1049
0
{
1050
0
    gdev_input_media_t media;
1051
1052
0
    media.PageSize[0] = media.PageSize[2] = (float) width_points;
1053
0
    media.PageSize[1] = media.PageSize[3] = (float) height_points;
1054
0
    media.MediaColor = 0;
1055
0
    media.MediaWeight = 0;
1056
0
    media.MediaType = 0;
1057
0
    return gdev_write_input_media(index, pdict, &media);
1058
0
}
1059
1060
int
1061
gdev_end_input_media(gs_param_list * mlist, gs_param_dict * pdict)
1062
0
{
1063
0
    return param_end_write_dict(mlist, "InputAttributes", pdict);
1064
0
}
1065
1066
/* Define output media. */
1067
1068
const gdev_output_media_t gdev_output_media_default =
1069
{
1070
    gdev_output_media_default_values
1071
};
1072
1073
int
1074
gdev_begin_output_media(gs_param_list * mlist, gs_param_dict * pdict,
1075
                        int count)
1076
0
{
1077
0
    pdict->size = count;
1078
0
    return param_begin_write_dict(mlist, "OutputAttributes", pdict, true);
1079
0
}
1080
1081
int
1082
gdev_write_output_media(int index, gs_param_dict * pdict,
1083
                        const gdev_output_media_t * pom)
1084
0
{
1085
0
    char key[25];
1086
0
    gs_param_dict mdict;
1087
0
    int code;
1088
1089
0
    gs_snprintf(key, sizeof(key), "%d", index);
1090
0
    mdict.size = 4;
1091
0
    code = param_begin_write_dict(pdict->list, key, &mdict, false);
1092
0
    if (code < 0)
1093
0
        return code;
1094
0
    code = finish_media(mdict.list, "OutputType", pom->OutputType);
1095
0
    if (code < 0)
1096
0
        return code;
1097
0
    return param_end_write_dict(pdict->list, key, &mdict);
1098
0
}
1099
1100
int
1101
gdev_end_output_media(gs_param_list * mlist, gs_param_dict * pdict)
1102
0
{
1103
0
    return param_end_write_dict(mlist, "OutputAttributes", pdict);
1104
0
}
1105
1106
/* ================ Putting parameters ================ */
1107
1108
/* Forward references */
1109
static int param_normalize_anti_alias_bits( uint max_gray, int bits );
1110
static int param_anti_alias_bits(gs_param_list *, gs_param_name, int *);
1111
static int param_MediaSize(gs_param_list *, gs_param_name,
1112
                            const float *, gs_param_float_array *);
1113
1114
static int param_check_bool(gs_param_list *, gs_param_name, bool, bool);
1115
static int param_check_long(gs_param_list *, gs_param_name, long, bool);
1116
#define param_check_int(plist, pname, ival, is_defined)\
1117
675k
  param_check_long(plist, pname, (long)(ival), is_defined)
1118
static int param_check_bytes(gs_param_list *, gs_param_name, const byte *,
1119
                              uint, bool);
1120
#define param_check_string(plist, pname, str, is_defined)\
1121
337k
  param_check_bytes(plist, pname, (const byte *)(str), \
1122
337k
                    (is_defined) ? strlen(str) : 0, is_defined)
1123
1124
/* Set the device parameters. */
1125
/* If the device was open and the put_params procedure closed it, */
1126
/* return 1; otherwise, return 0 or an error code as usual. */
1127
int
1128
gs_putdeviceparams(gx_device * dev, gs_param_list * plist)
1129
236k
{
1130
236k
    bool was_open = dev->is_open;
1131
236k
    int code;
1132
1133
    /* gs_param_list_dump(plist); */
1134
1135
236k
    fill_dev_proc(dev, put_params, gx_default_put_params);
1136
236k
    fill_dev_proc(dev, get_alpha_bits, gx_default_get_alpha_bits);
1137
236k
    code = (*dev_proc(dev, put_params)) (dev, plist);
1138
236k
    return (code < 0 ? code : was_open && !dev->is_open ? 1 : code);
1139
236k
}
1140
1141
static int
1142
gx_default_put_graydetection(bool graydetection, gx_device * dev)
1143
112k
{
1144
112k
    int code = 0;
1145
112k
    cmm_dev_profile_t *profile_struct;
1146
1147
    /* Although device methods should not be NULL, they are not completely filled in until
1148
     * gx_device_fill_in_procs is called, and its possible for us to get here before this
1149
     * happens, so we *must* make sure the method is not NULL before we use it.
1150
     */
1151
112k
    if (dev_proc(dev, get_profile) == NULL) {
1152
        /* This is an odd case where the device has not yet fully been
1153
           set up with its procedures yet.  We want to make sure that
1154
           we catch this so we assume here that we are dealing with
1155
           the target device.  For now allocate the profile structure
1156
           but do not intialize the profile yet as the color info
1157
           may not be fully set up at this time.  */
1158
20.6k
        if (dev->icc_struct == NULL) {
1159
            /* Allocate at this time the structure */
1160
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1161
0
            if (dev->icc_struct == NULL)
1162
0
                return_error(gs_error_VMerror);
1163
0
        }
1164
20.6k
        dev->icc_struct->graydetection = graydetection;
1165
20.6k
        dev->icc_struct->pageneutralcolor = graydetection;
1166
91.9k
    } else {
1167
91.9k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1168
91.9k
        if (profile_struct == NULL) {
1169
            /* Create now  */
1170
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1171
0
            if (dev->icc_struct == NULL)
1172
0
                return_error(gs_error_VMerror);
1173
0
            profile_struct =  dev->icc_struct;
1174
0
        }
1175
91.9k
        profile_struct->graydetection = graydetection;
1176
91.9k
        profile_struct->pageneutralcolor = graydetection;
1177
91.9k
    }
1178
112k
    return code;
1179
112k
}
1180
1181
static int
1182
gx_default_put_graytok(bool graytok, gx_device * dev)
1183
112k
{
1184
112k
    int code = 0;
1185
112k
    cmm_dev_profile_t *profile_struct;
1186
1187
    /* Although device methods should not be NULL, they are not completely filled in until
1188
     * gx_device_fill_in_procs is called, and its possible for us to get here before this
1189
     * happens, so we *must* make sure the method is not NULL before we use it.
1190
     */
1191
112k
    if (dev_proc(dev, get_profile) == NULL) {
1192
        /* This is an odd case where the device has not yet fully been
1193
           set up with its procedures yet.  We want to make sure that
1194
           we catch this so we assume here that we are dealing with
1195
           the target device.  For now allocate the profile structure
1196
           but do not intialize the profile yet as the color info
1197
           may not be fully set up at this time.  */
1198
20.6k
        if (dev->icc_struct == NULL) {
1199
            /* Allocate at this time the structure */
1200
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1201
0
            if (dev->icc_struct == NULL)
1202
0
                return_error(gs_error_VMerror);
1203
0
        }
1204
20.6k
        dev->icc_struct->devicegraytok = graytok;
1205
91.9k
    } else {
1206
91.9k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1207
91.9k
        if (profile_struct == NULL) {
1208
            /* Create now  */
1209
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1210
0
            profile_struct =  dev->icc_struct;
1211
0
            if (profile_struct == NULL)
1212
0
                return_error(gs_error_VMerror);
1213
0
        }
1214
91.9k
        profile_struct->devicegraytok = graytok;
1215
91.9k
    }
1216
112k
    return code;
1217
112k
}
1218
1219
static int
1220
gx_default_put_prebandthreshold(bool prebandthreshold, gx_device * dev)
1221
112k
{
1222
112k
    int code = 0;
1223
112k
    cmm_dev_profile_t *profile_struct;
1224
1225
    /* Although device methods should not be NULL, they are not completely filled in until
1226
     * gx_device_fill_in_procs is called, and its possible for us to get here before this
1227
     * happens, so we *must* make sure the method is not NULL before we use it.
1228
     */
1229
112k
    if (dev_proc(dev, get_profile) == NULL) {
1230
        /* This is an odd case where the device has not yet fully been
1231
           set up with its procedures yet.  We want to make sure that
1232
           we catch this so we assume here that we are dealing with
1233
           the target device.  For now allocate the profile structure
1234
           but do not intialize the profile yet as the color info
1235
           may not be fully set up at this time.  */
1236
20.6k
        if (dev->icc_struct == NULL) {
1237
            /* Allocate at this time the structure */
1238
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1239
0
            if (dev->icc_struct == NULL)
1240
0
                return_error(gs_error_VMerror);
1241
0
        }
1242
20.6k
        dev->icc_struct->prebandthreshold = prebandthreshold;
1243
91.9k
    } else {
1244
91.9k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1245
91.9k
        if (profile_struct == NULL) {
1246
            /* Create now  */
1247
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1248
0
            profile_struct =  dev->icc_struct;
1249
0
            if (profile_struct == NULL)
1250
0
                return_error(gs_error_VMerror);
1251
0
        }
1252
91.9k
        profile_struct->prebandthreshold = prebandthreshold;
1253
91.9k
    }
1254
112k
    return code;
1255
112k
}
1256
1257
static int
1258
gx_default_put_usefastcolor(bool fastcolor, gx_device * dev)
1259
112k
{
1260
112k
    int code = 0;
1261
112k
    cmm_dev_profile_t *profile_struct;
1262
1263
    /* Although device methods should not be NULL, they are not completely filled in until
1264
     * gx_device_fill_in_procs is called, and its possible for us to get here before this
1265
     * happens, so we *must* make sure the method is not NULL before we use it.
1266
     */
1267
112k
    if (dev_proc(dev, get_profile) == NULL) {
1268
        /* This is an odd case where the device has not yet fully been
1269
           set up with its procedures yet.  We want to make sure that
1270
           we catch this so we assume here that we are dealing with
1271
           the target device.  For now allocate the profile structure
1272
           but do not intialize the profile yet as the color info
1273
           may not be fully set up at this time.  */
1274
20.6k
        if (dev->icc_struct == NULL) {
1275
            /* Allocate at this time the structure */
1276
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1277
0
            if (dev->icc_struct == NULL)
1278
0
                return_error(gs_error_VMerror);
1279
0
        }
1280
20.6k
        dev->icc_struct->usefastcolor = fastcolor;
1281
91.9k
    } else {
1282
91.9k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1283
91.9k
        if (profile_struct == NULL) {
1284
            /* Create now  */
1285
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1286
0
            profile_struct =  dev->icc_struct;
1287
0
            if (profile_struct == NULL)
1288
0
                return_error(gs_error_VMerror);
1289
0
        }
1290
91.9k
        profile_struct->usefastcolor = fastcolor;
1291
91.9k
    }
1292
112k
    return code;
1293
112k
}
1294
1295
static int
1296
gx_default_put_blacktext(bool blacktext, gx_device* dev)
1297
112k
{
1298
112k
    int code = 0;
1299
112k
    cmm_dev_profile_t* profile_struct;
1300
1301
112k
    if (dev_proc(dev, get_profile) == NULL) {
1302
20.6k
        if (dev->icc_struct == NULL) {
1303
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1304
0
            if (dev->icc_struct == NULL)
1305
0
                return_error(gs_error_VMerror);
1306
0
        }
1307
20.6k
        dev->icc_struct->blacktext = blacktext;
1308
91.9k
    } else {
1309
91.9k
        code = dev_proc(dev, get_profile)(dev, &profile_struct);
1310
91.9k
        if (profile_struct == NULL) {
1311
            /* Create now  */
1312
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1313
0
            profile_struct = dev->icc_struct;
1314
0
            if (profile_struct == NULL)
1315
0
                return_error(gs_error_VMerror);
1316
0
        }
1317
91.9k
        profile_struct->blacktext = blacktext;
1318
91.9k
    }
1319
112k
    return code;
1320
112k
}
1321
1322
static int
1323
gx_default_put_blackthresholds(float blackthresholdL, float blackthresholdC, gx_device *dev)
1324
112k
{
1325
112k
    int code = 0;
1326
112k
    cmm_dev_profile_t* profile_struct;
1327
1328
112k
    if (dev_proc(dev, get_profile) == NULL) {
1329
20.6k
        if (dev->icc_struct == NULL) {
1330
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1331
0
            if (dev->icc_struct == NULL)
1332
0
                return_error(gs_error_VMerror);
1333
0
        }
1334
20.6k
        dev->icc_struct->blackthresholdL = blackthresholdL;
1335
20.6k
        dev->icc_struct->blackthresholdC = blackthresholdC;
1336
91.9k
    } else {
1337
91.9k
        code = dev_proc(dev, get_profile)(dev, &profile_struct);
1338
91.9k
        if (profile_struct == NULL) {
1339
            /* Create now  */
1340
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1341
0
            profile_struct = dev->icc_struct;
1342
0
            if (profile_struct == NULL)
1343
0
                return_error(gs_error_VMerror);
1344
0
        }
1345
91.9k
        profile_struct->blackthresholdL = blackthresholdL;
1346
91.9k
        profile_struct->blackthresholdC = blackthresholdC;
1347
91.9k
    }
1348
112k
    return code;
1349
112k
}
1350
1351
static int
1352
gx_default_put_blackvector(bool blackvector, gx_device* dev)
1353
112k
{
1354
112k
    int code = 0;
1355
112k
    cmm_dev_profile_t* profile_struct;
1356
1357
112k
    if (dev_proc(dev, get_profile) == NULL) {
1358
20.6k
        if (dev->icc_struct == NULL) {
1359
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1360
0
            if (dev->icc_struct == NULL)
1361
0
                return_error(gs_error_VMerror);
1362
0
        }
1363
20.6k
        dev->icc_struct->blackvector = blackvector;
1364
91.9k
    } else {
1365
91.9k
        code = dev_proc(dev, get_profile)(dev, &profile_struct);
1366
91.9k
        if (profile_struct == NULL) {
1367
            /* Create now  */
1368
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1369
0
            profile_struct = dev->icc_struct;
1370
0
            if (profile_struct == NULL)
1371
0
                return_error(gs_error_VMerror);
1372
0
        }
1373
91.9k
        profile_struct->blackvector = blackvector;
1374
91.9k
    }
1375
112k
    return code;
1376
112k
}
1377
1378
static int
1379
gx_default_put_overprint_control(gs_overprint_control_t overprint_control, gx_device * dev)
1380
112k
{
1381
112k
    int code = 0;
1382
112k
    cmm_dev_profile_t *profile_struct;
1383
1384
    /* Although device methods should not be NULL, they are not completely filled in until
1385
     * gx_device_fill_in_procs is called, and its possible for us to get here before this
1386
     * happens, so we *must* make sure the method is not NULL before we use it.
1387
     */
1388
112k
    if (dev_proc(dev, get_profile) == NULL) {
1389
        /* This is an odd case where the device has not yet fully been
1390
           set up with its procedures yet.  We want to make sure that
1391
           we catch this so we assume here that we are dealing with
1392
           the target device.  For now allocate the profile structure
1393
           but do not intialize the profile yet as the color info
1394
           may not be fully set up at this time.  */
1395
20.6k
        if (dev->icc_struct == NULL) {
1396
            /* Allocate at this time the structure */
1397
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1398
0
            if (dev->icc_struct == NULL)
1399
0
                return_error(gs_error_VMerror);
1400
0
        }
1401
20.6k
        dev->icc_struct->overprint_control = overprint_control;
1402
91.9k
    } else {
1403
91.9k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1404
91.9k
        if (profile_struct == NULL) {
1405
            /* Create now  */
1406
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1407
0
            profile_struct =  dev->icc_struct;
1408
0
            if (profile_struct == NULL)
1409
0
                return_error(gs_error_VMerror);
1410
0
        }
1411
91.9k
        profile_struct->overprint_control = overprint_control;
1412
91.9k
    }
1413
112k
    return code;
1414
112k
}
1415
1416
static int
1417
gx_default_put_intent(gsicc_rendering_intents_t icc_intent, gx_device * dev,
1418
                   gsicc_profile_types_t index)
1419
450k
{
1420
450k
    int code;
1421
450k
    cmm_dev_profile_t *profile_struct;
1422
1423
    /* Although device methods should not be NULL, they are not completely filled in until
1424
     * gx_device_fill_in_procs is called, and its possible for us to get here before this
1425
     * happens, so we *must* make sure the method is not NULL before we use it.
1426
     */
1427
450k
    if (dev_proc(dev, get_profile) == NULL) {
1428
        /* This is an odd case where the device has not yet fully been
1429
           set up with its procedures yet.  We want to make sure that
1430
           we catch this so we assume here that we are dealing with
1431
           the target device */
1432
82.4k
        if (dev->icc_struct == NULL) {
1433
            /* Intializes the device structure.  Not the profile though for index */
1434
10.3k
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1435
10.3k
            if (dev->icc_struct == NULL)
1436
0
                return_error(gs_error_VMerror);
1437
10.3k
        }
1438
82.4k
        code = gsicc_set_device_profile_intent(dev, icc_intent, index);
1439
367k
    } else {
1440
367k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1441
367k
        if (code < 0)
1442
0
            return code;
1443
367k
        if (profile_struct == NULL) {
1444
            /* Create now  */
1445
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1446
0
            if (dev->icc_struct == NULL)
1447
0
                return_error(gs_error_VMerror);
1448
0
        }
1449
367k
        code = gsicc_set_device_profile_intent(dev, icc_intent, index);
1450
367k
    }
1451
450k
    return code;
1452
450k
}
1453
1454
static int
1455
gx_default_put_blackpreserve(gsicc_blackpreserve_t blackpreserve, gx_device * dev,
1456
                           gsicc_profile_types_t index)
1457
450k
{
1458
450k
    int code;
1459
450k
    cmm_dev_profile_t *profile_struct;
1460
1461
    /* Although device methods should not be NULL, they are not completely filled in until
1462
     * gx_device_fill_in_procs is called, and its possible for us to get here before this
1463
     * happens, so we *must* make sure the method is not NULL before we use it.
1464
     */
1465
450k
    if (dev_proc(dev, get_profile) == NULL) {
1466
        /* This is an odd case where the device has not yet fully been
1467
           set up with its procedures yet.  We want to make sure that
1468
           we catch this so we assume here that we are dealing with
1469
           the target device */
1470
82.4k
        if (dev->icc_struct == NULL) {
1471
            /* Intializes the device structure.  Not the profile though for index */
1472
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1473
0
            if (dev->icc_struct == NULL)
1474
0
                return_error(gs_error_VMerror);
1475
0
        }
1476
82.4k
        code = gsicc_set_device_blackpreserve(dev, blackpreserve, index);
1477
367k
    } else {
1478
367k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1479
367k
        if (code < 0)
1480
0
            return code;
1481
367k
        if (profile_struct == NULL) {
1482
            /* Create now  */
1483
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1484
0
            if (dev->icc_struct == NULL)
1485
0
                return_error(gs_error_VMerror);
1486
0
        }
1487
367k
        code = gsicc_set_device_blackpreserve(dev, blackpreserve, index);
1488
367k
    }
1489
450k
    return code;
1490
450k
}
1491
1492
1493
1494
1495
static int
1496
gx_default_put_blackptcomp(gsicc_blackptcomp_t blackptcomp, gx_device * dev,
1497
                           gsicc_profile_types_t index)
1498
450k
{
1499
450k
    int code;
1500
450k
    cmm_dev_profile_t *profile_struct;
1501
1502
    /* Although device methods should not be NULL, they are not completely filled in until
1503
     * gx_device_fill_in_procs is called, and its possible for us to get here before this
1504
     * happens, so we *must* make sure the method is not NULL before we use it.
1505
     */
1506
450k
    if (dev_proc(dev, get_profile) == NULL) {
1507
        /* This is an odd case where the device has not yet fully been
1508
           set up with its procedures yet.  We want to make sure that
1509
           we catch this so we assume here that we are dealing with
1510
           the target device */
1511
82.4k
        if (dev->icc_struct == NULL) {
1512
            /* Intializes the device structure.  Not the profile though for index */
1513
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1514
0
            if (dev->icc_struct == NULL)
1515
0
                return_error(gs_error_VMerror);
1516
0
        }
1517
82.4k
        code = gsicc_set_device_blackptcomp(dev, blackptcomp, index);
1518
367k
    } else {
1519
367k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1520
367k
        if (code < 0)
1521
0
            return code;
1522
367k
        if (profile_struct == NULL) {
1523
            /* Create now  */
1524
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1525
0
            if (dev->icc_struct == NULL)
1526
0
                return_error(gs_error_VMerror);
1527
0
        }
1528
367k
        code = gsicc_set_device_blackptcomp(dev, blackptcomp, index);
1529
367k
    }
1530
450k
    return code;
1531
450k
}
1532
1533
static int
1534
gx_default_put_icc_colorants(gs_param_string *colorants, gx_device * dev)
1535
8.88k
{
1536
8.88k
    char *tempstr;
1537
8.88k
    int code;
1538
8.88k
    int len;
1539
8.88k
    unsigned short *tempstr2 = NULL;
1540
8.88k
    unsigned short *s;
1541
8.88k
    char *d;
1542
1543
8.88k
    if (colorants->size == 0) return 0;
1544
1545
    /* See below about this device fill proc */
1546
0
    fill_dev_proc(dev, get_profile, gx_default_get_profile);
1547
0
    tempstr = (char *) gs_alloc_bytes(dev->memory, colorants->size+1,
1548
0
                                      "gx_default_put_icc_colorants");
1549
0
    if (tempstr == NULL)
1550
0
        return_error(gs_error_VMerror);
1551
1552
0
    memcpy(tempstr, colorants->data, colorants->size);
1553
    /* Set last position to NULL. */
1554
0
    tempstr[colorants->size] = 0;
1555
1556
    /* The input colorants string is UTF-8 encoded. We want it to be put into the
1557
     * device as 8-bit 'raw' values. We therefore need to decode it here. Any
1558
     * UTF-8 chars that do not decode to 8 bits will be flagged up as a rangecheck.
1559
     */
1560
0
    len = gp_utf8_to_uint16(NULL, tempstr);
1561
0
    if (len >= 0)
1562
0
        tempstr2 = (unsigned short *)gs_alloc_bytes(dev->memory, len * sizeof(unsigned short),
1563
0
                                                "gx_default_put_icc_colorants");
1564
0
    if (tempstr2 == NULL)
1565
0
    {
1566
0
        gs_free_object(dev->memory, tempstr, "gx_default_put_icc_colorants");
1567
0
        return_error(gs_error_VMerror);
1568
0
    }
1569
0
    len = gp_utf8_to_uint16(tempstr2, tempstr);
1570
1571
    /* Now convert down to 8 bits. Reuse tempstr here, because we know it will
1572
     * be large enough. */
1573
0
    code = 0;
1574
0
    for (s = tempstr2, d = tempstr; *s; s++, d++)
1575
0
    {
1576
0
        unsigned short v = *s;
1577
0
        if (v & 0xff00)
1578
0
            code = gs_note_error(gs_error_rangecheck);
1579
0
        *d = v & 0xff;
1580
0
    }
1581
1582
0
    if (code < 0)
1583
0
        emprintf(dev->memory, "ICCColorants must fit (unencoded) in 8 bits");
1584
0
    else
1585
0
        code = gsicc_set_device_profile_colorants(dev, tempstr);
1586
0
    gs_free_object(dev->memory, tempstr, "gx_default_put_icc_colorants");
1587
0
    gs_free_object(dev->memory, tempstr2, "gx_default_put_icc_colorants");
1588
0
    return code;
1589
0
}
1590
1591
static int
1592
gx_default_put_icc(gs_param_string *icc_pro, gx_device * dev,
1593
                   gsicc_profile_types_t index)
1594
71.0k
{
1595
71.0k
    char *tempstr;
1596
71.0k
    int code = 0;
1597
1598
71.0k
    if (icc_pro->size == 0) return 0;
1599
    /* If this has not yet been set, then set it to the default.
1600
       I don't like doing this here but if we are in here trying to
1601
       set a profile for our device and if the proc for this has not
1602
       yet been set, we are going to lose the chance to set the profile.
1603
       Much like open, this proc should be set early on.  I leave that
1604
       exercise to the device start-up experts */
1605
8.88k
    fill_dev_proc(dev, get_profile, gx_default_get_profile);
1606
8.88k
    if (icc_pro->size < gp_file_name_sizeof) {
1607
8.88k
        tempstr = (char *) gs_alloc_bytes(dev->memory, icc_pro->size+1,
1608
8.88k
                                          "gx_default_put_icc");
1609
8.88k
        if (tempstr == NULL)
1610
0
            return_error(gs_error_VMerror);
1611
8.88k
        memcpy(tempstr, icc_pro->data, icc_pro->size);
1612
        /* Set last position to NULL. */
1613
8.88k
        tempstr[icc_pro->size] = 0;
1614
8.88k
        code = gsicc_init_device_profile_struct(dev, tempstr, index);
1615
8.88k
        gs_free_object(dev->memory, tempstr, "gx_default_put_icc");
1616
8.88k
    }
1617
8.88k
    return code;
1618
8.88k
}
1619
1620
void rc_free_NupControl(gs_memory_t * mem, void *ptr_in, client_name_t cname);  /* silence warning */
1621
/* Exported for use by nup_put_params in gdevnup.c */
1622
void
1623
rc_free_NupControl(gs_memory_t * mem, void *ptr_in, client_name_t cname)
1624
0
{
1625
0
    gdev_nupcontrol *pnupc = (gdev_nupcontrol *)ptr_in;
1626
1627
0
    if (pnupc->rc.ref_count <= 1) {
1628
0
        gs_free(mem->non_gc_memory, pnupc->nupcontrol_str, 1, strlen(pnupc->nupcontrol_str), "free nupcontrol string");
1629
0
        gs_free(mem->non_gc_memory, pnupc, 1, sizeof(gdev_nupcontrol), "free structure to hold nupcontrol string");
1630
0
    }
1631
0
}
1632
1633
static void
1634
rc_free_pages_list(gs_memory_t * mem, void *ptr_in, client_name_t cname)
1635
0
{
1636
0
    gdev_pagelist *PageList = (gdev_pagelist *)ptr_in;
1637
1638
0
    if (PageList->rc.ref_count <= 1) {
1639
0
        gs_free(mem->non_gc_memory, PageList->Pages, 1, strlen(PageList->Pages), "free page list");
1640
0
        gs_free(mem->non_gc_memory, PageList, 1, sizeof(gdev_pagelist), "free structure to hold page list");
1641
0
    }
1642
0
}
1643
1644
/* Set standard parameters. */
1645
/* Note that setting the size or resolution closes the device. */
1646
/* Window devices that don't want this to happen must temporarily */
1647
/* set is_open to false before calling gx_default_put_params, */
1648
/* and then taking appropriate action afterwards. */
1649
int
1650
gx_default_put_params(gx_device * dev, gs_param_list * plist)
1651
112k
{
1652
112k
    int ecode = 0;
1653
112k
    int code;
1654
112k
    gs_param_name param_name;
1655
112k
    gs_param_float_array hwra;
1656
112k
    gs_param_int_array hwsa;
1657
112k
    gs_param_float_array msa;
1658
112k
    gs_param_float_array ma;
1659
112k
    gs_param_float_array hwma;
1660
112k
    gs_param_string_array scna;
1661
112k
    int nci = dev->NumCopies;
1662
112k
    int ncset = dev->NumCopies_set;
1663
112k
    bool ignc = dev->IgnoreNumCopies;
1664
112k
    bool ucc = dev->UseCIEColor;
1665
112k
    gs_param_string icc_pro;
1666
112k
    bool locksafe = dev->LockSafetyParams;
1667
112k
    gs_param_float_array ibba;
1668
112k
    bool ibbnull = false;
1669
112k
    int colors = dev->color_info.num_components;
1670
112k
    int depth = dev->color_info.depth;
1671
112k
    int GrayValues = dev->color_info.max_gray + 1;
1672
112k
    int RGBValues = dev->color_info.max_color + 1;
1673
112k
    long ColorValues = (depth >= 32 ? -1 : 1L << depth);
1674
112k
    int tab = dev->color_info.anti_alias.text_bits;
1675
112k
    int gab = dev->color_info.anti_alias.graphics_bits;
1676
112k
    size_t mpbm = dev->MaxPatternBitmap;
1677
112k
    int ic = dev->interpolate_control;
1678
112k
    bool page_uses_transparency = dev->page_uses_transparency;
1679
112k
    bool page_uses_overprint = dev->page_uses_overprint;
1680
112k
    gdev_space_params sp = dev->space_params;
1681
112k
    gdev_space_params save_sp = dev->space_params;
1682
112k
    int rend_intent[NUM_DEVICE_PROFILES];
1683
112k
    int blackptcomp[NUM_DEVICE_PROFILES];
1684
112k
    int blackpreserve[NUM_DEVICE_PROFILES];
1685
112k
    gs_param_string cms, pagelist, nuplist;
1686
112k
    int leadingedge = dev->LeadingEdge;
1687
112k
    int k;
1688
112k
    int color_accuracy;
1689
112k
    bool devicegraytok = true;
1690
112k
    bool graydetection = false;
1691
112k
    bool usefastcolor = false;
1692
112k
    bool blacktext = false;
1693
112k
    bool blackvector = false;
1694
112k
    float blackthresholdL = BLACKTHRESHOLDL;
1695
112k
    float blackthresholdC = BLACKTHRESHOLDC;
1696
112k
    gs_overprint_control_t overprint_control = gs_overprint_control_enable;
1697
112k
    bool prebandthreshold = false;
1698
112k
    bool use_antidropout = dev->color_info.use_antidropout_downscaler;
1699
112k
    bool temp_bool;
1700
112k
    int  profile_types[NUM_DEVICE_PROFILES] = {gsDEFAULTPROFILE,
1701
112k
                                               gsGRAPHICPROFILE,
1702
112k
                                               gsIMAGEPROFILE,
1703
112k
                                               gsTEXTPROFILE};
1704
1705
112k
    color_accuracy = gsicc_currentcoloraccuracy(dev->memory);
1706
112k
    if (dev->icc_struct != NULL) {
1707
466k
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
1708
373k
            rend_intent[k] = dev->icc_struct->rendercond[k].rendering_intent;
1709
373k
            blackptcomp[k] = dev->icc_struct->rendercond[k].black_point_comp;
1710
373k
            blackpreserve[k] = dev->icc_struct->rendercond[k].preserve_black;
1711
373k
        }
1712
93.3k
        graydetection = dev->icc_struct->graydetection;
1713
93.3k
        devicegraytok = dev->icc_struct->devicegraytok;
1714
93.3k
        usefastcolor = dev->icc_struct->usefastcolor;
1715
93.3k
        blacktext = dev->icc_struct->blacktext;
1716
93.3k
        blackvector = dev->icc_struct->blackvector;
1717
93.3k
        blackthresholdL = dev->icc_struct->blackthresholdL;
1718
93.3k
        blackthresholdC = dev->icc_struct->blackthresholdC;
1719
93.3k
        prebandthreshold = dev->icc_struct->prebandthreshold;
1720
93.3k
        overprint_control = dev->icc_struct->overprint_control;
1721
93.3k
    } else {
1722
95.9k
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
1723
76.7k
            rend_intent[k] = gsRINOTSPECIFIED;
1724
76.7k
            blackptcomp[k] = gsBPNOTSPECIFIED;
1725
76.7k
            blackpreserve[k] = gsBKPRESNOTSPECIFIED;
1726
76.7k
        }
1727
19.1k
    }
1728
1729
    /*
1730
     * Template:
1731
     *   BEGIN_ARRAY_PARAM(param_read_xxx_array, "pname", pxxa, size, pxxe) {
1732
     *     ... check value if desired ...
1733
     *     if (success)
1734
     *       break;
1735
     *     ... set ecode ...
1736
     *   } END_ARRAY_PARAM(pxxa, pxxe);
1737
     */
1738
1739
112k
#define BEGIN_ARRAY_PARAM(pread, pname, pa, psize, e)\
1740
788k
    BEGIN\
1741
788k
    switch (code = pread(plist, (param_name = pname), &(pa))) {\
1742
171k
      case 0:\
1743
171k
        if ((pa).size != psize) {\
1744
0
          ecode = gs_note_error(gs_error_rangecheck);\
1745
0
          (pa).data = 0;  /* mark as not filled */\
1746
0
        } else
1747
112k
#define END_ARRAY_PARAM(pa, e)\
1748
112k
        goto e;\
1749
171k
      default:\
1750
16
        ecode = code;\
1751
16
e:  param_signal_error(plist, param_name, ecode);\
1752
616k
      case 1:\
1753
616k
        (pa).data = 0;   /* mark as not filled */\
1754
1.57M
    }\
1755
1.57M
    END
1756
1757
    /*
1758
     * The actual value of LeadingEdge must be changed inside this routine,
1759
     * so that we can detect that it has been changed. Thus, instead of a
1760
     * device setting the value itself, it signals a request, which is
1761
     * now executed.
1762
     */
1763
112k
    if (leadingedge & LEADINGEDGE_REQ_BIT) {
1764
0
        leadingedge = (leadingedge & LEADINGEDGE_SET_MASK) |
1765
0
            ((leadingedge >> LEADINGEDGE_REQ_VAL_SHIFT) & LEADINGEDGE_MASK);
1766
0
    }
1767
1768
    /*
1769
     * The HWResolution, HWSize, and MediaSize parameters interact in
1770
     * the following way:
1771
     *      1. Setting HWResolution recomputes HWSize from MediaSize.
1772
     *      2. Setting HWSize recomputes MediaSize from HWResolution.
1773
     *      3. Setting MediaSize recomputes HWSize from HWResolution.
1774
     * If more than one parameter is being set, we apply these rules
1775
     * in the order 1, 2, 3.  This does the right thing in the most
1776
     * common case of setting more than one parameter, namely,
1777
     * setting both HWResolution and HWSize.
1778
     *
1779
     * Changing of LeadingEdge is treated exactly the same as a
1780
     * change in HWResolution. In typical usage, MediaSize is
1781
     * short-edge (MediaSize[0] < MediaSize[1]), so if LeadingEdge
1782
     * is 1 or 3, then HWSize will become long-edge. For nonsquare
1783
     * resolutions, HWResolution[0] always corresponds with width
1784
     * (scan length), and [1] with height (number of scans).
1785
     */
1786
1787
131k
    BEGIN_ARRAY_PARAM(param_read_float_array, "HWResolution", hwra, 2, hwre) {
1788
19.1k
        if (hwra.data[0] <= 0 || hwra.data[1] <= 0)
1789
0
            ecode = gs_note_error(gs_error_rangecheck);
1790
19.1k
        else
1791
19.1k
            break;
1792
19.1k
    } END_ARRAY_PARAM(hwra, hwre);
1793
121k
    BEGIN_ARRAY_PARAM(param_read_int_array, "HWSize", hwsa, 2, hwsa) {
1794
        /* We need a special check to handle the nullpage device, */
1795
        /* whose size is legitimately [0 0]. */
1796
8.88k
        if ((hwsa.data[0] <= 0 && hwsa.data[0] != dev->width) ||
1797
8.88k
            (hwsa.data[1] <= 0 && hwsa.data[1] != dev->height)
1798
8.88k
        )
1799
0
            ecode = gs_note_error(gs_error_rangecheck);
1800
26.6k
#define max_coord (max_fixed / fixed_1)
1801
8.88k
#if max_coord < max_int
1802
8.88k
        else if (hwsa.data[0] > max_coord || hwsa.data[1] > max_coord)
1803
0
            ecode = gs_note_error(gs_error_limitcheck);
1804
8.88k
#endif
1805
8.88k
#undef max_coord
1806
8.88k
        else
1807
8.88k
            break;
1808
8.88k
    } END_ARRAY_PARAM(hwsa, hwse);
1809
112k
    {
1810
112k
        int t;
1811
1812
112k
        code = param_read_int(plist, "LeadingEdge", &t);
1813
112k
        if (code < 0) {
1814
8.88k
            if (param_read_null(plist, "LeadingEdge") == 0) {
1815
                /* if param is null, clear explicitly-set flag */
1816
8.88k
                leadingedge &= ~LEADINGEDGE_SET_MASK;
1817
8.88k
            } else {
1818
0
                ecode = code;
1819
0
            }
1820
103k
        } else if (code == 0) {
1821
0
            if (t < 0 || t > 3)
1822
0
                param_signal_error(plist, "LeadingEdge",
1823
0
                                   ecode = gs_error_rangecheck);
1824
0
            else
1825
0
                leadingedge = LEADINGEDGE_SET_MASK | t;
1826
0
        }
1827
112k
    }
1828
112k
    {
1829
112k
        const float *res = (hwra.data == 0 ? dev->HWResolution : hwra.data);
1830
1831
112k
#ifdef PAGESIZE_IS_MEDIASIZE
1832
112k
        const float *data;
1833
1834
        /* .MediaSize takes precedence over PageSize, so */
1835
        /* we read PageSize first. */
1836
112k
        code = param_MediaSize(plist, "PageSize", res, &msa);
1837
112k
        if (code < 0)
1838
0
            ecode = code;
1839
        /* Prevent data from being set to 0 if PageSize is specified */
1840
        /* but .MediaSize is not. */
1841
112k
        data = msa.data;
1842
112k
        code = param_MediaSize(plist, ".MediaSize", res, &msa);
1843
112k
        if (code < 0)
1844
16
            ecode = code;
1845
112k
        else if (msa.data == 0)
1846
49.6k
            msa.data = data;
1847
#else
1848
        code = param_MediaSize(plist, ".MediaSize", res, &msa);
1849
        if (code < 0)
1850
            ecode = code;
1851
#endif
1852
112k
    }
1853
1854
121k
    BEGIN_ARRAY_PARAM(param_read_float_array, "Margins", ma, 2, me) {
1855
8.88k
        break;
1856
8.88k
    } END_ARRAY_PARAM(ma, me);
1857
121k
    BEGIN_ARRAY_PARAM(param_read_float_array, ".HWMargins", hwma, 4, hwme) {
1858
8.88k
        break;
1859
8.88k
    } END_ARRAY_PARAM(hwma, hwme);
1860
112k
    switch (code = param_read_bool(plist, (param_name = ".IgnoreNumCopies"), &ignc)) {
1861
0
        default:
1862
0
            ecode = code;
1863
0
            param_signal_error(plist, param_name, ecode);
1864
8.88k
        case 0:
1865
112k
        case 1:
1866
112k
            break;
1867
112k
    }
1868
112k
    if (dev->NumCopies_set >= 0 &&
1869
112k
        (*dev_proc(dev, get_page_device))(dev) != 0
1870
112k
        ) {
1871
112k
        switch (code = param_read_int(plist, (param_name = "NumCopies"), &nci)) {
1872
0
            case 0:
1873
0
                if (nci < 0)
1874
0
                    ecode = gs_error_rangecheck;
1875
0
                else {
1876
0
                    ncset = 1;
1877
0
                    break;
1878
0
                }
1879
0
                goto nce;
1880
8.88k
            default:
1881
8.88k
                if ((code = param_read_null(plist, param_name)) == 0) {
1882
8.88k
                    ncset = 0;
1883
8.88k
                    break;
1884
8.88k
                }
1885
0
                ecode = code; /* can't be 1 */
1886
0
nce:
1887
0
                param_signal_error(plist, param_name, ecode);
1888
103k
            case 1:
1889
103k
                break;
1890
112k
        }
1891
112k
    }
1892
    /* Set the ICC output colors first */
1893
112k
    if ((code = param_read_string(plist, "ICCOutputColors", &icc_pro)) != 1) {
1894
8.88k
        if (code < 0) {
1895
0
            ecode = code;
1896
0
            param_signal_error(plist, "ICCOutputColors", ecode);
1897
8.88k
        } else {
1898
8.88k
            if ((code = gx_default_put_icc_colorants(&icc_pro, dev)) < 0) {
1899
0
                ecode = code;
1900
0
                param_signal_error(plist, "ICCOutputColors", ecode);
1901
0
            }
1902
8.88k
        }
1903
8.88k
    }
1904
112k
    if ((code = param_read_string(plist, "DeviceLinkProfile", &icc_pro)) != 1) {
1905
8.88k
        if (code < 0) {
1906
0
            ecode = code;
1907
0
            param_signal_error(plist, "DeviceLinkProfile", ecode);
1908
8.88k
        } else {
1909
8.88k
            if ((code = gx_default_put_icc(&icc_pro, dev, gsLINKPROFILE)) < 0) {
1910
0
                ecode = code;
1911
0
                param_signal_error(plist, "DeviceLinkProfile", ecode);
1912
0
            }
1913
8.88k
        }
1914
8.88k
    }
1915
112k
    if ((code = param_read_string(plist, "PostRenderProfile", &icc_pro)) != 1) {
1916
8.88k
        if (code < 0) {
1917
0
            ecode = code;
1918
0
            param_signal_error(plist, "PostRenderProfile", ecode);
1919
8.88k
        } else {
1920
8.88k
            if ((code = gx_default_put_icc(&icc_pro, dev, gsPRPROFILE)) < 0) {
1921
0
                ecode = code;
1922
0
                param_signal_error(plist, "PostRenderProfile", ecode);
1923
0
            }
1924
8.88k
        }
1925
8.88k
    }
1926
112k
    if ((code = param_read_string(plist, "OutputICCProfile", &icc_pro)) != 1) {
1927
8.88k
        if (code < 0) {
1928
0
            ecode = code;
1929
0
            param_signal_error(plist, "OutputICCProfile", ecode);
1930
8.88k
        } else {
1931
8.88k
            if ((code = gx_default_put_icc(&icc_pro, dev, gsDEFAULTPROFILE)) < 0) {
1932
0
                ecode = code;
1933
0
                param_signal_error(plist, "OutputICCProfile", ecode);
1934
0
            }
1935
8.88k
        }
1936
8.88k
    }
1937
    /* Note, if a change is made to NUM_DEVICE_PROFILES we need to update
1938
       this with the name of the profile */
1939
112k
    if ((code = param_read_string(plist, "VectorICCProfile", &icc_pro)) != 1) {
1940
8.88k
        if (code < 0) {
1941
0
            ecode = code;
1942
0
            param_signal_error(plist, "VectorICCProfile", ecode);
1943
8.88k
        } else {
1944
8.88k
            if ((code = gx_default_put_icc(&icc_pro, dev, gsGRAPHICPROFILE)) < 0) {
1945
0
                ecode = code;
1946
0
                param_signal_error(plist, "VectorICCProfile", ecode);
1947
0
            }
1948
8.88k
        }
1949
8.88k
    }
1950
112k
    if ((code = param_read_string(plist, "ImageICCProfile", &icc_pro)) != 1) {
1951
8.88k
        if (code < 0) {
1952
0
            ecode = code;
1953
0
            param_signal_error(plist, "ImageICCProfile", ecode);
1954
8.88k
        } else {
1955
8.88k
            if ((code = gx_default_put_icc(&icc_pro, dev, gsIMAGEPROFILE)) < 0) {
1956
0
                ecode = code;
1957
0
                param_signal_error(plist, "ImageICCProfile", ecode);
1958
0
            }
1959
8.88k
        }
1960
8.88k
    }
1961
112k
    if ((code = param_read_string(plist, "TextICCProfile", &icc_pro)) != 1) {
1962
8.88k
        if (code < 0) {
1963
0
            ecode = code;
1964
0
            param_signal_error(plist, "TextICCProfile", ecode);
1965
8.88k
        } else {
1966
8.88k
            if ((code = gx_default_put_icc(&icc_pro, dev, gsTEXTPROFILE)) < 0) {
1967
0
                ecode = code;
1968
0
                param_signal_error(plist, "TextICCProfile", ecode);
1969
0
            }
1970
8.88k
        }
1971
8.88k
    }
1972
112k
    if ((code = param_read_string(plist, "ProofProfile", &icc_pro)) != 1) {
1973
8.88k
        if (code < 0) {
1974
0
            ecode = code;
1975
0
            param_signal_error(plist, "ProofProfile", ecode);
1976
8.88k
        } else {
1977
8.88k
            if ((code = gx_default_put_icc(&icc_pro, dev, gsPROOFPROFILE)) < 0) {
1978
0
                ecode = code;
1979
0
                param_signal_error(plist, "ProofProfile", ecode);
1980
0
            }
1981
8.88k
        }
1982
8.88k
    }
1983
112k
    if ((code = param_read_string(plist, "BlendColorProfile", &icc_pro)) != 1) {
1984
8.88k
        if (code < 0) {
1985
0
            ecode = code;
1986
0
            param_signal_error(plist, "BlendColorProfile", ecode);
1987
8.88k
        } else {
1988
8.88k
            if ((code = gx_default_put_icc(&icc_pro, dev, gsBLENDPROFILE)) < 0) {
1989
0
                ecode = code;
1990
0
                param_signal_error(plist, "BlendColorProfile", ecode);
1991
0
            }
1992
8.88k
        }
1993
8.88k
    }
1994
112k
    if ((code = param_read_int(plist, (param_name = "RenderIntent"),
1995
112k
                                                    &(rend_intent[0]))) < 0) {
1996
0
        ecode = code;
1997
0
        param_signal_error(plist, param_name, ecode);
1998
0
    }
1999
112k
    if ((code = param_read_int(plist, (param_name = "VectorIntent"),
2000
112k
                                                    &(rend_intent[1]))) < 0) {
2001
0
        ecode = code;
2002
0
        param_signal_error(plist, param_name, ecode);
2003
0
    }
2004
112k
    if ((code = param_read_int(plist, (param_name = "ImageIntent"),
2005
112k
                                                    &(rend_intent[2]))) < 0) {
2006
0
        ecode = code;
2007
0
        param_signal_error(plist, param_name, ecode);
2008
0
    }
2009
112k
    if ((code = param_read_int(plist, (param_name = "TextIntent"),
2010
112k
                                                    &(rend_intent[3]))) < 0) {
2011
0
        ecode = code;
2012
0
        param_signal_error(plist, param_name, ecode);
2013
0
    }
2014
112k
    if ((code = param_read_int(plist, (param_name = "BlackPtComp"),
2015
112k
                                                    &(blackptcomp[0]))) < 0) {
2016
0
        ecode = code;
2017
0
        param_signal_error(plist, param_name, ecode);
2018
0
    }
2019
112k
    if ((code = param_read_int(plist, (param_name = "VectorBlackPt"),
2020
112k
                                                    &(blackptcomp[1]))) < 0) {
2021
0
        ecode = code;
2022
0
        param_signal_error(plist, param_name, ecode);
2023
0
    }
2024
112k
    if ((code = param_read_int(plist, (param_name = "ImageBlackPt"),
2025
112k
                                                    &(blackptcomp[2]))) < 0) {
2026
0
        ecode = code;
2027
0
        param_signal_error(plist, param_name, ecode);
2028
0
    }
2029
112k
    if ((code = param_read_int(plist, (param_name = "TextBlackPt"),
2030
112k
                                                    &(blackptcomp[3]))) < 0) {
2031
0
        ecode = code;
2032
0
        param_signal_error(plist, param_name, ecode);
2033
0
    }
2034
112k
    if ((code = param_read_int(plist, (param_name = "KPreserve"),
2035
112k
                                                    &(blackpreserve[0]))) < 0) {
2036
0
        ecode = code;
2037
0
        param_signal_error(plist, param_name, ecode);
2038
0
    }
2039
112k
    if ((code = param_read_int(plist, (param_name = "VectorKPreserve"),
2040
112k
                                                    &(blackpreserve[1]))) < 0) {
2041
0
        ecode = code;
2042
0
        param_signal_error(plist, param_name, ecode);
2043
0
    }
2044
112k
    if ((code = param_read_int(plist, (param_name = "ImageKPreserve"),
2045
112k
                                                    &(blackpreserve[2]))) < 0) {
2046
0
        ecode = code;
2047
0
        param_signal_error(plist, param_name, ecode);
2048
0
    }
2049
112k
    if ((code = param_read_int(plist, (param_name = "TextKPreserve"),
2050
112k
                                                    &(blackpreserve[3]))) < 0) {
2051
0
        ecode = code;
2052
0
        param_signal_error(plist, param_name, ecode);
2053
0
    }
2054
112k
    if ((code = param_read_int(plist, (param_name = "ColorAccuracy"),
2055
112k
                                                        &color_accuracy)) < 0) {
2056
0
        ecode = code;
2057
0
        param_signal_error(plist, param_name, ecode);
2058
0
    }
2059
112k
    if ((code = param_read_bool(plist, (param_name = "DeviceGrayToK"),
2060
112k
                                                        &devicegraytok)) < 0) {
2061
0
        ecode = code;
2062
0
        param_signal_error(plist, param_name, ecode);
2063
0
    }
2064
112k
    if ((code = param_read_bool(plist, (param_name = "GrayDetection"),
2065
112k
                                                        &graydetection)) < 0) {
2066
0
        ecode = code;
2067
0
        param_signal_error(plist, param_name, ecode);
2068
0
    }
2069
112k
    if ((code = param_read_bool(plist, (param_name = "UseFastColor"),
2070
112k
                                                        &usefastcolor)) < 0) {
2071
0
        ecode = code;
2072
0
        param_signal_error(plist, param_name, ecode);
2073
0
    }
2074
112k
    if ((code = param_read_bool(plist, (param_name = "BlackText"),
2075
112k
                                                        &blacktext)) < 0) {
2076
0
        ecode = code;
2077
0
        param_signal_error(plist, param_name, ecode);
2078
0
    }
2079
112k
    if ((code = param_read_bool(plist, (param_name = "BlackVector"),
2080
112k
                                                        &blackvector)) < 0) {
2081
0
        ecode = code;
2082
0
        param_signal_error(plist, param_name, ecode);
2083
0
    }
2084
112k
    if ((code = param_read_float(plist, (param_name = "BlackThresholdL"),
2085
112k
                                                        &blackthresholdL)) < 0) {
2086
0
        ecode = code;
2087
0
        param_signal_error(plist, param_name, ecode);
2088
0
    }
2089
112k
    if ((code = param_read_float(plist, (param_name = "BlackThresholdC"),
2090
112k
                                                        &blackthresholdC)) < 0) {
2091
0
        ecode = code;
2092
0
        param_signal_error(plist, param_name, ecode);
2093
0
    }
2094
112k
    if ((code = param_put_enum(plist, "Overprint",
2095
112k
                           (int*)&overprint_control, overprint_control_names, ecode)) < 0) {
2096
16
        ecode = code;
2097
16
        param_signal_error(plist, param_name, ecode);
2098
16
    }
2099
112k
    if ((code = param_read_bool(plist, (param_name = "PreBandThreshold"),
2100
112k
                                                        &prebandthreshold)) < 0) {
2101
0
        ecode = code;
2102
0
        param_signal_error(plist, param_name, ecode);
2103
0
    }
2104
112k
    if ((code = param_read_bool(plist, (param_name = "UseCIEColor"), &ucc)) < 0) {
2105
0
        ecode = code;
2106
0
        param_signal_error(plist, param_name, ecode);
2107
0
    }
2108
112k
    if ((code = param_anti_alias_bits(plist, "TextAlphaBits", &tab)) < 0)
2109
0
        ecode = code;
2110
112k
    if ((code = param_anti_alias_bits(plist, "GraphicsAlphaBits", &gab)) < 0)
2111
0
        ecode = code;
2112
112k
    if ((code = param_read_bool(plist, "AntidropoutDownscaler", &use_antidropout)) < 0)
2113
0
        ecode = code;
2114
112k
    if ((code = param_read_size_t(plist, "MaxPatternBitmap", &mpbm)) < 0)
2115
0
        ecode = code;
2116
112k
    if ((code = param_read_int(plist, "InterpolateControl", &ic)) < 0)
2117
0
        ecode = code;
2118
112k
    if ((code = param_read_bool(plist, (param_name = "PageUsesTransparency"),
2119
112k
                                &page_uses_transparency)) < 0) {
2120
0
        ecode = code;
2121
0
        param_signal_error(plist, param_name, ecode);
2122
0
    }
2123
112k
    if ((code = param_read_bool(plist, (param_name = "PageUsesOverprint"),
2124
112k
                                &page_uses_overprint)) < 0) {
2125
0
        ecode = code;
2126
0
        param_signal_error(plist, param_name, ecode);
2127
0
    }
2128
112k
    if ((code = param_read_size_t(plist, "MaxBitmap", &sp.MaxBitmap)) < 0)
2129
0
        ecode = code;
2130
2131
112k
#define CHECK_PARAM_CASES(member, bad, label)\
2132
112k
    case 0:\
2133
45.8k
        if ((sp.params_are_read_only ? sp.member != save_sp.member : bad))\
2134
0
            ecode = gs_error_rangecheck;\
2135
0
        else\
2136
45.8k
            break;\
2137
0
        goto label;\
2138
0
    default:\
2139
0
        ecode = code;\
2140
0
label:\
2141
0
        param_signal_error(plist, param_name, ecode);\
2142
404k
    case 1:\
2143
404k
        break
2144
2145
112k
    switch (code = param_read_size_t(plist, (param_name = "BufferSpace"), &sp.BufferSpace)) {
2146
112k
        CHECK_PARAM_CASES(BufferSpace, sp.BufferSpace < 10000, bse);
2147
112k
    }
2148
2149
112k
    switch (code = param_read_int(plist, (param_name = "BandWidth"), &sp.band.BandWidth)) {
2150
112k
        CHECK_PARAM_CASES(band.BandWidth, sp.band.BandWidth < 0, bwe);
2151
112k
    }
2152
2153
112k
    switch (code = param_read_int(plist, (param_name = "BandHeight"), &sp.band.BandHeight)) {
2154
112k
        CHECK_PARAM_CASES(band.BandHeight, sp.band.BandHeight < -1, bhe);
2155
112k
    }
2156
112k
    if (sp.band.BandHeight == -1)
2157
0
        sp.band.BandHeight = dev->height; /* 1 band for the page requested */
2158
2159
112k
    switch (code = param_read_size_t(plist, (param_name = "BandBufferSpace"), &sp.band.BandBufferSpace)) {
2160
112k
        CHECK_PARAM_CASES(band.BandBufferSpace, 0, bbse);
2161
112k
    }
2162
2163
2164
112k
    switch (code = param_read_bool(plist, (param_name = ".LockSafetyParams"), &locksafe)) {
2165
8.88k
        case 0:
2166
8.88k
            if (dev->LockSafetyParams && !locksafe)
2167
0
                code = gs_note_error(gs_error_invalidaccess);
2168
8.88k
            else
2169
8.88k
                break;
2170
0
        default:
2171
0
            ecode = code;
2172
0
            param_signal_error(plist, param_name, ecode);
2173
103k
        case 1:
2174
103k
            break;
2175
112k
    }
2176
    /* Ignore parameters that only have meaning for printers. */
2177
112k
#define IGNORE_INT_PARAM(pname)\
2178
450k
  { int igni;\
2179
450k
    switch ( code = param_read_int(plist, (param_name = pname), &igni) )\
2180
450k
      { default:\
2181
0
          ecode = code;\
2182
0
          param_signal_error(plist, param_name, ecode);\
2183
134k
        case 0:\
2184
450k
        case 1:\
2185
450k
          break;\
2186
450k
      }\
2187
450k
  }
2188
112k
    IGNORE_INT_PARAM("%MediaSource")
2189
112k
        IGNORE_INT_PARAM("%MediaDestination")
2190
112k
        switch (code = param_read_float_array(plist, (param_name = "ImagingBBox"), &ibba)) {
2191
0
        case 0:
2192
0
            if (ibba.size != 4 ||
2193
0
                ibba.data[2] < ibba.data[0] || ibba.data[3] < ibba.data[1]
2194
0
                )
2195
0
                ecode = gs_note_error(gs_error_rangecheck);
2196
0
            else
2197
0
                break;
2198
0
            goto ibbe;
2199
0
        default:
2200
0
            if ((code = param_read_null(plist, param_name)) == 0) {
2201
0
                ibbnull = true;
2202
0
                ibba.data = 0;
2203
0
                break;
2204
0
            }
2205
0
            ecode = code; /* can't be 1 */
2206
0
          ibbe:param_signal_error(plist, param_name, ecode);
2207
112k
        case 1:
2208
112k
            ibba.data = 0;
2209
112k
            break;
2210
112k
    }
2211
2212
    /* Separation, DeviceN Color, and ProcessColorModel related parameters. */
2213
112k
    {
2214
112k
        const char * pcms = get_process_color_model_name(dev);
2215
        /* the device should have set a process model name at this point */
2216
112k
        if ((code = param_check_string(plist, "ProcessColorModel", pcms, (pcms != NULL))) < 0)
2217
0
            ecode = code;
2218
112k
    }
2219
112k
    IGNORE_INT_PARAM("MaxSeparations")
2220
112k
    if ((code = param_check_bool(plist, "Separations", false, true)) < 0)
2221
1
        ecode = code;
2222
2223
175k
    BEGIN_ARRAY_PARAM(param_read_name_array, "SeparationColorNames", scna, scna.size, scne) {
2224
62.9k
        break;
2225
62.9k
    } END_ARRAY_PARAM(scna, scne);
2226
2227
    /* Now check nominally read-only parameters. */
2228
112k
    if ((code = param_check_string(plist, "OutputDevice", dev->dname, true)) < 0)
2229
0
        ecode = code;
2230
112k
    if ((code = param_check_string(plist, "Name", dev->dname, true)) < 0)
2231
0
        ecode = code;
2232
112k
    if ((code = param_check_int(plist, "Colors", colors, true)) < 0)
2233
0
        ecode = code;
2234
112k
    if ((code = param_check_int(plist, "BitsPerPixel", depth, true)) < 0)
2235
0
        ecode = code;
2236
112k
    if ((code = param_check_int(plist, "GrayValues", GrayValues, true)) < 0)
2237
0
        ecode = code;
2238
2239
    /* with saved-pages, PageCount can't be checked. No harm in letting it change */
2240
112k
    IGNORE_INT_PARAM("PageCount")
2241
2242
112k
    if ((code = param_check_int(plist, "RedValues", RGBValues, true)) < 0)
2243
0
        ecode = code;
2244
112k
    if ((code = param_check_int(plist, "GreenValues", RGBValues, true)) < 0)
2245
0
        ecode = code;
2246
112k
    if ((code = param_check_int(plist, "BlueValues", RGBValues, true)) < 0)
2247
0
        ecode = code;
2248
112k
    if ((code = param_check_long(plist, "ColorValues", ColorValues, true)) < 0)
2249
0
        ecode = code;
2250
112k
    if (param_read_string(plist, "HWColorMap", &cms) != 1) {
2251
0
        byte palette[3 << 8];
2252
2253
0
        if (param_HWColorMap(dev, palette))
2254
0
            code = param_check_bytes(plist, "HWColorMap", palette,
2255
0
                                     colors << depth, true);
2256
0
        else
2257
0
            code = param_check_bytes(plist, "HWColorMap", 0, 0, false);
2258
0
        if (code < 0)
2259
0
            ecode = code;
2260
0
    }
2261
2262
112k
    code = param_read_int(plist, "FirstPage", &dev->FirstPage);
2263
112k
    if (code < 0)
2264
0
        ecode = code;
2265
2266
112k
    code = param_read_int(plist,  "LastPage", &dev->LastPage);
2267
112k
    if (code < 0)
2268
0
        ecode = code;
2269
2270
112k
    code = param_read_bool(plist, "DisablePageHandler", &temp_bool);
2271
112k
    if (code < 0)
2272
0
        ecode = code;
2273
112k
    if (code == 0)
2274
8.88k
        dev->DisablePageHandler = temp_bool;
2275
2276
    /* If we have an NupControl subclass device (N-up) installed, this param will have  */
2277
    /* been handled there, so the check for different will be false, meaning that this  */
2278
    /* code won't end up doing anything. This will catch the first occurence and needs  */
2279
    /* to install the N-up subclass device.           */
2280
112k
    code = param_read_string(plist, "NupControl", &nuplist);
2281
112k
    if (code < 0)
2282
0
        ecode = code;
2283
112k
    if (code == 0) {
2284
8.88k
        if (dev->NupControl && (
2285
0
            nuplist.size == 0 ||
2286
0
            (strncmp(dev->NupControl->nupcontrol_str, (const char *)nuplist.data, nuplist.size) != 0))) {
2287
            /* There was a NupControl, but this one is different -- no longer use the old one */
2288
0
            rc_decrement(dev->NupControl, "default put_params NupControl");
2289
0
            dev->NupControl = NULL;
2290
0
        }
2291
8.88k
    }
2292
112k
    if (dev->NupControl == NULL && code == 0 && nuplist.size > 0) {
2293
0
        gx_device *next_dev;
2294
2295
0
        dev->NupControl = (gdev_nupcontrol *)gs_alloc_bytes(dev->memory->non_gc_memory,
2296
0
                                                          sizeof(gdev_nupcontrol), "structure to hold nupcontrol_str");
2297
0
        if (dev->NupControl == NULL)
2298
0
            return gs_note_error(gs_error_VMerror);
2299
0
        dev->NupControl->nupcontrol_str = (void *)gs_alloc_bytes(dev->memory->non_gc_memory,
2300
0
                                                                 nuplist.size + 1, "nupcontrol string");
2301
0
        if (dev->NupControl->nupcontrol_str == NULL){
2302
0
            gs_free(dev->memory->non_gc_memory, dev->NupControl, 1, sizeof(gdev_nupcontrol),
2303
0
                    "free structure to hold nupcontrol string");
2304
0
            dev->NupControl = 0;
2305
0
            return gs_note_error(gs_error_VMerror);
2306
0
        }
2307
0
        memset(dev->NupControl->nupcontrol_str, 0x00, nuplist.size + 1);
2308
0
        memcpy(dev->NupControl->nupcontrol_str, nuplist.data, nuplist.size);
2309
0
        rc_init_free(dev->NupControl, dev->memory->non_gc_memory, 1, rc_free_NupControl);
2310
2311
        /* Propagate the new NupControl struct to children */
2312
0
        next_dev = dev->child;
2313
0
        while (next_dev != NULL) {
2314
0
            if (next_dev->NupControl)
2315
0
                rc_decrement(next_dev->NupControl, "nup_put_params");
2316
0
            next_dev->NupControl = dev->NupControl;
2317
0
            rc_increment(dev->NupControl);
2318
0
            next_dev = next_dev->child;
2319
0
        }
2320
        /* Propagate the new NupControl struct to parents */
2321
0
        next_dev = dev->parent;
2322
0
        while (next_dev != NULL) {
2323
0
            if (next_dev->NupControl)
2324
0
                rc_decrement(next_dev->NupControl, "nup_put_params");
2325
0
            next_dev->NupControl = dev->NupControl;
2326
0
            rc_increment(dev->NupControl);
2327
0
            next_dev = next_dev->parent;
2328
0
        }
2329
0
    }
2330
2331
112k
    code = param_read_string(plist, "PageList", &pagelist);
2332
112k
    if (code < 0)
2333
0
        ecode = code;
2334
112k
    if (code == 0) {
2335
8.88k
        if (dev->PageList)
2336
8.88k
            rc_decrement(dev->PageList, "default put_params PageList");
2337
8.88k
        dev->PageList = NULL;
2338
8.88k
    }
2339
2340
112k
    if (code == 0 && pagelist.size > 0) {
2341
0
        dev->PageList = (gdev_pagelist *)gs_alloc_bytes(dev->memory->non_gc_memory, sizeof(gdev_pagelist), "structure to hold page list");
2342
0
        if (!dev->PageList)
2343
0
            return gs_note_error(gs_error_VMerror);
2344
0
        dev->PageList->Pages = (void *)gs_alloc_bytes(dev->memory->non_gc_memory, pagelist.size + 1, "String to hold page list");
2345
0
        if (!dev->PageList->Pages){
2346
0
            gs_free(dev->memory->non_gc_memory, dev->PageList, 1, sizeof(gdev_pagelist), "free structure to hold page list");
2347
0
            dev->PageList = 0;
2348
0
            return gs_note_error(gs_error_VMerror);
2349
0
        }
2350
0
        memset(dev->PageList->Pages, 0x00, pagelist.size + 1);
2351
0
        memcpy(dev->PageList->Pages, pagelist.data, pagelist.size);
2352
0
        rc_init_free(dev->PageList, dev->memory->non_gc_memory, 1, rc_free_pages_list);
2353
0
    }
2354
2355
112k
    code = param_read_bool(plist, "FILTERIMAGE", &temp_bool);
2356
112k
    if (code < 0)
2357
0
        ecode = code;
2358
112k
    if (code == 0) {
2359
8.88k
        if (temp_bool)
2360
0
            dev->ObjectFilter |= FILTERIMAGE;
2361
8.88k
        else
2362
8.88k
            dev->ObjectFilter &= ~FILTERIMAGE;
2363
8.88k
    }
2364
2365
112k
    code = param_read_bool(plist, "FILTERTEXT", &temp_bool);
2366
112k
    if (code < 0)
2367
0
        ecode = code;
2368
112k
    if (code == 0) {
2369
8.88k
        if (temp_bool)
2370
0
            dev->ObjectFilter |= FILTERTEXT;
2371
8.88k
        else
2372
8.88k
            dev->ObjectFilter &= ~FILTERTEXT;
2373
8.88k
    }
2374
2375
112k
    code = param_read_bool(plist, "FILTERVECTOR", &temp_bool);
2376
112k
    if (code < 0)
2377
0
        ecode = code;
2378
112k
    if (code == 0) {
2379
8.88k
        if (temp_bool)
2380
0
            dev->ObjectFilter |= FILTERVECTOR;
2381
8.88k
        else
2382
8.88k
            dev->ObjectFilter &= ~FILTERVECTOR;
2383
8.88k
    }
2384
2385
    /* We must 'commit', in order to detect unknown parameters, */
2386
    /* even if there were errors. */
2387
112k
    code = param_commit(plist);
2388
112k
    if (ecode < 0) {
2389
        /* restore_page_device (zdevice2.c) will turn off LockSafetyParams, and relies on putparams
2390
         * to put it back if we are restoring a device. The locksafe value is picked up above from the
2391
         * device we are restoring to, and we *must* make sure it is preserved, even if setting the
2392
         * params failed. Otherwise an attacker can use a failed grestore to reset LockSafetyParams.
2393
         * See bug #699687.
2394
         */
2395
17
        dev->LockSafetyParams = locksafe;
2396
17
        return ecode;
2397
17
    }
2398
112k
    if (code < 0) {
2399
24
        dev->LockSafetyParams = locksafe;
2400
24
        return code;
2401
24
    }
2402
2403
    /*
2404
     * Now actually make the changes. Changing resolution, rotation
2405
     * (through LeadingEdge) or page size requires closing the device,
2406
     * but changing margins or ImagingBBox does not. In order not to
2407
     * close and reopen the device unnecessarily, we check for
2408
     * replacing the values with the same ones.
2409
     */
2410
2411
112k
    dev->color_info.use_antidropout_downscaler = use_antidropout;
2412
2413
112k
    if (hwra.data != 0 &&
2414
112k
        (dev->HWResolution[0] != hwra.data[0] ||
2415
19.1k
         dev->HWResolution[1] != hwra.data[1])
2416
112k
        ) {
2417
10.3k
        if (dev->is_open)
2418
0
            gs_closedevice(dev);
2419
10.3k
        gx_device_set_resolution(dev, hwra.data[0], hwra.data[1]);
2420
10.3k
    }
2421
112k
    if ((leadingedge & LEADINGEDGE_MASK) !=
2422
112k
        (dev->LeadingEdge & LEADINGEDGE_MASK)) {
2423
        /* If the LeadingEdge_set flag changes but the value of LeadingEdge
2424
           itself does not, don't close device and recompute page size. */
2425
0
        dev->LeadingEdge = leadingedge;
2426
0
        if (dev->is_open)
2427
0
            gs_closedevice(dev);
2428
0
        gx_device_set_resolution(dev, dev->HWResolution[0], dev->HWResolution[1]);
2429
0
    }
2430
    /* clear leadingedge request, preserve "set" flag */
2431
112k
    dev->LeadingEdge &= LEADINGEDGE_MASK;
2432
112k
    dev->LeadingEdge |= (leadingedge & LEADINGEDGE_SET_MASK);
2433
2434
112k
    if (hwsa.data != 0 &&
2435
112k
        (dev->width != hwsa.data[0] ||
2436
8.88k
         dev->height != hwsa.data[1])
2437
112k
        ) {
2438
7.19k
        if (dev->is_open)
2439
0
            gs_closedevice(dev);
2440
7.19k
        gx_device_set_width_height(dev, hwsa.data[0], hwsa.data[1]);
2441
7.19k
    }
2442
112k
    if (msa.data != 0 &&
2443
112k
        (dev->MediaSize[0] != msa.data[0] ||
2444
62.8k
         dev->MediaSize[1] != msa.data[1])
2445
112k
        ) {
2446
10.9k
        if (dev->is_open)
2447
0
            gs_closedevice(dev);
2448
10.9k
        gx_device_set_page_size(dev, msa.data[0], msa.data[1]);
2449
10.9k
    }
2450
112k
    if (ma.data != 0) {
2451
8.88k
        dev->Margins[0] = ma.data[0];
2452
8.88k
        dev->Margins[1] = ma.data[1];
2453
8.88k
    }
2454
112k
    if (hwma.data != 0) {
2455
8.88k
        dev->HWMargins[0] = hwma.data[0];
2456
8.88k
        dev->HWMargins[1] = hwma.data[1];
2457
8.88k
        dev->HWMargins[2] = hwma.data[2];
2458
8.88k
        dev->HWMargins[3] = hwma.data[3];
2459
8.88k
    }
2460
112k
    dev->NumCopies = nci;
2461
112k
    dev->NumCopies_set = ncset;
2462
112k
    dev->IgnoreNumCopies = ignc;
2463
112k
    if (ibba.data != 0) {
2464
0
        dev->ImagingBBox[0] = ibba.data[0];
2465
0
        dev->ImagingBBox[1] = ibba.data[1];
2466
0
        dev->ImagingBBox[2] = ibba.data[2];
2467
0
        dev->ImagingBBox[3] = ibba.data[3];
2468
0
        dev->ImagingBBox_set = true;
2469
112k
    } else if (ibbnull) {
2470
0
        dev->ImagingBBox_set = false;
2471
0
    }
2472
112k
    dev->UseCIEColor = ucc;
2473
112k
        dev->color_info.anti_alias.text_bits =
2474
112k
                param_normalize_anti_alias_bits(max(dev->color_info.max_gray,
2475
112k
                        dev->color_info.max_color), tab);
2476
112k
        dev->color_info.anti_alias.graphics_bits =
2477
112k
                param_normalize_anti_alias_bits(max(dev->color_info.max_gray,
2478
112k
                        dev->color_info.max_color), gab);
2479
112k
    dev->LockSafetyParams = locksafe;
2480
112k
    dev->MaxPatternBitmap = mpbm;
2481
112k
    dev->interpolate_control = ic;
2482
112k
    dev->space_params = sp;
2483
112k
    dev->page_uses_transparency = page_uses_transparency;
2484
112k
    dev->page_uses_overprint = page_uses_overprint;
2485
112k
    gx_device_decache_colors(dev);
2486
2487
    /* Take care of the rendering intents and blackpts.  For those that
2488
       are not set special, the default provides an override */
2489
    /* Set the default object */
2490
112k
    code = gx_default_put_intent(rend_intent[0], dev, gsDEFAULTPROFILE);
2491
112k
    if (code < 0)
2492
0
        return code;
2493
112k
    code = gx_default_put_blackptcomp(blackptcomp[0], dev, gsDEFAULTPROFILE);
2494
112k
    if (code < 0)
2495
0
        return code;
2496
112k
    code = gx_default_put_blackpreserve(blackpreserve[0], dev, gsDEFAULTPROFILE);
2497
112k
    if (code < 0)
2498
0
        return code;
2499
    /* If the default was specified and not a specialized one (e.g. graphic
2500
       image or text) then the special one will get set to the default.  */
2501
450k
    for (k = 1; k < NUM_DEVICE_PROFILES; k++) {
2502
337k
        if (rend_intent[0] != gsRINOTSPECIFIED &&
2503
337k
            rend_intent[k] == gsRINOTSPECIFIED) {
2504
0
            code = gx_default_put_intent(rend_intent[0], dev, profile_types[k]);
2505
337k
        } else {
2506
337k
            code = gx_default_put_intent(rend_intent[k], dev, profile_types[k]);
2507
337k
        }
2508
337k
        if (code < 0)
2509
0
            return code;
2510
337k
        if (blackptcomp[0] != gsBPNOTSPECIFIED &&
2511
337k
            blackptcomp[k] == gsBPNOTSPECIFIED) {
2512
0
            code = gx_default_put_blackptcomp(blackptcomp[0], dev, profile_types[k]);
2513
337k
        } else {
2514
337k
            code = gx_default_put_blackptcomp(blackptcomp[k], dev, profile_types[k]);
2515
337k
        }
2516
337k
        if (code < 0)
2517
0
            return code;
2518
337k
        if (blackpreserve[0] != gsBKPRESNOTSPECIFIED &&
2519
337k
            blackpreserve[k] == gsBKPRESNOTSPECIFIED) {
2520
0
            code = gx_default_put_blackpreserve(blackpreserve[0], dev, profile_types[k]);
2521
337k
        } else {
2522
337k
            code = gx_default_put_blackpreserve(blackpreserve[k], dev, profile_types[k]);
2523
337k
        }
2524
337k
        if (code < 0)
2525
0
            return code;
2526
337k
    }
2527
112k
    gsicc_setcoloraccuracy(dev->memory, color_accuracy);
2528
112k
    code = gx_default_put_graytok(devicegraytok, dev);
2529
112k
    if (code < 0)
2530
0
        return code;
2531
112k
    code = gx_default_put_usefastcolor(usefastcolor, dev);
2532
112k
    if (code < 0)
2533
0
        return code;
2534
112k
    code = gx_default_put_blacktext(blacktext, dev);
2535
112k
    if (code < 0)
2536
0
        return code;
2537
112k
    code = gx_default_put_blackvector(blackvector, dev);
2538
112k
    if (code < 0)
2539
0
        return code;
2540
112k
    code = gx_default_put_blackthresholds(blackthresholdL, blackthresholdC, dev);
2541
112k
    if (code < 0)
2542
0
        return code;
2543
112k
    code = gx_default_put_overprint_control(overprint_control, dev);
2544
112k
    if (code < 0)
2545
0
        return code;
2546
112k
    code = gx_default_put_graydetection(graydetection, dev);
2547
112k
    if (code < 0)
2548
0
        return code;
2549
112k
    return gx_default_put_prebandthreshold(prebandthreshold, dev);
2550
112k
}
2551
2552
void
2553
gx_device_request_leadingedge(gx_device *dev, int le_req)
2554
0
{
2555
0
    dev->LeadingEdge = (dev->LeadingEdge & ~LEADINGEDGE_REQ_VAL) |
2556
0
        ((le_req << LEADINGEDGE_REQ_VAL_SHIFT) & LEADINGEDGE_REQ_VAL) |
2557
0
        LEADINGEDGE_REQ_BIT;
2558
0
}
2559
2560
/* Limit the anti-alias bit values to the maximum legal value for the
2561
 * current color depth.
2562
 */
2563
static int
2564
param_normalize_anti_alias_bits( uint max_gray, int bits )
2565
225k
{
2566
225k
        int max_bits = ilog2( max_gray + 1);
2567
2568
225k
        return  (bits > max_bits ? max_bits : bits);
2569
225k
}
2570
2571
/* Read TextAlphaBits or GraphicsAlphaBits. */
2572
static int
2573
param_anti_alias_bits(gs_param_list * plist, gs_param_name param_name, int *pa)
2574
225k
{
2575
225k
    int code = param_read_int(plist, param_name, pa);
2576
2577
225k
    switch (code) {
2578
17.7k
    case 0:
2579
17.7k
        switch (*pa) {
2580
17.7k
        case 1: case 2: case 4:
2581
17.7k
            return 0;
2582
0
        default:
2583
0
            code = gs_error_rangecheck;
2584
17.7k
        }
2585
        /* fall through */
2586
0
    default:
2587
0
        param_signal_error(plist, param_name, code);
2588
207k
    case 1:
2589
207k
        ;
2590
225k
    }
2591
207k
    return code;
2592
225k
}
2593
2594
/* Read .MediaSize or, if supported as a synonym, PageSize. */
2595
static int
2596
param_MediaSize(gs_param_list * plist, gs_param_name pname,
2597
                const float *res, gs_param_float_array * pa)
2598
225k
{
2599
225k
    gs_param_name param_name;
2600
225k
    int ecode = 0;
2601
225k
    int code;
2602
2603
288k
    BEGIN_ARRAY_PARAM(param_read_float_array, pname, *pa, 2, mse) {
2604
62.9k
        float width_new = pa->data[0] * res[0] / 72;
2605
62.9k
        float height_new = pa->data[1] * res[1] / 72;
2606
2607
62.9k
        if (width_new < 0 || height_new < 0)
2608
0
            ecode = gs_note_error(gs_error_rangecheck);
2609
188k
#define max_coord (max_fixed / fixed_1)
2610
62.9k
#if max_coord < max_int
2611
62.9k
        else if (width_new > (long)max_coord || height_new > (long)max_coord)
2612
16
            ecode = gs_note_error(gs_error_limitcheck);
2613
62.9k
#endif
2614
62.9k
#undef max_coord
2615
62.9k
        else
2616
62.9k
            break;
2617
62.9k
    } END_ARRAY_PARAM(*pa, mse);
2618
225k
    return ecode;
2619
225k
}
2620
2621
/* Check that a nominally read-only parameter is being set to */
2622
/* its existing value. */
2623
static int
2624
param_check_bool(gs_param_list * plist, gs_param_name pname, bool value,
2625
                 bool is_defined)
2626
112k
{
2627
112k
    int code;
2628
112k
    bool new_value;
2629
2630
112k
    switch (code = param_read_bool(plist, pname, &new_value)) {
2631
8.88k
        case 0:
2632
8.88k
            if (is_defined && new_value == value)
2633
8.88k
                break;
2634
1
            code = gs_note_error(gs_error_rangecheck);
2635
1
            goto e;
2636
0
        default:
2637
0
            if (param_read_null(plist, pname) == 0)
2638
0
                return 1;
2639
1
          e:param_signal_error(plist, pname, code);
2640
103k
        case 1:
2641
103k
            ;
2642
112k
    }
2643
112k
    return code;
2644
112k
}
2645
static int
2646
param_check_long(gs_param_list * plist, gs_param_name pname, long value,
2647
                 bool is_defined)
2648
788k
{
2649
788k
    int code;
2650
788k
    long new_value;
2651
2652
788k
    switch (code = param_read_long(plist, pname, &new_value)) {
2653
13.3k
        case 0:
2654
13.3k
            if (is_defined && new_value == value)
2655
13.3k
                break;
2656
0
            code = gs_note_error(gs_error_rangecheck);
2657
0
            goto e;
2658
0
        default:
2659
0
            if (param_read_null(plist, pname) == 0)
2660
0
                return 1;
2661
0
          e:param_signal_error(plist, pname, code);
2662
774k
        case 1:
2663
774k
            ;
2664
788k
    }
2665
788k
    return code;
2666
788k
}
2667
static int
2668
param_check_bytes(gs_param_list * plist, gs_param_name pname, const byte * str,
2669
                  uint size, bool is_defined)
2670
337k
{
2671
337k
    int code;
2672
337k
    gs_param_string new_value;
2673
2674
337k
    switch (code = param_read_string(plist, pname, &new_value)) {
2675
8.88k
        case 0:
2676
8.88k
            if (is_defined && new_value.size == size &&
2677
8.88k
                !memcmp((const char *)str, (const char *)new_value.data,
2678
8.88k
                        size)
2679
8.88k
                )
2680
8.88k
                break;
2681
0
            code = gs_note_error(gs_error_rangecheck);
2682
0
            goto e;
2683
0
        default:
2684
0
            if (param_read_null(plist, pname) == 0)
2685
0
                return 1;
2686
0
          e:param_signal_error(plist, pname, code);
2687
328k
        case 1:
2688
328k
            ;
2689
337k
    }
2690
337k
    return code;
2691
337k
}