Coverage Report

Created: 2025-06-10 06:59

/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
994k
#define BLACKTHRESHOLDL 90
38
994k
#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
234k
{
55
    /*
56
     * We must be prepared to copy the device if it is the read-only
57
     * prototype.
58
     */
59
234k
    gx_device *dev;
60
234k
    int code = 0;
61
62
234k
    if (orig_dev->memory)
63
234k
        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
234k
    fill_dev_proc(dev, get_params, gx_default_get_params);
70
234k
    fill_dev_proc(dev, get_page_device, gx_default_get_page_device);
71
234k
    fill_dev_proc(dev, get_alpha_bits, gx_default_get_alpha_bits);
72
234k
    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
234k
    } else {
76
234k
        if (dev_proc(dev, get_params) != NULL)
77
234k
            code = (*dev_proc(dev, get_params)) (dev, plist);
78
234k
    }
79
234k
    if (dev != orig_dev)
80
0
        gx_device_retain(dev, false);  /* frees the copy */
81
234k
    return code;
82
234k
}
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
668k
{
128
668k
    gs_param_list * plist = (gs_param_list *)list;
129
668k
    int k, colors = dev->color_info.num_components;
130
668k
    gs_param_string profile_array[NUM_DEVICE_PROFILES];
131
668k
    gs_param_string postren_profile, blend_profile;
132
668k
    gs_param_string proof_profile, link_profile, icc_colorants;
133
668k
    gsicc_rendering_intents_t profile_intents[NUM_DEVICE_PROFILES];
134
668k
    gsicc_blackptcomp_t blackptcomps[NUM_DEVICE_PROFILES];
135
668k
    gsicc_blackpreserve_t blackpreserve[NUM_DEVICE_PROFILES];
136
668k
    int color_accuracy = MAX_COLOR_ACCURACY;
137
668k
    int depth = dev->color_info.depth;
138
668k
    cmm_dev_profile_t *dev_profile;
139
668k
    char null_str[1]={'\0'};
140
668k
#define set_param_array(a, d, s)\
141
668k
  (a.data = d, a.size = s, a.persistent = false);
142
668k
    bool devicegraytok = true;  /* Default if device profile stuct not set */
143
668k
    bool graydetection = false;
144
668k
    bool usefastcolor = false;  /* set for unmanaged color */
145
668k
    bool blacktext = false;
146
668k
    bool blackvector = false;
147
668k
    float blackthresholdL = BLACKTHRESHOLDL;
148
668k
    float blackthresholdC = BLACKTHRESHOLDC;
149
    /* By default overprinting only valid with cmyk devices */
150
668k
    gs_overprint_control_t overprint_control = gs_overprint_control_enable;
151
668k
    bool prebandthreshold = true, temp_bool = false;
152
153
668k
    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
668k
#ifdef PAGESIZE_IS_MEDIASIZE
159
668k
    if (strcmp(Param, "PageSize") == 0) {
160
19.7k
        gs_param_float_array msa;
161
19.7k
        set_param_array(msa, dev->MediaSize, 2);
162
19.7k
        return param_write_float_array(plist, "PageSize", &msa);
163
19.7k
    }
164
648k
#endif
165
648k
    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
648k
    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
648k
    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
648k
    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
648k
    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
648k
    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
648k
    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
648k
    if (strcmp(Param, "Separations") == 0) {
214
0
        bool seprs = false;
215
0
        return param_write_bool(plist, "Separations", &seprs);
216
0
    }
217
648k
    if (strcmp(Param, "UseCIEColor") == 0) {
218
0
        return param_write_bool(plist, "UseCIEColor", &dev->UseCIEColor);
219
0
    }
220
221
    /* Non-standard parameters */
222
648k
    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
648k
    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
648k
    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
648k
    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
648k
    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
648k
    if (strcmp(Param, "BitsPerPixel") == 0) {
251
0
        return param_write_int(plist, "BitsPerPixel", &depth);
252
0
    }
253
648k
    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
648k
    if (strcmp(Param, "PageCount") == 0) {
258
0
        return param_write_long(plist, "PageCount", &dev->PageCount);
259
0
    }
260
648k
    if (strcmp(Param, ".IgnoreNumCopies") == 0) {
261
0
        return param_write_bool(plist, ".IgnoreNumCopies", &dev->IgnoreNumCopies);
262
0
    }
263
648k
    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
648k
    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
648k
    if (strcmp(Param, "AntidropoutDownscaler") == 0) {
272
0
        return param_write_bool(plist, "AntidropoutDownscaler",
273
0
                                &dev->color_info.use_antidropout_downscaler);
274
0
    }
275
648k
    if (strcmp(Param, ".LockSafetyParams") == 0) {
276
0
        return param_write_bool(plist, ".LockSafetyParams", &dev->LockSafetyParams);
277
0
    }
278
648k
    if (strcmp(Param, "MaxPatternBitmap") == 0) {
279
0
        return param_write_size_t(plist, "MaxPatternBitmap", &dev->MaxPatternBitmap);
280
0
    }
281
648k
    if (strcmp(Param, "PageUsesTransparency") == 0) {
282
0
        return param_write_bool(plist, "PageUsesTransparency", &dev->page_uses_transparency);
283
0
    }
284
648k
    if (strcmp(Param, "PageUsesOverprint") == 0) {
285
0
        return param_write_bool(plist, "PageUsesOverprint", &dev->page_uses_overprint);
286
0
    }
287
648k
    if (strcmp(Param, "MaxBitmap") == 0) {
288
0
        return param_write_size_t(plist, "MaxBitmap", &(dev->space_params.MaxBitmap));
289
0
    }
290
648k
    if (strcmp(Param, "BandBufferSpace") == 0) {
291
0
        return param_write_size_t(plist, "BandBufferSpace", &dev->space_params.band.BandBufferSpace);
292
0
    }
293
648k
    if (strcmp(Param, "BandHeight") == 0) {
294
0
        return param_write_int(plist, "BandHeight", &dev->space_params.band.BandHeight);
295
0
    }
296
648k
    if (strcmp(Param, "BandWidth") == 0) {
297
0
        return param_write_int(plist, "BandWidth", &dev->space_params.band.BandWidth);
298
0
    }
299
648k
    if (strcmp(Param, "BufferSpace") == 0) {
300
0
        return param_write_size_t(plist, "BufferSpace", &dev->space_params.BufferSpace);
301
0
    }
302
648k
    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
648k
    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
648k
    if (dev->color_info.num_components > 1) {
315
0
        int RGBValues = dev->color_info.max_color + 1;
316
0
        long ColorValues = (depth >= 32 ? -1 : 1L << depth); /* value can only be 32 bits */
317
318
0
        if (strcmp(Param, "RedValues") == 0) {
319
0
            return param_write_int(plist, "RedValues", &RGBValues);
320
0
        }
321
0
        if (strcmp(Param, "GreenValues") == 0) {
322
0
            return param_write_int(plist, "GreenValues", &RGBValues);
323
0
        }
324
0
        if (strcmp(Param, "BlueValues") == 0) {
325
0
            return param_write_int(plist, "BlueValues", &RGBValues);
326
0
        }
327
0
        if (strcmp(Param, "ColorValues") == 0) {
328
0
            return param_write_long(plist, "ColorValues", &ColorValues);
329
0
        }
330
0
    }
331
648k
    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
648k
    if (dev_proc(dev, get_profile) != NULL) {
352
648k
        int code;
353
648k
        code = dev_proc(dev, get_profile)(dev,  &dev_profile);
354
648k
        if (code < 0)
355
0
            return code;
356
648k
        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
3.24M
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
365
2.59M
            if (dev_profile->device_profile[k] == NULL
366
2.59M
                || dev_profile->device_profile[k]->name == NULL) {
367
1.94M
                param_string_from_string(profile_array[k], null_str);
368
1.94M
                profile_intents[k] = gsRINOTSPECIFIED;
369
1.94M
                blackptcomps[k] = gsBPNOTSPECIFIED;
370
1.94M
                blackpreserve[k] = gsBKPRESNOTSPECIFIED;
371
1.94M
            } else {
372
648k
                param_string_from_transient_string(profile_array[k],
373
648k
                    dev_profile->device_profile[k]->name);
374
648k
                profile_intents[k] = dev_profile->rendercond[k].rendering_intent;
375
648k
                blackptcomps[k] = dev_profile->rendercond[k].black_point_comp;
376
648k
                blackpreserve[k] = dev_profile->rendercond[k].preserve_black;
377
648k
            }
378
2.59M
        }
379
648k
        if (dev_profile->blend_profile == NULL) {
380
648k
            param_string_from_string(blend_profile, null_str);
381
648k
        } else {
382
0
            param_string_from_transient_string(blend_profile,
383
0
                dev_profile->blend_profile->name);
384
0
        }
385
648k
        if (dev_profile->postren_profile == NULL) {
386
648k
            param_string_from_string(postren_profile, null_str);
387
648k
        } else {
388
0
            param_string_from_transient_string(postren_profile,
389
0
                dev_profile->postren_profile->name);
390
0
        }
391
648k
        if (dev_profile->proof_profile == NULL) {
392
648k
            param_string_from_string(proof_profile, null_str);
393
648k
        } else {
394
0
            param_string_from_transient_string(proof_profile,
395
0
                                     dev_profile->proof_profile->name);
396
0
        }
397
648k
        if (dev_profile->link_profile == NULL) {
398
648k
            param_string_from_string(link_profile, null_str);
399
648k
        } else {
400
0
            param_string_from_transient_string(link_profile,
401
0
                                     dev_profile->link_profile->name);
402
0
        }
403
648k
        devicegraytok = dev_profile->devicegraytok;
404
648k
        graydetection = dev_profile->graydetection;
405
648k
        usefastcolor = dev_profile->usefastcolor;
406
648k
        blacktext = dev_profile->blacktext;
407
648k
        blackvector = dev_profile->blackvector;
408
648k
        blackthresholdC = dev_profile->blackthresholdC;
409
648k
        blackthresholdL = dev_profile->blackthresholdL;
410
648k
        overprint_control = dev_profile->overprint_control;
411
648k
        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
648k
        if (dev_profile->spotnames == NULL) {
416
648k
            param_string_from_string(icc_colorants, null_str);
417
648k
        } 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
648k
    } 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
648k
    if (strcmp(Param, "DeviceGrayToK") == 0) {
444
0
        return param_write_bool(plist, "DeviceGrayToK", &devicegraytok);
445
0
    }
446
648k
    if (strcmp(Param, "GrayDetection") == 0) {
447
0
        return param_write_bool(plist, "GrayDetection", &graydetection);
448
0
    }
449
648k
    if (strcmp(Param, "UseFastColor") == 0) {
450
0
        return param_write_bool(plist, "UseFastColor", &usefastcolor);
451
0
    }
452
648k
    if (strcmp(Param, "BlackText") == 0) {
453
0
        return param_write_bool(plist, "BlackText", &blacktext);
454
0
    }
455
648k
    if (strcmp(Param, "BlackVector") == 0) {
456
0
        return param_write_bool(plist, "BlackVector", &blackvector);
457
0
    }
458
648k
    if (strcmp(Param, "BlackThresholdL") == 0) {
459
0
        return param_write_float(plist, "BlackThresholdL", &blackthresholdL);
460
0
    }
461
648k
    if (strcmp(Param, "BlackThresholdC") == 0) {
462
0
        return param_write_float(plist, "BlackThresholdC", &blackthresholdC);
463
0
    }
464
648k
    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
648k
    if (strcmp(Param, "PreBandThreshold") == 0) {
472
0
        return param_write_bool(plist, "PreBandThreshold", &prebandthreshold);
473
0
    }
474
648k
    if (strcmp(Param, "PostRenderProfile") == 0) {
475
0
        return param_write_string(plist, "PostRenderProfile", &(postren_profile));
476
0
    }
477
648k
    if (strcmp(Param, "BlendColorProfile") == 0) {
478
0
        return param_write_string(plist, "BlendColorProfile", &(blend_profile));
479
0
    }
480
648k
    if (strcmp(Param, "ProofProfile") == 0) {
481
0
        return param_write_string(plist,"ProofProfile", &(proof_profile));
482
0
    }
483
648k
    if (strcmp(Param, "DeviceLinkProfile") == 0) {
484
0
        return param_write_string(plist,"DeviceLinkProfile", &(link_profile));
485
0
    }
486
648k
    if (strcmp(Param, "ICCOutputColors") == 0) {
487
0
        return param_write_string(plist,"ICCOutputColors", &(icc_colorants));
488
0
    }
489
648k
    if (strcmp(Param, "OutputICCProfile") == 0) {
490
0
        return param_write_string(plist,"OutputICCProfile", &(profile_array[0]));
491
0
    }
492
648k
    if (strcmp(Param, "VectorICCProfile") == 0) {
493
0
        return param_write_string(plist,"VectorICCProfile", &(profile_array[1]));
494
0
    }
495
648k
    if (strcmp(Param, "ImageICCProfile") == 0) {
496
0
        return param_write_string(plist,"ImageICCProfile", &(profile_array[2]));
497
0
    }
498
648k
    if (strcmp(Param, "TextICCProfile") == 0) {
499
0
        return param_write_string(plist,"TextICCProfile", &(profile_array[3]));
500
0
    }
501
648k
    if (strcmp(Param, "ColorAccuracy") == 0) {
502
0
        return param_write_int(plist, "ColorAccuracy", (const int *)(&(color_accuracy)));
503
0
    }
504
648k
    if (strcmp(Param, "RenderIntent") == 0) {
505
0
        return param_write_int(plist,"RenderIntent", (const int *) (&(profile_intents[0])));
506
0
    }
507
648k
    if (strcmp(Param, "VectorIntent") == 0) {
508
0
        return param_write_int(plist,"VectorIntent", (const int *) &(profile_intents[1]));
509
0
    }
510
648k
    if (strcmp(Param, "ImageIntent") == 0) {
511
0
        return param_write_int(plist,"ImageIntent", (const int *) &(profile_intents[2]));
512
0
    }
513
648k
    if (strcmp(Param, "TextIntent") == 0) {
514
0
        return param_write_int(plist,"TextIntent", (const int *) &(profile_intents[3]));
515
0
    }
516
648k
    if (strcmp(Param, "BlackPtComp") == 0) {
517
0
        return param_write_int(plist,"BlackPtComp", (const int *) (&(blackptcomps[0])));
518
0
    }
519
648k
    if (strcmp(Param, "VectorBlackPt") == 0) {
520
0
        return param_write_int(plist,"VectorBlackPt", (const int *) &(blackptcomps[1]));
521
0
    }
522
648k
    if (strcmp(Param, "ImageBlackPt") == 0) {
523
0
        return param_write_int(plist,"ImageBlackPt", (const int *) &(blackptcomps[2]));
524
0
    }
525
648k
    if (strcmp(Param, "TextBlackPt") == 0) {
526
0
        return param_write_int(plist,"TextBlackPt", (const int *) &(blackptcomps[3]));
527
0
    }
528
648k
    if (strcmp(Param, "KPreserve") == 0) {
529
0
        return param_write_int(plist,"KPreserve", (const int *) (&(blackpreserve[0])));
530
0
    }
531
648k
    if (strcmp(Param, "VectorKPreserve") == 0) {
532
0
        return param_write_int(plist,"VectorKPreserve", (const int *) &(blackpreserve[1]));
533
0
    }
534
648k
    if (strcmp(Param, "ImageKPreserve") == 0) {
535
0
        return param_write_int(plist,"ImageKPreserve", (const int *) &(blackpreserve[2]));
536
0
    }
537
648k
    if (strcmp(Param, "TextKPreserve") == 0) {
538
0
        return param_write_int(plist,"TextKPreserve", (const int *) &(blackpreserve[3]));
539
0
    }
540
648k
    if (strcmp(Param, "FirstPage") == 0) {
541
0
        return param_write_int(plist, "FirstPage", &dev->FirstPage);
542
0
    }
543
648k
    if (strcmp(Param, "LastPage") == 0) {
544
0
        return param_write_int(plist, "LastPage", &dev->LastPage);
545
0
    }
546
648k
    if (strcmp(Param, "DisablePageHandler") == 0) {
547
0
        temp_bool = dev->DisablePageHandler;
548
0
        return param_write_bool(plist, "DisablePageHandler", &temp_bool);
549
0
    }
550
648k
    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
648k
    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
648k
    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
648k
    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
648k
    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
648k
    return_error(gs_error_undefined);
585
648k
}
586
587
/* Get standard parameters. */
588
int
589
gx_default_get_params(gx_device * dev, gs_param_list * plist)
590
234k
{
591
234k
    int code;
592
593
    /* Standard page device parameters: */
594
595
234k
    bool seprs = false;
596
234k
    gs_param_string dns, pcms, profile_array[NUM_DEVICE_PROFILES];
597
234k
    gs_param_string blend_profile, postren_profile, pagelist, nuplist;
598
234k
    gs_param_string proof_profile, link_profile, icc_colorants;
599
234k
    gsicc_rendering_intents_t profile_intents[NUM_DEVICE_PROFILES];
600
234k
    gsicc_blackptcomp_t blackptcomps[NUM_DEVICE_PROFILES];
601
234k
    gsicc_blackpreserve_t blackpreserve[NUM_DEVICE_PROFILES];
602
234k
    bool devicegraytok = true;  /* Default if device profile stuct not set */
603
234k
    bool graydetection = false;
604
234k
    bool usefastcolor = false;  /* set for unmanaged color */
605
234k
    bool blacktext = false;
606
234k
    bool blackvector = false;
607
234k
    float blackthresholdL = BLACKTHRESHOLDL;
608
234k
    float blackthresholdC = BLACKTHRESHOLDC;
609
    /* By default, only overprint if the device supports it */
610
234k
    gs_overprint_control_t overprint_control = gs_overprint_control_enable;
611
234k
    bool prebandthreshold = true, temp_bool;
612
234k
    int k;
613
234k
    int color_accuracy = MAX_COLOR_ACCURACY;
614
234k
    gs_param_float_array msa, ibba, hwra, ma;
615
234k
    gs_param_string_array scna;
616
234k
    char null_str[1]={'\0'};
617
618
234k
#define set_param_array(a, d, s)\
619
1.63M
  (a.data = d, a.size = s, a.persistent = false);
620
621
    /* Non-standard parameters: */
622
234k
    int colors = dev->color_info.num_components;
623
234k
    int mns = dev->color_info.max_components;
624
234k
    int depth = dev->color_info.depth;
625
234k
    int GrayValues = dev->color_info.max_gray + 1;
626
234k
    int HWSize[2];
627
234k
    gs_param_int_array hwsa;
628
234k
    gs_param_float_array hwma;
629
234k
    cmm_dev_profile_t *dev_profile;
630
234k
    char *colorant_names = NULL;
631
632
    /* Fill in page device parameters. */
633
634
234k
    param_string_from_string(dns, dev->dname);
635
234k
    {
636
234k
        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
234k
        if ((cms != NULL) && (*cms != '\0'))
641
234k
            param_string_from_string(pcms, cms);
642
0
        else
643
0
            pcms.data = 0;
644
234k
    }
645
646
234k
    set_param_array(hwra, dev->HWResolution, 2);
647
234k
    set_param_array(msa, dev->MediaSize, 2);
648
234k
    set_param_array(ibba, dev->ImagingBBox, 4);
649
234k
    set_param_array(ma, dev->Margins, 2);
650
234k
    set_param_array(scna, NULL, 0);
651
652
    /* Fill in non-standard parameters. */
653
234k
    HWSize[0] = dev->width;
654
234k
    HWSize[1] = dev->height;
655
234k
    set_param_array(hwsa, HWSize, 2);
656
234k
    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
234k
    if (dev_proc(dev, get_profile) != NULL) {
665
214k
        code = dev_proc(dev, get_profile)(dev,  &dev_profile);
666
214k
        if (code < 0)
667
0
            return code;
668
669
214k
        if (dev_profile == NULL) {
670
0
            code = gsicc_init_device_profile_struct(dev, NULL, 0);
671
0
            if (code < 0)
672
0
                return code;
673
0
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
674
0
            if (code < 0)
675
0
                return code;
676
0
        }
677
        /* It is possible that the current device profile name is NULL if we
678
           have a pdf14 device in line with a transparency group that is in a
679
           color space specified from a source defined ICC profile. Check for
680
           that here to avoid any access violations.  Bug 692558 */
681
1.07M
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
682
857k
            if (dev_profile->device_profile[k] == NULL
683
857k
                || dev_profile->device_profile[k]->name == NULL) {
684
642k
                param_string_from_string(profile_array[k], null_str);
685
642k
                profile_intents[k] = gsRINOTSPECIFIED;
686
642k
                blackptcomps[k] = gsBPNOTSPECIFIED;
687
642k
                blackpreserve[k] = gsBKPRESNOTSPECIFIED;
688
642k
            } else {
689
214k
                param_string_from_transient_string(profile_array[k],
690
214k
                    dev_profile->device_profile[k]->name);
691
214k
                profile_intents[k] = dev_profile->rendercond[k].rendering_intent;
692
214k
                blackptcomps[k] = dev_profile->rendercond[k].black_point_comp;
693
214k
                blackpreserve[k] = dev_profile->rendercond[k].preserve_black;
694
214k
            }
695
857k
        }
696
        /* The proof, link and post render profile */
697
214k
        if (dev_profile->proof_profile == NULL) {
698
214k
            param_string_from_string(proof_profile, null_str);
699
214k
        } else {
700
0
            param_string_from_transient_string(proof_profile,
701
0
                                     dev_profile->proof_profile->name);
702
0
        }
703
214k
        if (dev_profile->link_profile == NULL) {
704
214k
            param_string_from_string(link_profile, null_str);
705
214k
        } else {
706
0
            param_string_from_transient_string(link_profile,
707
0
                                     dev_profile->link_profile->name);
708
0
        }
709
214k
        if (dev_profile->postren_profile == NULL) {
710
214k
            param_string_from_string(postren_profile, null_str);
711
214k
        } else {
712
0
            param_string_from_transient_string(postren_profile,
713
0
                dev_profile->postren_profile->name);
714
0
        }
715
214k
        if (dev_profile->blend_profile == NULL) {
716
214k
            param_string_from_string(blend_profile, null_str);
717
214k
        } else {
718
0
            param_string_from_transient_string(blend_profile,
719
0
                dev_profile->blend_profile->name);
720
0
        }
721
214k
        devicegraytok = dev_profile->devicegraytok;
722
214k
        graydetection = dev_profile->graydetection;
723
214k
        usefastcolor = dev_profile->usefastcolor;
724
214k
        blacktext = dev_profile->blacktext;
725
214k
        blackvector = dev_profile->blackvector;
726
214k
        blackthresholdC = dev_profile->blackthresholdC;
727
214k
        blackthresholdL = dev_profile->blackthresholdL;
728
214k
        overprint_control = dev_profile->overprint_control;
729
214k
        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
214k
        if (dev_profile->spotnames == NULL) {
734
214k
            param_string_from_string(icc_colorants, null_str);
735
214k
        } 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
214k
    } else {
746
98.6k
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
747
78.8k
            param_string_from_string(profile_array[k], null_str);
748
78.8k
            profile_intents[k] = gsRINOTSPECIFIED;
749
78.8k
            blackptcomps[k] = gsBPNOTSPECIFIED;
750
78.8k
            blackpreserve[k] = gsBKPRESNOTSPECIFIED;
751
78.8k
        }
752
19.7k
        param_string_from_string(proof_profile, null_str);
753
19.7k
        param_string_from_string(link_profile, null_str);
754
19.7k
        param_string_from_string(icc_colorants, null_str);
755
19.7k
        param_string_from_string(postren_profile, null_str);
756
19.7k
        param_string_from_string(blend_profile, null_str);
757
19.7k
    }
758
    /* Transmit the values. */
759
    /* Standard parameters */
760
234k
    if (
761
234k
        (code = param_write_name(plist, "OutputDevice", &dns)) < 0 ||
762
234k
#ifdef PAGESIZE_IS_MEDIASIZE
763
234k
        (code = param_write_float_array(plist, "PageSize", &msa)) < 0 ||
764
234k
#endif
765
234k
        (code = (pcms.data == 0 ? 0 :
766
234k
                 param_write_name(plist, "ProcessColorModel", &pcms))) < 0 ||
767
234k
        (code = param_write_float_array(plist, "HWResolution", &hwra)) < 0 ||
768
234k
        (code = (dev->ImagingBBox_set ?
769
0
                 param_write_float_array(plist, "ImagingBBox", &ibba) :
770
234k
                 param_write_null(plist, "ImagingBBox"))) < 0 ||
771
234k
        (code = param_write_float_array(plist, "Margins", &ma)) < 0 ||
772
234k
        (code = param_write_int(plist, "MaxSeparations", &mns)) < 0 ||
773
234k
        (code = (dev->NumCopies_set < 0 ||
774
234k
                 (*dev_proc(dev, get_page_device))(dev) == 0 ? 0:
775
234k
                 dev->NumCopies_set ?
776
0
                 param_write_int(plist, "NumCopies", &dev->NumCopies) :
777
234k
                 param_write_null(plist, "NumCopies"))) < 0 ||
778
234k
        (code = param_write_name_array(plist, "SeparationColorNames", &scna)) < 0 ||
779
234k
        (code = param_write_bool(plist, "Separations", &seprs)) < 0 ||
780
234k
        (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
234k
        (code = param_write_bool(plist, "DeviceGrayToK", &devicegraytok)) < 0 ||
785
234k
        (code = param_write_bool(plist, "GrayDetection", &graydetection)) < 0 ||
786
234k
        (code = param_write_bool(plist, "UseFastColor", &usefastcolor)) < 0 ||
787
234k
        (code = param_write_bool(plist, "BlackText", &blacktext)) < 0 ||
788
234k
        (code = param_write_bool(plist, "BlackVector", &blackvector)) < 0 ||
789
234k
        (code = param_write_float(plist, "BlackThresholdL", &blackthresholdL)) < 0 ||
790
234k
        (code = param_write_float(plist, "BlackThresholdC", &blackthresholdC)) < 0 ||
791
234k
        (code = param_write_bool(plist, "PreBandThreshold", &prebandthreshold)) < 0 ||
792
234k
        (code = param_write_string(plist,"OutputICCProfile", &(profile_array[0]))) < 0 ||
793
234k
        (code = param_write_string(plist,"VectorICCProfile", &(profile_array[1]))) < 0 ||
794
234k
        (code = param_write_string(plist,"ImageICCProfile", &(profile_array[2]))) < 0 ||
795
234k
        (code = param_write_string(plist,"TextICCProfile", &(profile_array[3]))) < 0 ||
796
234k
        (code = param_write_string(plist,"ProofProfile", &(proof_profile))) < 0 ||
797
234k
        (code = param_write_string(plist, "PostRenderProfile", &(postren_profile))) < 0 ||
798
234k
        (code = param_write_string(plist, "BlendColorProfile", &(blend_profile))) < 0 ||
799
234k
        (code = param_write_string(plist,"DeviceLinkProfile", &(link_profile))) < 0 ||
800
234k
        (code = param_write_string(plist,"ICCOutputColors", &(icc_colorants))) < 0 ||
801
234k
        (code = param_write_int(plist, "RenderIntent", (const int *)(&(profile_intents[0])))) < 0 ||
802
234k
        (code = param_write_int(plist, "ColorAccuracy", (const int *)(&(color_accuracy)))) < 0 ||
803
234k
        (code = param_write_int(plist,"VectorIntent", (const int *) &(profile_intents[1]))) < 0 ||
804
234k
        (code = param_write_int(plist,"ImageIntent", (const int *) &(profile_intents[2]))) < 0 ||
805
234k
        (code = param_write_int(plist,"TextIntent", (const int *) &(profile_intents[3]))) < 0 ||
806
234k
        (code = param_write_int(plist,"BlackPtComp", (const int *) (&(blackptcomps[0])))) < 0 ||
807
234k
        (code = param_write_int(plist,"VectorBlackPt", (const int *) &(blackptcomps[1]))) < 0 ||
808
234k
        (code = param_write_int(plist,"ImageBlackPt", (const int *) &(blackptcomps[2]))) < 0 ||
809
234k
        (code = param_write_int(plist,"TextBlackPt", (const int *) &(blackptcomps[3]))) < 0 ||
810
234k
        (code = param_write_int(plist,"KPreserve", (const int *) (&(blackpreserve[0])))) < 0 ||
811
234k
        (code = param_write_int(plist,"VectorKPreserve", (const int *) &(blackpreserve[1]))) < 0 ||
812
234k
        (code = param_write_int(plist,"ImageKPreserve", (const int *) &(blackpreserve[2]))) < 0 ||
813
234k
        (code = param_write_int(plist,"TextKPreserve", (const int *) &(blackpreserve[3]))) < 0 ||
814
234k
        (code = param_write_int_array(plist, "HWSize", &hwsa)) < 0 ||
815
234k
        (code = param_write_float_array(plist, ".HWMargins", &hwma)) < 0 ||
816
234k
        (code = param_write_float_array(plist, ".MediaSize", &msa)) < 0 ||
817
234k
        (code = param_write_string(plist, "Name", &dns)) < 0 ||
818
234k
        (code = param_write_int(plist, "Colors", &colors)) < 0 ||
819
234k
        (code = param_write_int(plist, "BitsPerPixel", &depth)) < 0 ||
820
234k
        (code = param_write_int(plist, "GrayValues", &GrayValues)) < 0 ||
821
234k
        (code = param_write_long(plist, "PageCount", &dev->PageCount)) < 0 ||
822
234k
        (code = param_write_bool(plist, ".IgnoreNumCopies", &dev->IgnoreNumCopies)) < 0 ||
823
234k
        (code = param_write_int(plist, "TextAlphaBits",
824
234k
                                &dev->color_info.anti_alias.text_bits)) < 0 ||
825
234k
        (code = param_write_int(plist, "GraphicsAlphaBits",
826
234k
                                &dev->color_info.anti_alias.graphics_bits)) < 0 ||
827
234k
        (code = param_write_bool(plist, "AntidropoutDownscaler",
828
234k
                                &dev->color_info.use_antidropout_downscaler)) < 0 ||
829
234k
        (code = param_write_bool(plist, ".LockSafetyParams", &dev->LockSafetyParams)) < 0 ||
830
234k
        (code = param_write_size_t(plist, "MaxPatternBitmap", &dev->MaxPatternBitmap)) < 0 ||
831
234k
        (code = param_write_bool(plist, "PageUsesTransparency", &dev->page_uses_transparency)) < 0 ||
832
234k
        (code = param_write_bool(plist, "PageUsesOverprint", &dev->page_uses_overprint)) < 0 ||
833
234k
        (code = param_write_size_t(plist, "MaxBitmap", &(dev->space_params.MaxBitmap))) < 0 ||
834
234k
        (code = param_write_size_t(plist, "BandBufferSpace", &dev->space_params.band.BandBufferSpace)) < 0 ||
835
234k
        (code = param_write_int(plist, "BandHeight", &dev->space_params.band.BandHeight)) < 0 ||
836
234k
        (code = param_write_int(plist, "BandWidth", &dev->space_params.band.BandWidth)) < 0 ||
837
234k
        (code = param_write_size_t(plist, "BufferSpace", &dev->space_params.BufferSpace)) < 0 ||
838
234k
        (code = param_write_int(plist, "InterpolateControl", &dev->interpolate_control)) < 0
839
234k
        )
840
0
    {
841
0
        gs_free_object(dev->memory, colorant_names, "gx_default_get_param");
842
0
        return code;
843
0
    }
844
234k
    gs_free_object(dev->memory, colorant_names, "gx_default_get_param");
845
234k
    {
846
234k
        gs_param_string opc_name;
847
234k
        const char *s = overprint_control_names[(int)overprint_control];
848
849
234k
        param_string_from_string(opc_name, s);
850
234k
        param_write_name(plist, "Overprint", &opc_name);
851
234k
    }
852
    /* If LeadingEdge was set explicitly, report it here. */
853
234k
    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
234k
        code = param_write_null(plist, "LeadingEdge");
858
234k
    if (code < 0)
859
0
        return code;
860
861
234k
    if ((code = param_write_int(plist, "FirstPage", &dev->FirstPage)) < 0)
862
0
        return code;
863
234k
    if ((code = param_write_int(plist, "LastPage", &dev->LastPage)) < 0)
864
0
        return code;
865
866
234k
    temp_bool = dev->DisablePageHandler;
867
234k
    if ((code = param_write_bool(plist, "DisablePageHandler", &temp_bool)) < 0)
868
0
        return code;
869
870
234k
    if (dev->NupControl) {
871
0
        gdev_nupcontrol *p = (gdev_nupcontrol *)dev->NupControl;
872
0
        param_string_from_string(nuplist, p->nupcontrol_str);
873
234k
    } else {
874
234k
        param_string_from_string(nuplist, null_str);
875
234k
    }
876
234k
    if ((code = param_write_string(plist, "NupControl", &nuplist)) < 0)
877
0
        return code;
878
879
234k
    if (dev->PageList) {
880
0
        gdev_pagelist *p = (gdev_pagelist *)dev->PageList;
881
0
        param_string_from_transient_string(pagelist, p->Pages);
882
234k
    } else {
883
234k
        param_string_from_string(pagelist, null_str);
884
234k
    }
885
234k
    if ((code = param_write_string(plist, "PageList", &pagelist)) < 0)
886
0
        return code;
887
888
234k
    temp_bool = dev->ObjectFilter & FILTERIMAGE;
889
234k
    if ((code = param_write_bool(plist, "FILTERIMAGE", &temp_bool)) < 0)
890
0
        return code;
891
234k
    temp_bool = dev->ObjectFilter & FILTERTEXT;
892
234k
    if ((code = param_write_bool(plist, "FILTERTEXT", &temp_bool)) < 0)
893
0
        return code;
894
234k
    temp_bool = dev->ObjectFilter & FILTERVECTOR;
895
234k
    if ((code = param_write_bool(plist, "FILTERVECTOR", &temp_bool)) < 0)
896
0
        return code;
897
898
    /* Fill in color information. */
899
900
234k
    if (colors > 1) {
901
0
        int RGBValues = dev->color_info.max_color + 1;
902
0
        long ColorValues = (depth >= 32 ? -1 : 1L << depth); /* value can only be 32 bits */
903
904
0
        if ((code = param_write_int(plist, "RedValues", &RGBValues)) < 0 ||
905
0
            (code = param_write_int(plist, "GreenValues", &RGBValues)) < 0 ||
906
0
            (code = param_write_int(plist, "BlueValues", &RGBValues)) < 0 ||
907
0
            (code = param_write_long(plist, "ColorValues", &ColorValues)) < 0
908
0
            )
909
0
            return code;
910
0
    }
911
234k
    if (param_requested(plist, "HWColorMap")) {
912
29.5k
        byte palette[3 << 8];
913
914
29.5k
        if (param_HWColorMap(dev, palette)) {
915
29.5k
            gs_param_string hwcms;
916
917
29.5k
            hwcms.data = palette, hwcms.size = colors << depth,
918
29.5k
                hwcms.persistent = false;
919
29.5k
            if ((code = param_write_string(plist, "HWColorMap", &hwcms)) < 0)
920
0
                return code;
921
29.5k
        }
922
29.5k
    }
923
924
234k
    return 0;
925
234k
}
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
29.5k
{
931
29.5k
    int depth = dev->color_info.depth;
932
29.5k
    int colors = dev->color_info.num_components;
933
934
29.5k
    if (depth <= 8 && colors <= 3) {
935
29.5k
        byte *p = palette;
936
29.5k
        gx_color_value rgb[3];
937
29.5k
        gx_color_index i;
938
939
29.5k
        fill_dev_proc(dev, map_color_rgb, gx_default_map_color_rgb);
940
7.60M
        for (i = 0; (i >> depth) == 0; i++) {
941
7.57M
            int j;
942
943
7.57M
            if ((*dev_proc(dev, map_color_rgb)) (dev, i, rgb) < 0)
944
0
                return false;
945
15.1M
            for (j = 0; j < colors; j++)
946
7.57M
                *p++ = gx_color_value_to_byte(rgb[j]);
947
7.57M
        }
948
29.5k
        return true;
949
29.5k
    }
950
0
    return false;
951
29.5k
}
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
556k
  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
278k
  param_check_bytes(plist, pname, (const byte *)(str), \
1122
278k
                    (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
92.7k
{
1130
92.7k
    bool was_open = dev->is_open;
1131
92.7k
    int code;
1132
1133
    /* gs_param_list_dump(plist); */
1134
1135
92.7k
    fill_dev_proc(dev, put_params, gx_default_put_params);
1136
92.7k
    fill_dev_proc(dev, get_alpha_bits, gx_default_get_alpha_bits);
1137
92.7k
    code = (*dev_proc(dev, put_params)) (dev, plist);
1138
92.7k
    return (code < 0 ? code : was_open && !dev->is_open ? 1 : code);
1139
92.7k
}
1140
1141
static int
1142
gx_default_put_graydetection(bool graydetection, gx_device * dev)
1143
92.6k
{
1144
92.6k
    int code = 0;
1145
92.6k
    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
92.6k
    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
39.4k
        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
39.4k
        dev->icc_struct->graydetection = graydetection;
1165
39.4k
        dev->icc_struct->pageneutralcolor = graydetection;
1166
53.2k
    } else {
1167
53.2k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1168
53.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
53.2k
        profile_struct->graydetection = graydetection;
1176
53.2k
        profile_struct->pageneutralcolor = graydetection;
1177
53.2k
    }
1178
92.6k
    return code;
1179
92.6k
}
1180
1181
static int
1182
gx_default_put_graytok(bool graytok, gx_device * dev)
1183
92.6k
{
1184
92.6k
    int code = 0;
1185
92.6k
    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
92.6k
    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
39.4k
        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
39.4k
        dev->icc_struct->devicegraytok = graytok;
1205
53.2k
    } else {
1206
53.2k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1207
53.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
53.2k
        profile_struct->devicegraytok = graytok;
1215
53.2k
    }
1216
92.6k
    return code;
1217
92.6k
}
1218
1219
static int
1220
gx_default_put_prebandthreshold(bool prebandthreshold, gx_device * dev)
1221
92.6k
{
1222
92.6k
    int code = 0;
1223
92.6k
    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
92.6k
    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
39.4k
        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
39.4k
        dev->icc_struct->prebandthreshold = prebandthreshold;
1243
53.2k
    } else {
1244
53.2k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1245
53.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
53.2k
        profile_struct->prebandthreshold = prebandthreshold;
1253
53.2k
    }
1254
92.6k
    return code;
1255
92.6k
}
1256
1257
static int
1258
gx_default_put_usefastcolor(bool fastcolor, gx_device * dev)
1259
92.6k
{
1260
92.6k
    int code = 0;
1261
92.6k
    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
92.6k
    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
39.4k
        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
39.4k
        dev->icc_struct->usefastcolor = fastcolor;
1281
53.2k
    } else {
1282
53.2k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1283
53.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
53.2k
        profile_struct->usefastcolor = fastcolor;
1291
53.2k
    }
1292
92.6k
    return code;
1293
92.6k
}
1294
1295
static int
1296
gx_default_put_blacktext(bool blacktext, gx_device* dev)
1297
92.6k
{
1298
92.6k
    int code = 0;
1299
92.6k
    cmm_dev_profile_t* profile_struct;
1300
1301
92.6k
    if (dev_proc(dev, get_profile) == NULL) {
1302
39.4k
        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
39.4k
        dev->icc_struct->blacktext = blacktext;
1308
53.2k
    } else {
1309
53.2k
        code = dev_proc(dev, get_profile)(dev, &profile_struct);
1310
53.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
53.2k
        profile_struct->blacktext = blacktext;
1318
53.2k
    }
1319
92.6k
    return code;
1320
92.6k
}
1321
1322
static int
1323
gx_default_put_blackthresholds(float blackthresholdL, float blackthresholdC, gx_device *dev)
1324
92.6k
{
1325
92.6k
    int code = 0;
1326
92.6k
    cmm_dev_profile_t* profile_struct;
1327
1328
92.6k
    if (dev_proc(dev, get_profile) == NULL) {
1329
39.4k
        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
39.4k
        dev->icc_struct->blackthresholdL = blackthresholdL;
1335
39.4k
        dev->icc_struct->blackthresholdC = blackthresholdC;
1336
53.2k
    } else {
1337
53.2k
        code = dev_proc(dev, get_profile)(dev, &profile_struct);
1338
53.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
53.2k
        profile_struct->blackthresholdL = blackthresholdL;
1346
53.2k
        profile_struct->blackthresholdC = blackthresholdC;
1347
53.2k
    }
1348
92.6k
    return code;
1349
92.6k
}
1350
1351
static int
1352
gx_default_put_blackvector(bool blackvector, gx_device* dev)
1353
92.6k
{
1354
92.6k
    int code = 0;
1355
92.6k
    cmm_dev_profile_t* profile_struct;
1356
1357
92.6k
    if (dev_proc(dev, get_profile) == NULL) {
1358
39.4k
        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
39.4k
        dev->icc_struct->blackvector = blackvector;
1364
53.2k
    } else {
1365
53.2k
        code = dev_proc(dev, get_profile)(dev, &profile_struct);
1366
53.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
53.2k
        profile_struct->blackvector = blackvector;
1374
53.2k
    }
1375
92.6k
    return code;
1376
92.6k
}
1377
1378
static int
1379
gx_default_put_overprint_control(gs_overprint_control_t overprint_control, gx_device * dev)
1380
92.6k
{
1381
92.6k
    int code = 0;
1382
92.6k
    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
92.6k
    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
39.4k
        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
39.4k
        dev->icc_struct->overprint_control = overprint_control;
1402
53.2k
    } else {
1403
53.2k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1404
53.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
53.2k
        profile_struct->overprint_control = overprint_control;
1412
53.2k
    }
1413
92.6k
    return code;
1414
92.6k
}
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
370k
{
1420
370k
    int code;
1421
370k
    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
370k
    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
157k
        if (dev->icc_struct == NULL) {
1433
            /* Intializes the device structure.  Not the profile though for index */
1434
19.7k
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1435
19.7k
            if (dev->icc_struct == NULL)
1436
0
                return_error(gs_error_VMerror);
1437
19.7k
        }
1438
157k
        code = gsicc_set_device_profile_intent(dev, icc_intent, index);
1439
213k
    } else {
1440
213k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1441
213k
        if (code < 0)
1442
0
            return code;
1443
213k
        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
213k
        code = gsicc_set_device_profile_intent(dev, icc_intent, index);
1450
213k
    }
1451
370k
    return code;
1452
370k
}
1453
1454
static int
1455
gx_default_put_blackpreserve(gsicc_blackpreserve_t blackpreserve, gx_device * dev,
1456
                           gsicc_profile_types_t index)
1457
370k
{
1458
370k
    int code;
1459
370k
    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
370k
    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
157k
        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
157k
        code = gsicc_set_device_blackpreserve(dev, blackpreserve, index);
1477
213k
    } else {
1478
213k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1479
213k
        if (code < 0)
1480
0
            return code;
1481
213k
        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
213k
        code = gsicc_set_device_blackpreserve(dev, blackpreserve, index);
1488
213k
    }
1489
370k
    return code;
1490
370k
}
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
370k
{
1499
370k
    int code;
1500
370k
    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
370k
    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
157k
        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
157k
        code = gsicc_set_device_blackptcomp(dev, blackptcomp, index);
1518
213k
    } else {
1519
213k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1520
213k
        if (code < 0)
1521
0
            return code;
1522
213k
        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
213k
        code = gsicc_set_device_blackptcomp(dev, blackptcomp, index);
1529
213k
    }
1530
370k
    return code;
1531
370k
}
1532
1533
static int
1534
gx_default_put_icc_colorants(gs_param_string *colorants, gx_device * dev)
1535
7.29k
{
1536
7.29k
    char *tempstr;
1537
7.29k
    int code;
1538
7.29k
    int len;
1539
7.29k
    unsigned short *tempstr2 = NULL;
1540
7.29k
    unsigned short *s;
1541
7.29k
    char *d;
1542
1543
7.29k
    if (colorants->size == 0) return 0;
1544
1545
    /* See below about this device fill proc */
1546
0
    fill_dev_proc(dev, get_profile, gx_default_get_profile);
1547
0
    tempstr = (char *) gs_alloc_bytes(dev->memory, colorants->size+1,
1548
0
                                      "gx_default_put_icc_colorants");
1549
0
    if (tempstr == NULL)
1550
0
        return_error(gs_error_VMerror);
1551
1552
0
    memcpy(tempstr, colorants->data, colorants->size);
1553
    /* Set last position to NULL. */
1554
0
    tempstr[colorants->size] = 0;
1555
1556
    /* The input colorants string is UTF-8 encoded. We want it to be put into the
1557
     * device as 8-bit 'raw' values. We therefore need to decode it here. Any
1558
     * UTF-8 chars that do not decode to 8 bits will be flagged up as a rangecheck.
1559
     */
1560
0
    len = gp_utf8_to_uint16(NULL, tempstr);
1561
0
    if (len >= 0)
1562
0
        tempstr2 = (unsigned short *)gs_alloc_bytes(dev->memory, len * sizeof(unsigned short),
1563
0
                                                "gx_default_put_icc_colorants");
1564
0
    if (tempstr2 == NULL)
1565
0
    {
1566
0
        gs_free_object(dev->memory, tempstr, "gx_default_put_icc_colorants");
1567
0
        return_error(gs_error_VMerror);
1568
0
    }
1569
0
    len = gp_utf8_to_uint16(tempstr2, tempstr);
1570
1571
    /* Now convert down to 8 bits. Reuse tempstr here, because we know it will
1572
     * be large enough. */
1573
0
    code = 0;
1574
0
    for (s = tempstr2, d = tempstr; *s; s++, d++)
1575
0
    {
1576
0
        unsigned short v = *s;
1577
0
        if (v & 0xff00)
1578
0
            code = gs_note_error(gs_error_rangecheck);
1579
0
        *d = v & 0xff;
1580
0
    }
1581
1582
0
    if (code < 0)
1583
0
        emprintf(dev->memory, "ICCColorants must fit (unencoded) in 8 bits");
1584
0
    else
1585
0
        code = gsicc_set_device_profile_colorants(dev, tempstr);
1586
0
    gs_free_object(dev->memory, tempstr, "gx_default_put_icc_colorants");
1587
0
    gs_free_object(dev->memory, tempstr2, "gx_default_put_icc_colorants");
1588
0
    return code;
1589
0
}
1590
1591
static int
1592
gx_default_put_icc(gs_param_string *icc_pro, gx_device * dev,
1593
                   gsicc_profile_types_t index)
1594
58.3k
{
1595
58.3k
    char *tempstr;
1596
58.3k
    int code = 0;
1597
1598
58.3k
    if (icc_pro->size == 0) return 0;
1599
    /* If this has not yet been set, then set it to the default.
1600
       I don't like doing this here but if we are in here trying to
1601
       set a profile for our device and if the proc for this has not
1602
       yet been set, we are going to lose the chance to set the profile.
1603
       Much like open, this proc should be set early on.  I leave that
1604
       exercise to the device start-up experts */
1605
7.29k
    fill_dev_proc(dev, get_profile, gx_default_get_profile);
1606
7.29k
    if (icc_pro->size < gp_file_name_sizeof) {
1607
7.29k
        tempstr = (char *) gs_alloc_bytes(dev->memory, icc_pro->size+1,
1608
7.29k
                                          "gx_default_put_icc");
1609
7.29k
        if (tempstr == NULL)
1610
0
            return_error(gs_error_VMerror);
1611
7.29k
        memcpy(tempstr, icc_pro->data, icc_pro->size);
1612
        /* Set last position to NULL. */
1613
7.29k
        tempstr[icc_pro->size] = 0;
1614
7.29k
        code = gsicc_init_device_profile_struct(dev, tempstr, index);
1615
7.29k
        gs_free_object(dev->memory, tempstr, "gx_default_put_icc");
1616
7.29k
    }
1617
7.29k
    return code;
1618
7.29k
}
1619
1620
void rc_free_NupControl(gs_memory_t * mem, void *ptr_in, client_name_t cname);  /* silence warning */
1621
/* Exported for use by nup_put_params in gdevnup.c */
1622
void
1623
rc_free_NupControl(gs_memory_t * mem, void *ptr_in, client_name_t cname)
1624
0
{
1625
0
    gdev_nupcontrol *pnupc = (gdev_nupcontrol *)ptr_in;
1626
1627
0
    if (pnupc->rc.ref_count <= 1) {
1628
0
        gs_free(mem->non_gc_memory, pnupc->nupcontrol_str, 1, strlen(pnupc->nupcontrol_str), "free nupcontrol string");
1629
0
        gs_free(mem->non_gc_memory, pnupc, 1, sizeof(gdev_nupcontrol), "free structure to hold nupcontrol string");
1630
0
    }
1631
0
}
1632
1633
static void
1634
rc_free_pages_list(gs_memory_t * mem, void *ptr_in, client_name_t cname)
1635
0
{
1636
0
    gdev_pagelist *PageList = (gdev_pagelist *)ptr_in;
1637
1638
0
    if (PageList->rc.ref_count <= 1) {
1639
0
        gs_free(mem->non_gc_memory, PageList->Pages, 1, strlen(PageList->Pages), "free page list");
1640
0
        gs_free(mem->non_gc_memory, PageList, 1, sizeof(gdev_pagelist), "free structure to hold page list");
1641
0
    }
1642
0
}
1643
1644
/* Set standard parameters. */
1645
/* Note that setting the size or resolution closes the device. */
1646
/* Window devices that don't want this to happen must temporarily */
1647
/* set is_open to false before calling gx_default_put_params, */
1648
/* and then taking appropriate action afterwards. */
1649
int
1650
gx_default_put_params(gx_device * dev, gs_param_list * plist)
1651
92.7k
{
1652
92.7k
    int ecode = 0;
1653
92.7k
    int code;
1654
92.7k
    gs_param_name param_name;
1655
92.7k
    gs_param_float_array hwra;
1656
92.7k
    gs_param_int_array hwsa;
1657
92.7k
    gs_param_float_array msa;
1658
92.7k
    gs_param_float_array ma;
1659
92.7k
    gs_param_float_array hwma;
1660
92.7k
    gs_param_string_array scna;
1661
92.7k
    int nci = dev->NumCopies;
1662
92.7k
    int ncset = dev->NumCopies_set;
1663
92.7k
    bool ignc = dev->IgnoreNumCopies;
1664
92.7k
    bool ucc = dev->UseCIEColor;
1665
92.7k
    gs_param_string icc_pro;
1666
92.7k
    bool locksafe = dev->LockSafetyParams;
1667
92.7k
    gs_param_float_array ibba;
1668
92.7k
    bool ibbnull = false;
1669
92.7k
    int colors = dev->color_info.num_components;
1670
92.7k
    int depth = dev->color_info.depth;
1671
92.7k
    int GrayValues = dev->color_info.max_gray + 1;
1672
92.7k
    int RGBValues = dev->color_info.max_color + 1;
1673
92.7k
    long ColorValues = (depth >= 32 ? -1 : 1L << depth);
1674
92.7k
    int tab = dev->color_info.anti_alias.text_bits;
1675
92.7k
    int gab = dev->color_info.anti_alias.graphics_bits;
1676
92.7k
    size_t mpbm = dev->MaxPatternBitmap;
1677
92.7k
    int ic = dev->interpolate_control;
1678
92.7k
    bool page_uses_transparency = dev->page_uses_transparency;
1679
92.7k
    bool page_uses_overprint = dev->page_uses_overprint;
1680
92.7k
    gdev_space_params sp = dev->space_params;
1681
92.7k
    gdev_space_params save_sp = dev->space_params;
1682
92.7k
    int rend_intent[NUM_DEVICE_PROFILES];
1683
92.7k
    int blackptcomp[NUM_DEVICE_PROFILES];
1684
92.7k
    int blackpreserve[NUM_DEVICE_PROFILES];
1685
92.7k
    gs_param_string cms, pagelist, nuplist;
1686
92.7k
    int leadingedge = dev->LeadingEdge;
1687
92.7k
    int k;
1688
92.7k
    int color_accuracy;
1689
92.7k
    bool devicegraytok = true;
1690
92.7k
    bool graydetection = false;
1691
92.7k
    bool usefastcolor = false;
1692
92.7k
    bool blacktext = false;
1693
92.7k
    bool blackvector = false;
1694
92.7k
    float blackthresholdL = BLACKTHRESHOLDL;
1695
92.7k
    float blackthresholdC = BLACKTHRESHOLDC;
1696
92.7k
    gs_overprint_control_t overprint_control = gs_overprint_control_enable;
1697
92.7k
    bool prebandthreshold = false;
1698
92.7k
    bool use_antidropout = dev->color_info.use_antidropout_downscaler;
1699
92.7k
    bool temp_bool;
1700
92.7k
    int  profile_types[NUM_DEVICE_PROFILES] = {gsDEFAULTPROFILE,
1701
92.7k
                                               gsGRAPHICPROFILE,
1702
92.7k
                                               gsIMAGEPROFILE,
1703
92.7k
                                               gsTEXTPROFILE};
1704
1705
92.7k
    color_accuracy = gsicc_currentcoloraccuracy(dev->memory);
1706
92.7k
    if (dev->icc_struct != NULL) {
1707
365k
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
1708
292k
            rend_intent[k] = dev->icc_struct->rendercond[k].rendering_intent;
1709
292k
            blackptcomp[k] = dev->icc_struct->rendercond[k].black_point_comp;
1710
292k
            blackpreserve[k] = dev->icc_struct->rendercond[k].preserve_black;
1711
292k
        }
1712
73.0k
        graydetection = dev->icc_struct->graydetection;
1713
73.0k
        devicegraytok = dev->icc_struct->devicegraytok;
1714
73.0k
        usefastcolor = dev->icc_struct->usefastcolor;
1715
73.0k
        blacktext = dev->icc_struct->blacktext;
1716
73.0k
        blackvector = dev->icc_struct->blackvector;
1717
73.0k
        blackthresholdL = dev->icc_struct->blackthresholdL;
1718
73.0k
        blackthresholdC = dev->icc_struct->blackthresholdC;
1719
73.0k
        prebandthreshold = dev->icc_struct->prebandthreshold;
1720
73.0k
        overprint_control = dev->icc_struct->overprint_control;
1721
73.0k
    } else {
1722
98.6k
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
1723
78.8k
            rend_intent[k] = gsRINOTSPECIFIED;
1724
78.8k
            blackptcomp[k] = gsBPNOTSPECIFIED;
1725
78.8k
            blackpreserve[k] = gsBKPRESNOTSPECIFIED;
1726
78.8k
        }
1727
19.7k
    }
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
92.7k
#define BEGIN_ARRAY_PARAM(pread, pname, pa, psize, e)\
1740
649k
    BEGIN\
1741
649k
    switch (code = pread(plist, (param_name = pname), &(pa))) {\
1742
136k
      case 0:\
1743
136k
        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
92.7k
#define END_ARRAY_PARAM(pa, e)\
1748
92.7k
        goto e;\
1749
136k
      default:\
1750
24
        ecode = code;\
1751
24
e:  param_signal_error(plist, param_name, ecode);\
1752
512k
      case 1:\
1753
512k
        (pa).data = 0;   /* mark as not filled */\
1754
1.29M
    }\
1755
1.29M
    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
92.7k
    if (leadingedge & LEADINGEDGE_REQ_BIT) {
1764
0
        leadingedge = (leadingedge & LEADINGEDGE_SET_MASK) |
1765
0
            ((leadingedge >> LEADINGEDGE_REQ_VAL_SHIFT) & LEADINGEDGE_MASK);
1766
0
    }
1767
1768
    /*
1769
     * The HWResolution, HWSize, and MediaSize parameters interact in
1770
     * the following way:
1771
     *      1. Setting HWResolution recomputes HWSize from MediaSize.
1772
     *      2. Setting HWSize recomputes MediaSize from HWResolution.
1773
     *      3. Setting MediaSize recomputes HWSize from HWResolution.
1774
     * If more than one parameter is being set, we apply these rules
1775
     * in the order 1, 2, 3.  This does the right thing in the most
1776
     * common case of setting more than one parameter, namely,
1777
     * setting both HWResolution and HWSize.
1778
     *
1779
     * Changing of LeadingEdge is treated exactly the same as a
1780
     * change in HWResolution. In typical usage, MediaSize is
1781
     * short-edge (MediaSize[0] < MediaSize[1]), so if LeadingEdge
1782
     * is 1 or 3, then HWSize will become long-edge. For nonsquare
1783
     * resolutions, HWResolution[0] always corresponds with width
1784
     * (scan length), and [1] with height (number of scans).
1785
     */
1786
1787
109k
    BEGIN_ARRAY_PARAM(param_read_float_array, "HWResolution", hwra, 2, hwre) {
1788
17.1k
        if (hwra.data[0] <= 0 || hwra.data[1] <= 0)
1789
0
            ecode = gs_note_error(gs_error_rangecheck);
1790
17.1k
        else
1791
17.1k
            break;
1792
17.1k
    } END_ARRAY_PARAM(hwra, hwre);
1793
100k
    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
7.29k
        if ((hwsa.data[0] <= 0 && hwsa.data[0] != dev->width) ||
1797
7.29k
            (hwsa.data[1] <= 0 && hwsa.data[1] != dev->height)
1798
7.29k
        )
1799
0
            ecode = gs_note_error(gs_error_rangecheck);
1800
21.8k
#define max_coord (max_fixed / fixed_1)
1801
7.29k
#if max_coord < max_int
1802
7.29k
        else if (hwsa.data[0] > max_coord || hwsa.data[1] > max_coord)
1803
0
            ecode = gs_note_error(gs_error_limitcheck);
1804
7.29k
#endif
1805
7.29k
#undef max_coord
1806
7.29k
        else
1807
7.29k
            break;
1808
7.29k
    } END_ARRAY_PARAM(hwsa, hwse);
1809
92.7k
    {
1810
92.7k
        int t;
1811
1812
92.7k
        code = param_read_int(plist, "LeadingEdge", &t);
1813
92.7k
        if (code < 0) {
1814
7.29k
            if (param_read_null(plist, "LeadingEdge") == 0) {
1815
                /* if param is null, clear explicitly-set flag */
1816
7.29k
                leadingedge &= ~LEADINGEDGE_SET_MASK;
1817
7.29k
            } else {
1818
0
                ecode = code;
1819
0
            }
1820
85.4k
        } 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
92.7k
    }
1828
92.7k
    {
1829
92.7k
        const float *res = (hwra.data == 0 ? dev->HWResolution : hwra.data);
1830
1831
92.7k
#ifdef PAGESIZE_IS_MEDIASIZE
1832
92.7k
        const float *data;
1833
1834
        /* .MediaSize takes precedence over PageSize, so */
1835
        /* we read PageSize first. */
1836
92.7k
        code = param_MediaSize(plist, "PageSize", res, &msa);
1837
92.7k
        if (code < 0)
1838
0
            ecode = code;
1839
        /* Prevent data from being set to 0 if PageSize is specified */
1840
        /* but .MediaSize is not. */
1841
92.7k
        data = msa.data;
1842
92.7k
        code = param_MediaSize(plist, ".MediaSize", res, &msa);
1843
92.7k
        if (code < 0)
1844
24
            ecode = code;
1845
92.7k
        else if (msa.data == 0)
1846
44.1k
            msa.data = data;
1847
#else
1848
        code = param_MediaSize(plist, ".MediaSize", res, &msa);
1849
        if (code < 0)
1850
            ecode = code;
1851
#endif
1852
92.7k
    }
1853
1854
100k
    BEGIN_ARRAY_PARAM(param_read_float_array, "Margins", ma, 2, me) {
1855
7.29k
        break;
1856
7.29k
    } END_ARRAY_PARAM(ma, me);
1857
100k
    BEGIN_ARRAY_PARAM(param_read_float_array, ".HWMargins", hwma, 4, hwme) {
1858
7.29k
        break;
1859
7.29k
    } END_ARRAY_PARAM(hwma, hwme);
1860
92.7k
    switch (code = param_read_bool(plist, (param_name = ".IgnoreNumCopies"), &ignc)) {
1861
0
        default:
1862
0
            ecode = code;
1863
0
            param_signal_error(plist, param_name, ecode);
1864
7.29k
        case 0:
1865
92.7k
        case 1:
1866
92.7k
            break;
1867
92.7k
    }
1868
92.7k
    if (dev->NumCopies_set >= 0 &&
1869
92.7k
        (*dev_proc(dev, get_page_device))(dev) != 0
1870
92.7k
        ) {
1871
92.7k
        switch (code = param_read_int(plist, (param_name = "NumCopies"), &nci)) {
1872
0
            case 0:
1873
0
                if (nci < 0)
1874
0
                    ecode = gs_error_rangecheck;
1875
0
                else {
1876
0
                    ncset = 1;
1877
0
                    break;
1878
0
                }
1879
0
                goto nce;
1880
7.29k
            default:
1881
7.29k
                if ((code = param_read_null(plist, param_name)) == 0) {
1882
7.29k
                    ncset = 0;
1883
7.29k
                    break;
1884
7.29k
                }
1885
0
                ecode = code; /* can't be 1 */
1886
0
nce:
1887
0
                param_signal_error(plist, param_name, ecode);
1888
85.4k
            case 1:
1889
85.4k
                break;
1890
92.7k
        }
1891
92.7k
    }
1892
    /* Set the ICC output colors first */
1893
92.7k
    if ((code = param_read_string(plist, "ICCOutputColors", &icc_pro)) != 1) {
1894
7.29k
        if (code < 0) {
1895
0
            ecode = code;
1896
0
            param_signal_error(plist, "ICCOutputColors", ecode);
1897
7.29k
        } else {
1898
7.29k
            if ((code = gx_default_put_icc_colorants(&icc_pro, dev)) < 0) {
1899
0
                ecode = code;
1900
0
                param_signal_error(plist, "ICCOutputColors", ecode);
1901
0
            }
1902
7.29k
        }
1903
7.29k
    }
1904
92.7k
    if ((code = param_read_string(plist, "DeviceLinkProfile", &icc_pro)) != 1) {
1905
7.29k
        if (code < 0) {
1906
0
            ecode = code;
1907
0
            param_signal_error(plist, "DeviceLinkProfile", ecode);
1908
7.29k
        } else {
1909
7.29k
            if ((code = gx_default_put_icc(&icc_pro, dev, gsLINKPROFILE)) < 0) {
1910
0
                ecode = code;
1911
0
                param_signal_error(plist, "DeviceLinkProfile", ecode);
1912
0
            }
1913
7.29k
        }
1914
7.29k
    }
1915
92.7k
    if ((code = param_read_string(plist, "PostRenderProfile", &icc_pro)) != 1) {
1916
7.29k
        if (code < 0) {
1917
0
            ecode = code;
1918
0
            param_signal_error(plist, "PostRenderProfile", ecode);
1919
7.29k
        } else {
1920
7.29k
            if ((code = gx_default_put_icc(&icc_pro, dev, gsPRPROFILE)) < 0) {
1921
0
                ecode = code;
1922
0
                param_signal_error(plist, "PostRenderProfile", ecode);
1923
0
            }
1924
7.29k
        }
1925
7.29k
    }
1926
92.7k
    if ((code = param_read_string(plist, "OutputICCProfile", &icc_pro)) != 1) {
1927
7.29k
        if (code < 0) {
1928
0
            ecode = code;
1929
0
            param_signal_error(plist, "OutputICCProfile", ecode);
1930
7.29k
        } else {
1931
7.29k
            if ((code = gx_default_put_icc(&icc_pro, dev, gsDEFAULTPROFILE)) < 0) {
1932
0
                ecode = code;
1933
0
                param_signal_error(plist, "OutputICCProfile", ecode);
1934
0
            }
1935
7.29k
        }
1936
7.29k
    }
1937
    /* Note, if a change is made to NUM_DEVICE_PROFILES we need to update
1938
       this with the name of the profile */
1939
92.7k
    if ((code = param_read_string(plist, "VectorICCProfile", &icc_pro)) != 1) {
1940
7.29k
        if (code < 0) {
1941
0
            ecode = code;
1942
0
            param_signal_error(plist, "VectorICCProfile", ecode);
1943
7.29k
        } else {
1944
7.29k
            if ((code = gx_default_put_icc(&icc_pro, dev, gsGRAPHICPROFILE)) < 0) {
1945
0
                ecode = code;
1946
0
                param_signal_error(plist, "VectorICCProfile", ecode);
1947
0
            }
1948
7.29k
        }
1949
7.29k
    }
1950
92.7k
    if ((code = param_read_string(plist, "ImageICCProfile", &icc_pro)) != 1) {
1951
7.29k
        if (code < 0) {
1952
0
            ecode = code;
1953
0
            param_signal_error(plist, "ImageICCProfile", ecode);
1954
7.29k
        } else {
1955
7.29k
            if ((code = gx_default_put_icc(&icc_pro, dev, gsIMAGEPROFILE)) < 0) {
1956
0
                ecode = code;
1957
0
                param_signal_error(plist, "ImageICCProfile", ecode);
1958
0
            }
1959
7.29k
        }
1960
7.29k
    }
1961
92.7k
    if ((code = param_read_string(plist, "TextICCProfile", &icc_pro)) != 1) {
1962
7.29k
        if (code < 0) {
1963
0
            ecode = code;
1964
0
            param_signal_error(plist, "TextICCProfile", ecode);
1965
7.29k
        } else {
1966
7.29k
            if ((code = gx_default_put_icc(&icc_pro, dev, gsTEXTPROFILE)) < 0) {
1967
0
                ecode = code;
1968
0
                param_signal_error(plist, "TextICCProfile", ecode);
1969
0
            }
1970
7.29k
        }
1971
7.29k
    }
1972
92.7k
    if ((code = param_read_string(plist, "ProofProfile", &icc_pro)) != 1) {
1973
7.29k
        if (code < 0) {
1974
0
            ecode = code;
1975
0
            param_signal_error(plist, "ProofProfile", ecode);
1976
7.29k
        } else {
1977
7.29k
            if ((code = gx_default_put_icc(&icc_pro, dev, gsPROOFPROFILE)) < 0) {
1978
0
                ecode = code;
1979
0
                param_signal_error(plist, "ProofProfile", ecode);
1980
0
            }
1981
7.29k
        }
1982
7.29k
    }
1983
92.7k
    if ((code = param_read_string(plist, "BlendColorProfile", &icc_pro)) != 1) {
1984
7.29k
        if (code < 0) {
1985
0
            ecode = code;
1986
0
            param_signal_error(plist, "BlendColorProfile", ecode);
1987
7.29k
        } else {
1988
7.29k
            if ((code = gx_default_put_icc(&icc_pro, dev, gsBLENDPROFILE)) < 0) {
1989
0
                ecode = code;
1990
0
                param_signal_error(plist, "BlendColorProfile", ecode);
1991
0
            }
1992
7.29k
        }
1993
7.29k
    }
1994
92.7k
    if ((code = param_read_int(plist, (param_name = "RenderIntent"),
1995
92.7k
                                                    &(rend_intent[0]))) < 0) {
1996
0
        ecode = code;
1997
0
        param_signal_error(plist, param_name, ecode);
1998
0
    }
1999
92.7k
    if ((code = param_read_int(plist, (param_name = "VectorIntent"),
2000
92.7k
                                                    &(rend_intent[1]))) < 0) {
2001
0
        ecode = code;
2002
0
        param_signal_error(plist, param_name, ecode);
2003
0
    }
2004
92.7k
    if ((code = param_read_int(plist, (param_name = "ImageIntent"),
2005
92.7k
                                                    &(rend_intent[2]))) < 0) {
2006
0
        ecode = code;
2007
0
        param_signal_error(plist, param_name, ecode);
2008
0
    }
2009
92.7k
    if ((code = param_read_int(plist, (param_name = "TextIntent"),
2010
92.7k
                                                    &(rend_intent[3]))) < 0) {
2011
0
        ecode = code;
2012
0
        param_signal_error(plist, param_name, ecode);
2013
0
    }
2014
92.7k
    if ((code = param_read_int(plist, (param_name = "BlackPtComp"),
2015
92.7k
                                                    &(blackptcomp[0]))) < 0) {
2016
0
        ecode = code;
2017
0
        param_signal_error(plist, param_name, ecode);
2018
0
    }
2019
92.7k
    if ((code = param_read_int(plist, (param_name = "VectorBlackPt"),
2020
92.7k
                                                    &(blackptcomp[1]))) < 0) {
2021
0
        ecode = code;
2022
0
        param_signal_error(plist, param_name, ecode);
2023
0
    }
2024
92.7k
    if ((code = param_read_int(plist, (param_name = "ImageBlackPt"),
2025
92.7k
                                                    &(blackptcomp[2]))) < 0) {
2026
0
        ecode = code;
2027
0
        param_signal_error(plist, param_name, ecode);
2028
0
    }
2029
92.7k
    if ((code = param_read_int(plist, (param_name = "TextBlackPt"),
2030
92.7k
                                                    &(blackptcomp[3]))) < 0) {
2031
0
        ecode = code;
2032
0
        param_signal_error(plist, param_name, ecode);
2033
0
    }
2034
92.7k
    if ((code = param_read_int(plist, (param_name = "KPreserve"),
2035
92.7k
                                                    &(blackpreserve[0]))) < 0) {
2036
0
        ecode = code;
2037
0
        param_signal_error(plist, param_name, ecode);
2038
0
    }
2039
92.7k
    if ((code = param_read_int(plist, (param_name = "VectorKPreserve"),
2040
92.7k
                                                    &(blackpreserve[1]))) < 0) {
2041
0
        ecode = code;
2042
0
        param_signal_error(plist, param_name, ecode);
2043
0
    }
2044
92.7k
    if ((code = param_read_int(plist, (param_name = "ImageKPreserve"),
2045
92.7k
                                                    &(blackpreserve[2]))) < 0) {
2046
0
        ecode = code;
2047
0
        param_signal_error(plist, param_name, ecode);
2048
0
    }
2049
92.7k
    if ((code = param_read_int(plist, (param_name = "TextKPreserve"),
2050
92.7k
                                                    &(blackpreserve[3]))) < 0) {
2051
0
        ecode = code;
2052
0
        param_signal_error(plist, param_name, ecode);
2053
0
    }
2054
92.7k
    if ((code = param_read_int(plist, (param_name = "ColorAccuracy"),
2055
92.7k
                                                        &color_accuracy)) < 0) {
2056
0
        ecode = code;
2057
0
        param_signal_error(plist, param_name, ecode);
2058
0
    }
2059
92.7k
    if ((code = param_read_bool(plist, (param_name = "DeviceGrayToK"),
2060
92.7k
                                                        &devicegraytok)) < 0) {
2061
0
        ecode = code;
2062
0
        param_signal_error(plist, param_name, ecode);
2063
0
    }
2064
92.7k
    if ((code = param_read_bool(plist, (param_name = "GrayDetection"),
2065
92.7k
                                                        &graydetection)) < 0) {
2066
0
        ecode = code;
2067
0
        param_signal_error(plist, param_name, ecode);
2068
0
    }
2069
92.7k
    if ((code = param_read_bool(plist, (param_name = "UseFastColor"),
2070
92.7k
                                                        &usefastcolor)) < 0) {
2071
0
        ecode = code;
2072
0
        param_signal_error(plist, param_name, ecode);
2073
0
    }
2074
92.7k
    if ((code = param_read_bool(plist, (param_name = "BlackText"),
2075
92.7k
                                                        &blacktext)) < 0) {
2076
0
        ecode = code;
2077
0
        param_signal_error(plist, param_name, ecode);
2078
0
    }
2079
92.7k
    if ((code = param_read_bool(plist, (param_name = "BlackVector"),
2080
92.7k
                                                        &blackvector)) < 0) {
2081
0
        ecode = code;
2082
0
        param_signal_error(plist, param_name, ecode);
2083
0
    }
2084
92.7k
    if ((code = param_read_float(plist, (param_name = "BlackThresholdL"),
2085
92.7k
                                                        &blackthresholdL)) < 0) {
2086
0
        ecode = code;
2087
0
        param_signal_error(plist, param_name, ecode);
2088
0
    }
2089
92.7k
    if ((code = param_read_float(plist, (param_name = "BlackThresholdC"),
2090
92.7k
                                                        &blackthresholdC)) < 0) {
2091
0
        ecode = code;
2092
0
        param_signal_error(plist, param_name, ecode);
2093
0
    }
2094
92.7k
    if ((code = param_put_enum(plist, "Overprint",
2095
92.7k
                           (int*)&overprint_control, overprint_control_names, ecode)) < 0) {
2096
24
        ecode = code;
2097
24
        param_signal_error(plist, param_name, ecode);
2098
24
    }
2099
92.7k
    if ((code = param_read_bool(plist, (param_name = "PreBandThreshold"),
2100
92.7k
                                                        &prebandthreshold)) < 0) {
2101
0
        ecode = code;
2102
0
        param_signal_error(plist, param_name, ecode);
2103
0
    }
2104
92.7k
    if ((code = param_read_bool(plist, (param_name = "UseCIEColor"), &ucc)) < 0) {
2105
0
        ecode = code;
2106
0
        param_signal_error(plist, param_name, ecode);
2107
0
    }
2108
92.7k
    if ((code = param_anti_alias_bits(plist, "TextAlphaBits", &tab)) < 0)
2109
0
        ecode = code;
2110
92.7k
    if ((code = param_anti_alias_bits(plist, "GraphicsAlphaBits", &gab)) < 0)
2111
0
        ecode = code;
2112
92.7k
    if ((code = param_read_bool(plist, "AntidropoutDownscaler", &use_antidropout)) < 0)
2113
0
        ecode = code;
2114
92.7k
    if ((code = param_read_size_t(plist, "MaxPatternBitmap", &mpbm)) < 0)
2115
0
        ecode = code;
2116
92.7k
    if ((code = param_read_int(plist, "InterpolateControl", &ic)) < 0)
2117
0
        ecode = code;
2118
92.7k
    if ((code = param_read_bool(plist, (param_name = "PageUsesTransparency"),
2119
92.7k
                                &page_uses_transparency)) < 0) {
2120
0
        ecode = code;
2121
0
        param_signal_error(plist, param_name, ecode);
2122
0
    }
2123
92.7k
    if ((code = param_read_bool(plist, (param_name = "PageUsesOverprint"),
2124
92.7k
                                &page_uses_overprint)) < 0) {
2125
0
        ecode = code;
2126
0
        param_signal_error(plist, param_name, ecode);
2127
0
    }
2128
92.7k
    if ((code = param_read_size_t(plist, "MaxBitmap", &sp.MaxBitmap)) < 0)
2129
0
        ecode = code;
2130
2131
92.7k
#define CHECK_PARAM_CASES(member, bad, label)\
2132
92.7k
    case 0:\
2133
39.0k
        if ((sp.params_are_read_only ? sp.member != save_sp.member : bad))\
2134
0
            ecode = gs_error_rangecheck;\
2135
0
        else\
2136
39.0k
            break;\
2137
0
        goto label;\
2138
0
    default:\
2139
0
        ecode = code;\
2140
0
label:\
2141
0
        param_signal_error(plist, param_name, ecode);\
2142
331k
    case 1:\
2143
331k
        break
2144
2145
92.7k
    switch (code = param_read_size_t(plist, (param_name = "BufferSpace"), &sp.BufferSpace)) {
2146
92.7k
        CHECK_PARAM_CASES(BufferSpace, sp.BufferSpace < 10000, bse);
2147
92.7k
    }
2148
2149
92.7k
    switch (code = param_read_int(plist, (param_name = "BandWidth"), &sp.band.BandWidth)) {
2150
92.7k
        CHECK_PARAM_CASES(band.BandWidth, sp.band.BandWidth < 0, bwe);
2151
92.7k
    }
2152
2153
92.7k
    switch (code = param_read_int(plist, (param_name = "BandHeight"), &sp.band.BandHeight)) {
2154
92.7k
        CHECK_PARAM_CASES(band.BandHeight, sp.band.BandHeight < -1, bhe);
2155
92.7k
    }
2156
92.7k
    if (sp.band.BandHeight == -1)
2157
0
        sp.band.BandHeight = dev->height; /* 1 band for the page requested */
2158
2159
92.7k
    switch (code = param_read_size_t(plist, (param_name = "BandBufferSpace"), &sp.band.BandBufferSpace)) {
2160
92.7k
        CHECK_PARAM_CASES(band.BandBufferSpace, 0, bbse);
2161
92.7k
    }
2162
2163
2164
92.7k
    switch (code = param_read_bool(plist, (param_name = ".LockSafetyParams"), &locksafe)) {
2165
7.29k
        case 0:
2166
7.29k
            if (dev->LockSafetyParams && !locksafe)
2167
0
                code = gs_note_error(gs_error_invalidaccess);
2168
7.29k
            else
2169
7.29k
                break;
2170
0
        default:
2171
0
            ecode = code;
2172
0
            param_signal_error(plist, param_name, ecode);
2173
85.4k
        case 1:
2174
85.4k
            break;
2175
92.7k
    }
2176
    /* Ignore parameters that only have meaning for printers. */
2177
92.7k
#define IGNORE_INT_PARAM(pname)\
2178
370k
  { int igni;\
2179
370k
    switch ( code = param_read_int(plist, (param_name = pname), &igni) )\
2180
370k
      { default:\
2181
0
          ecode = code;\
2182
0
          param_signal_error(plist, param_name, ecode);\
2183
104k
        case 0:\
2184
370k
        case 1:\
2185
370k
          break;\
2186
370k
      }\
2187
370k
  }
2188
92.7k
    IGNORE_INT_PARAM("%MediaSource")
2189
92.7k
        IGNORE_INT_PARAM("%MediaDestination")
2190
92.7k
        switch (code = param_read_float_array(plist, (param_name = "ImagingBBox"), &ibba)) {
2191
0
        case 0:
2192
0
            if (ibba.size != 4 ||
2193
0
                ibba.data[2] < ibba.data[0] || ibba.data[3] < ibba.data[1]
2194
0
                )
2195
0
                ecode = gs_note_error(gs_error_rangecheck);
2196
0
            else
2197
0
                break;
2198
0
            goto ibbe;
2199
0
        default:
2200
0
            if ((code = param_read_null(plist, param_name)) == 0) {
2201
0
                ibbnull = true;
2202
0
                ibba.data = 0;
2203
0
                break;
2204
0
            }
2205
0
            ecode = code; /* can't be 1 */
2206
0
          ibbe:param_signal_error(plist, param_name, ecode);
2207
92.7k
        case 1:
2208
92.7k
            ibba.data = 0;
2209
92.7k
            break;
2210
92.7k
    }
2211
2212
    /* Separation, DeviceN Color, and ProcessColorModel related parameters. */
2213
92.7k
    {
2214
92.7k
        const char * pcms = get_process_color_model_name(dev);
2215
        /* the device should have set a process model name at this point */
2216
92.7k
        if ((code = param_check_string(plist, "ProcessColorModel", pcms, (pcms != NULL))) < 0)
2217
0
            ecode = code;
2218
92.7k
    }
2219
92.7k
    IGNORE_INT_PARAM("MaxSeparations")
2220
92.7k
    if ((code = param_check_bool(plist, "Separations", false, true)) < 0)
2221
1
        ecode = code;
2222
2223
141k
    BEGIN_ARRAY_PARAM(param_read_name_array, "SeparationColorNames", scna, scna.size, scne) {
2224
48.6k
        break;
2225
48.6k
    } END_ARRAY_PARAM(scna, scne);
2226
2227
    /* Now check nominally read-only parameters. */
2228
92.7k
    if ((code = param_check_string(plist, "OutputDevice", dev->dname, true)) < 0)
2229
0
        ecode = code;
2230
92.7k
    if ((code = param_check_string(plist, "Name", dev->dname, true)) < 0)
2231
0
        ecode = code;
2232
92.7k
    if ((code = param_check_int(plist, "Colors", colors, true)) < 0)
2233
0
        ecode = code;
2234
92.7k
    if ((code = param_check_int(plist, "BitsPerPixel", depth, true)) < 0)
2235
0
        ecode = code;
2236
92.7k
    if ((code = param_check_int(plist, "GrayValues", GrayValues, true)) < 0)
2237
0
        ecode = code;
2238
2239
    /* with saved-pages, PageCount can't be checked. No harm in letting it change */
2240
92.7k
    IGNORE_INT_PARAM("PageCount")
2241
2242
92.7k
    if ((code = param_check_int(plist, "RedValues", RGBValues, true)) < 0)
2243
0
        ecode = code;
2244
92.7k
    if ((code = param_check_int(plist, "GreenValues", RGBValues, true)) < 0)
2245
0
        ecode = code;
2246
92.7k
    if ((code = param_check_int(plist, "BlueValues", RGBValues, true)) < 0)
2247
0
        ecode = code;
2248
92.7k
    if ((code = param_check_long(plist, "ColorValues", ColorValues, true)) < 0)
2249
0
        ecode = code;
2250
92.7k
    if (param_read_string(plist, "HWColorMap", &cms) != 1) {
2251
0
        byte palette[3 << 8];
2252
2253
0
        if (param_HWColorMap(dev, palette))
2254
0
            code = param_check_bytes(plist, "HWColorMap", palette,
2255
0
                                     colors << depth, true);
2256
0
        else
2257
0
            code = param_check_bytes(plist, "HWColorMap", 0, 0, false);
2258
0
        if (code < 0)
2259
0
            ecode = code;
2260
0
    }
2261
2262
92.7k
    code = param_read_int(plist, "FirstPage", &dev->FirstPage);
2263
92.7k
    if (code < 0)
2264
0
        ecode = code;
2265
2266
92.7k
    code = param_read_int(plist,  "LastPage", &dev->LastPage);
2267
92.7k
    if (code < 0)
2268
0
        ecode = code;
2269
2270
92.7k
    code = param_read_bool(plist, "DisablePageHandler", &temp_bool);
2271
92.7k
    if (code < 0)
2272
0
        ecode = code;
2273
92.7k
    if (code == 0)
2274
7.29k
        dev->DisablePageHandler = temp_bool;
2275
2276
    /* If we have an NupControl subclass device (N-up) installed, this param will have  */
2277
    /* been handled there, so the check for different will be false, meaning that this  */
2278
    /* code won't end up doing anything. This will catch the first occurence and needs  */
2279
    /* to install the N-up subclass device.           */
2280
92.7k
    code = param_read_string(plist, "NupControl", &nuplist);
2281
92.7k
    if (code < 0)
2282
0
        ecode = code;
2283
92.7k
    if (code == 0) {
2284
7.29k
        if (dev->NupControl && (
2285
0
            nuplist.size == 0 ||
2286
0
            (strncmp(dev->NupControl->nupcontrol_str, (const char *)nuplist.data, nuplist.size) != 0))) {
2287
            /* There was a NupControl, but this one is different -- no longer use the old one */
2288
0
            rc_decrement(dev->NupControl, "default put_params NupControl");
2289
0
            dev->NupControl = NULL;
2290
0
        }
2291
7.29k
    }
2292
92.7k
    if (dev->NupControl == NULL && code == 0 && nuplist.size > 0) {
2293
0
        gx_device *next_dev;
2294
2295
0
        dev->NupControl = (gdev_nupcontrol *)gs_alloc_bytes(dev->memory->non_gc_memory,
2296
0
                                                          sizeof(gdev_nupcontrol), "structure to hold nupcontrol_str");
2297
0
        if (dev->NupControl == NULL)
2298
0
            return gs_note_error(gs_error_VMerror);
2299
0
        dev->NupControl->nupcontrol_str = (void *)gs_alloc_bytes(dev->memory->non_gc_memory,
2300
0
                                                                 nuplist.size + 1, "nupcontrol string");
2301
0
        if (dev->NupControl->nupcontrol_str == NULL){
2302
0
            gs_free(dev->memory->non_gc_memory, dev->NupControl, 1, sizeof(gdev_nupcontrol),
2303
0
                    "free structure to hold nupcontrol string");
2304
0
            dev->NupControl = 0;
2305
0
            return gs_note_error(gs_error_VMerror);
2306
0
        }
2307
0
        memset(dev->NupControl->nupcontrol_str, 0x00, nuplist.size + 1);
2308
0
        memcpy(dev->NupControl->nupcontrol_str, nuplist.data, nuplist.size);
2309
0
        rc_init_free(dev->NupControl, dev->memory->non_gc_memory, 1, rc_free_NupControl);
2310
2311
        /* Propagate the new NupControl struct to children */
2312
0
        next_dev = dev->child;
2313
0
        while (next_dev != NULL) {
2314
0
            if (next_dev->NupControl)
2315
0
                rc_decrement(next_dev->NupControl, "nup_put_params");
2316
0
            next_dev->NupControl = dev->NupControl;
2317
0
            rc_increment(dev->NupControl);
2318
0
            next_dev = next_dev->child;
2319
0
        }
2320
        /* Propagate the new NupControl struct to parents */
2321
0
        next_dev = dev->parent;
2322
0
        while (next_dev != NULL) {
2323
0
            if (next_dev->NupControl)
2324
0
                rc_decrement(next_dev->NupControl, "nup_put_params");
2325
0
            next_dev->NupControl = dev->NupControl;
2326
0
            rc_increment(dev->NupControl);
2327
0
            next_dev = next_dev->parent;
2328
0
        }
2329
0
    }
2330
2331
92.7k
    code = param_read_string(plist, "PageList", &pagelist);
2332
92.7k
    if (code < 0)
2333
0
        ecode = code;
2334
92.7k
    if (code == 0) {
2335
7.29k
        if (dev->PageList)
2336
7.29k
            rc_decrement(dev->PageList, "default put_params PageList");
2337
7.29k
        dev->PageList = NULL;
2338
7.29k
    }
2339
2340
92.7k
    if (code == 0 && pagelist.size > 0) {
2341
0
        dev->PageList = (gdev_pagelist *)gs_alloc_bytes(dev->memory->non_gc_memory, sizeof(gdev_pagelist), "structure to hold page list");
2342
0
        if (!dev->PageList)
2343
0
            return gs_note_error(gs_error_VMerror);
2344
0
        dev->PageList->Pages = (void *)gs_alloc_bytes(dev->memory->non_gc_memory, pagelist.size + 1, "String to hold page list");
2345
0
        if (!dev->PageList->Pages){
2346
0
            gs_free(dev->memory->non_gc_memory, dev->PageList, 1, sizeof(gdev_pagelist), "free structure to hold page list");
2347
0
            dev->PageList = 0;
2348
0
            return gs_note_error(gs_error_VMerror);
2349
0
        }
2350
0
        memset(dev->PageList->Pages, 0x00, pagelist.size + 1);
2351
0
        memcpy(dev->PageList->Pages, pagelist.data, pagelist.size);
2352
0
        rc_init_free(dev->PageList, dev->memory->non_gc_memory, 1, rc_free_pages_list);
2353
0
    }
2354
2355
92.7k
    code = param_read_bool(plist, "FILTERIMAGE", &temp_bool);
2356
92.7k
    if (code < 0)
2357
0
        ecode = code;
2358
92.7k
    if (code == 0) {
2359
7.29k
        if (temp_bool)
2360
0
            dev->ObjectFilter |= FILTERIMAGE;
2361
7.29k
        else
2362
7.29k
            dev->ObjectFilter &= ~FILTERIMAGE;
2363
7.29k
    }
2364
2365
92.7k
    code = param_read_bool(plist, "FILTERTEXT", &temp_bool);
2366
92.7k
    if (code < 0)
2367
0
        ecode = code;
2368
92.7k
    if (code == 0) {
2369
7.29k
        if (temp_bool)
2370
0
            dev->ObjectFilter |= FILTERTEXT;
2371
7.29k
        else
2372
7.29k
            dev->ObjectFilter &= ~FILTERTEXT;
2373
7.29k
    }
2374
2375
92.7k
    code = param_read_bool(plist, "FILTERVECTOR", &temp_bool);
2376
92.7k
    if (code < 0)
2377
0
        ecode = code;
2378
92.7k
    if (code == 0) {
2379
7.29k
        if (temp_bool)
2380
0
            dev->ObjectFilter |= FILTERVECTOR;
2381
7.29k
        else
2382
7.29k
            dev->ObjectFilter &= ~FILTERVECTOR;
2383
7.29k
    }
2384
2385
    /* We must 'commit', in order to detect unknown parameters, */
2386
    /* even if there were errors. */
2387
92.7k
    code = param_commit(plist);
2388
92.7k
    if (ecode < 0) {
2389
        /* restore_page_device (zdevice2.c) will turn off LockSafetyParams, and relies on putparams
2390
         * to put it back if we are restoring a device. The locksafe value is picked up above from the
2391
         * device we are restoring to, and we *must* make sure it is preserved, even if setting the
2392
         * params failed. Otherwise an attacker can use a failed grestore to reset LockSafetyParams.
2393
         * See bug #699687.
2394
         */
2395
25
        dev->LockSafetyParams = locksafe;
2396
25
        return ecode;
2397
25
    }
2398
92.7k
    if (code < 0) {
2399
1
        dev->LockSafetyParams = locksafe;
2400
1
        return code;
2401
1
    }
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
92.6k
    dev->color_info.use_antidropout_downscaler = use_antidropout;
2412
2413
92.6k
    if (hwra.data != 0 &&
2414
92.6k
        (dev->HWResolution[0] != hwra.data[0] ||
2415
17.1k
         dev->HWResolution[1] != hwra.data[1])
2416
92.6k
        ) {
2417
9.86k
        if (dev->is_open)
2418
0
            gs_closedevice(dev);
2419
9.86k
        gx_device_set_resolution(dev, hwra.data[0], hwra.data[1]);
2420
9.86k
    }
2421
92.6k
    if ((leadingedge & LEADINGEDGE_MASK) !=
2422
92.6k
        (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
92.6k
    dev->LeadingEdge &= LEADINGEDGE_MASK;
2432
92.6k
    dev->LeadingEdge |= (leadingedge & LEADINGEDGE_SET_MASK);
2433
2434
92.6k
    if (hwsa.data != 0 &&
2435
92.6k
        (dev->width != hwsa.data[0] ||
2436
7.29k
         dev->height != hwsa.data[1])
2437
92.6k
        ) {
2438
6.17k
        if (dev->is_open)
2439
0
            gs_closedevice(dev);
2440
6.17k
        gx_device_set_width_height(dev, hwsa.data[0], hwsa.data[1]);
2441
6.17k
    }
2442
92.6k
    if (msa.data != 0 &&
2443
92.6k
        (dev->MediaSize[0] != msa.data[0] ||
2444
48.5k
         dev->MediaSize[1] != msa.data[1])
2445
92.6k
        ) {
2446
9.49k
        if (dev->is_open)
2447
0
            gs_closedevice(dev);
2448
9.49k
        gx_device_set_page_size(dev, msa.data[0], msa.data[1]);
2449
9.49k
    }
2450
92.6k
    if (ma.data != 0) {
2451
7.29k
        dev->Margins[0] = ma.data[0];
2452
7.29k
        dev->Margins[1] = ma.data[1];
2453
7.29k
    }
2454
92.6k
    if (hwma.data != 0) {
2455
7.29k
        dev->HWMargins[0] = hwma.data[0];
2456
7.29k
        dev->HWMargins[1] = hwma.data[1];
2457
7.29k
        dev->HWMargins[2] = hwma.data[2];
2458
7.29k
        dev->HWMargins[3] = hwma.data[3];
2459
7.29k
    }
2460
92.6k
    dev->NumCopies = nci;
2461
92.6k
    dev->NumCopies_set = ncset;
2462
92.6k
    dev->IgnoreNumCopies = ignc;
2463
92.6k
    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
92.6k
    } else if (ibbnull) {
2470
0
        dev->ImagingBBox_set = false;
2471
0
    }
2472
92.6k
    dev->UseCIEColor = ucc;
2473
92.6k
        dev->color_info.anti_alias.text_bits =
2474
92.6k
                param_normalize_anti_alias_bits(max(dev->color_info.max_gray,
2475
92.6k
                        dev->color_info.max_color), tab);
2476
92.6k
        dev->color_info.anti_alias.graphics_bits =
2477
92.6k
                param_normalize_anti_alias_bits(max(dev->color_info.max_gray,
2478
92.6k
                        dev->color_info.max_color), gab);
2479
92.6k
    dev->LockSafetyParams = locksafe;
2480
92.6k
    dev->MaxPatternBitmap = mpbm;
2481
92.6k
    dev->interpolate_control = ic;
2482
92.6k
    dev->space_params = sp;
2483
92.6k
    dev->page_uses_transparency = page_uses_transparency;
2484
92.6k
    dev->page_uses_overprint = page_uses_overprint;
2485
92.6k
    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
92.6k
    code = gx_default_put_intent(rend_intent[0], dev, gsDEFAULTPROFILE);
2491
92.6k
    if (code < 0)
2492
0
        return code;
2493
92.6k
    code = gx_default_put_blackptcomp(blackptcomp[0], dev, gsDEFAULTPROFILE);
2494
92.6k
    if (code < 0)
2495
0
        return code;
2496
92.6k
    code = gx_default_put_blackpreserve(blackpreserve[0], dev, gsDEFAULTPROFILE);
2497
92.6k
    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
370k
    for (k = 1; k < NUM_DEVICE_PROFILES; k++) {
2502
278k
        if (rend_intent[0] != gsRINOTSPECIFIED &&
2503
278k
            rend_intent[k] == gsRINOTSPECIFIED) {
2504
0
            code = gx_default_put_intent(rend_intent[0], dev, profile_types[k]);
2505
278k
        } else {
2506
278k
            code = gx_default_put_intent(rend_intent[k], dev, profile_types[k]);
2507
278k
        }
2508
278k
        if (code < 0)
2509
0
            return code;
2510
278k
        if (blackptcomp[0] != gsBPNOTSPECIFIED &&
2511
278k
            blackptcomp[k] == gsBPNOTSPECIFIED) {
2512
0
            code = gx_default_put_blackptcomp(blackptcomp[0], dev, profile_types[k]);
2513
278k
        } else {
2514
278k
            code = gx_default_put_blackptcomp(blackptcomp[k], dev, profile_types[k]);
2515
278k
        }
2516
278k
        if (code < 0)
2517
0
            return code;
2518
278k
        if (blackpreserve[0] != gsBKPRESNOTSPECIFIED &&
2519
278k
            blackpreserve[k] == gsBKPRESNOTSPECIFIED) {
2520
0
            code = gx_default_put_blackpreserve(blackpreserve[0], dev, profile_types[k]);
2521
278k
        } else {
2522
278k
            code = gx_default_put_blackpreserve(blackpreserve[k], dev, profile_types[k]);
2523
278k
        }
2524
278k
        if (code < 0)
2525
0
            return code;
2526
278k
    }
2527
92.6k
    gsicc_setcoloraccuracy(dev->memory, color_accuracy);
2528
92.6k
    code = gx_default_put_graytok(devicegraytok, dev);
2529
92.6k
    if (code < 0)
2530
0
        return code;
2531
92.6k
    code = gx_default_put_usefastcolor(usefastcolor, dev);
2532
92.6k
    if (code < 0)
2533
0
        return code;
2534
92.6k
    code = gx_default_put_blacktext(blacktext, dev);
2535
92.6k
    if (code < 0)
2536
0
        return code;
2537
92.6k
    code = gx_default_put_blackvector(blackvector, dev);
2538
92.6k
    if (code < 0)
2539
0
        return code;
2540
92.6k
    code = gx_default_put_blackthresholds(blackthresholdL, blackthresholdC, dev);
2541
92.6k
    if (code < 0)
2542
0
        return code;
2543
92.6k
    code = gx_default_put_overprint_control(overprint_control, dev);
2544
92.6k
    if (code < 0)
2545
0
        return code;
2546
92.6k
    code = gx_default_put_graydetection(graydetection, dev);
2547
92.6k
    if (code < 0)
2548
0
        return code;
2549
92.6k
    return gx_default_put_prebandthreshold(prebandthreshold, dev);
2550
92.6k
}
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
185k
{
2566
185k
        int max_bits = ilog2( max_gray + 1);
2567
2568
185k
        return  (bits > max_bits ? max_bits : bits);
2569
185k
}
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
185k
{
2575
185k
    int code = param_read_int(plist, param_name, pa);
2576
2577
185k
    switch (code) {
2578
14.5k
    case 0:
2579
14.5k
        switch (*pa) {
2580
14.5k
        case 1: case 2: case 4:
2581
14.5k
            return 0;
2582
0
        default:
2583
0
            code = gs_error_rangecheck;
2584
14.5k
        }
2585
        /* fall through */
2586
0
    default:
2587
0
        param_signal_error(plist, param_name, code);
2588
170k
    case 1:
2589
170k
        ;
2590
185k
    }
2591
170k
    return code;
2592
185k
}
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
185k
{
2599
185k
    gs_param_name param_name;
2600
185k
    int ecode = 0;
2601
185k
    int code;
2602
2603
234k
    BEGIN_ARRAY_PARAM(param_read_float_array, pname, *pa, 2, mse) {
2604
48.6k
        float width_new = pa->data[0] * res[0] / 72;
2605
48.6k
        float height_new = pa->data[1] * res[1] / 72;
2606
2607
48.6k
        if (width_new < 0 || height_new < 0)
2608
0
            ecode = gs_note_error(gs_error_rangecheck);
2609
145k
#define max_coord (max_fixed / fixed_1)
2610
48.6k
#if max_coord < max_int
2611
48.6k
        else if (width_new > (long)max_coord || height_new > (long)max_coord)
2612
24
            ecode = gs_note_error(gs_error_limitcheck);
2613
48.5k
#endif
2614
48.5k
#undef max_coord
2615
48.5k
        else
2616
48.5k
            break;
2617
48.6k
    } END_ARRAY_PARAM(*pa, mse);
2618
185k
    return ecode;
2619
185k
}
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
92.7k
{
2627
92.7k
    int code;
2628
92.7k
    bool new_value;
2629
2630
92.7k
    switch (code = param_read_bool(plist, pname, &new_value)) {
2631
7.30k
        case 0:
2632
7.30k
            if (is_defined && new_value == value)
2633
7.29k
                break;
2634
1
            code = gs_note_error(gs_error_rangecheck);
2635
1
            goto e;
2636
0
        default:
2637
0
            if (param_read_null(plist, pname) == 0)
2638
0
                return 1;
2639
1
          e:param_signal_error(plist, pname, code);
2640
85.4k
        case 1:
2641
85.4k
            ;
2642
92.7k
    }
2643
92.7k
    return code;
2644
92.7k
}
2645
static int
2646
param_check_long(gs_param_list * plist, gs_param_name pname, long value,
2647
                 bool is_defined)
2648
649k
{
2649
649k
    int code;
2650
649k
    long new_value;
2651
2652
649k
    switch (code = param_read_long(plist, pname, &new_value)) {
2653
3.06k
        case 0:
2654
3.06k
            if (is_defined && new_value == value)
2655
3.06k
                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
646k
        case 1:
2663
646k
            ;
2664
649k
    }
2665
649k
    return code;
2666
649k
}
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
278k
{
2671
278k
    int code;
2672
278k
    gs_param_string new_value;
2673
2674
278k
    switch (code = param_read_string(plist, pname, &new_value)) {
2675
7.29k
        case 0:
2676
7.29k
            if (is_defined && new_value.size == size &&
2677
7.29k
                !memcmp((const char *)str, (const char *)new_value.data,
2678
7.29k
                        size)
2679
7.29k
                )
2680
7.29k
                break;
2681
0
            code = gs_note_error(gs_error_rangecheck);
2682
0
            goto e;
2683
0
        default:
2684
0
            if (param_read_null(plist, pname) == 0)
2685
0
                return 1;
2686
0
          e:param_signal_error(plist, pname, code);
2687
270k
        case 1:
2688
270k
            ;
2689
278k
    }
2690
278k
    return code;
2691
278k
}