Coverage Report

Created: 2025-06-10 07:26

/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
595k
#define BLACKTHRESHOLDL 90
38
595k
#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
204k
{
55
    /*
56
     * We must be prepared to copy the device if it is the read-only
57
     * prototype.
58
     */
59
204k
    gx_device *dev;
60
204k
    int code = 0;
61
62
204k
    if (orig_dev->memory)
63
204k
        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
204k
    fill_dev_proc(dev, get_params, gx_default_get_params);
70
204k
    fill_dev_proc(dev, get_page_device, gx_default_get_page_device);
71
204k
    fill_dev_proc(dev, get_alpha_bits, gx_default_get_alpha_bits);
72
204k
    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
204k
    } else {
76
204k
        if (dev_proc(dev, get_params) != NULL)
77
204k
            code = (*dev_proc(dev, get_params)) (dev, plist);
78
204k
    }
79
204k
    if (dev != orig_dev)
80
0
        gx_device_retain(dev, false);  /* frees the copy */
81
204k
    return code;
82
204k
}
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
315k
{
128
315k
    gs_param_list * plist = (gs_param_list *)list;
129
315k
    int k, colors = dev->color_info.num_components;
130
315k
    gs_param_string profile_array[NUM_DEVICE_PROFILES];
131
315k
    gs_param_string postren_profile, blend_profile;
132
315k
    gs_param_string proof_profile, link_profile, icc_colorants;
133
315k
    gsicc_rendering_intents_t profile_intents[NUM_DEVICE_PROFILES];
134
315k
    gsicc_blackptcomp_t blackptcomps[NUM_DEVICE_PROFILES];
135
315k
    gsicc_blackpreserve_t blackpreserve[NUM_DEVICE_PROFILES];
136
315k
    int color_accuracy = MAX_COLOR_ACCURACY;
137
315k
    int depth = dev->color_info.depth;
138
315k
    cmm_dev_profile_t *dev_profile;
139
315k
    char null_str[1]={'\0'};
140
315k
#define set_param_array(a, d, s)\
141
315k
  (a.data = d, a.size = s, a.persistent = false);
142
315k
    bool devicegraytok = true;  /* Default if device profile stuct not set */
143
315k
    bool graydetection = false;
144
315k
    bool usefastcolor = false;  /* set for unmanaged color */
145
315k
    bool blacktext = false;
146
315k
    bool blackvector = false;
147
315k
    float blackthresholdL = BLACKTHRESHOLDL;
148
315k
    float blackthresholdC = BLACKTHRESHOLDC;
149
    /* By default overprinting only valid with cmyk devices */
150
315k
    gs_overprint_control_t overprint_control = gs_overprint_control_enable;
151
315k
    bool prebandthreshold = true, temp_bool = false;
152
153
315k
    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
315k
#ifdef PAGESIZE_IS_MEDIASIZE
159
315k
    if (strcmp(Param, "PageSize") == 0) {
160
18.4k
        gs_param_float_array msa;
161
18.4k
        set_param_array(msa, dev->MediaSize, 2);
162
18.4k
        return param_write_float_array(plist, "PageSize", &msa);
163
18.4k
    }
164
296k
#endif
165
296k
    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
296k
    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
296k
    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
296k
    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
296k
    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
296k
    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
296k
    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
296k
    if (strcmp(Param, "Separations") == 0) {
214
0
        bool seprs = false;
215
0
        return param_write_bool(plist, "Separations", &seprs);
216
0
    }
217
296k
    if (strcmp(Param, "UseCIEColor") == 0) {
218
0
        return param_write_bool(plist, "UseCIEColor", &dev->UseCIEColor);
219
0
    }
220
221
    /* Non-standard parameters */
222
296k
    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
296k
    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
296k
    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
296k
    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
296k
    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
296k
    if (strcmp(Param, "BitsPerPixel") == 0) {
251
0
        return param_write_int(plist, "BitsPerPixel", &depth);
252
0
    }
253
296k
    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
296k
    if (strcmp(Param, "PageCount") == 0) {
258
0
        return param_write_long(plist, "PageCount", &dev->PageCount);
259
0
    }
260
296k
    if (strcmp(Param, ".IgnoreNumCopies") == 0) {
261
0
        return param_write_bool(plist, ".IgnoreNumCopies", &dev->IgnoreNumCopies);
262
0
    }
263
296k
    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
296k
    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
296k
    if (strcmp(Param, "AntidropoutDownscaler") == 0) {
272
0
        return param_write_bool(plist, "AntidropoutDownscaler",
273
0
                                &dev->color_info.use_antidropout_downscaler);
274
0
    }
275
296k
    if (strcmp(Param, ".LockSafetyParams") == 0) {
276
0
        return param_write_bool(plist, ".LockSafetyParams", &dev->LockSafetyParams);
277
0
    }
278
296k
    if (strcmp(Param, "MaxPatternBitmap") == 0) {
279
0
        return param_write_size_t(plist, "MaxPatternBitmap", &dev->MaxPatternBitmap);
280
0
    }
281
296k
    if (strcmp(Param, "PageUsesTransparency") == 0) {
282
0
        return param_write_bool(plist, "PageUsesTransparency", &dev->page_uses_transparency);
283
0
    }
284
296k
    if (strcmp(Param, "PageUsesOverprint") == 0) {
285
0
        return param_write_bool(plist, "PageUsesOverprint", &dev->page_uses_overprint);
286
0
    }
287
296k
    if (strcmp(Param, "MaxBitmap") == 0) {
288
0
        return param_write_size_t(plist, "MaxBitmap", &(dev->space_params.MaxBitmap));
289
0
    }
290
296k
    if (strcmp(Param, "BandBufferSpace") == 0) {
291
0
        return param_write_size_t(plist, "BandBufferSpace", &dev->space_params.band.BandBufferSpace);
292
0
    }
293
296k
    if (strcmp(Param, "BandHeight") == 0) {
294
0
        return param_write_int(plist, "BandHeight", &dev->space_params.band.BandHeight);
295
0
    }
296
296k
    if (strcmp(Param, "BandWidth") == 0) {
297
0
        return param_write_int(plist, "BandWidth", &dev->space_params.band.BandWidth);
298
0
    }
299
296k
    if (strcmp(Param, "BufferSpace") == 0) {
300
0
        return param_write_size_t(plist, "BufferSpace", &dev->space_params.BufferSpace);
301
0
    }
302
296k
    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
296k
    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
296k
    if (dev->color_info.num_components > 1) {
315
296k
        int RGBValues = dev->color_info.max_color + 1;
316
296k
        long ColorValues = (depth >= 32 ? -1 : 1L << depth); /* value can only be 32 bits */
317
318
296k
        if (strcmp(Param, "RedValues") == 0) {
319
0
            return param_write_int(plist, "RedValues", &RGBValues);
320
0
        }
321
296k
        if (strcmp(Param, "GreenValues") == 0) {
322
0
            return param_write_int(plist, "GreenValues", &RGBValues);
323
0
        }
324
296k
        if (strcmp(Param, "BlueValues") == 0) {
325
0
            return param_write_int(plist, "BlueValues", &RGBValues);
326
0
        }
327
296k
        if (strcmp(Param, "ColorValues") == 0) {
328
0
            return param_write_long(plist, "ColorValues", &ColorValues);
329
0
        }
330
296k
    }
331
296k
    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
296k
    if (dev_proc(dev, get_profile) != NULL) {
352
296k
        int code;
353
296k
        code = dev_proc(dev, get_profile)(dev,  &dev_profile);
354
296k
        if (code < 0)
355
0
            return code;
356
296k
        if (dev_profile == NULL) {
357
0
            code = gsicc_init_device_profile_struct(dev, NULL, 0);
358
0
            if (code < 0)
359
0
                return code;
360
0
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
361
0
            if (code < 0)
362
0
                return code;
363
0
        }
364
1.48M
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
365
1.18M
            if (dev_profile->device_profile[k] == NULL
366
1.18M
                || dev_profile->device_profile[k]->name == NULL) {
367
890k
                param_string_from_string(profile_array[k], null_str);
368
890k
                profile_intents[k] = gsRINOTSPECIFIED;
369
890k
                blackptcomps[k] = gsBPNOTSPECIFIED;
370
890k
                blackpreserve[k] = gsBKPRESNOTSPECIFIED;
371
890k
            } else {
372
296k
                param_string_from_transient_string(profile_array[k],
373
296k
                    dev_profile->device_profile[k]->name);
374
296k
                profile_intents[k] = dev_profile->rendercond[k].rendering_intent;
375
296k
                blackptcomps[k] = dev_profile->rendercond[k].black_point_comp;
376
296k
                blackpreserve[k] = dev_profile->rendercond[k].preserve_black;
377
296k
            }
378
1.18M
        }
379
296k
        if (dev_profile->blend_profile == NULL) {
380
296k
            param_string_from_string(blend_profile, null_str);
381
296k
        } else {
382
0
            param_string_from_transient_string(blend_profile,
383
0
                dev_profile->blend_profile->name);
384
0
        }
385
296k
        if (dev_profile->postren_profile == NULL) {
386
296k
            param_string_from_string(postren_profile, null_str);
387
296k
        } else {
388
0
            param_string_from_transient_string(postren_profile,
389
0
                dev_profile->postren_profile->name);
390
0
        }
391
296k
        if (dev_profile->proof_profile == NULL) {
392
296k
            param_string_from_string(proof_profile, null_str);
393
296k
        } else {
394
0
            param_string_from_transient_string(proof_profile,
395
0
                                     dev_profile->proof_profile->name);
396
0
        }
397
296k
        if (dev_profile->link_profile == NULL) {
398
296k
            param_string_from_string(link_profile, null_str);
399
296k
        } else {
400
0
            param_string_from_transient_string(link_profile,
401
0
                                     dev_profile->link_profile->name);
402
0
        }
403
296k
        devicegraytok = dev_profile->devicegraytok;
404
296k
        graydetection = dev_profile->graydetection;
405
296k
        usefastcolor = dev_profile->usefastcolor;
406
296k
        blacktext = dev_profile->blacktext;
407
296k
        blackvector = dev_profile->blackvector;
408
296k
        blackthresholdC = dev_profile->blackthresholdC;
409
296k
        blackthresholdL = dev_profile->blackthresholdL;
410
296k
        overprint_control = dev_profile->overprint_control;
411
296k
        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
296k
        if (dev_profile->spotnames == NULL) {
416
296k
            param_string_from_string(icc_colorants, null_str);
417
296k
        } 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
296k
    } 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
296k
    if (strcmp(Param, "DeviceGrayToK") == 0) {
444
0
        return param_write_bool(plist, "DeviceGrayToK", &devicegraytok);
445
0
    }
446
296k
    if (strcmp(Param, "GrayDetection") == 0) {
447
0
        return param_write_bool(plist, "GrayDetection", &graydetection);
448
0
    }
449
296k
    if (strcmp(Param, "UseFastColor") == 0) {
450
0
        return param_write_bool(plist, "UseFastColor", &usefastcolor);
451
0
    }
452
296k
    if (strcmp(Param, "BlackText") == 0) {
453
0
        return param_write_bool(plist, "BlackText", &blacktext);
454
0
    }
455
296k
    if (strcmp(Param, "BlackVector") == 0) {
456
0
        return param_write_bool(plist, "BlackVector", &blackvector);
457
0
    }
458
296k
    if (strcmp(Param, "BlackThresholdL") == 0) {
459
0
        return param_write_float(plist, "BlackThresholdL", &blackthresholdL);
460
0
    }
461
296k
    if (strcmp(Param, "BlackThresholdC") == 0) {
462
0
        return param_write_float(plist, "BlackThresholdC", &blackthresholdC);
463
0
    }
464
296k
    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
296k
    if (strcmp(Param, "PreBandThreshold") == 0) {
472
0
        return param_write_bool(plist, "PreBandThreshold", &prebandthreshold);
473
0
    }
474
296k
    if (strcmp(Param, "PostRenderProfile") == 0) {
475
0
        return param_write_string(plist, "PostRenderProfile", &(postren_profile));
476
0
    }
477
296k
    if (strcmp(Param, "BlendColorProfile") == 0) {
478
0
        return param_write_string(plist, "BlendColorProfile", &(blend_profile));
479
0
    }
480
296k
    if (strcmp(Param, "ProofProfile") == 0) {
481
0
        return param_write_string(plist,"ProofProfile", &(proof_profile));
482
0
    }
483
296k
    if (strcmp(Param, "DeviceLinkProfile") == 0) {
484
0
        return param_write_string(plist,"DeviceLinkProfile", &(link_profile));
485
0
    }
486
296k
    if (strcmp(Param, "ICCOutputColors") == 0) {
487
0
        return param_write_string(plist,"ICCOutputColors", &(icc_colorants));
488
0
    }
489
296k
    if (strcmp(Param, "OutputICCProfile") == 0) {
490
0
        return param_write_string(plist,"OutputICCProfile", &(profile_array[0]));
491
0
    }
492
296k
    if (strcmp(Param, "VectorICCProfile") == 0) {
493
0
        return param_write_string(plist,"VectorICCProfile", &(profile_array[1]));
494
0
    }
495
296k
    if (strcmp(Param, "ImageICCProfile") == 0) {
496
0
        return param_write_string(plist,"ImageICCProfile", &(profile_array[2]));
497
0
    }
498
296k
    if (strcmp(Param, "TextICCProfile") == 0) {
499
0
        return param_write_string(plist,"TextICCProfile", &(profile_array[3]));
500
0
    }
501
296k
    if (strcmp(Param, "ColorAccuracy") == 0) {
502
0
        return param_write_int(plist, "ColorAccuracy", (const int *)(&(color_accuracy)));
503
0
    }
504
296k
    if (strcmp(Param, "RenderIntent") == 0) {
505
0
        return param_write_int(plist,"RenderIntent", (const int *) (&(profile_intents[0])));
506
0
    }
507
296k
    if (strcmp(Param, "VectorIntent") == 0) {
508
0
        return param_write_int(plist,"VectorIntent", (const int *) &(profile_intents[1]));
509
0
    }
510
296k
    if (strcmp(Param, "ImageIntent") == 0) {
511
0
        return param_write_int(plist,"ImageIntent", (const int *) &(profile_intents[2]));
512
0
    }
513
296k
    if (strcmp(Param, "TextIntent") == 0) {
514
0
        return param_write_int(plist,"TextIntent", (const int *) &(profile_intents[3]));
515
0
    }
516
296k
    if (strcmp(Param, "BlackPtComp") == 0) {
517
0
        return param_write_int(plist,"BlackPtComp", (const int *) (&(blackptcomps[0])));
518
0
    }
519
296k
    if (strcmp(Param, "VectorBlackPt") == 0) {
520
0
        return param_write_int(plist,"VectorBlackPt", (const int *) &(blackptcomps[1]));
521
0
    }
522
296k
    if (strcmp(Param, "ImageBlackPt") == 0) {
523
0
        return param_write_int(plist,"ImageBlackPt", (const int *) &(blackptcomps[2]));
524
0
    }
525
296k
    if (strcmp(Param, "TextBlackPt") == 0) {
526
0
        return param_write_int(plist,"TextBlackPt", (const int *) &(blackptcomps[3]));
527
0
    }
528
296k
    if (strcmp(Param, "KPreserve") == 0) {
529
0
        return param_write_int(plist,"KPreserve", (const int *) (&(blackpreserve[0])));
530
0
    }
531
296k
    if (strcmp(Param, "VectorKPreserve") == 0) {
532
0
        return param_write_int(plist,"VectorKPreserve", (const int *) &(blackpreserve[1]));
533
0
    }
534
296k
    if (strcmp(Param, "ImageKPreserve") == 0) {
535
0
        return param_write_int(plist,"ImageKPreserve", (const int *) &(blackpreserve[2]));
536
0
    }
537
296k
    if (strcmp(Param, "TextKPreserve") == 0) {
538
0
        return param_write_int(plist,"TextKPreserve", (const int *) &(blackpreserve[3]));
539
0
    }
540
296k
    if (strcmp(Param, "FirstPage") == 0) {
541
0
        return param_write_int(plist, "FirstPage", &dev->FirstPage);
542
0
    }
543
296k
    if (strcmp(Param, "LastPage") == 0) {
544
0
        return param_write_int(plist, "LastPage", &dev->LastPage);
545
0
    }
546
296k
    if (strcmp(Param, "DisablePageHandler") == 0) {
547
0
        temp_bool = dev->DisablePageHandler;
548
0
        return param_write_bool(plist, "DisablePageHandler", &temp_bool);
549
0
    }
550
296k
    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
296k
    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
296k
    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
296k
    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
296k
    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
296k
    return_error(gs_error_undefined);
585
296k
}
586
587
/* Get standard parameters. */
588
int
589
gx_default_get_params(gx_device * dev, gs_param_list * plist)
590
204k
{
591
204k
    int code;
592
593
    /* Standard page device parameters: */
594
595
204k
    bool seprs = false;
596
204k
    gs_param_string dns, pcms, profile_array[NUM_DEVICE_PROFILES];
597
204k
    gs_param_string blend_profile, postren_profile, pagelist, nuplist;
598
204k
    gs_param_string proof_profile, link_profile, icc_colorants;
599
204k
    gsicc_rendering_intents_t profile_intents[NUM_DEVICE_PROFILES];
600
204k
    gsicc_blackptcomp_t blackptcomps[NUM_DEVICE_PROFILES];
601
204k
    gsicc_blackpreserve_t blackpreserve[NUM_DEVICE_PROFILES];
602
204k
    bool devicegraytok = true;  /* Default if device profile stuct not set */
603
204k
    bool graydetection = false;
604
204k
    bool usefastcolor = false;  /* set for unmanaged color */
605
204k
    bool blacktext = false;
606
204k
    bool blackvector = false;
607
204k
    float blackthresholdL = BLACKTHRESHOLDL;
608
204k
    float blackthresholdC = BLACKTHRESHOLDC;
609
    /* By default, only overprint if the device supports it */
610
204k
    gs_overprint_control_t overprint_control = gs_overprint_control_enable;
611
204k
    bool prebandthreshold = true, temp_bool;
612
204k
    int k;
613
204k
    int color_accuracy = MAX_COLOR_ACCURACY;
614
204k
    gs_param_float_array msa, ibba, hwra, ma;
615
204k
    gs_param_string_array scna;
616
204k
    char null_str[1]={'\0'};
617
618
204k
#define set_param_array(a, d, s)\
619
1.43M
  (a.data = d, a.size = s, a.persistent = false);
620
621
    /* Non-standard parameters: */
622
204k
    int colors = dev->color_info.num_components;
623
204k
    int mns = dev->color_info.max_components;
624
204k
    int depth = dev->color_info.depth;
625
204k
    int GrayValues = dev->color_info.max_gray + 1;
626
204k
    int HWSize[2];
627
204k
    gs_param_int_array hwsa;
628
204k
    gs_param_float_array hwma;
629
204k
    cmm_dev_profile_t *dev_profile;
630
204k
    char *colorant_names = NULL;
631
632
    /* Fill in page device parameters. */
633
634
204k
    param_string_from_string(dns, dev->dname);
635
204k
    {
636
204k
        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
204k
        if ((cms != NULL) && (*cms != '\0'))
641
204k
            param_string_from_string(pcms, cms);
642
0
        else
643
0
            pcms.data = 0;
644
204k
    }
645
646
204k
    set_param_array(hwra, dev->HWResolution, 2);
647
204k
    set_param_array(msa, dev->MediaSize, 2);
648
204k
    set_param_array(ibba, dev->ImagingBBox, 4);
649
204k
    set_param_array(ma, dev->Margins, 2);
650
204k
    set_param_array(scna, NULL, 0);
651
652
    /* Fill in non-standard parameters. */
653
204k
    HWSize[0] = dev->width;
654
204k
    HWSize[1] = dev->height;
655
204k
    set_param_array(hwsa, HWSize, 2);
656
204k
    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
204k
    if (dev_proc(dev, get_profile) != NULL) {
665
185k
        code = dev_proc(dev, get_profile)(dev,  &dev_profile);
666
185k
        if (code < 0)
667
0
            return code;
668
669
185k
        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
929k
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
682
743k
            if (dev_profile->device_profile[k] == NULL
683
743k
                || dev_profile->device_profile[k]->name == NULL) {
684
557k
                param_string_from_string(profile_array[k], null_str);
685
557k
                profile_intents[k] = gsRINOTSPECIFIED;
686
557k
                blackptcomps[k] = gsBPNOTSPECIFIED;
687
557k
                blackpreserve[k] = gsBKPRESNOTSPECIFIED;
688
557k
            } else {
689
185k
                param_string_from_transient_string(profile_array[k],
690
185k
                    dev_profile->device_profile[k]->name);
691
185k
                profile_intents[k] = dev_profile->rendercond[k].rendering_intent;
692
185k
                blackptcomps[k] = dev_profile->rendercond[k].black_point_comp;
693
185k
                blackpreserve[k] = dev_profile->rendercond[k].preserve_black;
694
185k
            }
695
743k
        }
696
        /* The proof, link and post render profile */
697
185k
        if (dev_profile->proof_profile == NULL) {
698
185k
            param_string_from_string(proof_profile, null_str);
699
185k
        } else {
700
0
            param_string_from_transient_string(proof_profile,
701
0
                                     dev_profile->proof_profile->name);
702
0
        }
703
185k
        if (dev_profile->link_profile == NULL) {
704
185k
            param_string_from_string(link_profile, null_str);
705
185k
        } else {
706
0
            param_string_from_transient_string(link_profile,
707
0
                                     dev_profile->link_profile->name);
708
0
        }
709
185k
        if (dev_profile->postren_profile == NULL) {
710
185k
            param_string_from_string(postren_profile, null_str);
711
185k
        } else {
712
0
            param_string_from_transient_string(postren_profile,
713
0
                dev_profile->postren_profile->name);
714
0
        }
715
185k
        if (dev_profile->blend_profile == NULL) {
716
185k
            param_string_from_string(blend_profile, null_str);
717
185k
        } else {
718
0
            param_string_from_transient_string(blend_profile,
719
0
                dev_profile->blend_profile->name);
720
0
        }
721
185k
        devicegraytok = dev_profile->devicegraytok;
722
185k
        graydetection = dev_profile->graydetection;
723
185k
        usefastcolor = dev_profile->usefastcolor;
724
185k
        blacktext = dev_profile->blacktext;
725
185k
        blackvector = dev_profile->blackvector;
726
185k
        blackthresholdC = dev_profile->blackthresholdC;
727
185k
        blackthresholdL = dev_profile->blackthresholdL;
728
185k
        overprint_control = dev_profile->overprint_control;
729
185k
        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
185k
        if (dev_profile->spotnames == NULL) {
734
185k
            param_string_from_string(icc_colorants, null_str);
735
185k
        } 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
185k
    } else {
746
92.2k
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
747
73.7k
            param_string_from_string(profile_array[k], null_str);
748
73.7k
            profile_intents[k] = gsRINOTSPECIFIED;
749
73.7k
            blackptcomps[k] = gsBPNOTSPECIFIED;
750
73.7k
            blackpreserve[k] = gsBKPRESNOTSPECIFIED;
751
73.7k
        }
752
18.4k
        param_string_from_string(proof_profile, null_str);
753
18.4k
        param_string_from_string(link_profile, null_str);
754
18.4k
        param_string_from_string(icc_colorants, null_str);
755
18.4k
        param_string_from_string(postren_profile, null_str);
756
18.4k
        param_string_from_string(blend_profile, null_str);
757
18.4k
    }
758
    /* Transmit the values. */
759
    /* Standard parameters */
760
204k
    if (
761
204k
        (code = param_write_name(plist, "OutputDevice", &dns)) < 0 ||
762
204k
#ifdef PAGESIZE_IS_MEDIASIZE
763
204k
        (code = param_write_float_array(plist, "PageSize", &msa)) < 0 ||
764
204k
#endif
765
204k
        (code = (pcms.data == 0 ? 0 :
766
204k
                 param_write_name(plist, "ProcessColorModel", &pcms))) < 0 ||
767
204k
        (code = param_write_float_array(plist, "HWResolution", &hwra)) < 0 ||
768
204k
        (code = (dev->ImagingBBox_set ?
769
0
                 param_write_float_array(plist, "ImagingBBox", &ibba) :
770
204k
                 param_write_null(plist, "ImagingBBox"))) < 0 ||
771
204k
        (code = param_write_float_array(plist, "Margins", &ma)) < 0 ||
772
204k
        (code = param_write_int(plist, "MaxSeparations", &mns)) < 0 ||
773
204k
        (code = (dev->NumCopies_set < 0 ||
774
204k
                 (*dev_proc(dev, get_page_device))(dev) == 0 ? 0:
775
204k
                 dev->NumCopies_set ?
776
0
                 param_write_int(plist, "NumCopies", &dev->NumCopies) :
777
204k
                 param_write_null(plist, "NumCopies"))) < 0 ||
778
204k
        (code = param_write_name_array(plist, "SeparationColorNames", &scna)) < 0 ||
779
204k
        (code = param_write_bool(plist, "Separations", &seprs)) < 0 ||
780
204k
        (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
204k
        (code = param_write_bool(plist, "DeviceGrayToK", &devicegraytok)) < 0 ||
785
204k
        (code = param_write_bool(plist, "GrayDetection", &graydetection)) < 0 ||
786
204k
        (code = param_write_bool(plist, "UseFastColor", &usefastcolor)) < 0 ||
787
204k
        (code = param_write_bool(plist, "BlackText", &blacktext)) < 0 ||
788
204k
        (code = param_write_bool(plist, "BlackVector", &blackvector)) < 0 ||
789
204k
        (code = param_write_float(plist, "BlackThresholdL", &blackthresholdL)) < 0 ||
790
204k
        (code = param_write_float(plist, "BlackThresholdC", &blackthresholdC)) < 0 ||
791
204k
        (code = param_write_bool(plist, "PreBandThreshold", &prebandthreshold)) < 0 ||
792
204k
        (code = param_write_string(plist,"OutputICCProfile", &(profile_array[0]))) < 0 ||
793
204k
        (code = param_write_string(plist,"VectorICCProfile", &(profile_array[1]))) < 0 ||
794
204k
        (code = param_write_string(plist,"ImageICCProfile", &(profile_array[2]))) < 0 ||
795
204k
        (code = param_write_string(plist,"TextICCProfile", &(profile_array[3]))) < 0 ||
796
204k
        (code = param_write_string(plist,"ProofProfile", &(proof_profile))) < 0 ||
797
204k
        (code = param_write_string(plist, "PostRenderProfile", &(postren_profile))) < 0 ||
798
204k
        (code = param_write_string(plist, "BlendColorProfile", &(blend_profile))) < 0 ||
799
204k
        (code = param_write_string(plist,"DeviceLinkProfile", &(link_profile))) < 0 ||
800
204k
        (code = param_write_string(plist,"ICCOutputColors", &(icc_colorants))) < 0 ||
801
204k
        (code = param_write_int(plist, "RenderIntent", (const int *)(&(profile_intents[0])))) < 0 ||
802
204k
        (code = param_write_int(plist, "ColorAccuracy", (const int *)(&(color_accuracy)))) < 0 ||
803
204k
        (code = param_write_int(plist,"VectorIntent", (const int *) &(profile_intents[1]))) < 0 ||
804
204k
        (code = param_write_int(plist,"ImageIntent", (const int *) &(profile_intents[2]))) < 0 ||
805
204k
        (code = param_write_int(plist,"TextIntent", (const int *) &(profile_intents[3]))) < 0 ||
806
204k
        (code = param_write_int(plist,"BlackPtComp", (const int *) (&(blackptcomps[0])))) < 0 ||
807
204k
        (code = param_write_int(plist,"VectorBlackPt", (const int *) &(blackptcomps[1]))) < 0 ||
808
204k
        (code = param_write_int(plist,"ImageBlackPt", (const int *) &(blackptcomps[2]))) < 0 ||
809
204k
        (code = param_write_int(plist,"TextBlackPt", (const int *) &(blackptcomps[3]))) < 0 ||
810
204k
        (code = param_write_int(plist,"KPreserve", (const int *) (&(blackpreserve[0])))) < 0 ||
811
204k
        (code = param_write_int(plist,"VectorKPreserve", (const int *) &(blackpreserve[1]))) < 0 ||
812
204k
        (code = param_write_int(plist,"ImageKPreserve", (const int *) &(blackpreserve[2]))) < 0 ||
813
204k
        (code = param_write_int(plist,"TextKPreserve", (const int *) &(blackpreserve[3]))) < 0 ||
814
204k
        (code = param_write_int_array(plist, "HWSize", &hwsa)) < 0 ||
815
204k
        (code = param_write_float_array(plist, ".HWMargins", &hwma)) < 0 ||
816
204k
        (code = param_write_float_array(plist, ".MediaSize", &msa)) < 0 ||
817
204k
        (code = param_write_string(plist, "Name", &dns)) < 0 ||
818
204k
        (code = param_write_int(plist, "Colors", &colors)) < 0 ||
819
204k
        (code = param_write_int(plist, "BitsPerPixel", &depth)) < 0 ||
820
204k
        (code = param_write_int(plist, "GrayValues", &GrayValues)) < 0 ||
821
204k
        (code = param_write_long(plist, "PageCount", &dev->PageCount)) < 0 ||
822
204k
        (code = param_write_bool(plist, ".IgnoreNumCopies", &dev->IgnoreNumCopies)) < 0 ||
823
204k
        (code = param_write_int(plist, "TextAlphaBits",
824
204k
                                &dev->color_info.anti_alias.text_bits)) < 0 ||
825
204k
        (code = param_write_int(plist, "GraphicsAlphaBits",
826
204k
                                &dev->color_info.anti_alias.graphics_bits)) < 0 ||
827
204k
        (code = param_write_bool(plist, "AntidropoutDownscaler",
828
204k
                                &dev->color_info.use_antidropout_downscaler)) < 0 ||
829
204k
        (code = param_write_bool(plist, ".LockSafetyParams", &dev->LockSafetyParams)) < 0 ||
830
204k
        (code = param_write_size_t(plist, "MaxPatternBitmap", &dev->MaxPatternBitmap)) < 0 ||
831
204k
        (code = param_write_bool(plist, "PageUsesTransparency", &dev->page_uses_transparency)) < 0 ||
832
204k
        (code = param_write_bool(plist, "PageUsesOverprint", &dev->page_uses_overprint)) < 0 ||
833
204k
        (code = param_write_size_t(plist, "MaxBitmap", &(dev->space_params.MaxBitmap))) < 0 ||
834
204k
        (code = param_write_size_t(plist, "BandBufferSpace", &dev->space_params.band.BandBufferSpace)) < 0 ||
835
204k
        (code = param_write_int(plist, "BandHeight", &dev->space_params.band.BandHeight)) < 0 ||
836
204k
        (code = param_write_int(plist, "BandWidth", &dev->space_params.band.BandWidth)) < 0 ||
837
204k
        (code = param_write_size_t(plist, "BufferSpace", &dev->space_params.BufferSpace)) < 0 ||
838
204k
        (code = param_write_int(plist, "InterpolateControl", &dev->interpolate_control)) < 0
839
204k
        )
840
0
    {
841
0
        gs_free_object(dev->memory, colorant_names, "gx_default_get_param");
842
0
        return code;
843
0
    }
844
204k
    gs_free_object(dev->memory, colorant_names, "gx_default_get_param");
845
204k
    {
846
204k
        gs_param_string opc_name;
847
204k
        const char *s = overprint_control_names[(int)overprint_control];
848
849
204k
        param_string_from_string(opc_name, s);
850
204k
        param_write_name(plist, "Overprint", &opc_name);
851
204k
    }
852
    /* If LeadingEdge was set explicitly, report it here. */
853
204k
    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
204k
        code = param_write_null(plist, "LeadingEdge");
858
204k
    if (code < 0)
859
0
        return code;
860
861
204k
    if ((code = param_write_int(plist, "FirstPage", &dev->FirstPage)) < 0)
862
0
        return code;
863
204k
    if ((code = param_write_int(plist, "LastPage", &dev->LastPage)) < 0)
864
0
        return code;
865
866
204k
    temp_bool = dev->DisablePageHandler;
867
204k
    if ((code = param_write_bool(plist, "DisablePageHandler", &temp_bool)) < 0)
868
0
        return code;
869
870
204k
    if (dev->NupControl) {
871
0
        gdev_nupcontrol *p = (gdev_nupcontrol *)dev->NupControl;
872
0
        param_string_from_string(nuplist, p->nupcontrol_str);
873
204k
    } else {
874
204k
        param_string_from_string(nuplist, null_str);
875
204k
    }
876
204k
    if ((code = param_write_string(plist, "NupControl", &nuplist)) < 0)
877
0
        return code;
878
879
204k
    if (dev->PageList) {
880
0
        gdev_pagelist *p = (gdev_pagelist *)dev->PageList;
881
0
        param_string_from_transient_string(pagelist, p->Pages);
882
204k
    } else {
883
204k
        param_string_from_string(pagelist, null_str);
884
204k
    }
885
204k
    if ((code = param_write_string(plist, "PageList", &pagelist)) < 0)
886
0
        return code;
887
888
204k
    temp_bool = dev->ObjectFilter & FILTERIMAGE;
889
204k
    if ((code = param_write_bool(plist, "FILTERIMAGE", &temp_bool)) < 0)
890
0
        return code;
891
204k
    temp_bool = dev->ObjectFilter & FILTERTEXT;
892
204k
    if ((code = param_write_bool(plist, "FILTERTEXT", &temp_bool)) < 0)
893
0
        return code;
894
204k
    temp_bool = dev->ObjectFilter & FILTERVECTOR;
895
204k
    if ((code = param_write_bool(plist, "FILTERVECTOR", &temp_bool)) < 0)
896
0
        return code;
897
898
    /* Fill in color information. */
899
900
204k
    if (colors > 1) {
901
185k
        int RGBValues = dev->color_info.max_color + 1;
902
185k
        long ColorValues = (depth >= 32 ? -1 : 1L << depth); /* value can only be 32 bits */
903
904
185k
        if ((code = param_write_int(plist, "RedValues", &RGBValues)) < 0 ||
905
185k
            (code = param_write_int(plist, "GreenValues", &RGBValues)) < 0 ||
906
185k
            (code = param_write_int(plist, "BlueValues", &RGBValues)) < 0 ||
907
185k
            (code = param_write_long(plist, "ColorValues", &ColorValues)) < 0
908
185k
            )
909
0
            return code;
910
185k
    }
911
204k
    if (param_requested(plist, "HWColorMap")) {
912
27.6k
        byte palette[3 << 8];
913
914
27.6k
        if (param_HWColorMap(dev, palette)) {
915
27.6k
            gs_param_string hwcms;
916
917
27.6k
            hwcms.data = palette, hwcms.size = colors << depth,
918
27.6k
                hwcms.persistent = false;
919
27.6k
            if ((code = param_write_string(plist, "HWColorMap", &hwcms)) < 0)
920
0
                return code;
921
27.6k
        }
922
27.6k
    }
923
924
204k
    return 0;
925
204k
}
926
927
/* Get the color map for a device.  Return true if there is one. */
928
static bool
929
param_HWColorMap(gx_device * dev, byte * palette /* 3 << 8 */ )
930
27.6k
{
931
27.6k
    int depth = dev->color_info.depth;
932
27.6k
    int colors = dev->color_info.num_components;
933
934
27.6k
    if (depth <= 8 && colors <= 3) {
935
27.6k
        byte *p = palette;
936
27.6k
        gx_color_value rgb[3];
937
27.6k
        gx_color_index i;
938
939
27.6k
        fill_dev_proc(dev, map_color_rgb, gx_default_map_color_rgb);
940
341k
        for (i = 0; (i >> depth) == 0; i++) {
941
313k
            int j;
942
943
313k
            if ((*dev_proc(dev, map_color_rgb)) (dev, i, rgb) < 0)
944
0
                return false;
945
1.21M
            for (j = 0; j < colors; j++)
946
903k
                *p++ = gx_color_value_to_byte(rgb[j]);
947
313k
        }
948
27.6k
        return true;
949
27.6k
    }
950
0
    return false;
951
27.6k
}
952
953
/* Get hardware-detected parameters. Default action is no hardware params. */
954
int
955
gx_default_get_hardware_params(gx_device * dev, gs_param_list * plist)
956
0
{
957
0
    return 0;
958
0
}
959
960
/* ---------------- Input and output media ---------------- */
961
962
/* Finish defining input or output media. */
963
static int
964
finish_media(gs_param_list * mlist, gs_param_name key, const char *media_type)
965
0
{
966
0
    int code = 0;
967
968
0
    if (media_type != 0) {
969
0
        gs_param_string as;
970
971
0
        param_string_from_string(as, media_type);
972
0
        code = param_write_string(mlist, key, &as);
973
0
    }
974
0
    return code;
975
0
}
976
977
/* Define input media. */
978
979
const gdev_input_media_t gdev_input_media_default =
980
{
981
    gdev_input_media_default_values
982
};
983
984
int
985
gdev_begin_input_media(gs_param_list * mlist, gs_param_dict * pdict,
986
                       int count)
987
0
{
988
0
    pdict->size = count;
989
0
    return param_begin_write_dict(mlist, "InputAttributes", pdict, true);
990
0
}
991
992
int
993
gdev_write_input_media(int index, gs_param_dict * pdict,
994
                       const gdev_input_media_t * pim)
995
0
{
996
0
    char key[25];
997
0
    gs_param_dict mdict;
998
0
    int code;
999
0
    gs_param_string as;
1000
1001
0
    gs_snprintf(key, sizeof(key), "%d", index);
1002
0
    mdict.size = 4;
1003
0
    code = param_begin_write_dict(pdict->list, key, &mdict, false);
1004
0
    if (code < 0)
1005
0
        return code;
1006
0
    if ((pim->PageSize[0] != 0 && pim->PageSize[1] != 0) ||
1007
0
        (pim->PageSize[2] != 0 && pim->PageSize[3] != 0)
1008
0
        ) {
1009
0
        gs_param_float_array psa;
1010
1011
0
        psa.data = pim->PageSize;
1012
0
        psa.size =
1013
0
            (pim->PageSize[0] == pim->PageSize[2] &&
1014
0
             pim->PageSize[1] == pim->PageSize[3] ? 2 : 4);
1015
0
        psa.persistent = false;
1016
0
        code = param_write_float_array(mdict.list, "PageSize",
1017
0
                                       &psa);
1018
0
        if (code < 0)
1019
0
            return code;
1020
0
    }
1021
0
    if (pim->MediaColor != 0) {
1022
0
        param_string_from_string(as, pim->MediaColor);
1023
0
        code = param_write_string(mdict.list, "MediaColor",
1024
0
                                  &as);
1025
0
        if (code < 0)
1026
0
            return code;
1027
0
    }
1028
0
    if (pim->MediaWeight != 0) {
1029
        /*
1030
         * We do the following silly thing in order to avoid
1031
         * having to work around the 'const' in the arg list.
1032
         */
1033
0
        float weight = pim->MediaWeight;
1034
1035
0
        code = param_write_float(mdict.list, "MediaWeight",
1036
0
                                 &weight);
1037
0
        if (code < 0)
1038
0
            return code;
1039
0
    }
1040
0
    code = finish_media(mdict.list, "MediaType", pim->MediaType);
1041
0
    if (code < 0)
1042
0
        return code;
1043
0
    return param_end_write_dict(pdict->list, key, &mdict);
1044
0
}
1045
1046
int
1047
gdev_write_input_page_size(int index, gs_param_dict * pdict,
1048
                           double width_points, double height_points)
1049
0
{
1050
0
    gdev_input_media_t media;
1051
1052
0
    media.PageSize[0] = media.PageSize[2] = (float) width_points;
1053
0
    media.PageSize[1] = media.PageSize[3] = (float) height_points;
1054
0
    media.MediaColor = 0;
1055
0
    media.MediaWeight = 0;
1056
0
    media.MediaType = 0;
1057
0
    return gdev_write_input_media(index, pdict, &media);
1058
0
}
1059
1060
int
1061
gdev_end_input_media(gs_param_list * mlist, gs_param_dict * pdict)
1062
0
{
1063
0
    return param_end_write_dict(mlist, "InputAttributes", pdict);
1064
0
}
1065
1066
/* Define output media. */
1067
1068
const gdev_output_media_t gdev_output_media_default =
1069
{
1070
    gdev_output_media_default_values
1071
};
1072
1073
int
1074
gdev_begin_output_media(gs_param_list * mlist, gs_param_dict * pdict,
1075
                        int count)
1076
0
{
1077
0
    pdict->size = count;
1078
0
    return param_begin_write_dict(mlist, "OutputAttributes", pdict, true);
1079
0
}
1080
1081
int
1082
gdev_write_output_media(int index, gs_param_dict * pdict,
1083
                        const gdev_output_media_t * pom)
1084
0
{
1085
0
    char key[25];
1086
0
    gs_param_dict mdict;
1087
0
    int code;
1088
1089
0
    gs_snprintf(key, sizeof(key), "%d", index);
1090
0
    mdict.size = 4;
1091
0
    code = param_begin_write_dict(pdict->list, key, &mdict, false);
1092
0
    if (code < 0)
1093
0
        return code;
1094
0
    code = finish_media(mdict.list, "OutputType", pom->OutputType);
1095
0
    if (code < 0)
1096
0
        return code;
1097
0
    return param_end_write_dict(pdict->list, key, &mdict);
1098
0
}
1099
1100
int
1101
gdev_end_output_media(gs_param_list * mlist, gs_param_dict * pdict)
1102
0
{
1103
0
    return param_end_write_dict(mlist, "OutputAttributes", pdict);
1104
0
}
1105
1106
/* ================ Putting parameters ================ */
1107
1108
/* Forward references */
1109
static int param_normalize_anti_alias_bits( uint max_gray, int bits );
1110
static int param_anti_alias_bits(gs_param_list *, gs_param_name, int *);
1111
static int param_MediaSize(gs_param_list *, gs_param_name,
1112
                            const float *, gs_param_float_array *);
1113
1114
static int param_check_bool(gs_param_list *, gs_param_name, bool, bool);
1115
static int param_check_long(gs_param_list *, gs_param_name, long, bool);
1116
#define param_check_int(plist, pname, ival, is_defined)\
1117
456k
  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
228k
  param_check_bytes(plist, pname, (const byte *)(str), \
1122
228k
                    (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
76.0k
{
1130
76.0k
    bool was_open = dev->is_open;
1131
76.0k
    int code;
1132
1133
    /* gs_param_list_dump(plist); */
1134
1135
76.0k
    fill_dev_proc(dev, put_params, gx_default_put_params);
1136
76.0k
    fill_dev_proc(dev, get_alpha_bits, gx_default_get_alpha_bits);
1137
76.0k
    code = (*dev_proc(dev, put_params)) (dev, plist);
1138
76.0k
    return (code < 0 ? code : was_open && !dev->is_open ? 1 : code);
1139
76.0k
}
1140
1141
static int
1142
gx_default_put_graydetection(bool graydetection, gx_device * dev)
1143
75.9k
{
1144
75.9k
    int code = 0;
1145
75.9k
    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
75.9k
    if (dev_proc(dev, get_profile) == NULL) {
1152
        /* This is an odd case where the device has not yet fully been
1153
           set up with its procedures yet.  We want to make sure that
1154
           we catch this so we assume here that we are dealing with
1155
           the target device.  For now allocate the profile structure
1156
           but do not intialize the profile yet as the color info
1157
           may not be fully set up at this time.  */
1158
36.8k
        if (dev->icc_struct == NULL) {
1159
            /* Allocate at this time the structure */
1160
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1161
0
            if (dev->icc_struct == NULL)
1162
0
                return_error(gs_error_VMerror);
1163
0
        }
1164
36.8k
        dev->icc_struct->graydetection = graydetection;
1165
36.8k
        dev->icc_struct->pageneutralcolor = graydetection;
1166
39.0k
    } else {
1167
39.0k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1168
39.0k
        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
39.0k
        profile_struct->graydetection = graydetection;
1176
39.0k
        profile_struct->pageneutralcolor = graydetection;
1177
39.0k
    }
1178
75.9k
    return code;
1179
75.9k
}
1180
1181
static int
1182
gx_default_put_graytok(bool graytok, gx_device * dev)
1183
75.9k
{
1184
75.9k
    int code = 0;
1185
75.9k
    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
75.9k
    if (dev_proc(dev, get_profile) == NULL) {
1192
        /* This is an odd case where the device has not yet fully been
1193
           set up with its procedures yet.  We want to make sure that
1194
           we catch this so we assume here that we are dealing with
1195
           the target device.  For now allocate the profile structure
1196
           but do not intialize the profile yet as the color info
1197
           may not be fully set up at this time.  */
1198
36.8k
        if (dev->icc_struct == NULL) {
1199
            /* Allocate at this time the structure */
1200
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1201
0
            if (dev->icc_struct == NULL)
1202
0
                return_error(gs_error_VMerror);
1203
0
        }
1204
36.8k
        dev->icc_struct->devicegraytok = graytok;
1205
39.0k
    } else {
1206
39.0k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1207
39.0k
        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
39.0k
        profile_struct->devicegraytok = graytok;
1215
39.0k
    }
1216
75.9k
    return code;
1217
75.9k
}
1218
1219
static int
1220
gx_default_put_prebandthreshold(bool prebandthreshold, gx_device * dev)
1221
75.9k
{
1222
75.9k
    int code = 0;
1223
75.9k
    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
75.9k
    if (dev_proc(dev, get_profile) == NULL) {
1230
        /* This is an odd case where the device has not yet fully been
1231
           set up with its procedures yet.  We want to make sure that
1232
           we catch this so we assume here that we are dealing with
1233
           the target device.  For now allocate the profile structure
1234
           but do not intialize the profile yet as the color info
1235
           may not be fully set up at this time.  */
1236
36.8k
        if (dev->icc_struct == NULL) {
1237
            /* Allocate at this time the structure */
1238
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1239
0
            if (dev->icc_struct == NULL)
1240
0
                return_error(gs_error_VMerror);
1241
0
        }
1242
36.8k
        dev->icc_struct->prebandthreshold = prebandthreshold;
1243
39.0k
    } else {
1244
39.0k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1245
39.0k
        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
39.0k
        profile_struct->prebandthreshold = prebandthreshold;
1253
39.0k
    }
1254
75.9k
    return code;
1255
75.9k
}
1256
1257
static int
1258
gx_default_put_usefastcolor(bool fastcolor, gx_device * dev)
1259
75.9k
{
1260
75.9k
    int code = 0;
1261
75.9k
    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
75.9k
    if (dev_proc(dev, get_profile) == NULL) {
1268
        /* This is an odd case where the device has not yet fully been
1269
           set up with its procedures yet.  We want to make sure that
1270
           we catch this so we assume here that we are dealing with
1271
           the target device.  For now allocate the profile structure
1272
           but do not intialize the profile yet as the color info
1273
           may not be fully set up at this time.  */
1274
36.8k
        if (dev->icc_struct == NULL) {
1275
            /* Allocate at this time the structure */
1276
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1277
0
            if (dev->icc_struct == NULL)
1278
0
                return_error(gs_error_VMerror);
1279
0
        }
1280
36.8k
        dev->icc_struct->usefastcolor = fastcolor;
1281
39.0k
    } else {
1282
39.0k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1283
39.0k
        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
39.0k
        profile_struct->usefastcolor = fastcolor;
1291
39.0k
    }
1292
75.9k
    return code;
1293
75.9k
}
1294
1295
static int
1296
gx_default_put_blacktext(bool blacktext, gx_device* dev)
1297
75.9k
{
1298
75.9k
    int code = 0;
1299
75.9k
    cmm_dev_profile_t* profile_struct;
1300
1301
75.9k
    if (dev_proc(dev, get_profile) == NULL) {
1302
36.8k
        if (dev->icc_struct == NULL) {
1303
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1304
0
            if (dev->icc_struct == NULL)
1305
0
                return_error(gs_error_VMerror);
1306
0
        }
1307
36.8k
        dev->icc_struct->blacktext = blacktext;
1308
39.0k
    } else {
1309
39.0k
        code = dev_proc(dev, get_profile)(dev, &profile_struct);
1310
39.0k
        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
39.0k
        profile_struct->blacktext = blacktext;
1318
39.0k
    }
1319
75.9k
    return code;
1320
75.9k
}
1321
1322
static int
1323
gx_default_put_blackthresholds(float blackthresholdL, float blackthresholdC, gx_device *dev)
1324
75.9k
{
1325
75.9k
    int code = 0;
1326
75.9k
    cmm_dev_profile_t* profile_struct;
1327
1328
75.9k
    if (dev_proc(dev, get_profile) == NULL) {
1329
36.8k
        if (dev->icc_struct == NULL) {
1330
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1331
0
            if (dev->icc_struct == NULL)
1332
0
                return_error(gs_error_VMerror);
1333
0
        }
1334
36.8k
        dev->icc_struct->blackthresholdL = blackthresholdL;
1335
36.8k
        dev->icc_struct->blackthresholdC = blackthresholdC;
1336
39.0k
    } else {
1337
39.0k
        code = dev_proc(dev, get_profile)(dev, &profile_struct);
1338
39.0k
        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
39.0k
        profile_struct->blackthresholdL = blackthresholdL;
1346
39.0k
        profile_struct->blackthresholdC = blackthresholdC;
1347
39.0k
    }
1348
75.9k
    return code;
1349
75.9k
}
1350
1351
static int
1352
gx_default_put_blackvector(bool blackvector, gx_device* dev)
1353
75.9k
{
1354
75.9k
    int code = 0;
1355
75.9k
    cmm_dev_profile_t* profile_struct;
1356
1357
75.9k
    if (dev_proc(dev, get_profile) == NULL) {
1358
36.8k
        if (dev->icc_struct == NULL) {
1359
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1360
0
            if (dev->icc_struct == NULL)
1361
0
                return_error(gs_error_VMerror);
1362
0
        }
1363
36.8k
        dev->icc_struct->blackvector = blackvector;
1364
39.0k
    } else {
1365
39.0k
        code = dev_proc(dev, get_profile)(dev, &profile_struct);
1366
39.0k
        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
39.0k
        profile_struct->blackvector = blackvector;
1374
39.0k
    }
1375
75.9k
    return code;
1376
75.9k
}
1377
1378
static int
1379
gx_default_put_overprint_control(gs_overprint_control_t overprint_control, gx_device * dev)
1380
75.9k
{
1381
75.9k
    int code = 0;
1382
75.9k
    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
75.9k
    if (dev_proc(dev, get_profile) == NULL) {
1389
        /* This is an odd case where the device has not yet fully been
1390
           set up with its procedures yet.  We want to make sure that
1391
           we catch this so we assume here that we are dealing with
1392
           the target device.  For now allocate the profile structure
1393
           but do not intialize the profile yet as the color info
1394
           may not be fully set up at this time.  */
1395
36.8k
        if (dev->icc_struct == NULL) {
1396
            /* Allocate at this time the structure */
1397
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1398
0
            if (dev->icc_struct == NULL)
1399
0
                return_error(gs_error_VMerror);
1400
0
        }
1401
36.8k
        dev->icc_struct->overprint_control = overprint_control;
1402
39.0k
    } else {
1403
39.0k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1404
39.0k
        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
39.0k
        profile_struct->overprint_control = overprint_control;
1412
39.0k
    }
1413
75.9k
    return code;
1414
75.9k
}
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
303k
{
1420
303k
    int code;
1421
303k
    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
303k
    if (dev_proc(dev, get_profile) == NULL) {
1428
        /* This is an odd case where the device has not yet fully been
1429
           set up with its procedures yet.  We want to make sure that
1430
           we catch this so we assume here that we are dealing with
1431
           the target device */
1432
147k
        if (dev->icc_struct == NULL) {
1433
            /* Intializes the device structure.  Not the profile though for index */
1434
9.22k
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1435
9.22k
            if (dev->icc_struct == NULL)
1436
0
                return_error(gs_error_VMerror);
1437
9.22k
        }
1438
147k
        code = gsicc_set_device_profile_intent(dev, icc_intent, index);
1439
156k
    } else {
1440
156k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1441
156k
        if (code < 0)
1442
0
            return code;
1443
156k
        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
156k
        code = gsicc_set_device_profile_intent(dev, icc_intent, index);
1450
156k
    }
1451
303k
    return code;
1452
303k
}
1453
1454
static int
1455
gx_default_put_blackpreserve(gsicc_blackpreserve_t blackpreserve, gx_device * dev,
1456
                           gsicc_profile_types_t index)
1457
303k
{
1458
303k
    int code;
1459
303k
    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
303k
    if (dev_proc(dev, get_profile) == NULL) {
1466
        /* This is an odd case where the device has not yet fully been
1467
           set up with its procedures yet.  We want to make sure that
1468
           we catch this so we assume here that we are dealing with
1469
           the target device */
1470
147k
        if (dev->icc_struct == NULL) {
1471
            /* Intializes the device structure.  Not the profile though for index */
1472
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1473
0
            if (dev->icc_struct == NULL)
1474
0
                return_error(gs_error_VMerror);
1475
0
        }
1476
147k
        code = gsicc_set_device_blackpreserve(dev, blackpreserve, index);
1477
156k
    } else {
1478
156k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1479
156k
        if (code < 0)
1480
0
            return code;
1481
156k
        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
156k
        code = gsicc_set_device_blackpreserve(dev, blackpreserve, index);
1488
156k
    }
1489
303k
    return code;
1490
303k
}
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
303k
{
1499
303k
    int code;
1500
303k
    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
303k
    if (dev_proc(dev, get_profile) == NULL) {
1507
        /* This is an odd case where the device has not yet fully been
1508
           set up with its procedures yet.  We want to make sure that
1509
           we catch this so we assume here that we are dealing with
1510
           the target device */
1511
147k
        if (dev->icc_struct == NULL) {
1512
            /* Intializes the device structure.  Not the profile though for index */
1513
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1514
0
            if (dev->icc_struct == NULL)
1515
0
                return_error(gs_error_VMerror);
1516
0
        }
1517
147k
        code = gsicc_set_device_blackptcomp(dev, blackptcomp, index);
1518
156k
    } else {
1519
156k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1520
156k
        if (code < 0)
1521
0
            return code;
1522
156k
        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
156k
        code = gsicc_set_device_blackptcomp(dev, blackptcomp, index);
1529
156k
    }
1530
303k
    return code;
1531
303k
}
1532
1533
static int
1534
gx_default_put_icc_colorants(gs_param_string *colorants, gx_device * dev)
1535
7.46k
{
1536
7.46k
    char *tempstr;
1537
7.46k
    int code;
1538
7.46k
    int len;
1539
7.46k
    unsigned short *tempstr2 = NULL;
1540
7.46k
    unsigned short *s;
1541
7.46k
    char *d;
1542
1543
7.46k
    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
59.7k
{
1595
59.7k
    char *tempstr;
1596
59.7k
    int code = 0;
1597
1598
59.7k
    if (icc_pro->size == 0) return 0;
1599
    /* If this has not yet been set, then set it to the default.
1600
       I don't like doing this here but if we are in here trying to
1601
       set a profile for our device and if the proc for this has not
1602
       yet been set, we are going to lose the chance to set the profile.
1603
       Much like open, this proc should be set early on.  I leave that
1604
       exercise to the device start-up experts */
1605
7.46k
    fill_dev_proc(dev, get_profile, gx_default_get_profile);
1606
7.46k
    if (icc_pro->size < gp_file_name_sizeof) {
1607
7.46k
        tempstr = (char *) gs_alloc_bytes(dev->memory, icc_pro->size+1,
1608
7.46k
                                          "gx_default_put_icc");
1609
7.46k
        if (tempstr == NULL)
1610
0
            return_error(gs_error_VMerror);
1611
7.46k
        memcpy(tempstr, icc_pro->data, icc_pro->size);
1612
        /* Set last position to NULL. */
1613
7.46k
        tempstr[icc_pro->size] = 0;
1614
7.46k
        code = gsicc_init_device_profile_struct(dev, tempstr, index);
1615
7.46k
        gs_free_object(dev->memory, tempstr, "gx_default_put_icc");
1616
7.46k
    }
1617
7.46k
    return code;
1618
7.46k
}
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
76.0k
{
1652
76.0k
    int ecode = 0;
1653
76.0k
    int code;
1654
76.0k
    gs_param_name param_name;
1655
76.0k
    gs_param_float_array hwra;
1656
76.0k
    gs_param_int_array hwsa;
1657
76.0k
    gs_param_float_array msa;
1658
76.0k
    gs_param_float_array ma;
1659
76.0k
    gs_param_float_array hwma;
1660
76.0k
    gs_param_string_array scna;
1661
76.0k
    int nci = dev->NumCopies;
1662
76.0k
    int ncset = dev->NumCopies_set;
1663
76.0k
    bool ignc = dev->IgnoreNumCopies;
1664
76.0k
    bool ucc = dev->UseCIEColor;
1665
76.0k
    gs_param_string icc_pro;
1666
76.0k
    bool locksafe = dev->LockSafetyParams;
1667
76.0k
    gs_param_float_array ibba;
1668
76.0k
    bool ibbnull = false;
1669
76.0k
    int colors = dev->color_info.num_components;
1670
76.0k
    int depth = dev->color_info.depth;
1671
76.0k
    int GrayValues = dev->color_info.max_gray + 1;
1672
76.0k
    int RGBValues = dev->color_info.max_color + 1;
1673
76.0k
    long ColorValues = (depth >= 32 ? -1 : 1L << depth);
1674
76.0k
    int tab = dev->color_info.anti_alias.text_bits;
1675
76.0k
    int gab = dev->color_info.anti_alias.graphics_bits;
1676
76.0k
    size_t mpbm = dev->MaxPatternBitmap;
1677
76.0k
    int ic = dev->interpolate_control;
1678
76.0k
    bool page_uses_transparency = dev->page_uses_transparency;
1679
76.0k
    bool page_uses_overprint = dev->page_uses_overprint;
1680
76.0k
    gdev_space_params sp = dev->space_params;
1681
76.0k
    gdev_space_params save_sp = dev->space_params;
1682
76.0k
    int rend_intent[NUM_DEVICE_PROFILES];
1683
76.0k
    int blackptcomp[NUM_DEVICE_PROFILES];
1684
76.0k
    int blackpreserve[NUM_DEVICE_PROFILES];
1685
76.0k
    gs_param_string cms, pagelist, nuplist;
1686
76.0k
    int leadingedge = dev->LeadingEdge;
1687
76.0k
    int k;
1688
76.0k
    int color_accuracy;
1689
76.0k
    bool devicegraytok = true;
1690
76.0k
    bool graydetection = false;
1691
76.0k
    bool usefastcolor = false;
1692
76.0k
    bool blacktext = false;
1693
76.0k
    bool blackvector = false;
1694
76.0k
    float blackthresholdL = BLACKTHRESHOLDL;
1695
76.0k
    float blackthresholdC = BLACKTHRESHOLDC;
1696
76.0k
    gs_overprint_control_t overprint_control = gs_overprint_control_enable;
1697
76.0k
    bool prebandthreshold = false;
1698
76.0k
    bool use_antidropout = dev->color_info.use_antidropout_downscaler;
1699
76.0k
    bool temp_bool;
1700
76.0k
    int  profile_types[NUM_DEVICE_PROFILES] = {gsDEFAULTPROFILE,
1701
76.0k
                                               gsGRAPHICPROFILE,
1702
76.0k
                                               gsIMAGEPROFILE,
1703
76.0k
                                               gsTEXTPROFILE};
1704
1705
76.0k
    color_accuracy = gsicc_currentcoloraccuracy(dev->memory);
1706
76.0k
    if (dev->icc_struct != NULL) {
1707
333k
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
1708
267k
            rend_intent[k] = dev->icc_struct->rendercond[k].rendering_intent;
1709
267k
            blackptcomp[k] = dev->icc_struct->rendercond[k].black_point_comp;
1710
267k
            blackpreserve[k] = dev->icc_struct->rendercond[k].preserve_black;
1711
267k
        }
1712
66.7k
        graydetection = dev->icc_struct->graydetection;
1713
66.7k
        devicegraytok = dev->icc_struct->devicegraytok;
1714
66.7k
        usefastcolor = dev->icc_struct->usefastcolor;
1715
66.7k
        blacktext = dev->icc_struct->blacktext;
1716
66.7k
        blackvector = dev->icc_struct->blackvector;
1717
66.7k
        blackthresholdL = dev->icc_struct->blackthresholdL;
1718
66.7k
        blackthresholdC = dev->icc_struct->blackthresholdC;
1719
66.7k
        prebandthreshold = dev->icc_struct->prebandthreshold;
1720
66.7k
        overprint_control = dev->icc_struct->overprint_control;
1721
66.7k
    } else {
1722
46.1k
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
1723
36.8k
            rend_intent[k] = gsRINOTSPECIFIED;
1724
36.8k
            blackptcomp[k] = gsBPNOTSPECIFIED;
1725
36.8k
            blackpreserve[k] = gsBKPRESNOTSPECIFIED;
1726
36.8k
        }
1727
9.22k
    }
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
76.0k
#define BEGIN_ARRAY_PARAM(pread, pname, pa, psize, e)\
1740
532k
    BEGIN\
1741
532k
    switch (code = pread(plist, (param_name = pname), &(pa))) {\
1742
117k
      case 0:\
1743
117k
        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
76.0k
#define END_ARRAY_PARAM(pa, e)\
1748
76.0k
        goto e;\
1749
117k
      default:\
1750
42
        ecode = code;\
1751
42
e:  param_signal_error(plist, param_name, ecode);\
1752
414k
      case 1:\
1753
414k
        (pa).data = 0;   /* mark as not filled */\
1754
1.06M
    }\
1755
1.06M
    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
76.0k
    if (leadingedge & LEADINGEDGE_REQ_BIT) {
1764
0
        leadingedge = (leadingedge & LEADINGEDGE_SET_MASK) |
1765
0
            ((leadingedge >> LEADINGEDGE_REQ_VAL_SHIFT) & LEADINGEDGE_MASK);
1766
0
    }
1767
1768
    /*
1769
     * The HWResolution, HWSize, and MediaSize parameters interact in
1770
     * the following way:
1771
     *      1. Setting HWResolution recomputes HWSize from MediaSize.
1772
     *      2. Setting HWSize recomputes MediaSize from HWResolution.
1773
     *      3. Setting MediaSize recomputes HWSize from HWResolution.
1774
     * If more than one parameter is being set, we apply these rules
1775
     * in the order 1, 2, 3.  This does the right thing in the most
1776
     * common case of setting more than one parameter, namely,
1777
     * setting both HWResolution and HWSize.
1778
     *
1779
     * Changing of LeadingEdge is treated exactly the same as a
1780
     * change in HWResolution. In typical usage, MediaSize is
1781
     * short-edge (MediaSize[0] < MediaSize[1]), so if LeadingEdge
1782
     * is 1 or 3, then HWSize will become long-edge. For nonsquare
1783
     * resolutions, HWResolution[0] always corresponds with width
1784
     * (scan length), and [1] with height (number of scans).
1785
     */
1786
1787
92.7k
    BEGIN_ARRAY_PARAM(param_read_float_array, "HWResolution", hwra, 2, hwre) {
1788
16.6k
        if (hwra.data[0] <= 0 || hwra.data[1] <= 0)
1789
0
            ecode = gs_note_error(gs_error_rangecheck);
1790
16.6k
        else
1791
16.6k
            break;
1792
16.6k
    } END_ARRAY_PARAM(hwra, hwre);
1793
83.4k
    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.46k
        if ((hwsa.data[0] <= 0 && hwsa.data[0] != dev->width) ||
1797
7.46k
            (hwsa.data[1] <= 0 && hwsa.data[1] != dev->height)
1798
7.46k
        )
1799
0
            ecode = gs_note_error(gs_error_rangecheck);
1800
22.4k
#define max_coord (max_fixed / fixed_1)
1801
7.46k
#if max_coord < max_int
1802
7.46k
        else if (hwsa.data[0] > max_coord || hwsa.data[1] > max_coord)
1803
0
            ecode = gs_note_error(gs_error_limitcheck);
1804
7.46k
#endif
1805
7.46k
#undef max_coord
1806
7.46k
        else
1807
7.46k
            break;
1808
7.46k
    } END_ARRAY_PARAM(hwsa, hwse);
1809
76.0k
    {
1810
76.0k
        int t;
1811
1812
76.0k
        code = param_read_int(plist, "LeadingEdge", &t);
1813
76.0k
        if (code < 0) {
1814
7.46k
            if (param_read_null(plist, "LeadingEdge") == 0) {
1815
                /* if param is null, clear explicitly-set flag */
1816
7.46k
                leadingedge &= ~LEADINGEDGE_SET_MASK;
1817
7.46k
            } else {
1818
0
                ecode = code;
1819
0
            }
1820
68.5k
        } 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
76.0k
    }
1828
76.0k
    {
1829
76.0k
        const float *res = (hwra.data == 0 ? dev->HWResolution : hwra.data);
1830
1831
76.0k
#ifdef PAGESIZE_IS_MEDIASIZE
1832
76.0k
        const float *data;
1833
1834
        /* .MediaSize takes precedence over PageSize, so */
1835
        /* we read PageSize first. */
1836
76.0k
        code = param_MediaSize(plist, "PageSize", res, &msa);
1837
76.0k
        if (code < 0)
1838
0
            ecode = code;
1839
        /* Prevent data from being set to 0 if PageSize is specified */
1840
        /* but .MediaSize is not. */
1841
76.0k
        data = msa.data;
1842
76.0k
        code = param_MediaSize(plist, ".MediaSize", res, &msa);
1843
76.0k
        if (code < 0)
1844
42
            ecode = code;
1845
75.9k
        else if (msa.data == 0)
1846
36.8k
            msa.data = data;
1847
#else
1848
        code = param_MediaSize(plist, ".MediaSize", res, &msa);
1849
        if (code < 0)
1850
            ecode = code;
1851
#endif
1852
76.0k
    }
1853
1854
83.4k
    BEGIN_ARRAY_PARAM(param_read_float_array, "Margins", ma, 2, me) {
1855
7.46k
        break;
1856
7.46k
    } END_ARRAY_PARAM(ma, me);
1857
83.4k
    BEGIN_ARRAY_PARAM(param_read_float_array, ".HWMargins", hwma, 4, hwme) {
1858
7.46k
        break;
1859
7.46k
    } END_ARRAY_PARAM(hwma, hwme);
1860
76.0k
    switch (code = param_read_bool(plist, (param_name = ".IgnoreNumCopies"), &ignc)) {
1861
0
        default:
1862
0
            ecode = code;
1863
0
            param_signal_error(plist, param_name, ecode);
1864
7.46k
        case 0:
1865
76.0k
        case 1:
1866
76.0k
            break;
1867
76.0k
    }
1868
76.0k
    if (dev->NumCopies_set >= 0 &&
1869
76.0k
        (*dev_proc(dev, get_page_device))(dev) != 0
1870
76.0k
        ) {
1871
76.0k
        switch (code = param_read_int(plist, (param_name = "NumCopies"), &nci)) {
1872
0
            case 0:
1873
0
                if (nci < 0)
1874
0
                    ecode = gs_error_rangecheck;
1875
0
                else {
1876
0
                    ncset = 1;
1877
0
                    break;
1878
0
                }
1879
0
                goto nce;
1880
7.46k
            default:
1881
7.46k
                if ((code = param_read_null(plist, param_name)) == 0) {
1882
7.46k
                    ncset = 0;
1883
7.46k
                    break;
1884
7.46k
                }
1885
0
                ecode = code; /* can't be 1 */
1886
0
nce:
1887
0
                param_signal_error(plist, param_name, ecode);
1888
68.5k
            case 1:
1889
68.5k
                break;
1890
76.0k
        }
1891
76.0k
    }
1892
    /* Set the ICC output colors first */
1893
76.0k
    if ((code = param_read_string(plist, "ICCOutputColors", &icc_pro)) != 1) {
1894
7.46k
        if (code < 0) {
1895
0
            ecode = code;
1896
0
            param_signal_error(plist, "ICCOutputColors", ecode);
1897
7.46k
        } else {
1898
7.46k
            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.46k
        }
1903
7.46k
    }
1904
76.0k
    if ((code = param_read_string(plist, "DeviceLinkProfile", &icc_pro)) != 1) {
1905
7.46k
        if (code < 0) {
1906
0
            ecode = code;
1907
0
            param_signal_error(plist, "DeviceLinkProfile", ecode);
1908
7.46k
        } else {
1909
7.46k
            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.46k
        }
1914
7.46k
    }
1915
76.0k
    if ((code = param_read_string(plist, "PostRenderProfile", &icc_pro)) != 1) {
1916
7.46k
        if (code < 0) {
1917
0
            ecode = code;
1918
0
            param_signal_error(plist, "PostRenderProfile", ecode);
1919
7.46k
        } else {
1920
7.46k
            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.46k
        }
1925
7.46k
    }
1926
76.0k
    if ((code = param_read_string(plist, "OutputICCProfile", &icc_pro)) != 1) {
1927
7.46k
        if (code < 0) {
1928
0
            ecode = code;
1929
0
            param_signal_error(plist, "OutputICCProfile", ecode);
1930
7.46k
        } else {
1931
7.46k
            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.46k
        }
1936
7.46k
    }
1937
    /* Note, if a change is made to NUM_DEVICE_PROFILES we need to update
1938
       this with the name of the profile */
1939
76.0k
    if ((code = param_read_string(plist, "VectorICCProfile", &icc_pro)) != 1) {
1940
7.46k
        if (code < 0) {
1941
0
            ecode = code;
1942
0
            param_signal_error(plist, "VectorICCProfile", ecode);
1943
7.46k
        } else {
1944
7.46k
            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.46k
        }
1949
7.46k
    }
1950
76.0k
    if ((code = param_read_string(plist, "ImageICCProfile", &icc_pro)) != 1) {
1951
7.46k
        if (code < 0) {
1952
0
            ecode = code;
1953
0
            param_signal_error(plist, "ImageICCProfile", ecode);
1954
7.46k
        } else {
1955
7.46k
            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.46k
        }
1960
7.46k
    }
1961
76.0k
    if ((code = param_read_string(plist, "TextICCProfile", &icc_pro)) != 1) {
1962
7.46k
        if (code < 0) {
1963
0
            ecode = code;
1964
0
            param_signal_error(plist, "TextICCProfile", ecode);
1965
7.46k
        } else {
1966
7.46k
            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.46k
        }
1971
7.46k
    }
1972
76.0k
    if ((code = param_read_string(plist, "ProofProfile", &icc_pro)) != 1) {
1973
7.46k
        if (code < 0) {
1974
0
            ecode = code;
1975
0
            param_signal_error(plist, "ProofProfile", ecode);
1976
7.46k
        } else {
1977
7.46k
            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.46k
        }
1982
7.46k
    }
1983
76.0k
    if ((code = param_read_string(plist, "BlendColorProfile", &icc_pro)) != 1) {
1984
7.46k
        if (code < 0) {
1985
0
            ecode = code;
1986
0
            param_signal_error(plist, "BlendColorProfile", ecode);
1987
7.46k
        } else {
1988
7.46k
            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.46k
        }
1993
7.46k
    }
1994
76.0k
    if ((code = param_read_int(plist, (param_name = "RenderIntent"),
1995
76.0k
                                                    &(rend_intent[0]))) < 0) {
1996
0
        ecode = code;
1997
0
        param_signal_error(plist, param_name, ecode);
1998
0
    }
1999
76.0k
    if ((code = param_read_int(plist, (param_name = "VectorIntent"),
2000
76.0k
                                                    &(rend_intent[1]))) < 0) {
2001
0
        ecode = code;
2002
0
        param_signal_error(plist, param_name, ecode);
2003
0
    }
2004
76.0k
    if ((code = param_read_int(plist, (param_name = "ImageIntent"),
2005
76.0k
                                                    &(rend_intent[2]))) < 0) {
2006
0
        ecode = code;
2007
0
        param_signal_error(plist, param_name, ecode);
2008
0
    }
2009
76.0k
    if ((code = param_read_int(plist, (param_name = "TextIntent"),
2010
76.0k
                                                    &(rend_intent[3]))) < 0) {
2011
0
        ecode = code;
2012
0
        param_signal_error(plist, param_name, ecode);
2013
0
    }
2014
76.0k
    if ((code = param_read_int(plist, (param_name = "BlackPtComp"),
2015
76.0k
                                                    &(blackptcomp[0]))) < 0) {
2016
0
        ecode = code;
2017
0
        param_signal_error(plist, param_name, ecode);
2018
0
    }
2019
76.0k
    if ((code = param_read_int(plist, (param_name = "VectorBlackPt"),
2020
76.0k
                                                    &(blackptcomp[1]))) < 0) {
2021
0
        ecode = code;
2022
0
        param_signal_error(plist, param_name, ecode);
2023
0
    }
2024
76.0k
    if ((code = param_read_int(plist, (param_name = "ImageBlackPt"),
2025
76.0k
                                                    &(blackptcomp[2]))) < 0) {
2026
0
        ecode = code;
2027
0
        param_signal_error(plist, param_name, ecode);
2028
0
    }
2029
76.0k
    if ((code = param_read_int(plist, (param_name = "TextBlackPt"),
2030
76.0k
                                                    &(blackptcomp[3]))) < 0) {
2031
0
        ecode = code;
2032
0
        param_signal_error(plist, param_name, ecode);
2033
0
    }
2034
76.0k
    if ((code = param_read_int(plist, (param_name = "KPreserve"),
2035
76.0k
                                                    &(blackpreserve[0]))) < 0) {
2036
0
        ecode = code;
2037
0
        param_signal_error(plist, param_name, ecode);
2038
0
    }
2039
76.0k
    if ((code = param_read_int(plist, (param_name = "VectorKPreserve"),
2040
76.0k
                                                    &(blackpreserve[1]))) < 0) {
2041
0
        ecode = code;
2042
0
        param_signal_error(plist, param_name, ecode);
2043
0
    }
2044
76.0k
    if ((code = param_read_int(plist, (param_name = "ImageKPreserve"),
2045
76.0k
                                                    &(blackpreserve[2]))) < 0) {
2046
0
        ecode = code;
2047
0
        param_signal_error(plist, param_name, ecode);
2048
0
    }
2049
76.0k
    if ((code = param_read_int(plist, (param_name = "TextKPreserve"),
2050
76.0k
                                                    &(blackpreserve[3]))) < 0) {
2051
0
        ecode = code;
2052
0
        param_signal_error(plist, param_name, ecode);
2053
0
    }
2054
76.0k
    if ((code = param_read_int(plist, (param_name = "ColorAccuracy"),
2055
76.0k
                                                        &color_accuracy)) < 0) {
2056
0
        ecode = code;
2057
0
        param_signal_error(plist, param_name, ecode);
2058
0
    }
2059
76.0k
    if ((code = param_read_bool(plist, (param_name = "DeviceGrayToK"),
2060
76.0k
                                                        &devicegraytok)) < 0) {
2061
0
        ecode = code;
2062
0
        param_signal_error(plist, param_name, ecode);
2063
0
    }
2064
76.0k
    if ((code = param_read_bool(plist, (param_name = "GrayDetection"),
2065
76.0k
                                                        &graydetection)) < 0) {
2066
0
        ecode = code;
2067
0
        param_signal_error(plist, param_name, ecode);
2068
0
    }
2069
76.0k
    if ((code = param_read_bool(plist, (param_name = "UseFastColor"),
2070
76.0k
                                                        &usefastcolor)) < 0) {
2071
0
        ecode = code;
2072
0
        param_signal_error(plist, param_name, ecode);
2073
0
    }
2074
76.0k
    if ((code = param_read_bool(plist, (param_name = "BlackText"),
2075
76.0k
                                                        &blacktext)) < 0) {
2076
0
        ecode = code;
2077
0
        param_signal_error(plist, param_name, ecode);
2078
0
    }
2079
76.0k
    if ((code = param_read_bool(plist, (param_name = "BlackVector"),
2080
76.0k
                                                        &blackvector)) < 0) {
2081
0
        ecode = code;
2082
0
        param_signal_error(plist, param_name, ecode);
2083
0
    }
2084
76.0k
    if ((code = param_read_float(plist, (param_name = "BlackThresholdL"),
2085
76.0k
                                                        &blackthresholdL)) < 0) {
2086
0
        ecode = code;
2087
0
        param_signal_error(plist, param_name, ecode);
2088
0
    }
2089
76.0k
    if ((code = param_read_float(plist, (param_name = "BlackThresholdC"),
2090
76.0k
                                                        &blackthresholdC)) < 0) {
2091
0
        ecode = code;
2092
0
        param_signal_error(plist, param_name, ecode);
2093
0
    }
2094
76.0k
    if ((code = param_put_enum(plist, "Overprint",
2095
76.0k
                           (int*)&overprint_control, overprint_control_names, ecode)) < 0) {
2096
42
        ecode = code;
2097
42
        param_signal_error(plist, param_name, ecode);
2098
42
    }
2099
76.0k
    if ((code = param_read_bool(plist, (param_name = "PreBandThreshold"),
2100
76.0k
                                                        &prebandthreshold)) < 0) {
2101
0
        ecode = code;
2102
0
        param_signal_error(plist, param_name, ecode);
2103
0
    }
2104
76.0k
    if ((code = param_read_bool(plist, (param_name = "UseCIEColor"), &ucc)) < 0) {
2105
0
        ecode = code;
2106
0
        param_signal_error(plist, param_name, ecode);
2107
0
    }
2108
76.0k
    if ((code = param_anti_alias_bits(plist, "TextAlphaBits", &tab)) < 0)
2109
0
        ecode = code;
2110
76.0k
    if ((code = param_anti_alias_bits(plist, "GraphicsAlphaBits", &gab)) < 0)
2111
0
        ecode = code;
2112
76.0k
    if ((code = param_read_bool(plist, "AntidropoutDownscaler", &use_antidropout)) < 0)
2113
0
        ecode = code;
2114
76.0k
    if ((code = param_read_size_t(plist, "MaxPatternBitmap", &mpbm)) < 0)
2115
0
        ecode = code;
2116
76.0k
    if ((code = param_read_int(plist, "InterpolateControl", &ic)) < 0)
2117
0
        ecode = code;
2118
76.0k
    if ((code = param_read_bool(plist, (param_name = "PageUsesTransparency"),
2119
76.0k
                                &page_uses_transparency)) < 0) {
2120
0
        ecode = code;
2121
0
        param_signal_error(plist, param_name, ecode);
2122
0
    }
2123
76.0k
    if ((code = param_read_bool(plist, (param_name = "PageUsesOverprint"),
2124
76.0k
                                &page_uses_overprint)) < 0) {
2125
0
        ecode = code;
2126
0
        param_signal_error(plist, param_name, ecode);
2127
0
    }
2128
76.0k
    if ((code = param_read_size_t(plist, "MaxBitmap", &sp.MaxBitmap)) < 0)
2129
0
        ecode = code;
2130
2131
76.0k
#define CHECK_PARAM_CASES(member, bad, label)\
2132
76.0k
    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
264k
    case 1:\
2143
264k
        break
2144
2145
76.0k
    switch (code = param_read_size_t(plist, (param_name = "BufferSpace"), &sp.BufferSpace)) {
2146
76.0k
        CHECK_PARAM_CASES(BufferSpace, sp.BufferSpace < 10000, bse);
2147
76.0k
    }
2148
2149
76.0k
    switch (code = param_read_int(plist, (param_name = "BandWidth"), &sp.band.BandWidth)) {
2150
76.0k
        CHECK_PARAM_CASES(band.BandWidth, sp.band.BandWidth < 0, bwe);
2151
76.0k
    }
2152
2153
76.0k
    switch (code = param_read_int(plist, (param_name = "BandHeight"), &sp.band.BandHeight)) {
2154
76.0k
        CHECK_PARAM_CASES(band.BandHeight, sp.band.BandHeight < -1, bhe);
2155
76.0k
    }
2156
76.0k
    if (sp.band.BandHeight == -1)
2157
0
        sp.band.BandHeight = dev->height; /* 1 band for the page requested */
2158
2159
76.0k
    switch (code = param_read_size_t(plist, (param_name = "BandBufferSpace"), &sp.band.BandBufferSpace)) {
2160
76.0k
        CHECK_PARAM_CASES(band.BandBufferSpace, 0, bbse);
2161
76.0k
    }
2162
2163
2164
76.0k
    switch (code = param_read_bool(plist, (param_name = ".LockSafetyParams"), &locksafe)) {
2165
7.46k
        case 0:
2166
7.46k
            if (dev->LockSafetyParams && !locksafe)
2167
0
                code = gs_note_error(gs_error_invalidaccess);
2168
7.46k
            else
2169
7.46k
                break;
2170
0
        default:
2171
0
            ecode = code;
2172
0
            param_signal_error(plist, param_name, ecode);
2173
68.5k
        case 1:
2174
68.5k
            break;
2175
76.0k
    }
2176
    /* Ignore parameters that only have meaning for printers. */
2177
76.0k
#define IGNORE_INT_PARAM(pname)\
2178
304k
  { int igni;\
2179
304k
    switch ( code = param_read_int(plist, (param_name = pname), &igni) )\
2180
304k
      { default:\
2181
0
          ecode = code;\
2182
0
          param_signal_error(plist, param_name, ecode);\
2183
85.7k
        case 0:\
2184
304k
        case 1:\
2185
304k
          break;\
2186
304k
      }\
2187
304k
  }
2188
76.0k
    IGNORE_INT_PARAM("%MediaSource")
2189
76.0k
        IGNORE_INT_PARAM("%MediaDestination")
2190
76.0k
        switch (code = param_read_float_array(plist, (param_name = "ImagingBBox"), &ibba)) {
2191
0
        case 0:
2192
0
            if (ibba.size != 4 ||
2193
0
                ibba.data[2] < ibba.data[0] || ibba.data[3] < ibba.data[1]
2194
0
                )
2195
0
                ecode = gs_note_error(gs_error_rangecheck);
2196
0
            else
2197
0
                break;
2198
0
            goto ibbe;
2199
0
        default:
2200
0
            if ((code = param_read_null(plist, param_name)) == 0) {
2201
0
                ibbnull = true;
2202
0
                ibba.data = 0;
2203
0
                break;
2204
0
            }
2205
0
            ecode = code; /* can't be 1 */
2206
0
          ibbe:param_signal_error(plist, param_name, ecode);
2207
76.0k
        case 1:
2208
76.0k
            ibba.data = 0;
2209
76.0k
            break;
2210
76.0k
    }
2211
2212
    /* Separation, DeviceN Color, and ProcessColorModel related parameters. */
2213
76.0k
    {
2214
76.0k
        const char * pcms = get_process_color_model_name(dev);
2215
        /* the device should have set a process model name at this point */
2216
76.0k
        if ((code = param_check_string(plist, "ProcessColorModel", pcms, (pcms != NULL))) < 0)
2217
0
            ecode = code;
2218
76.0k
    }
2219
76.0k
    IGNORE_INT_PARAM("MaxSeparations")
2220
76.0k
    if ((code = param_check_bool(plist, "Separations", false, true)) < 0)
2221
0
        ecode = code;
2222
2223
115k
    BEGIN_ARRAY_PARAM(param_read_name_array, "SeparationColorNames", scna, scna.size, scne) {
2224
39.1k
        break;
2225
39.1k
    } END_ARRAY_PARAM(scna, scne);
2226
2227
    /* Now check nominally read-only parameters. */
2228
76.0k
    if ((code = param_check_string(plist, "OutputDevice", dev->dname, true)) < 0)
2229
0
        ecode = code;
2230
76.0k
    if ((code = param_check_string(plist, "Name", dev->dname, true)) < 0)
2231
0
        ecode = code;
2232
76.0k
    if ((code = param_check_int(plist, "Colors", colors, true)) < 0)
2233
0
        ecode = code;
2234
76.0k
    if ((code = param_check_int(plist, "BitsPerPixel", depth, true)) < 0)
2235
0
        ecode = code;
2236
76.0k
    if ((code = param_check_int(plist, "GrayValues", GrayValues, true)) < 0)
2237
0
        ecode = code;
2238
2239
    /* with saved-pages, PageCount can't be checked. No harm in letting it change */
2240
76.0k
    IGNORE_INT_PARAM("PageCount")
2241
2242
76.0k
    if ((code = param_check_int(plist, "RedValues", RGBValues, true)) < 0)
2243
0
        ecode = code;
2244
76.0k
    if ((code = param_check_int(plist, "GreenValues", RGBValues, true)) < 0)
2245
0
        ecode = code;
2246
76.0k
    if ((code = param_check_int(plist, "BlueValues", RGBValues, true)) < 0)
2247
0
        ecode = code;
2248
76.0k
    if ((code = param_check_long(plist, "ColorValues", ColorValues, true)) < 0)
2249
0
        ecode = code;
2250
76.0k
    if (param_read_string(plist, "HWColorMap", &cms) != 1) {
2251
0
        byte palette[3 << 8];
2252
2253
0
        if (param_HWColorMap(dev, palette))
2254
0
            code = param_check_bytes(plist, "HWColorMap", palette,
2255
0
                                     colors << depth, true);
2256
0
        else
2257
0
            code = param_check_bytes(plist, "HWColorMap", 0, 0, false);
2258
0
        if (code < 0)
2259
0
            ecode = code;
2260
0
    }
2261
2262
76.0k
    code = param_read_int(plist, "FirstPage", &dev->FirstPage);
2263
76.0k
    if (code < 0)
2264
0
        ecode = code;
2265
2266
76.0k
    code = param_read_int(plist,  "LastPage", &dev->LastPage);
2267
76.0k
    if (code < 0)
2268
0
        ecode = code;
2269
2270
76.0k
    code = param_read_bool(plist, "DisablePageHandler", &temp_bool);
2271
76.0k
    if (code < 0)
2272
0
        ecode = code;
2273
76.0k
    if (code == 0)
2274
7.46k
        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
76.0k
    code = param_read_string(plist, "NupControl", &nuplist);
2281
76.0k
    if (code < 0)
2282
0
        ecode = code;
2283
76.0k
    if (code == 0) {
2284
7.46k
        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.46k
    }
2292
76.0k
    if (dev->NupControl == NULL && code == 0 && nuplist.size > 0) {
2293
0
        gx_device *next_dev;
2294
2295
0
        dev->NupControl = (gdev_nupcontrol *)gs_alloc_bytes(dev->memory->non_gc_memory,
2296
0
                                                          sizeof(gdev_nupcontrol), "structure to hold nupcontrol_str");
2297
0
        if (dev->NupControl == NULL)
2298
0
            return gs_note_error(gs_error_VMerror);
2299
0
        dev->NupControl->nupcontrol_str = (void *)gs_alloc_bytes(dev->memory->non_gc_memory,
2300
0
                                                                 nuplist.size + 1, "nupcontrol string");
2301
0
        if (dev->NupControl->nupcontrol_str == NULL){
2302
0
            gs_free(dev->memory->non_gc_memory, dev->NupControl, 1, sizeof(gdev_nupcontrol),
2303
0
                    "free structure to hold nupcontrol string");
2304
0
            dev->NupControl = 0;
2305
0
            return gs_note_error(gs_error_VMerror);
2306
0
        }
2307
0
        memset(dev->NupControl->nupcontrol_str, 0x00, nuplist.size + 1);
2308
0
        memcpy(dev->NupControl->nupcontrol_str, nuplist.data, nuplist.size);
2309
0
        rc_init_free(dev->NupControl, dev->memory->non_gc_memory, 1, rc_free_NupControl);
2310
2311
        /* Propagate the new NupControl struct to children */
2312
0
        next_dev = dev->child;
2313
0
        while (next_dev != NULL) {
2314
0
            if (next_dev->NupControl)
2315
0
                rc_decrement(next_dev->NupControl, "nup_put_params");
2316
0
            next_dev->NupControl = dev->NupControl;
2317
0
            rc_increment(dev->NupControl);
2318
0
            next_dev = next_dev->child;
2319
0
        }
2320
        /* Propagate the new NupControl struct to parents */
2321
0
        next_dev = dev->parent;
2322
0
        while (next_dev != NULL) {
2323
0
            if (next_dev->NupControl)
2324
0
                rc_decrement(next_dev->NupControl, "nup_put_params");
2325
0
            next_dev->NupControl = dev->NupControl;
2326
0
            rc_increment(dev->NupControl);
2327
0
            next_dev = next_dev->parent;
2328
0
        }
2329
0
    }
2330
2331
76.0k
    code = param_read_string(plist, "PageList", &pagelist);
2332
76.0k
    if (code < 0)
2333
0
        ecode = code;
2334
76.0k
    if (code == 0) {
2335
7.46k
        if (dev->PageList)
2336
7.46k
            rc_decrement(dev->PageList, "default put_params PageList");
2337
7.46k
        dev->PageList = NULL;
2338
7.46k
    }
2339
2340
76.0k
    if (code == 0 && pagelist.size > 0) {
2341
0
        dev->PageList = (gdev_pagelist *)gs_alloc_bytes(dev->memory->non_gc_memory, sizeof(gdev_pagelist), "structure to hold page list");
2342
0
        if (!dev->PageList)
2343
0
            return gs_note_error(gs_error_VMerror);
2344
0
        dev->PageList->Pages = (void *)gs_alloc_bytes(dev->memory->non_gc_memory, pagelist.size + 1, "String to hold page list");
2345
0
        if (!dev->PageList->Pages){
2346
0
            gs_free(dev->memory->non_gc_memory, dev->PageList, 1, sizeof(gdev_pagelist), "free structure to hold page list");
2347
0
            dev->PageList = 0;
2348
0
            return gs_note_error(gs_error_VMerror);
2349
0
        }
2350
0
        memset(dev->PageList->Pages, 0x00, pagelist.size + 1);
2351
0
        memcpy(dev->PageList->Pages, pagelist.data, pagelist.size);
2352
0
        rc_init_free(dev->PageList, dev->memory->non_gc_memory, 1, rc_free_pages_list);
2353
0
    }
2354
2355
76.0k
    code = param_read_bool(plist, "FILTERIMAGE", &temp_bool);
2356
76.0k
    if (code < 0)
2357
0
        ecode = code;
2358
76.0k
    if (code == 0) {
2359
7.46k
        if (temp_bool)
2360
0
            dev->ObjectFilter |= FILTERIMAGE;
2361
7.46k
        else
2362
7.46k
            dev->ObjectFilter &= ~FILTERIMAGE;
2363
7.46k
    }
2364
2365
76.0k
    code = param_read_bool(plist, "FILTERTEXT", &temp_bool);
2366
76.0k
    if (code < 0)
2367
0
        ecode = code;
2368
76.0k
    if (code == 0) {
2369
7.46k
        if (temp_bool)
2370
0
            dev->ObjectFilter |= FILTERTEXT;
2371
7.46k
        else
2372
7.46k
            dev->ObjectFilter &= ~FILTERTEXT;
2373
7.46k
    }
2374
2375
76.0k
    code = param_read_bool(plist, "FILTERVECTOR", &temp_bool);
2376
76.0k
    if (code < 0)
2377
0
        ecode = code;
2378
76.0k
    if (code == 0) {
2379
7.46k
        if (temp_bool)
2380
0
            dev->ObjectFilter |= FILTERVECTOR;
2381
7.46k
        else
2382
7.46k
            dev->ObjectFilter &= ~FILTERVECTOR;
2383
7.46k
    }
2384
2385
    /* We must 'commit', in order to detect unknown parameters, */
2386
    /* even if there were errors. */
2387
76.0k
    code = param_commit(plist);
2388
76.0k
    if (ecode < 0) {
2389
        /* restore_page_device (zdevice2.c) will turn off LockSafetyParams, and relies on putparams
2390
         * to put it back if we are restoring a device. The locksafe value is picked up above from the
2391
         * device we are restoring to, and we *must* make sure it is preserved, even if setting the
2392
         * params failed. Otherwise an attacker can use a failed grestore to reset LockSafetyParams.
2393
         * See bug #699687.
2394
         */
2395
42
        dev->LockSafetyParams = locksafe;
2396
42
        return ecode;
2397
42
    }
2398
75.9k
    if (code < 0) {
2399
0
        dev->LockSafetyParams = locksafe;
2400
0
        return code;
2401
0
    }
2402
2403
    /*
2404
     * Now actually make the changes. Changing resolution, rotation
2405
     * (through LeadingEdge) or page size requires closing the device,
2406
     * but changing margins or ImagingBBox does not. In order not to
2407
     * close and reopen the device unnecessarily, we check for
2408
     * replacing the values with the same ones.
2409
     */
2410
2411
75.9k
    dev->color_info.use_antidropout_downscaler = use_antidropout;
2412
2413
75.9k
    if (hwra.data != 0 &&
2414
75.9k
        (dev->HWResolution[0] != hwra.data[0] ||
2415
16.6k
         dev->HWResolution[1] != hwra.data[1])
2416
75.9k
        ) {
2417
9.22k
        if (dev->is_open)
2418
0
            gs_closedevice(dev);
2419
9.22k
        gx_device_set_resolution(dev, hwra.data[0], hwra.data[1]);
2420
9.22k
    }
2421
75.9k
    if ((leadingedge & LEADINGEDGE_MASK) !=
2422
75.9k
        (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
75.9k
    dev->LeadingEdge &= LEADINGEDGE_MASK;
2432
75.9k
    dev->LeadingEdge |= (leadingedge & LEADINGEDGE_SET_MASK);
2433
2434
75.9k
    if (hwsa.data != 0 &&
2435
75.9k
        (dev->width != hwsa.data[0] ||
2436
7.46k
         dev->height != hwsa.data[1])
2437
75.9k
        ) {
2438
5.40k
        if (dev->is_open)
2439
0
            gs_closedevice(dev);
2440
5.40k
        gx_device_set_width_height(dev, hwsa.data[0], hwsa.data[1]);
2441
5.40k
    }
2442
75.9k
    if (msa.data != 0 &&
2443
75.9k
        (dev->MediaSize[0] != msa.data[0] ||
2444
39.0k
         dev->MediaSize[1] != msa.data[1])
2445
75.9k
        ) {
2446
5.60k
        if (dev->is_open)
2447
0
            gs_closedevice(dev);
2448
5.60k
        gx_device_set_page_size(dev, msa.data[0], msa.data[1]);
2449
5.60k
    }
2450
75.9k
    if (ma.data != 0) {
2451
7.46k
        dev->Margins[0] = ma.data[0];
2452
7.46k
        dev->Margins[1] = ma.data[1];
2453
7.46k
    }
2454
75.9k
    if (hwma.data != 0) {
2455
7.46k
        dev->HWMargins[0] = hwma.data[0];
2456
7.46k
        dev->HWMargins[1] = hwma.data[1];
2457
7.46k
        dev->HWMargins[2] = hwma.data[2];
2458
7.46k
        dev->HWMargins[3] = hwma.data[3];
2459
7.46k
    }
2460
75.9k
    dev->NumCopies = nci;
2461
75.9k
    dev->NumCopies_set = ncset;
2462
75.9k
    dev->IgnoreNumCopies = ignc;
2463
75.9k
    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
75.9k
    } else if (ibbnull) {
2470
0
        dev->ImagingBBox_set = false;
2471
0
    }
2472
75.9k
    dev->UseCIEColor = ucc;
2473
75.9k
        dev->color_info.anti_alias.text_bits =
2474
75.9k
                param_normalize_anti_alias_bits(max(dev->color_info.max_gray,
2475
75.9k
                        dev->color_info.max_color), tab);
2476
75.9k
        dev->color_info.anti_alias.graphics_bits =
2477
75.9k
                param_normalize_anti_alias_bits(max(dev->color_info.max_gray,
2478
75.9k
                        dev->color_info.max_color), gab);
2479
75.9k
    dev->LockSafetyParams = locksafe;
2480
75.9k
    dev->MaxPatternBitmap = mpbm;
2481
75.9k
    dev->interpolate_control = ic;
2482
75.9k
    dev->space_params = sp;
2483
75.9k
    dev->page_uses_transparency = page_uses_transparency;
2484
75.9k
    dev->page_uses_overprint = page_uses_overprint;
2485
75.9k
    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
75.9k
    code = gx_default_put_intent(rend_intent[0], dev, gsDEFAULTPROFILE);
2491
75.9k
    if (code < 0)
2492
0
        return code;
2493
75.9k
    code = gx_default_put_blackptcomp(blackptcomp[0], dev, gsDEFAULTPROFILE);
2494
75.9k
    if (code < 0)
2495
0
        return code;
2496
75.9k
    code = gx_default_put_blackpreserve(blackpreserve[0], dev, gsDEFAULTPROFILE);
2497
75.9k
    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
303k
    for (k = 1; k < NUM_DEVICE_PROFILES; k++) {
2502
227k
        if (rend_intent[0] != gsRINOTSPECIFIED &&
2503
227k
            rend_intent[k] == gsRINOTSPECIFIED) {
2504
0
            code = gx_default_put_intent(rend_intent[0], dev, profile_types[k]);
2505
227k
        } else {
2506
227k
            code = gx_default_put_intent(rend_intent[k], dev, profile_types[k]);
2507
227k
        }
2508
227k
        if (code < 0)
2509
0
            return code;
2510
227k
        if (blackptcomp[0] != gsBPNOTSPECIFIED &&
2511
227k
            blackptcomp[k] == gsBPNOTSPECIFIED) {
2512
0
            code = gx_default_put_blackptcomp(blackptcomp[0], dev, profile_types[k]);
2513
227k
        } else {
2514
227k
            code = gx_default_put_blackptcomp(blackptcomp[k], dev, profile_types[k]);
2515
227k
        }
2516
227k
        if (code < 0)
2517
0
            return code;
2518
227k
        if (blackpreserve[0] != gsBKPRESNOTSPECIFIED &&
2519
227k
            blackpreserve[k] == gsBKPRESNOTSPECIFIED) {
2520
0
            code = gx_default_put_blackpreserve(blackpreserve[0], dev, profile_types[k]);
2521
227k
        } else {
2522
227k
            code = gx_default_put_blackpreserve(blackpreserve[k], dev, profile_types[k]);
2523
227k
        }
2524
227k
        if (code < 0)
2525
0
            return code;
2526
227k
    }
2527
75.9k
    gsicc_setcoloraccuracy(dev->memory, color_accuracy);
2528
75.9k
    code = gx_default_put_graytok(devicegraytok, dev);
2529
75.9k
    if (code < 0)
2530
0
        return code;
2531
75.9k
    code = gx_default_put_usefastcolor(usefastcolor, dev);
2532
75.9k
    if (code < 0)
2533
0
        return code;
2534
75.9k
    code = gx_default_put_blacktext(blacktext, dev);
2535
75.9k
    if (code < 0)
2536
0
        return code;
2537
75.9k
    code = gx_default_put_blackvector(blackvector, dev);
2538
75.9k
    if (code < 0)
2539
0
        return code;
2540
75.9k
    code = gx_default_put_blackthresholds(blackthresholdL, blackthresholdC, dev);
2541
75.9k
    if (code < 0)
2542
0
        return code;
2543
75.9k
    code = gx_default_put_overprint_control(overprint_control, dev);
2544
75.9k
    if (code < 0)
2545
0
        return code;
2546
75.9k
    code = gx_default_put_graydetection(graydetection, dev);
2547
75.9k
    if (code < 0)
2548
0
        return code;
2549
75.9k
    return gx_default_put_prebandthreshold(prebandthreshold, dev);
2550
75.9k
}
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
151k
{
2566
151k
        int max_bits = ilog2( max_gray + 1);
2567
2568
151k
        return  (bits > max_bits ? max_bits : bits);
2569
151k
}
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
152k
{
2575
152k
    int code = param_read_int(plist, param_name, pa);
2576
2577
152k
    switch (code) {
2578
14.9k
    case 0:
2579
14.9k
        switch (*pa) {
2580
14.9k
        case 1: case 2: case 4:
2581
14.9k
            return 0;
2582
0
        default:
2583
0
            code = gs_error_rangecheck;
2584
14.9k
        }
2585
        /* fall through */
2586
0
    default:
2587
0
        param_signal_error(plist, param_name, code);
2588
137k
    case 1:
2589
137k
        ;
2590
152k
    }
2591
137k
    return code;
2592
152k
}
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
152k
{
2599
152k
    gs_param_name param_name;
2600
152k
    int ecode = 0;
2601
152k
    int code;
2602
2603
191k
    BEGIN_ARRAY_PARAM(param_read_float_array, pname, *pa, 2, mse) {
2604
39.1k
        float width_new = pa->data[0] * res[0] / 72;
2605
39.1k
        float height_new = pa->data[1] * res[1] / 72;
2606
2607
39.1k
        if (width_new < 0 || height_new < 0)
2608
0
            ecode = gs_note_error(gs_error_rangecheck);
2609
117k
#define max_coord (max_fixed / fixed_1)
2610
39.1k
#if max_coord < max_int
2611
39.1k
        else if (width_new > (long)max_coord || height_new > (long)max_coord)
2612
42
            ecode = gs_note_error(gs_error_limitcheck);
2613
39.0k
#endif
2614
39.0k
#undef max_coord
2615
39.0k
        else
2616
39.0k
            break;
2617
39.1k
    } END_ARRAY_PARAM(*pa, mse);
2618
152k
    return ecode;
2619
152k
}
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
76.0k
{
2627
76.0k
    int code;
2628
76.0k
    bool new_value;
2629
2630
76.0k
    switch (code = param_read_bool(plist, pname, &new_value)) {
2631
7.46k
        case 0:
2632
7.46k
            if (is_defined && new_value == value)
2633
7.46k
                break;
2634
0
            code = gs_note_error(gs_error_rangecheck);
2635
0
            goto e;
2636
0
        default:
2637
0
            if (param_read_null(plist, pname) == 0)
2638
0
                return 1;
2639
0
          e:param_signal_error(plist, pname, code);
2640
68.5k
        case 1:
2641
68.5k
            ;
2642
76.0k
    }
2643
76.0k
    return code;
2644
76.0k
}
2645
static int
2646
param_check_long(gs_param_list * plist, gs_param_name pname, long value,
2647
                 bool is_defined)
2648
532k
{
2649
532k
    int code;
2650
532k
    long new_value;
2651
2652
532k
    switch (code = param_read_long(plist, pname, &new_value)) {
2653
0
        case 0:
2654
0
            if (is_defined && new_value == value)
2655
0
                break;
2656
0
            code = gs_note_error(gs_error_rangecheck);
2657
0
            goto e;
2658
0
        default:
2659
0
            if (param_read_null(plist, pname) == 0)
2660
0
                return 1;
2661
0
          e:param_signal_error(plist, pname, code);
2662
532k
        case 1:
2663
532k
            ;
2664
532k
    }
2665
532k
    return code;
2666
532k
}
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
228k
{
2671
228k
    int code;
2672
228k
    gs_param_string new_value;
2673
2674
228k
    switch (code = param_read_string(plist, pname, &new_value)) {
2675
7.46k
        case 0:
2676
7.46k
            if (is_defined && new_value.size == size &&
2677
7.46k
                !memcmp((const char *)str, (const char *)new_value.data,
2678
7.46k
                        size)
2679
7.46k
                )
2680
7.46k
                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
220k
        case 1:
2688
220k
            ;
2689
228k
    }
2690
228k
    return code;
2691
228k
}