Coverage Report

Created: 2025-06-10 07:27

/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
560k
#define BLACKTHRESHOLDL 90
38
560k
#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
199k
{
55
    /*
56
     * We must be prepared to copy the device if it is the read-only
57
     * prototype.
58
     */
59
199k
    gx_device *dev;
60
199k
    int code = 0;
61
62
199k
    if (orig_dev->memory)
63
199k
        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
199k
    fill_dev_proc(dev, get_params, gx_default_get_params);
70
199k
    fill_dev_proc(dev, get_page_device, gx_default_get_page_device);
71
199k
    fill_dev_proc(dev, get_alpha_bits, gx_default_get_alpha_bits);
72
199k
    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
199k
    } else {
76
199k
        if (dev_proc(dev, get_params) != NULL)
77
199k
            code = (*dev_proc(dev, get_params)) (dev, plist);
78
199k
    }
79
199k
    if (dev != orig_dev)
80
0
        gx_device_retain(dev, false);  /* frees the copy */
81
199k
    return code;
82
199k
}
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
281k
{
128
281k
    gs_param_list * plist = (gs_param_list *)list;
129
281k
    int k, colors = dev->color_info.num_components;
130
281k
    gs_param_string profile_array[NUM_DEVICE_PROFILES];
131
281k
    gs_param_string postren_profile, blend_profile;
132
281k
    gs_param_string proof_profile, link_profile, icc_colorants;
133
281k
    gsicc_rendering_intents_t profile_intents[NUM_DEVICE_PROFILES];
134
281k
    gsicc_blackptcomp_t blackptcomps[NUM_DEVICE_PROFILES];
135
281k
    gsicc_blackpreserve_t blackpreserve[NUM_DEVICE_PROFILES];
136
281k
    int color_accuracy = MAX_COLOR_ACCURACY;
137
281k
    int depth = dev->color_info.depth;
138
281k
    cmm_dev_profile_t *dev_profile;
139
281k
    char null_str[1]={'\0'};
140
281k
#define set_param_array(a, d, s)\
141
281k
  (a.data = d, a.size = s, a.persistent = false);
142
281k
    bool devicegraytok = true;  /* Default if device profile stuct not set */
143
281k
    bool graydetection = false;
144
281k
    bool usefastcolor = false;  /* set for unmanaged color */
145
281k
    bool blacktext = false;
146
281k
    bool blackvector = false;
147
281k
    float blackthresholdL = BLACKTHRESHOLDL;
148
281k
    float blackthresholdC = BLACKTHRESHOLDC;
149
    /* By default overprinting only valid with cmyk devices */
150
281k
    gs_overprint_control_t overprint_control = gs_overprint_control_enable;
151
281k
    bool prebandthreshold = true, temp_bool = false;
152
153
281k
    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
281k
#ifdef PAGESIZE_IS_MEDIASIZE
159
281k
    if (strcmp(Param, "PageSize") == 0) {
160
21.6k
        gs_param_float_array msa;
161
21.6k
        set_param_array(msa, dev->MediaSize, 2);
162
21.6k
        return param_write_float_array(plist, "PageSize", &msa);
163
21.6k
    }
164
259k
#endif
165
259k
    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
259k
    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
259k
    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
259k
    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
259k
    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
259k
    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
259k
    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
259k
    if (strcmp(Param, "Separations") == 0) {
214
0
        bool seprs = false;
215
0
        return param_write_bool(plist, "Separations", &seprs);
216
0
    }
217
259k
    if (strcmp(Param, "UseCIEColor") == 0) {
218
0
        return param_write_bool(plist, "UseCIEColor", &dev->UseCIEColor);
219
0
    }
220
221
    /* Non-standard parameters */
222
259k
    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
259k
    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
259k
    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
259k
    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
259k
    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
259k
    if (strcmp(Param, "BitsPerPixel") == 0) {
251
0
        return param_write_int(plist, "BitsPerPixel", &depth);
252
0
    }
253
259k
    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
259k
    if (strcmp(Param, "PageCount") == 0) {
258
0
        return param_write_long(plist, "PageCount", &dev->PageCount);
259
0
    }
260
259k
    if (strcmp(Param, ".IgnoreNumCopies") == 0) {
261
0
        return param_write_bool(plist, ".IgnoreNumCopies", &dev->IgnoreNumCopies);
262
0
    }
263
259k
    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
259k
    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
259k
    if (strcmp(Param, "AntidropoutDownscaler") == 0) {
272
0
        return param_write_bool(plist, "AntidropoutDownscaler",
273
0
                                &dev->color_info.use_antidropout_downscaler);
274
0
    }
275
259k
    if (strcmp(Param, ".LockSafetyParams") == 0) {
276
0
        return param_write_bool(plist, ".LockSafetyParams", &dev->LockSafetyParams);
277
0
    }
278
259k
    if (strcmp(Param, "MaxPatternBitmap") == 0) {
279
0
        return param_write_size_t(plist, "MaxPatternBitmap", &dev->MaxPatternBitmap);
280
0
    }
281
259k
    if (strcmp(Param, "PageUsesTransparency") == 0) {
282
0
        return param_write_bool(plist, "PageUsesTransparency", &dev->page_uses_transparency);
283
0
    }
284
259k
    if (strcmp(Param, "PageUsesOverprint") == 0) {
285
0
        return param_write_bool(plist, "PageUsesOverprint", &dev->page_uses_overprint);
286
0
    }
287
259k
    if (strcmp(Param, "MaxBitmap") == 0) {
288
0
        return param_write_size_t(plist, "MaxBitmap", &(dev->space_params.MaxBitmap));
289
0
    }
290
259k
    if (strcmp(Param, "BandBufferSpace") == 0) {
291
0
        return param_write_size_t(plist, "BandBufferSpace", &dev->space_params.band.BandBufferSpace);
292
0
    }
293
259k
    if (strcmp(Param, "BandHeight") == 0) {
294
0
        return param_write_int(plist, "BandHeight", &dev->space_params.band.BandHeight);
295
0
    }
296
259k
    if (strcmp(Param, "BandWidth") == 0) {
297
0
        return param_write_int(plist, "BandWidth", &dev->space_params.band.BandWidth);
298
0
    }
299
259k
    if (strcmp(Param, "BufferSpace") == 0) {
300
0
        return param_write_size_t(plist, "BufferSpace", &dev->space_params.BufferSpace);
301
0
    }
302
259k
    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
259k
    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
259k
    if (dev->color_info.num_components > 1) {
315
259k
        int RGBValues = dev->color_info.max_color + 1;
316
259k
        long ColorValues = (depth >= 32 ? -1 : 1L << depth); /* value can only be 32 bits */
317
318
259k
        if (strcmp(Param, "RedValues") == 0) {
319
0
            return param_write_int(plist, "RedValues", &RGBValues);
320
0
        }
321
259k
        if (strcmp(Param, "GreenValues") == 0) {
322
0
            return param_write_int(plist, "GreenValues", &RGBValues);
323
0
        }
324
259k
        if (strcmp(Param, "BlueValues") == 0) {
325
0
            return param_write_int(plist, "BlueValues", &RGBValues);
326
0
        }
327
259k
        if (strcmp(Param, "ColorValues") == 0) {
328
0
            return param_write_long(plist, "ColorValues", &ColorValues);
329
0
        }
330
259k
    }
331
259k
    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
259k
    if (dev_proc(dev, get_profile) != NULL) {
352
259k
        int code;
353
259k
        code = dev_proc(dev, get_profile)(dev,  &dev_profile);
354
259k
        if (code < 0)
355
0
            return code;
356
259k
        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
1.29M
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
365
1.03M
            if (dev_profile->device_profile[k] == NULL
366
1.03M
                || dev_profile->device_profile[k]->name == NULL) {
367
779k
                param_string_from_string(profile_array[k], null_str);
368
779k
                profile_intents[k] = gsRINOTSPECIFIED;
369
779k
                blackptcomps[k] = gsBPNOTSPECIFIED;
370
779k
                blackpreserve[k] = gsBKPRESNOTSPECIFIED;
371
779k
            } else {
372
259k
                param_string_from_transient_string(profile_array[k],
373
259k
                    dev_profile->device_profile[k]->name);
374
259k
                profile_intents[k] = dev_profile->rendercond[k].rendering_intent;
375
259k
                blackptcomps[k] = dev_profile->rendercond[k].black_point_comp;
376
259k
                blackpreserve[k] = dev_profile->rendercond[k].preserve_black;
377
259k
            }
378
1.03M
        }
379
259k
        if (dev_profile->blend_profile == NULL) {
380
259k
            param_string_from_string(blend_profile, null_str);
381
259k
        } else {
382
0
            param_string_from_transient_string(blend_profile,
383
0
                dev_profile->blend_profile->name);
384
0
        }
385
259k
        if (dev_profile->postren_profile == NULL) {
386
259k
            param_string_from_string(postren_profile, null_str);
387
259k
        } else {
388
0
            param_string_from_transient_string(postren_profile,
389
0
                dev_profile->postren_profile->name);
390
0
        }
391
259k
        if (dev_profile->proof_profile == NULL) {
392
259k
            param_string_from_string(proof_profile, null_str);
393
259k
        } else {
394
0
            param_string_from_transient_string(proof_profile,
395
0
                                     dev_profile->proof_profile->name);
396
0
        }
397
259k
        if (dev_profile->link_profile == NULL) {
398
259k
            param_string_from_string(link_profile, null_str);
399
259k
        } else {
400
0
            param_string_from_transient_string(link_profile,
401
0
                                     dev_profile->link_profile->name);
402
0
        }
403
259k
        devicegraytok = dev_profile->devicegraytok;
404
259k
        graydetection = dev_profile->graydetection;
405
259k
        usefastcolor = dev_profile->usefastcolor;
406
259k
        blacktext = dev_profile->blacktext;
407
259k
        blackvector = dev_profile->blackvector;
408
259k
        blackthresholdC = dev_profile->blackthresholdC;
409
259k
        blackthresholdL = dev_profile->blackthresholdL;
410
259k
        overprint_control = dev_profile->overprint_control;
411
259k
        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
259k
        if (dev_profile->spotnames == NULL) {
416
259k
            param_string_from_string(icc_colorants, null_str);
417
259k
        } 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
259k
    } 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
259k
    if (strcmp(Param, "DeviceGrayToK") == 0) {
444
0
        return param_write_bool(plist, "DeviceGrayToK", &devicegraytok);
445
0
    }
446
259k
    if (strcmp(Param, "GrayDetection") == 0) {
447
0
        return param_write_bool(plist, "GrayDetection", &graydetection);
448
0
    }
449
259k
    if (strcmp(Param, "UseFastColor") == 0) {
450
0
        return param_write_bool(plist, "UseFastColor", &usefastcolor);
451
0
    }
452
259k
    if (strcmp(Param, "BlackText") == 0) {
453
0
        return param_write_bool(plist, "BlackText", &blacktext);
454
0
    }
455
259k
    if (strcmp(Param, "BlackVector") == 0) {
456
0
        return param_write_bool(plist, "BlackVector", &blackvector);
457
0
    }
458
259k
    if (strcmp(Param, "BlackThresholdL") == 0) {
459
0
        return param_write_float(plist, "BlackThresholdL", &blackthresholdL);
460
0
    }
461
259k
    if (strcmp(Param, "BlackThresholdC") == 0) {
462
0
        return param_write_float(plist, "BlackThresholdC", &blackthresholdC);
463
0
    }
464
259k
    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
259k
    if (strcmp(Param, "PreBandThreshold") == 0) {
472
0
        return param_write_bool(plist, "PreBandThreshold", &prebandthreshold);
473
0
    }
474
259k
    if (strcmp(Param, "PostRenderProfile") == 0) {
475
0
        return param_write_string(plist, "PostRenderProfile", &(postren_profile));
476
0
    }
477
259k
    if (strcmp(Param, "BlendColorProfile") == 0) {
478
0
        return param_write_string(plist, "BlendColorProfile", &(blend_profile));
479
0
    }
480
259k
    if (strcmp(Param, "ProofProfile") == 0) {
481
0
        return param_write_string(plist,"ProofProfile", &(proof_profile));
482
0
    }
483
259k
    if (strcmp(Param, "DeviceLinkProfile") == 0) {
484
0
        return param_write_string(plist,"DeviceLinkProfile", &(link_profile));
485
0
    }
486
259k
    if (strcmp(Param, "ICCOutputColors") == 0) {
487
0
        return param_write_string(plist,"ICCOutputColors", &(icc_colorants));
488
0
    }
489
259k
    if (strcmp(Param, "OutputICCProfile") == 0) {
490
0
        return param_write_string(plist,"OutputICCProfile", &(profile_array[0]));
491
0
    }
492
259k
    if (strcmp(Param, "VectorICCProfile") == 0) {
493
0
        return param_write_string(plist,"VectorICCProfile", &(profile_array[1]));
494
0
    }
495
259k
    if (strcmp(Param, "ImageICCProfile") == 0) {
496
0
        return param_write_string(plist,"ImageICCProfile", &(profile_array[2]));
497
0
    }
498
259k
    if (strcmp(Param, "TextICCProfile") == 0) {
499
0
        return param_write_string(plist,"TextICCProfile", &(profile_array[3]));
500
0
    }
501
259k
    if (strcmp(Param, "ColorAccuracy") == 0) {
502
0
        return param_write_int(plist, "ColorAccuracy", (const int *)(&(color_accuracy)));
503
0
    }
504
259k
    if (strcmp(Param, "RenderIntent") == 0) {
505
0
        return param_write_int(plist,"RenderIntent", (const int *) (&(profile_intents[0])));
506
0
    }
507
259k
    if (strcmp(Param, "VectorIntent") == 0) {
508
0
        return param_write_int(plist,"VectorIntent", (const int *) &(profile_intents[1]));
509
0
    }
510
259k
    if (strcmp(Param, "ImageIntent") == 0) {
511
0
        return param_write_int(plist,"ImageIntent", (const int *) &(profile_intents[2]));
512
0
    }
513
259k
    if (strcmp(Param, "TextIntent") == 0) {
514
0
        return param_write_int(plist,"TextIntent", (const int *) &(profile_intents[3]));
515
0
    }
516
259k
    if (strcmp(Param, "BlackPtComp") == 0) {
517
0
        return param_write_int(plist,"BlackPtComp", (const int *) (&(blackptcomps[0])));
518
0
    }
519
259k
    if (strcmp(Param, "VectorBlackPt") == 0) {
520
0
        return param_write_int(plist,"VectorBlackPt", (const int *) &(blackptcomps[1]));
521
0
    }
522
259k
    if (strcmp(Param, "ImageBlackPt") == 0) {
523
0
        return param_write_int(plist,"ImageBlackPt", (const int *) &(blackptcomps[2]));
524
0
    }
525
259k
    if (strcmp(Param, "TextBlackPt") == 0) {
526
0
        return param_write_int(plist,"TextBlackPt", (const int *) &(blackptcomps[3]));
527
0
    }
528
259k
    if (strcmp(Param, "KPreserve") == 0) {
529
0
        return param_write_int(plist,"KPreserve", (const int *) (&(blackpreserve[0])));
530
0
    }
531
259k
    if (strcmp(Param, "VectorKPreserve") == 0) {
532
0
        return param_write_int(plist,"VectorKPreserve", (const int *) &(blackpreserve[1]));
533
0
    }
534
259k
    if (strcmp(Param, "ImageKPreserve") == 0) {
535
0
        return param_write_int(plist,"ImageKPreserve", (const int *) &(blackpreserve[2]));
536
0
    }
537
259k
    if (strcmp(Param, "TextKPreserve") == 0) {
538
0
        return param_write_int(plist,"TextKPreserve", (const int *) &(blackpreserve[3]));
539
0
    }
540
259k
    if (strcmp(Param, "FirstPage") == 0) {
541
0
        return param_write_int(plist, "FirstPage", &dev->FirstPage);
542
0
    }
543
259k
    if (strcmp(Param, "LastPage") == 0) {
544
0
        return param_write_int(plist, "LastPage", &dev->LastPage);
545
0
    }
546
259k
    if (strcmp(Param, "DisablePageHandler") == 0) {
547
0
        temp_bool = dev->DisablePageHandler;
548
0
        return param_write_bool(plist, "DisablePageHandler", &temp_bool);
549
0
    }
550
259k
    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
259k
    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
259k
    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
259k
    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
259k
    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
259k
    return_error(gs_error_undefined);
585
259k
}
586
587
/* Get standard parameters. */
588
int
589
gx_default_get_params(gx_device * dev, gs_param_list * plist)
590
199k
{
591
199k
    int code;
592
593
    /* Standard page device parameters: */
594
595
199k
    bool seprs = false;
596
199k
    gs_param_string dns, pcms, profile_array[NUM_DEVICE_PROFILES];
597
199k
    gs_param_string blend_profile, postren_profile, pagelist, nuplist;
598
199k
    gs_param_string proof_profile, link_profile, icc_colorants;
599
199k
    gsicc_rendering_intents_t profile_intents[NUM_DEVICE_PROFILES];
600
199k
    gsicc_blackptcomp_t blackptcomps[NUM_DEVICE_PROFILES];
601
199k
    gsicc_blackpreserve_t blackpreserve[NUM_DEVICE_PROFILES];
602
199k
    bool devicegraytok = true;  /* Default if device profile stuct not set */
603
199k
    bool graydetection = false;
604
199k
    bool usefastcolor = false;  /* set for unmanaged color */
605
199k
    bool blacktext = false;
606
199k
    bool blackvector = false;
607
199k
    float blackthresholdL = BLACKTHRESHOLDL;
608
199k
    float blackthresholdC = BLACKTHRESHOLDC;
609
    /* By default, only overprint if the device supports it */
610
199k
    gs_overprint_control_t overprint_control = gs_overprint_control_enable;
611
199k
    bool prebandthreshold = true, temp_bool;
612
199k
    int k;
613
199k
    int color_accuracy = MAX_COLOR_ACCURACY;
614
199k
    gs_param_float_array msa, ibba, hwra, ma;
615
199k
    gs_param_string_array scna;
616
199k
    char null_str[1]={'\0'};
617
618
199k
#define set_param_array(a, d, s)\
619
1.39M
  (a.data = d, a.size = s, a.persistent = false);
620
621
    /* Non-standard parameters: */
622
199k
    int colors = dev->color_info.num_components;
623
199k
    int mns = dev->color_info.max_components;
624
199k
    int depth = dev->color_info.depth;
625
199k
    int GrayValues = dev->color_info.max_gray + 1;
626
199k
    int HWSize[2];
627
199k
    gs_param_int_array hwsa;
628
199k
    gs_param_float_array hwma;
629
199k
    cmm_dev_profile_t *dev_profile;
630
199k
    char *colorant_names = NULL;
631
632
    /* Fill in page device parameters. */
633
634
199k
    param_string_from_string(dns, dev->dname);
635
199k
    {
636
199k
        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
199k
        if ((cms != NULL) && (*cms != '\0'))
641
199k
            param_string_from_string(pcms, cms);
642
0
        else
643
0
            pcms.data = 0;
644
199k
    }
645
646
199k
    set_param_array(hwra, dev->HWResolution, 2);
647
199k
    set_param_array(msa, dev->MediaSize, 2);
648
199k
    set_param_array(ibba, dev->ImagingBBox, 4);
649
199k
    set_param_array(ma, dev->Margins, 2);
650
199k
    set_param_array(scna, NULL, 0);
651
652
    /* Fill in non-standard parameters. */
653
199k
    HWSize[0] = dev->width;
654
199k
    HWSize[1] = dev->height;
655
199k
    set_param_array(hwsa, HWSize, 2);
656
199k
    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
199k
    if (dev_proc(dev, get_profile) != NULL) {
665
178k
        code = dev_proc(dev, get_profile)(dev,  &dev_profile);
666
178k
        if (code < 0)
667
0
            return code;
668
669
178k
        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
891k
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
682
712k
            if (dev_profile->device_profile[k] == NULL
683
712k
                || dev_profile->device_profile[k]->name == NULL) {
684
534k
                param_string_from_string(profile_array[k], null_str);
685
534k
                profile_intents[k] = gsRINOTSPECIFIED;
686
534k
                blackptcomps[k] = gsBPNOTSPECIFIED;
687
534k
                blackpreserve[k] = gsBKPRESNOTSPECIFIED;
688
534k
            } else {
689
178k
                param_string_from_transient_string(profile_array[k],
690
178k
                    dev_profile->device_profile[k]->name);
691
178k
                profile_intents[k] = dev_profile->rendercond[k].rendering_intent;
692
178k
                blackptcomps[k] = dev_profile->rendercond[k].black_point_comp;
693
178k
                blackpreserve[k] = dev_profile->rendercond[k].preserve_black;
694
178k
            }
695
712k
        }
696
        /* The proof, link and post render profile */
697
178k
        if (dev_profile->proof_profile == NULL) {
698
178k
            param_string_from_string(proof_profile, null_str);
699
178k
        } else {
700
0
            param_string_from_transient_string(proof_profile,
701
0
                                     dev_profile->proof_profile->name);
702
0
        }
703
178k
        if (dev_profile->link_profile == NULL) {
704
178k
            param_string_from_string(link_profile, null_str);
705
178k
        } else {
706
0
            param_string_from_transient_string(link_profile,
707
0
                                     dev_profile->link_profile->name);
708
0
        }
709
178k
        if (dev_profile->postren_profile == NULL) {
710
178k
            param_string_from_string(postren_profile, null_str);
711
178k
        } else {
712
0
            param_string_from_transient_string(postren_profile,
713
0
                dev_profile->postren_profile->name);
714
0
        }
715
178k
        if (dev_profile->blend_profile == NULL) {
716
178k
            param_string_from_string(blend_profile, null_str);
717
178k
        } else {
718
0
            param_string_from_transient_string(blend_profile,
719
0
                dev_profile->blend_profile->name);
720
0
        }
721
178k
        devicegraytok = dev_profile->devicegraytok;
722
178k
        graydetection = dev_profile->graydetection;
723
178k
        usefastcolor = dev_profile->usefastcolor;
724
178k
        blacktext = dev_profile->blacktext;
725
178k
        blackvector = dev_profile->blackvector;
726
178k
        blackthresholdC = dev_profile->blackthresholdC;
727
178k
        blackthresholdL = dev_profile->blackthresholdL;
728
178k
        overprint_control = dev_profile->overprint_control;
729
178k
        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
178k
        if (dev_profile->spotnames == NULL) {
734
178k
            param_string_from_string(icc_colorants, null_str);
735
178k
        } 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
178k
    } else {
746
108k
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
747
86.6k
            param_string_from_string(profile_array[k], null_str);
748
86.6k
            profile_intents[k] = gsRINOTSPECIFIED;
749
86.6k
            blackptcomps[k] = gsBPNOTSPECIFIED;
750
86.6k
            blackpreserve[k] = gsBKPRESNOTSPECIFIED;
751
86.6k
        }
752
21.6k
        param_string_from_string(proof_profile, null_str);
753
21.6k
        param_string_from_string(link_profile, null_str);
754
21.6k
        param_string_from_string(icc_colorants, null_str);
755
21.6k
        param_string_from_string(postren_profile, null_str);
756
21.6k
        param_string_from_string(blend_profile, null_str);
757
21.6k
    }
758
    /* Transmit the values. */
759
    /* Standard parameters */
760
199k
    if (
761
199k
        (code = param_write_name(plist, "OutputDevice", &dns)) < 0 ||
762
199k
#ifdef PAGESIZE_IS_MEDIASIZE
763
199k
        (code = param_write_float_array(plist, "PageSize", &msa)) < 0 ||
764
199k
#endif
765
199k
        (code = (pcms.data == 0 ? 0 :
766
199k
                 param_write_name(plist, "ProcessColorModel", &pcms))) < 0 ||
767
199k
        (code = param_write_float_array(plist, "HWResolution", &hwra)) < 0 ||
768
199k
        (code = (dev->ImagingBBox_set ?
769
0
                 param_write_float_array(plist, "ImagingBBox", &ibba) :
770
199k
                 param_write_null(plist, "ImagingBBox"))) < 0 ||
771
199k
        (code = param_write_float_array(plist, "Margins", &ma)) < 0 ||
772
199k
        (code = param_write_int(plist, "MaxSeparations", &mns)) < 0 ||
773
199k
        (code = (dev->NumCopies_set < 0 ||
774
199k
                 (*dev_proc(dev, get_page_device))(dev) == 0 ? 0:
775
199k
                 dev->NumCopies_set ?
776
0
                 param_write_int(plist, "NumCopies", &dev->NumCopies) :
777
199k
                 param_write_null(plist, "NumCopies"))) < 0 ||
778
199k
        (code = param_write_name_array(plist, "SeparationColorNames", &scna)) < 0 ||
779
199k
        (code = param_write_bool(plist, "Separations", &seprs)) < 0 ||
780
199k
        (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
199k
        (code = param_write_bool(plist, "DeviceGrayToK", &devicegraytok)) < 0 ||
785
199k
        (code = param_write_bool(plist, "GrayDetection", &graydetection)) < 0 ||
786
199k
        (code = param_write_bool(plist, "UseFastColor", &usefastcolor)) < 0 ||
787
199k
        (code = param_write_bool(plist, "BlackText", &blacktext)) < 0 ||
788
199k
        (code = param_write_bool(plist, "BlackVector", &blackvector)) < 0 ||
789
199k
        (code = param_write_float(plist, "BlackThresholdL", &blackthresholdL)) < 0 ||
790
199k
        (code = param_write_float(plist, "BlackThresholdC", &blackthresholdC)) < 0 ||
791
199k
        (code = param_write_bool(plist, "PreBandThreshold", &prebandthreshold)) < 0 ||
792
199k
        (code = param_write_string(plist,"OutputICCProfile", &(profile_array[0]))) < 0 ||
793
199k
        (code = param_write_string(plist,"VectorICCProfile", &(profile_array[1]))) < 0 ||
794
199k
        (code = param_write_string(plist,"ImageICCProfile", &(profile_array[2]))) < 0 ||
795
199k
        (code = param_write_string(plist,"TextICCProfile", &(profile_array[3]))) < 0 ||
796
199k
        (code = param_write_string(plist,"ProofProfile", &(proof_profile))) < 0 ||
797
199k
        (code = param_write_string(plist, "PostRenderProfile", &(postren_profile))) < 0 ||
798
199k
        (code = param_write_string(plist, "BlendColorProfile", &(blend_profile))) < 0 ||
799
199k
        (code = param_write_string(plist,"DeviceLinkProfile", &(link_profile))) < 0 ||
800
199k
        (code = param_write_string(plist,"ICCOutputColors", &(icc_colorants))) < 0 ||
801
199k
        (code = param_write_int(plist, "RenderIntent", (const int *)(&(profile_intents[0])))) < 0 ||
802
199k
        (code = param_write_int(plist, "ColorAccuracy", (const int *)(&(color_accuracy)))) < 0 ||
803
199k
        (code = param_write_int(plist,"VectorIntent", (const int *) &(profile_intents[1]))) < 0 ||
804
199k
        (code = param_write_int(plist,"ImageIntent", (const int *) &(profile_intents[2]))) < 0 ||
805
199k
        (code = param_write_int(plist,"TextIntent", (const int *) &(profile_intents[3]))) < 0 ||
806
199k
        (code = param_write_int(plist,"BlackPtComp", (const int *) (&(blackptcomps[0])))) < 0 ||
807
199k
        (code = param_write_int(plist,"VectorBlackPt", (const int *) &(blackptcomps[1]))) < 0 ||
808
199k
        (code = param_write_int(plist,"ImageBlackPt", (const int *) &(blackptcomps[2]))) < 0 ||
809
199k
        (code = param_write_int(plist,"TextBlackPt", (const int *) &(blackptcomps[3]))) < 0 ||
810
199k
        (code = param_write_int(plist,"KPreserve", (const int *) (&(blackpreserve[0])))) < 0 ||
811
199k
        (code = param_write_int(plist,"VectorKPreserve", (const int *) &(blackpreserve[1]))) < 0 ||
812
199k
        (code = param_write_int(plist,"ImageKPreserve", (const int *) &(blackpreserve[2]))) < 0 ||
813
199k
        (code = param_write_int(plist,"TextKPreserve", (const int *) &(blackpreserve[3]))) < 0 ||
814
199k
        (code = param_write_int_array(plist, "HWSize", &hwsa)) < 0 ||
815
199k
        (code = param_write_float_array(plist, ".HWMargins", &hwma)) < 0 ||
816
199k
        (code = param_write_float_array(plist, ".MediaSize", &msa)) < 0 ||
817
199k
        (code = param_write_string(plist, "Name", &dns)) < 0 ||
818
199k
        (code = param_write_int(plist, "Colors", &colors)) < 0 ||
819
199k
        (code = param_write_int(plist, "BitsPerPixel", &depth)) < 0 ||
820
199k
        (code = param_write_int(plist, "GrayValues", &GrayValues)) < 0 ||
821
199k
        (code = param_write_long(plist, "PageCount", &dev->PageCount)) < 0 ||
822
199k
        (code = param_write_bool(plist, ".IgnoreNumCopies", &dev->IgnoreNumCopies)) < 0 ||
823
199k
        (code = param_write_int(plist, "TextAlphaBits",
824
199k
                                &dev->color_info.anti_alias.text_bits)) < 0 ||
825
199k
        (code = param_write_int(plist, "GraphicsAlphaBits",
826
199k
                                &dev->color_info.anti_alias.graphics_bits)) < 0 ||
827
199k
        (code = param_write_bool(plist, "AntidropoutDownscaler",
828
199k
                                &dev->color_info.use_antidropout_downscaler)) < 0 ||
829
199k
        (code = param_write_bool(plist, ".LockSafetyParams", &dev->LockSafetyParams)) < 0 ||
830
199k
        (code = param_write_size_t(plist, "MaxPatternBitmap", &dev->MaxPatternBitmap)) < 0 ||
831
199k
        (code = param_write_bool(plist, "PageUsesTransparency", &dev->page_uses_transparency)) < 0 ||
832
199k
        (code = param_write_bool(plist, "PageUsesOverprint", &dev->page_uses_overprint)) < 0 ||
833
199k
        (code = param_write_size_t(plist, "MaxBitmap", &(dev->space_params.MaxBitmap))) < 0 ||
834
199k
        (code = param_write_size_t(plist, "BandBufferSpace", &dev->space_params.band.BandBufferSpace)) < 0 ||
835
199k
        (code = param_write_int(plist, "BandHeight", &dev->space_params.band.BandHeight)) < 0 ||
836
199k
        (code = param_write_int(plist, "BandWidth", &dev->space_params.band.BandWidth)) < 0 ||
837
199k
        (code = param_write_size_t(plist, "BufferSpace", &dev->space_params.BufferSpace)) < 0 ||
838
199k
        (code = param_write_int(plist, "InterpolateControl", &dev->interpolate_control)) < 0
839
199k
        )
840
0
    {
841
0
        gs_free_object(dev->memory, colorant_names, "gx_default_get_param");
842
0
        return code;
843
0
    }
844
199k
    gs_free_object(dev->memory, colorant_names, "gx_default_get_param");
845
199k
    {
846
199k
        gs_param_string opc_name;
847
199k
        const char *s = overprint_control_names[(int)overprint_control];
848
849
199k
        param_string_from_string(opc_name, s);
850
199k
        param_write_name(plist, "Overprint", &opc_name);
851
199k
    }
852
    /* If LeadingEdge was set explicitly, report it here. */
853
199k
    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
199k
        code = param_write_null(plist, "LeadingEdge");
858
199k
    if (code < 0)
859
0
        return code;
860
861
199k
    if ((code = param_write_int(plist, "FirstPage", &dev->FirstPage)) < 0)
862
0
        return code;
863
199k
    if ((code = param_write_int(plist, "LastPage", &dev->LastPage)) < 0)
864
0
        return code;
865
866
199k
    temp_bool = dev->DisablePageHandler;
867
199k
    if ((code = param_write_bool(plist, "DisablePageHandler", &temp_bool)) < 0)
868
0
        return code;
869
870
199k
    if (dev->NupControl) {
871
0
        gdev_nupcontrol *p = (gdev_nupcontrol *)dev->NupControl;
872
0
        param_string_from_string(nuplist, p->nupcontrol_str);
873
199k
    } else {
874
199k
        param_string_from_string(nuplist, null_str);
875
199k
    }
876
199k
    if ((code = param_write_string(plist, "NupControl", &nuplist)) < 0)
877
0
        return code;
878
879
199k
    if (dev->PageList) {
880
0
        gdev_pagelist *p = (gdev_pagelist *)dev->PageList;
881
0
        param_string_from_transient_string(pagelist, p->Pages);
882
199k
    } else {
883
199k
        param_string_from_string(pagelist, null_str);
884
199k
    }
885
199k
    if ((code = param_write_string(plist, "PageList", &pagelist)) < 0)
886
0
        return code;
887
888
199k
    temp_bool = dev->ObjectFilter & FILTERIMAGE;
889
199k
    if ((code = param_write_bool(plist, "FILTERIMAGE", &temp_bool)) < 0)
890
0
        return code;
891
199k
    temp_bool = dev->ObjectFilter & FILTERTEXT;
892
199k
    if ((code = param_write_bool(plist, "FILTERTEXT", &temp_bool)) < 0)
893
0
        return code;
894
199k
    temp_bool = dev->ObjectFilter & FILTERVECTOR;
895
199k
    if ((code = param_write_bool(plist, "FILTERVECTOR", &temp_bool)) < 0)
896
0
        return code;
897
898
    /* Fill in color information. */
899
900
199k
    if (colors > 1) {
901
178k
        int RGBValues = dev->color_info.max_color + 1;
902
178k
        long ColorValues = (depth >= 32 ? -1 : 1L << depth); /* value can only be 32 bits */
903
904
178k
        if ((code = param_write_int(plist, "RedValues", &RGBValues)) < 0 ||
905
178k
            (code = param_write_int(plist, "GreenValues", &RGBValues)) < 0 ||
906
178k
            (code = param_write_int(plist, "BlueValues", &RGBValues)) < 0 ||
907
178k
            (code = param_write_long(plist, "ColorValues", &ColorValues)) < 0
908
178k
            )
909
0
            return code;
910
178k
    }
911
199k
    if (param_requested(plist, "HWColorMap")) {
912
32.4k
        byte palette[3 << 8];
913
914
32.4k
        if (param_HWColorMap(dev, palette)) {
915
32.4k
            gs_param_string hwcms;
916
917
32.4k
            hwcms.data = palette, hwcms.size = colors << depth,
918
32.4k
                hwcms.persistent = false;
919
32.4k
            if ((code = param_write_string(plist, "HWColorMap", &hwcms)) < 0)
920
0
                return code;
921
32.4k
        }
922
32.4k
    }
923
924
199k
    return 0;
925
199k
}
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
32.4k
{
931
32.4k
    int depth = dev->color_info.depth;
932
32.4k
    int colors = dev->color_info.num_components;
933
934
32.4k
    if (depth <= 8 && colors <= 3) {
935
32.4k
        byte *p = palette;
936
32.4k
        gx_color_value rgb[3];
937
32.4k
        gx_color_index i;
938
939
32.4k
        fill_dev_proc(dev, map_color_rgb, gx_default_map_color_rgb);
940
400k
        for (i = 0; (i >> depth) == 0; i++) {
941
368k
            int j;
942
943
368k
            if ((*dev_proc(dev, map_color_rgb)) (dev, i, rgb) < 0)
944
0
                return false;
945
1.42M
            for (j = 0; j < colors; j++)
946
1.06M
                *p++ = gx_color_value_to_byte(rgb[j]);
947
368k
        }
948
32.4k
        return true;
949
32.4k
    }
950
0
    return false;
951
32.4k
}
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
474k
  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
237k
  param_check_bytes(plist, pname, (const byte *)(str), \
1122
237k
                    (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
79.0k
{
1130
79.0k
    bool was_open = dev->is_open;
1131
79.0k
    int code;
1132
1133
    /* gs_param_list_dump(plist); */
1134
1135
79.0k
    fill_dev_proc(dev, put_params, gx_default_put_params);
1136
79.0k
    fill_dev_proc(dev, get_alpha_bits, gx_default_get_alpha_bits);
1137
79.0k
    code = (*dev_proc(dev, put_params)) (dev, plist);
1138
79.0k
    return (code < 0 ? code : was_open && !dev->is_open ? 1 : code);
1139
79.0k
}
1140
1141
static int
1142
gx_default_put_graydetection(bool graydetection, gx_device * dev)
1143
79.0k
{
1144
79.0k
    int code = 0;
1145
79.0k
    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
79.0k
    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
43.3k
        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
43.3k
        dev->icc_struct->graydetection = graydetection;
1165
43.3k
        dev->icc_struct->pageneutralcolor = graydetection;
1166
43.3k
    } else {
1167
35.7k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1168
35.7k
        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
35.7k
        profile_struct->graydetection = graydetection;
1176
35.7k
        profile_struct->pageneutralcolor = graydetection;
1177
35.7k
    }
1178
79.0k
    return code;
1179
79.0k
}
1180
1181
static int
1182
gx_default_put_graytok(bool graytok, gx_device * dev)
1183
79.0k
{
1184
79.0k
    int code = 0;
1185
79.0k
    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
79.0k
    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
43.3k
        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
43.3k
        dev->icc_struct->devicegraytok = graytok;
1205
43.3k
    } else {
1206
35.7k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1207
35.7k
        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
35.7k
        profile_struct->devicegraytok = graytok;
1215
35.7k
    }
1216
79.0k
    return code;
1217
79.0k
}
1218
1219
static int
1220
gx_default_put_prebandthreshold(bool prebandthreshold, gx_device * dev)
1221
79.0k
{
1222
79.0k
    int code = 0;
1223
79.0k
    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
79.0k
    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
43.3k
        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
43.3k
        dev->icc_struct->prebandthreshold = prebandthreshold;
1243
43.3k
    } else {
1244
35.7k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1245
35.7k
        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
35.7k
        profile_struct->prebandthreshold = prebandthreshold;
1253
35.7k
    }
1254
79.0k
    return code;
1255
79.0k
}
1256
1257
static int
1258
gx_default_put_usefastcolor(bool fastcolor, gx_device * dev)
1259
79.0k
{
1260
79.0k
    int code = 0;
1261
79.0k
    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
79.0k
    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
43.3k
        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
43.3k
        dev->icc_struct->usefastcolor = fastcolor;
1281
43.3k
    } else {
1282
35.7k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1283
35.7k
        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
35.7k
        profile_struct->usefastcolor = fastcolor;
1291
35.7k
    }
1292
79.0k
    return code;
1293
79.0k
}
1294
1295
static int
1296
gx_default_put_blacktext(bool blacktext, gx_device* dev)
1297
79.0k
{
1298
79.0k
    int code = 0;
1299
79.0k
    cmm_dev_profile_t* profile_struct;
1300
1301
79.0k
    if (dev_proc(dev, get_profile) == NULL) {
1302
43.3k
        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
43.3k
        dev->icc_struct->blacktext = blacktext;
1308
43.3k
    } else {
1309
35.7k
        code = dev_proc(dev, get_profile)(dev, &profile_struct);
1310
35.7k
        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
35.7k
        profile_struct->blacktext = blacktext;
1318
35.7k
    }
1319
79.0k
    return code;
1320
79.0k
}
1321
1322
static int
1323
gx_default_put_blackthresholds(float blackthresholdL, float blackthresholdC, gx_device *dev)
1324
79.0k
{
1325
79.0k
    int code = 0;
1326
79.0k
    cmm_dev_profile_t* profile_struct;
1327
1328
79.0k
    if (dev_proc(dev, get_profile) == NULL) {
1329
43.3k
        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
43.3k
        dev->icc_struct->blackthresholdL = blackthresholdL;
1335
43.3k
        dev->icc_struct->blackthresholdC = blackthresholdC;
1336
43.3k
    } else {
1337
35.7k
        code = dev_proc(dev, get_profile)(dev, &profile_struct);
1338
35.7k
        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
35.7k
        profile_struct->blackthresholdL = blackthresholdL;
1346
35.7k
        profile_struct->blackthresholdC = blackthresholdC;
1347
35.7k
    }
1348
79.0k
    return code;
1349
79.0k
}
1350
1351
static int
1352
gx_default_put_blackvector(bool blackvector, gx_device* dev)
1353
79.0k
{
1354
79.0k
    int code = 0;
1355
79.0k
    cmm_dev_profile_t* profile_struct;
1356
1357
79.0k
    if (dev_proc(dev, get_profile) == NULL) {
1358
43.3k
        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
43.3k
        dev->icc_struct->blackvector = blackvector;
1364
43.3k
    } else {
1365
35.7k
        code = dev_proc(dev, get_profile)(dev, &profile_struct);
1366
35.7k
        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
35.7k
        profile_struct->blackvector = blackvector;
1374
35.7k
    }
1375
79.0k
    return code;
1376
79.0k
}
1377
1378
static int
1379
gx_default_put_overprint_control(gs_overprint_control_t overprint_control, gx_device * dev)
1380
79.0k
{
1381
79.0k
    int code = 0;
1382
79.0k
    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
79.0k
    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
43.3k
        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
43.3k
        dev->icc_struct->overprint_control = overprint_control;
1402
43.3k
    } else {
1403
35.7k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1404
35.7k
        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
35.7k
        profile_struct->overprint_control = overprint_control;
1412
35.7k
    }
1413
79.0k
    return code;
1414
79.0k
}
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
316k
{
1420
316k
    int code;
1421
316k
    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
316k
    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
173k
        if (dev->icc_struct == NULL) {
1433
            /* Intializes the device structure.  Not the profile though for index */
1434
10.8k
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1435
10.8k
            if (dev->icc_struct == NULL)
1436
0
                return_error(gs_error_VMerror);
1437
10.8k
        }
1438
173k
        code = gsicc_set_device_profile_intent(dev, icc_intent, index);
1439
173k
    } else {
1440
143k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1441
143k
        if (code < 0)
1442
0
            return code;
1443
143k
        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
143k
        code = gsicc_set_device_profile_intent(dev, icc_intent, index);
1450
143k
    }
1451
316k
    return code;
1452
316k
}
1453
1454
static int
1455
gx_default_put_blackpreserve(gsicc_blackpreserve_t blackpreserve, gx_device * dev,
1456
                           gsicc_profile_types_t index)
1457
316k
{
1458
316k
    int code;
1459
316k
    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
316k
    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
173k
        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
173k
        code = gsicc_set_device_blackpreserve(dev, blackpreserve, index);
1477
173k
    } else {
1478
143k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1479
143k
        if (code < 0)
1480
0
            return code;
1481
143k
        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
143k
        code = gsicc_set_device_blackpreserve(dev, blackpreserve, index);
1488
143k
    }
1489
316k
    return code;
1490
316k
}
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
316k
{
1499
316k
    int code;
1500
316k
    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
316k
    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
173k
        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
173k
        code = gsicc_set_device_blackptcomp(dev, blackptcomp, index);
1518
173k
    } else {
1519
143k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1520
143k
        if (code < 0)
1521
0
            return code;
1522
143k
        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
143k
        code = gsicc_set_device_blackptcomp(dev, blackptcomp, index);
1529
143k
    }
1530
316k
    return code;
1531
316k
}
1532
1533
static int
1534
gx_default_put_icc_colorants(gs_param_string *colorants, gx_device * dev)
1535
4.29k
{
1536
4.29k
    char *tempstr;
1537
4.29k
    int code;
1538
4.29k
    int len;
1539
4.29k
    unsigned short *tempstr2 = NULL;
1540
4.29k
    unsigned short *s;
1541
4.29k
    char *d;
1542
1543
4.29k
    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
34.3k
{
1595
34.3k
    char *tempstr;
1596
34.3k
    int code = 0;
1597
1598
34.3k
    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
4.29k
    fill_dev_proc(dev, get_profile, gx_default_get_profile);
1606
4.29k
    if (icc_pro->size < gp_file_name_sizeof) {
1607
4.29k
        tempstr = (char *) gs_alloc_bytes(dev->memory, icc_pro->size+1,
1608
4.29k
                                          "gx_default_put_icc");
1609
4.29k
        if (tempstr == NULL)
1610
0
            return_error(gs_error_VMerror);
1611
4.29k
        memcpy(tempstr, icc_pro->data, icc_pro->size);
1612
        /* Set last position to NULL. */
1613
4.29k
        tempstr[icc_pro->size] = 0;
1614
4.29k
        code = gsicc_init_device_profile_struct(dev, tempstr, index);
1615
4.29k
        gs_free_object(dev->memory, tempstr, "gx_default_put_icc");
1616
4.29k
    }
1617
4.29k
    return code;
1618
4.29k
}
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
79.0k
{
1652
79.0k
    int ecode = 0;
1653
79.0k
    int code;
1654
79.0k
    gs_param_name param_name;
1655
79.0k
    gs_param_float_array hwra;
1656
79.0k
    gs_param_int_array hwsa;
1657
79.0k
    gs_param_float_array msa;
1658
79.0k
    gs_param_float_array ma;
1659
79.0k
    gs_param_float_array hwma;
1660
79.0k
    gs_param_string_array scna;
1661
79.0k
    int nci = dev->NumCopies;
1662
79.0k
    int ncset = dev->NumCopies_set;
1663
79.0k
    bool ignc = dev->IgnoreNumCopies;
1664
79.0k
    bool ucc = dev->UseCIEColor;
1665
79.0k
    gs_param_string icc_pro;
1666
79.0k
    bool locksafe = dev->LockSafetyParams;
1667
79.0k
    gs_param_float_array ibba;
1668
79.0k
    bool ibbnull = false;
1669
79.0k
    int colors = dev->color_info.num_components;
1670
79.0k
    int depth = dev->color_info.depth;
1671
79.0k
    int GrayValues = dev->color_info.max_gray + 1;
1672
79.0k
    int RGBValues = dev->color_info.max_color + 1;
1673
79.0k
    long ColorValues = (depth >= 32 ? -1 : 1L << depth);
1674
79.0k
    int tab = dev->color_info.anti_alias.text_bits;
1675
79.0k
    int gab = dev->color_info.anti_alias.graphics_bits;
1676
79.0k
    size_t mpbm = dev->MaxPatternBitmap;
1677
79.0k
    int ic = dev->interpolate_control;
1678
79.0k
    bool page_uses_transparency = dev->page_uses_transparency;
1679
79.0k
    bool page_uses_overprint = dev->page_uses_overprint;
1680
79.0k
    gdev_space_params sp = dev->space_params;
1681
79.0k
    gdev_space_params save_sp = dev->space_params;
1682
79.0k
    int rend_intent[NUM_DEVICE_PROFILES];
1683
79.0k
    int blackptcomp[NUM_DEVICE_PROFILES];
1684
79.0k
    int blackpreserve[NUM_DEVICE_PROFILES];
1685
79.0k
    gs_param_string cms, pagelist, nuplist;
1686
79.0k
    int leadingedge = dev->LeadingEdge;
1687
79.0k
    int k;
1688
79.0k
    int color_accuracy;
1689
79.0k
    bool devicegraytok = true;
1690
79.0k
    bool graydetection = false;
1691
79.0k
    bool usefastcolor = false;
1692
79.0k
    bool blacktext = false;
1693
79.0k
    bool blackvector = false;
1694
79.0k
    float blackthresholdL = BLACKTHRESHOLDL;
1695
79.0k
    float blackthresholdC = BLACKTHRESHOLDC;
1696
79.0k
    gs_overprint_control_t overprint_control = gs_overprint_control_enable;
1697
79.0k
    bool prebandthreshold = false;
1698
79.0k
    bool use_antidropout = dev->color_info.use_antidropout_downscaler;
1699
79.0k
    bool temp_bool;
1700
79.0k
    int  profile_types[NUM_DEVICE_PROFILES] = {gsDEFAULTPROFILE,
1701
79.0k
                                               gsGRAPHICPROFILE,
1702
79.0k
                                               gsIMAGEPROFILE,
1703
79.0k
                                               gsTEXTPROFILE};
1704
1705
79.0k
    color_accuracy = gsicc_currentcoloraccuracy(dev->memory);
1706
79.0k
    if (dev->icc_struct != NULL) {
1707
341k
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
1708
273k
            rend_intent[k] = dev->icc_struct->rendercond[k].rendering_intent;
1709
273k
            blackptcomp[k] = dev->icc_struct->rendercond[k].black_point_comp;
1710
273k
            blackpreserve[k] = dev->icc_struct->rendercond[k].preserve_black;
1711
273k
        }
1712
68.2k
        graydetection = dev->icc_struct->graydetection;
1713
68.2k
        devicegraytok = dev->icc_struct->devicegraytok;
1714
68.2k
        usefastcolor = dev->icc_struct->usefastcolor;
1715
68.2k
        blacktext = dev->icc_struct->blacktext;
1716
68.2k
        blackvector = dev->icc_struct->blackvector;
1717
68.2k
        blackthresholdL = dev->icc_struct->blackthresholdL;
1718
68.2k
        blackthresholdC = dev->icc_struct->blackthresholdC;
1719
68.2k
        prebandthreshold = dev->icc_struct->prebandthreshold;
1720
68.2k
        overprint_control = dev->icc_struct->overprint_control;
1721
68.2k
    } else {
1722
54.1k
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
1723
43.3k
            rend_intent[k] = gsRINOTSPECIFIED;
1724
43.3k
            blackptcomp[k] = gsBPNOTSPECIFIED;
1725
43.3k
            blackpreserve[k] = gsBKPRESNOTSPECIFIED;
1726
43.3k
        }
1727
10.8k
    }
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
79.0k
#define BEGIN_ARRAY_PARAM(pread, pname, pa, psize, e)\
1740
553k
    BEGIN\
1741
553k
    switch (code = pread(plist, (param_name = pname), &(pa))) {\
1742
98.6k
      case 0:\
1743
98.6k
        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
79.0k
#define END_ARRAY_PARAM(pa, e)\
1748
79.0k
        goto e;\
1749
98.6k
      default:\
1750
22
        ecode = code;\
1751
22
e:  param_signal_error(plist, param_name, ecode);\
1752
455k
      case 1:\
1753
455k
        (pa).data = 0;   /* mark as not filled */\
1754
1.10M
    }\
1755
1.10M
    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
79.0k
    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
94.2k
    BEGIN_ARRAY_PARAM(param_read_float_array, "HWResolution", hwra, 2, hwre) {
1788
15.1k
        if (hwra.data[0] <= 0 || hwra.data[1] <= 0)
1789
0
            ecode = gs_note_error(gs_error_rangecheck);
1790
15.1k
        else
1791
15.1k
            break;
1792
15.1k
    } END_ARRAY_PARAM(hwra, hwre);
1793
83.3k
    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
4.29k
        if ((hwsa.data[0] <= 0 && hwsa.data[0] != dev->width) ||
1797
4.29k
            (hwsa.data[1] <= 0 && hwsa.data[1] != dev->height)
1798
4.29k
        )
1799
0
            ecode = gs_note_error(gs_error_rangecheck);
1800
12.8k
#define max_coord (max_fixed / fixed_1)
1801
4.29k
#if max_coord < max_int
1802
4.29k
        else if (hwsa.data[0] > max_coord || hwsa.data[1] > max_coord)
1803
0
            ecode = gs_note_error(gs_error_limitcheck);
1804
4.29k
#endif
1805
4.29k
#undef max_coord
1806
4.29k
        else
1807
4.29k
            break;
1808
4.29k
    } END_ARRAY_PARAM(hwsa, hwse);
1809
79.0k
    {
1810
79.0k
        int t;
1811
1812
79.0k
        code = param_read_int(plist, "LeadingEdge", &t);
1813
79.0k
        if (code < 0) {
1814
4.29k
            if (param_read_null(plist, "LeadingEdge") == 0) {
1815
                /* if param is null, clear explicitly-set flag */
1816
4.29k
                leadingedge &= ~LEADINGEDGE_SET_MASK;
1817
4.29k
            } else {
1818
0
                ecode = code;
1819
0
            }
1820
74.7k
        } 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
79.0k
    }
1828
79.0k
    {
1829
79.0k
        const float *res = (hwra.data == 0 ? dev->HWResolution : hwra.data);
1830
1831
79.0k
#ifdef PAGESIZE_IS_MEDIASIZE
1832
79.0k
        const float *data;
1833
1834
        /* .MediaSize takes precedence over PageSize, so */
1835
        /* we read PageSize first. */
1836
79.0k
        code = param_MediaSize(plist, "PageSize", res, &msa);
1837
79.0k
        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
79.0k
        data = msa.data;
1842
79.0k
        code = param_MediaSize(plist, ".MediaSize", res, &msa);
1843
79.0k
        if (code < 0)
1844
22
            ecode = code;
1845
79.0k
        else if (msa.data == 0)
1846
43.7k
            msa.data = data;
1847
#else
1848
        code = param_MediaSize(plist, ".MediaSize", res, &msa);
1849
        if (code < 0)
1850
            ecode = code;
1851
#endif
1852
79.0k
    }
1853
1854
83.3k
    BEGIN_ARRAY_PARAM(param_read_float_array, "Margins", ma, 2, me) {
1855
4.29k
        break;
1856
4.29k
    } END_ARRAY_PARAM(ma, me);
1857
83.3k
    BEGIN_ARRAY_PARAM(param_read_float_array, ".HWMargins", hwma, 4, hwme) {
1858
4.29k
        break;
1859
4.29k
    } END_ARRAY_PARAM(hwma, hwme);
1860
79.0k
    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
4.29k
        case 0:
1865
79.0k
        case 1:
1866
79.0k
            break;
1867
79.0k
    }
1868
79.0k
    if (dev->NumCopies_set >= 0 &&
1869
79.0k
        (*dev_proc(dev, get_page_device))(dev) != 0
1870
79.0k
        ) {
1871
79.0k
        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
4.29k
            default:
1881
4.29k
                if ((code = param_read_null(plist, param_name)) == 0) {
1882
4.29k
                    ncset = 0;
1883
4.29k
                    break;
1884
4.29k
                }
1885
0
                ecode = code; /* can't be 1 */
1886
0
nce:
1887
0
                param_signal_error(plist, param_name, ecode);
1888
74.7k
            case 1:
1889
74.7k
                break;
1890
79.0k
        }
1891
79.0k
    }
1892
    /* Set the ICC output colors first */
1893
79.0k
    if ((code = param_read_string(plist, "ICCOutputColors", &icc_pro)) != 1) {
1894
4.29k
        if (code < 0) {
1895
0
            ecode = code;
1896
0
            param_signal_error(plist, "ICCOutputColors", ecode);
1897
4.29k
        } else {
1898
4.29k
            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
4.29k
        }
1903
4.29k
    }
1904
79.0k
    if ((code = param_read_string(plist, "DeviceLinkProfile", &icc_pro)) != 1) {
1905
4.29k
        if (code < 0) {
1906
0
            ecode = code;
1907
0
            param_signal_error(plist, "DeviceLinkProfile", ecode);
1908
4.29k
        } else {
1909
4.29k
            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
4.29k
        }
1914
4.29k
    }
1915
79.0k
    if ((code = param_read_string(plist, "PostRenderProfile", &icc_pro)) != 1) {
1916
4.29k
        if (code < 0) {
1917
0
            ecode = code;
1918
0
            param_signal_error(plist, "PostRenderProfile", ecode);
1919
4.29k
        } else {
1920
4.29k
            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
4.29k
        }
1925
4.29k
    }
1926
79.0k
    if ((code = param_read_string(plist, "OutputICCProfile", &icc_pro)) != 1) {
1927
4.29k
        if (code < 0) {
1928
0
            ecode = code;
1929
0
            param_signal_error(plist, "OutputICCProfile", ecode);
1930
4.29k
        } else {
1931
4.29k
            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
4.29k
        }
1936
4.29k
    }
1937
    /* Note, if a change is made to NUM_DEVICE_PROFILES we need to update
1938
       this with the name of the profile */
1939
79.0k
    if ((code = param_read_string(plist, "VectorICCProfile", &icc_pro)) != 1) {
1940
4.29k
        if (code < 0) {
1941
0
            ecode = code;
1942
0
            param_signal_error(plist, "VectorICCProfile", ecode);
1943
4.29k
        } else {
1944
4.29k
            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
4.29k
        }
1949
4.29k
    }
1950
79.0k
    if ((code = param_read_string(plist, "ImageICCProfile", &icc_pro)) != 1) {
1951
4.29k
        if (code < 0) {
1952
0
            ecode = code;
1953
0
            param_signal_error(plist, "ImageICCProfile", ecode);
1954
4.29k
        } else {
1955
4.29k
            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
4.29k
        }
1960
4.29k
    }
1961
79.0k
    if ((code = param_read_string(plist, "TextICCProfile", &icc_pro)) != 1) {
1962
4.29k
        if (code < 0) {
1963
0
            ecode = code;
1964
0
            param_signal_error(plist, "TextICCProfile", ecode);
1965
4.29k
        } else {
1966
4.29k
            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
4.29k
        }
1971
4.29k
    }
1972
79.0k
    if ((code = param_read_string(plist, "ProofProfile", &icc_pro)) != 1) {
1973
4.29k
        if (code < 0) {
1974
0
            ecode = code;
1975
0
            param_signal_error(plist, "ProofProfile", ecode);
1976
4.29k
        } else {
1977
4.29k
            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
4.29k
        }
1982
4.29k
    }
1983
79.0k
    if ((code = param_read_string(plist, "BlendColorProfile", &icc_pro)) != 1) {
1984
4.29k
        if (code < 0) {
1985
0
            ecode = code;
1986
0
            param_signal_error(plist, "BlendColorProfile", ecode);
1987
4.29k
        } else {
1988
4.29k
            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
4.29k
        }
1993
4.29k
    }
1994
79.0k
    if ((code = param_read_int(plist, (param_name = "RenderIntent"),
1995
79.0k
                                                    &(rend_intent[0]))) < 0) {
1996
0
        ecode = code;
1997
0
        param_signal_error(plist, param_name, ecode);
1998
0
    }
1999
79.0k
    if ((code = param_read_int(plist, (param_name = "VectorIntent"),
2000
79.0k
                                                    &(rend_intent[1]))) < 0) {
2001
0
        ecode = code;
2002
0
        param_signal_error(plist, param_name, ecode);
2003
0
    }
2004
79.0k
    if ((code = param_read_int(plist, (param_name = "ImageIntent"),
2005
79.0k
                                                    &(rend_intent[2]))) < 0) {
2006
0
        ecode = code;
2007
0
        param_signal_error(plist, param_name, ecode);
2008
0
    }
2009
79.0k
    if ((code = param_read_int(plist, (param_name = "TextIntent"),
2010
79.0k
                                                    &(rend_intent[3]))) < 0) {
2011
0
        ecode = code;
2012
0
        param_signal_error(plist, param_name, ecode);
2013
0
    }
2014
79.0k
    if ((code = param_read_int(plist, (param_name = "BlackPtComp"),
2015
79.0k
                                                    &(blackptcomp[0]))) < 0) {
2016
0
        ecode = code;
2017
0
        param_signal_error(plist, param_name, ecode);
2018
0
    }
2019
79.0k
    if ((code = param_read_int(plist, (param_name = "VectorBlackPt"),
2020
79.0k
                                                    &(blackptcomp[1]))) < 0) {
2021
0
        ecode = code;
2022
0
        param_signal_error(plist, param_name, ecode);
2023
0
    }
2024
79.0k
    if ((code = param_read_int(plist, (param_name = "ImageBlackPt"),
2025
79.0k
                                                    &(blackptcomp[2]))) < 0) {
2026
0
        ecode = code;
2027
0
        param_signal_error(plist, param_name, ecode);
2028
0
    }
2029
79.0k
    if ((code = param_read_int(plist, (param_name = "TextBlackPt"),
2030
79.0k
                                                    &(blackptcomp[3]))) < 0) {
2031
0
        ecode = code;
2032
0
        param_signal_error(plist, param_name, ecode);
2033
0
    }
2034
79.0k
    if ((code = param_read_int(plist, (param_name = "KPreserve"),
2035
79.0k
                                                    &(blackpreserve[0]))) < 0) {
2036
0
        ecode = code;
2037
0
        param_signal_error(plist, param_name, ecode);
2038
0
    }
2039
79.0k
    if ((code = param_read_int(plist, (param_name = "VectorKPreserve"),
2040
79.0k
                                                    &(blackpreserve[1]))) < 0) {
2041
0
        ecode = code;
2042
0
        param_signal_error(plist, param_name, ecode);
2043
0
    }
2044
79.0k
    if ((code = param_read_int(plist, (param_name = "ImageKPreserve"),
2045
79.0k
                                                    &(blackpreserve[2]))) < 0) {
2046
0
        ecode = code;
2047
0
        param_signal_error(plist, param_name, ecode);
2048
0
    }
2049
79.0k
    if ((code = param_read_int(plist, (param_name = "TextKPreserve"),
2050
79.0k
                                                    &(blackpreserve[3]))) < 0) {
2051
0
        ecode = code;
2052
0
        param_signal_error(plist, param_name, ecode);
2053
0
    }
2054
79.0k
    if ((code = param_read_int(plist, (param_name = "ColorAccuracy"),
2055
79.0k
                                                        &color_accuracy)) < 0) {
2056
0
        ecode = code;
2057
0
        param_signal_error(plist, param_name, ecode);
2058
0
    }
2059
79.0k
    if ((code = param_read_bool(plist, (param_name = "DeviceGrayToK"),
2060
79.0k
                                                        &devicegraytok)) < 0) {
2061
0
        ecode = code;
2062
0
        param_signal_error(plist, param_name, ecode);
2063
0
    }
2064
79.0k
    if ((code = param_read_bool(plist, (param_name = "GrayDetection"),
2065
79.0k
                                                        &graydetection)) < 0) {
2066
0
        ecode = code;
2067
0
        param_signal_error(plist, param_name, ecode);
2068
0
    }
2069
79.0k
    if ((code = param_read_bool(plist, (param_name = "UseFastColor"),
2070
79.0k
                                                        &usefastcolor)) < 0) {
2071
0
        ecode = code;
2072
0
        param_signal_error(plist, param_name, ecode);
2073
0
    }
2074
79.0k
    if ((code = param_read_bool(plist, (param_name = "BlackText"),
2075
79.0k
                                                        &blacktext)) < 0) {
2076
0
        ecode = code;
2077
0
        param_signal_error(plist, param_name, ecode);
2078
0
    }
2079
79.0k
    if ((code = param_read_bool(plist, (param_name = "BlackVector"),
2080
79.0k
                                                        &blackvector)) < 0) {
2081
0
        ecode = code;
2082
0
        param_signal_error(plist, param_name, ecode);
2083
0
    }
2084
79.0k
    if ((code = param_read_float(plist, (param_name = "BlackThresholdL"),
2085
79.0k
                                                        &blackthresholdL)) < 0) {
2086
0
        ecode = code;
2087
0
        param_signal_error(plist, param_name, ecode);
2088
0
    }
2089
79.0k
    if ((code = param_read_float(plist, (param_name = "BlackThresholdC"),
2090
79.0k
                                                        &blackthresholdC)) < 0) {
2091
0
        ecode = code;
2092
0
        param_signal_error(plist, param_name, ecode);
2093
0
    }
2094
79.0k
    if ((code = param_put_enum(plist, "Overprint",
2095
79.0k
                           (int*)&overprint_control, overprint_control_names, ecode)) < 0) {
2096
22
        ecode = code;
2097
22
        param_signal_error(plist, param_name, ecode);
2098
22
    }
2099
79.0k
    if ((code = param_read_bool(plist, (param_name = "PreBandThreshold"),
2100
79.0k
                                                        &prebandthreshold)) < 0) {
2101
0
        ecode = code;
2102
0
        param_signal_error(plist, param_name, ecode);
2103
0
    }
2104
79.0k
    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
79.0k
    if ((code = param_anti_alias_bits(plist, "TextAlphaBits", &tab)) < 0)
2109
0
        ecode = code;
2110
79.0k
    if ((code = param_anti_alias_bits(plist, "GraphicsAlphaBits", &gab)) < 0)
2111
0
        ecode = code;
2112
79.0k
    if ((code = param_read_bool(plist, "AntidropoutDownscaler", &use_antidropout)) < 0)
2113
0
        ecode = code;
2114
79.0k
    if ((code = param_read_size_t(plist, "MaxPatternBitmap", &mpbm)) < 0)
2115
0
        ecode = code;
2116
79.0k
    if ((code = param_read_int(plist, "InterpolateControl", &ic)) < 0)
2117
0
        ecode = code;
2118
79.0k
    if ((code = param_read_bool(plist, (param_name = "PageUsesTransparency"),
2119
79.0k
                                &page_uses_transparency)) < 0) {
2120
0
        ecode = code;
2121
0
        param_signal_error(plist, param_name, ecode);
2122
0
    }
2123
79.0k
    if ((code = param_read_bool(plist, (param_name = "PageUsesOverprint"),
2124
79.0k
                                &page_uses_overprint)) < 0) {
2125
0
        ecode = code;
2126
0
        param_signal_error(plist, param_name, ecode);
2127
0
    }
2128
79.0k
    if ((code = param_read_size_t(plist, "MaxBitmap", &sp.MaxBitmap)) < 0)
2129
0
        ecode = code;
2130
2131
79.0k
#define CHECK_PARAM_CASES(member, bad, label)\
2132
79.0k
    case 0:\
2133
28.0k
        if ((sp.params_are_read_only ? sp.member != save_sp.member : bad))\
2134
0
            ecode = gs_error_rangecheck;\
2135
0
        else\
2136
28.0k
            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
288k
    case 1:\
2143
288k
        break
2144
2145
79.0k
    switch (code = param_read_size_t(plist, (param_name = "BufferSpace"), &sp.BufferSpace)) {
2146
79.0k
        CHECK_PARAM_CASES(BufferSpace, sp.BufferSpace < 10000, bse);
2147
79.0k
    }
2148
2149
79.0k
    switch (code = param_read_int(plist, (param_name = "BandWidth"), &sp.band.BandWidth)) {
2150
79.0k
        CHECK_PARAM_CASES(band.BandWidth, sp.band.BandWidth < 0, bwe);
2151
79.0k
    }
2152
2153
79.0k
    switch (code = param_read_int(plist, (param_name = "BandHeight"), &sp.band.BandHeight)) {
2154
79.0k
        CHECK_PARAM_CASES(band.BandHeight, sp.band.BandHeight < -1, bhe);
2155
79.0k
    }
2156
79.0k
    if (sp.band.BandHeight == -1)
2157
0
        sp.band.BandHeight = dev->height; /* 1 band for the page requested */
2158
2159
79.0k
    switch (code = param_read_size_t(plist, (param_name = "BandBufferSpace"), &sp.band.BandBufferSpace)) {
2160
79.0k
        CHECK_PARAM_CASES(band.BandBufferSpace, 0, bbse);
2161
79.0k
    }
2162
2163
2164
79.0k
    switch (code = param_read_bool(plist, (param_name = ".LockSafetyParams"), &locksafe)) {
2165
4.29k
        case 0:
2166
4.29k
            if (dev->LockSafetyParams && !locksafe)
2167
0
                code = gs_note_error(gs_error_invalidaccess);
2168
4.29k
            else
2169
4.29k
                break;
2170
0
        default:
2171
0
            ecode = code;
2172
0
            param_signal_error(plist, param_name, ecode);
2173
74.7k
        case 1:
2174
74.7k
            break;
2175
79.0k
    }
2176
    /* Ignore parameters that only have meaning for printers. */
2177
79.0k
#define IGNORE_INT_PARAM(pname)\
2178
316k
  { int igni;\
2179
316k
    switch ( code = param_read_int(plist, (param_name = pname), &igni) )\
2180
316k
      { default:\
2181
0
          ecode = code;\
2182
0
          param_signal_error(plist, param_name, ecode);\
2183
74.9k
        case 0:\
2184
316k
        case 1:\
2185
316k
          break;\
2186
316k
      }\
2187
316k
  }
2188
79.0k
    IGNORE_INT_PARAM("%MediaSource")
2189
79.0k
        IGNORE_INT_PARAM("%MediaDestination")
2190
79.0k
        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
79.0k
        case 1:
2208
79.0k
            ibba.data = 0;
2209
79.0k
            break;
2210
79.0k
    }
2211
2212
    /* Separation, DeviceN Color, and ProcessColorModel related parameters. */
2213
79.0k
    {
2214
79.0k
        const char * pcms = get_process_color_model_name(dev);
2215
        /* the device should have set a process model name at this point */
2216
79.0k
        if ((code = param_check_string(plist, "ProcessColorModel", pcms, (pcms != NULL))) < 0)
2217
0
            ecode = code;
2218
79.0k
    }
2219
79.0k
    IGNORE_INT_PARAM("MaxSeparations")
2220
79.0k
    if ((code = param_check_bool(plist, "Separations", false, true)) < 0)
2221
0
        ecode = code;
2222
2223
114k
    BEGIN_ARRAY_PARAM(param_read_name_array, "SeparationColorNames", scna, scna.size, scne) {
2224
35.3k
        break;
2225
35.3k
    } END_ARRAY_PARAM(scna, scne);
2226
2227
    /* Now check nominally read-only parameters. */
2228
79.0k
    if ((code = param_check_string(plist, "OutputDevice", dev->dname, true)) < 0)
2229
0
        ecode = code;
2230
79.0k
    if ((code = param_check_string(plist, "Name", dev->dname, true)) < 0)
2231
0
        ecode = code;
2232
79.0k
    if ((code = param_check_int(plist, "Colors", colors, true)) < 0)
2233
0
        ecode = code;
2234
79.0k
    if ((code = param_check_int(plist, "BitsPerPixel", depth, true)) < 0)
2235
0
        ecode = code;
2236
79.0k
    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
79.0k
    IGNORE_INT_PARAM("PageCount")
2241
2242
79.0k
    if ((code = param_check_int(plist, "RedValues", RGBValues, true)) < 0)
2243
0
        ecode = code;
2244
79.0k
    if ((code = param_check_int(plist, "GreenValues", RGBValues, true)) < 0)
2245
0
        ecode = code;
2246
79.0k
    if ((code = param_check_int(plist, "BlueValues", RGBValues, true)) < 0)
2247
0
        ecode = code;
2248
79.0k
    if ((code = param_check_long(plist, "ColorValues", ColorValues, true)) < 0)
2249
0
        ecode = code;
2250
79.0k
    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
79.0k
    code = param_read_int(plist, "FirstPage", &dev->FirstPage);
2263
79.0k
    if (code < 0)
2264
0
        ecode = code;
2265
2266
79.0k
    code = param_read_int(plist,  "LastPage", &dev->LastPage);
2267
79.0k
    if (code < 0)
2268
0
        ecode = code;
2269
2270
79.0k
    code = param_read_bool(plist, "DisablePageHandler", &temp_bool);
2271
79.0k
    if (code < 0)
2272
0
        ecode = code;
2273
79.0k
    if (code == 0)
2274
4.29k
        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
79.0k
    code = param_read_string(plist, "NupControl", &nuplist);
2281
79.0k
    if (code < 0)
2282
0
        ecode = code;
2283
79.0k
    if (code == 0) {
2284
4.29k
        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
4.29k
    }
2292
79.0k
    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
79.0k
    code = param_read_string(plist, "PageList", &pagelist);
2332
79.0k
    if (code < 0)
2333
0
        ecode = code;
2334
79.0k
    if (code == 0) {
2335
4.29k
        if (dev->PageList)
2336
4.29k
            rc_decrement(dev->PageList, "default put_params PageList");
2337
4.29k
        dev->PageList = NULL;
2338
4.29k
    }
2339
2340
79.0k
    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
79.0k
    code = param_read_bool(plist, "FILTERIMAGE", &temp_bool);
2356
79.0k
    if (code < 0)
2357
0
        ecode = code;
2358
79.0k
    if (code == 0) {
2359
4.29k
        if (temp_bool)
2360
0
            dev->ObjectFilter |= FILTERIMAGE;
2361
4.29k
        else
2362
4.29k
            dev->ObjectFilter &= ~FILTERIMAGE;
2363
4.29k
    }
2364
2365
79.0k
    code = param_read_bool(plist, "FILTERTEXT", &temp_bool);
2366
79.0k
    if (code < 0)
2367
0
        ecode = code;
2368
79.0k
    if (code == 0) {
2369
4.29k
        if (temp_bool)
2370
0
            dev->ObjectFilter |= FILTERTEXT;
2371
4.29k
        else
2372
4.29k
            dev->ObjectFilter &= ~FILTERTEXT;
2373
4.29k
    }
2374
2375
79.0k
    code = param_read_bool(plist, "FILTERVECTOR", &temp_bool);
2376
79.0k
    if (code < 0)
2377
0
        ecode = code;
2378
79.0k
    if (code == 0) {
2379
4.29k
        if (temp_bool)
2380
0
            dev->ObjectFilter |= FILTERVECTOR;
2381
4.29k
        else
2382
4.29k
            dev->ObjectFilter &= ~FILTERVECTOR;
2383
4.29k
    }
2384
2385
    /* We must 'commit', in order to detect unknown parameters, */
2386
    /* even if there were errors. */
2387
79.0k
    code = param_commit(plist);
2388
79.0k
    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
22
        dev->LockSafetyParams = locksafe;
2396
22
        return ecode;
2397
22
    }
2398
79.0k
    if (code < 0) {
2399
2
        dev->LockSafetyParams = locksafe;
2400
2
        return code;
2401
2
    }
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
79.0k
    dev->color_info.use_antidropout_downscaler = use_antidropout;
2412
2413
79.0k
    if (hwra.data != 0 &&
2414
79.0k
        (dev->HWResolution[0] != hwra.data[0] ||
2415
15.1k
         dev->HWResolution[1] != hwra.data[1])
2416
79.0k
        ) {
2417
10.8k
        if (dev->is_open)
2418
0
            gs_closedevice(dev);
2419
10.8k
        gx_device_set_resolution(dev, hwra.data[0], hwra.data[1]);
2420
10.8k
    }
2421
79.0k
    if ((leadingedge & LEADINGEDGE_MASK) !=
2422
79.0k
        (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
79.0k
    dev->LeadingEdge &= LEADINGEDGE_MASK;
2432
79.0k
    dev->LeadingEdge |= (leadingedge & LEADINGEDGE_SET_MASK);
2433
2434
79.0k
    if (hwsa.data != 0 &&
2435
79.0k
        (dev->width != hwsa.data[0] ||
2436
4.29k
         dev->height != hwsa.data[1])
2437
79.0k
        ) {
2438
3.12k
        if (dev->is_open)
2439
0
            gs_closedevice(dev);
2440
3.12k
        gx_device_set_width_height(dev, hwsa.data[0], hwsa.data[1]);
2441
3.12k
    }
2442
79.0k
    if (msa.data != 0 &&
2443
79.0k
        (dev->MediaSize[0] != msa.data[0] ||
2444
35.2k
         dev->MediaSize[1] != msa.data[1])
2445
79.0k
        ) {
2446
7.30k
        if (dev->is_open)
2447
0
            gs_closedevice(dev);
2448
7.30k
        gx_device_set_page_size(dev, msa.data[0], msa.data[1]);
2449
7.30k
    }
2450
79.0k
    if (ma.data != 0) {
2451
4.29k
        dev->Margins[0] = ma.data[0];
2452
4.29k
        dev->Margins[1] = ma.data[1];
2453
4.29k
    }
2454
79.0k
    if (hwma.data != 0) {
2455
4.29k
        dev->HWMargins[0] = hwma.data[0];
2456
4.29k
        dev->HWMargins[1] = hwma.data[1];
2457
4.29k
        dev->HWMargins[2] = hwma.data[2];
2458
4.29k
        dev->HWMargins[3] = hwma.data[3];
2459
4.29k
    }
2460
79.0k
    dev->NumCopies = nci;
2461
79.0k
    dev->NumCopies_set = ncset;
2462
79.0k
    dev->IgnoreNumCopies = ignc;
2463
79.0k
    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
79.0k
    } else if (ibbnull) {
2470
0
        dev->ImagingBBox_set = false;
2471
0
    }
2472
79.0k
    dev->UseCIEColor = ucc;
2473
79.0k
        dev->color_info.anti_alias.text_bits =
2474
79.0k
                param_normalize_anti_alias_bits(max(dev->color_info.max_gray,
2475
79.0k
                        dev->color_info.max_color), tab);
2476
79.0k
        dev->color_info.anti_alias.graphics_bits =
2477
79.0k
                param_normalize_anti_alias_bits(max(dev->color_info.max_gray,
2478
79.0k
                        dev->color_info.max_color), gab);
2479
79.0k
    dev->LockSafetyParams = locksafe;
2480
79.0k
    dev->MaxPatternBitmap = mpbm;
2481
79.0k
    dev->interpolate_control = ic;
2482
79.0k
    dev->space_params = sp;
2483
79.0k
    dev->page_uses_transparency = page_uses_transparency;
2484
79.0k
    dev->page_uses_overprint = page_uses_overprint;
2485
79.0k
    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
79.0k
    code = gx_default_put_intent(rend_intent[0], dev, gsDEFAULTPROFILE);
2491
79.0k
    if (code < 0)
2492
0
        return code;
2493
79.0k
    code = gx_default_put_blackptcomp(blackptcomp[0], dev, gsDEFAULTPROFILE);
2494
79.0k
    if (code < 0)
2495
0
        return code;
2496
79.0k
    code = gx_default_put_blackpreserve(blackpreserve[0], dev, gsDEFAULTPROFILE);
2497
79.0k
    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
316k
    for (k = 1; k < NUM_DEVICE_PROFILES; k++) {
2502
237k
        if (rend_intent[0] != gsRINOTSPECIFIED &&
2503
237k
            rend_intent[k] == gsRINOTSPECIFIED) {
2504
0
            code = gx_default_put_intent(rend_intent[0], dev, profile_types[k]);
2505
237k
        } else {
2506
237k
            code = gx_default_put_intent(rend_intent[k], dev, profile_types[k]);
2507
237k
        }
2508
237k
        if (code < 0)
2509
0
            return code;
2510
237k
        if (blackptcomp[0] != gsBPNOTSPECIFIED &&
2511
237k
            blackptcomp[k] == gsBPNOTSPECIFIED) {
2512
0
            code = gx_default_put_blackptcomp(blackptcomp[0], dev, profile_types[k]);
2513
237k
        } else {
2514
237k
            code = gx_default_put_blackptcomp(blackptcomp[k], dev, profile_types[k]);
2515
237k
        }
2516
237k
        if (code < 0)
2517
0
            return code;
2518
237k
        if (blackpreserve[0] != gsBKPRESNOTSPECIFIED &&
2519
237k
            blackpreserve[k] == gsBKPRESNOTSPECIFIED) {
2520
0
            code = gx_default_put_blackpreserve(blackpreserve[0], dev, profile_types[k]);
2521
237k
        } else {
2522
237k
            code = gx_default_put_blackpreserve(blackpreserve[k], dev, profile_types[k]);
2523
237k
        }
2524
237k
        if (code < 0)
2525
0
            return code;
2526
237k
    }
2527
79.0k
    gsicc_setcoloraccuracy(dev->memory, color_accuracy);
2528
79.0k
    code = gx_default_put_graytok(devicegraytok, dev);
2529
79.0k
    if (code < 0)
2530
0
        return code;
2531
79.0k
    code = gx_default_put_usefastcolor(usefastcolor, dev);
2532
79.0k
    if (code < 0)
2533
0
        return code;
2534
79.0k
    code = gx_default_put_blacktext(blacktext, dev);
2535
79.0k
    if (code < 0)
2536
0
        return code;
2537
79.0k
    code = gx_default_put_blackvector(blackvector, dev);
2538
79.0k
    if (code < 0)
2539
0
        return code;
2540
79.0k
    code = gx_default_put_blackthresholds(blackthresholdL, blackthresholdC, dev);
2541
79.0k
    if (code < 0)
2542
0
        return code;
2543
79.0k
    code = gx_default_put_overprint_control(overprint_control, dev);
2544
79.0k
    if (code < 0)
2545
0
        return code;
2546
79.0k
    code = gx_default_put_graydetection(graydetection, dev);
2547
79.0k
    if (code < 0)
2548
0
        return code;
2549
79.0k
    return gx_default_put_prebandthreshold(prebandthreshold, dev);
2550
79.0k
}
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
158k
{
2566
158k
        int max_bits = ilog2( max_gray + 1);
2567
2568
158k
        return  (bits > max_bits ? max_bits : bits);
2569
158k
}
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
158k
{
2575
158k
    int code = param_read_int(plist, param_name, pa);
2576
2577
158k
    switch (code) {
2578
8.59k
    case 0:
2579
8.59k
        switch (*pa) {
2580
8.59k
        case 1: case 2: case 4:
2581
8.59k
            return 0;
2582
0
        default:
2583
0
            code = gs_error_rangecheck;
2584
8.59k
        }
2585
        /* fall through */
2586
0
    default:
2587
0
        param_signal_error(plist, param_name, code);
2588
149k
    case 1:
2589
149k
        ;
2590
158k
    }
2591
149k
    return code;
2592
158k
}
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
158k
{
2599
158k
    gs_param_name param_name;
2600
158k
    int ecode = 0;
2601
158k
    int code;
2602
2603
193k
    BEGIN_ARRAY_PARAM(param_read_float_array, pname, *pa, 2, mse) {
2604
35.3k
        float width_new = pa->data[0] * res[0] / 72;
2605
35.3k
        float height_new = pa->data[1] * res[1] / 72;
2606
2607
35.3k
        if (width_new < 0 || height_new < 0)
2608
0
            ecode = gs_note_error(gs_error_rangecheck);
2609
105k
#define max_coord (max_fixed / fixed_1)
2610
35.3k
#if max_coord < max_int
2611
35.3k
        else if (width_new > (long)max_coord || height_new > (long)max_coord)
2612
22
            ecode = gs_note_error(gs_error_limitcheck);
2613
35.2k
#endif
2614
35.2k
#undef max_coord
2615
35.2k
        else
2616
35.2k
            break;
2617
35.3k
    } END_ARRAY_PARAM(*pa, mse);
2618
158k
    return ecode;
2619
158k
}
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
79.0k
{
2627
79.0k
    int code;
2628
79.0k
    bool new_value;
2629
2630
79.0k
    switch (code = param_read_bool(plist, pname, &new_value)) {
2631
4.29k
        case 0:
2632
4.29k
            if (is_defined && new_value == value)
2633
4.29k
                break;
2634
0
            code = gs_note_error(gs_error_rangecheck);
2635
0
            goto e;
2636
0
        default:
2637
0
            if (param_read_null(plist, pname) == 0)
2638
0
                return 1;
2639
0
          e:param_signal_error(plist, pname, code);
2640
74.7k
        case 1:
2641
74.7k
            ;
2642
79.0k
    }
2643
79.0k
    return code;
2644
79.0k
}
2645
static int
2646
param_check_long(gs_param_list * plist, gs_param_name pname, long value,
2647
                 bool is_defined)
2648
553k
{
2649
553k
    int code;
2650
553k
    long new_value;
2651
2652
553k
    switch (code = param_read_long(plist, pname, &new_value)) {
2653
0
        case 0:
2654
0
            if (is_defined && new_value == value)
2655
0
                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
553k
        case 1:
2663
553k
            ;
2664
553k
    }
2665
553k
    return code;
2666
553k
}
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
237k
{
2671
237k
    int code;
2672
237k
    gs_param_string new_value;
2673
2674
237k
    switch (code = param_read_string(plist, pname, &new_value)) {
2675
4.29k
        case 0:
2676
4.29k
            if (is_defined && new_value.size == size &&
2677
4.29k
                !memcmp((const char *)str, (const char *)new_value.data,
2678
4.29k
                        size)
2679
4.29k
                )
2680
4.29k
                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
232k
        case 1:
2688
232k
            ;
2689
237k
    }
2690
237k
    return code;
2691
237k
}