Coverage Report

Created: 2025-06-10 06:58

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