Coverage Report

Created: 2025-06-10 06:56

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