Coverage Report

Created: 2025-06-10 07:06

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