Coverage Report

Created: 2025-06-10 07:17

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