Coverage Report

Created: 2026-08-08 08:00

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