Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/base/gsdparam.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2022 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.,  1305 Grant Avenue - Suite 200, Novato,
13
   CA 94945, U.S.A., +1(415)492-9861, 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
extern gx_device_nup gs_nup_device;
30
31
/* Define whether we accept PageSize as a synonym for MediaSize. */
32
/* This is for backward compatibility only. */
33
#define PAGESIZE_IS_MEDIASIZE
34
35
7.58M
#define BLACKTHRESHOLDL 90
36
7.58M
#define BLACKTHRESHOLDC 3
37
38
/* Names corresponding to gs_overprint_control_t enum */
39
static const char *const overprint_control_names[] = {
40
    gs_overprint_control_names, 0
41
};
42
43
/* ================ Getting parameters ================ */
44
45
/* Forward references */
46
static bool param_HWColorMap(gx_device *, byte *);
47
48
/* Get the device parameters. */
49
int
50
gs_get_device_or_hw_params(gx_device * orig_dev, gs_param_list * plist,
51
                           bool is_hardware)
52
1.96M
{
53
    /*
54
     * We must be prepared to copy the device if it is the read-only
55
     * prototype.
56
     */
57
1.96M
    gx_device *dev;
58
1.96M
    int code = 0;
59
60
1.96M
    if (orig_dev->memory)
61
1.96M
        dev = orig_dev;
62
0
    else {
63
0
        code = gs_copydevice(&dev, orig_dev, plist->memory);
64
0
        if (code < 0)
65
0
            return code;
66
0
    }
67
1.96M
    fill_dev_proc(dev, get_params, gx_default_get_params);
68
1.96M
    fill_dev_proc(dev, get_page_device, gx_default_get_page_device);
69
1.96M
    fill_dev_proc(dev, get_alpha_bits, gx_default_get_alpha_bits);
70
1.96M
    if (is_hardware) {
71
0
        if (dev_proc(dev, get_hardware_params) != NULL)
72
0
            code = (*dev_proc(dev, get_hardware_params)) (dev, plist);
73
1.96M
    } else {
74
1.96M
        if (dev_proc(dev, get_params) != NULL)
75
1.96M
            code = (*dev_proc(dev, get_params)) (dev, plist);
76
1.96M
    }
77
1.96M
    if (dev != orig_dev)
78
0
        gx_device_retain(dev, false);  /* frees the copy */
79
1.96M
    return code;
80
1.96M
}
81
82
int gx_default_get_param(gx_device *dev, char *Param, void *list)
83
4.80M
{
84
4.80M
    gs_param_list * plist = (gs_param_list *)list;
85
4.80M
    int k, colors = dev->color_info.num_components;
86
4.80M
    gs_param_string profile_array[NUM_DEVICE_PROFILES];
87
4.80M
    gs_param_string postren_profile, blend_profile;
88
4.80M
    gs_param_string proof_profile, link_profile, icc_colorants;
89
4.80M
    gsicc_rendering_intents_t profile_intents[NUM_DEVICE_PROFILES];
90
4.80M
    gsicc_blackptcomp_t blackptcomps[NUM_DEVICE_PROFILES];
91
4.80M
    gsicc_blackpreserve_t blackpreserve[NUM_DEVICE_PROFILES];
92
4.80M
    int color_accuracy = MAX_COLOR_ACCURACY;
93
4.80M
    int depth = dev->color_info.depth;
94
4.80M
    cmm_dev_profile_t *dev_profile;
95
4.80M
    char null_str[1]={'\0'};
96
4.80M
#define set_param_array(a, d, s)\
97
4.80M
  (a.data = d, a.size = s, a.persistent = false);
98
4.80M
    bool devicegraytok = true;  /* Default if device profile stuct not set */
99
4.80M
    bool graydetection = false;
100
4.80M
    bool usefastcolor = false;  /* set for unmanaged color */
101
4.80M
    bool blacktext = false;
102
4.80M
    bool blackvector = false;
103
4.80M
    float blackthresholdL = BLACKTHRESHOLDL;
104
4.80M
    float blackthresholdC = BLACKTHRESHOLDC;
105
    /* By default overprinting only valid with cmyk devices */
106
4.80M
    gs_overprint_control_t overprint_control = gs_overprint_control_enable;
107
4.80M
    bool prebandthreshold = true, temp_bool = false;
108
109
4.80M
    if(strcmp(Param, "OutputDevice") == 0){
110
0
        gs_param_string dns;
111
0
        param_string_from_string(dns, dev->dname);
112
0
        return param_write_name(plist, "OutputDevice", &dns);
113
0
    }
114
4.80M
#ifdef PAGESIZE_IS_MEDIASIZE
115
4.80M
    if (strcmp(Param, "PageSize") == 0) {
116
178k
        gs_param_float_array msa;
117
178k
        set_param_array(msa, dev->MediaSize, 2);
118
178k
        return param_write_float_array(plist, "PageSize", &msa);
119
178k
    }
120
4.63M
#endif
121
4.63M
    if (strcmp(Param, "ProcessColorModel") == 0) {
122
0
        const char *cms = get_process_color_model_name(dev);
123
124
        /* We might have an uninitialized device with */
125
        /* color_info.num_components = 0.... */
126
0
        if ((cms != NULL) && (*cms != '\0')) {
127
0
            gs_param_string pcms;
128
0
            param_string_from_string(pcms, cms);
129
0
            return param_write_name(plist, "ProcessColorModel", &pcms);
130
0
        }
131
0
    }
132
4.63M
    if (strcmp(Param, "HWResolution") == 0) {
133
0
        gs_param_float_array hwra;
134
0
        set_param_array(hwra, dev->HWResolution, 2);
135
0
        return param_write_float_array(plist, "HWResolution", &hwra);
136
0
    }
137
4.63M
    if (strcmp(Param, "ImagingBBox") == 0) {
138
0
        gs_param_float_array ibba;
139
0
        set_param_array(ibba, dev->ImagingBBox, 4);
140
0
        if (dev->ImagingBBox_set)
141
0
            return param_write_float_array(plist, "ImagingBBox", &ibba);
142
0
        else
143
0
            return param_write_null(plist, "ImagingBBox");
144
0
    }
145
4.63M
    if (strcmp(Param, "Margins") == 0) {
146
0
        gs_param_float_array ma;
147
0
        set_param_array(ma, dev->Margins, 2);
148
0
        return param_write_float_array(plist, "Margins", &ma);
149
0
    }
150
4.63M
    if (strcmp(Param, "MaxSeparations") == 0) {
151
0
        int max_sep = dev->color_info.max_components;
152
0
        return param_write_int(plist, "MaxSeparations", &max_sep);
153
0
    }
154
4.63M
    if (strcmp(Param, "NumCopies") == 0) {
155
0
        if (dev->NumCopies_set < 0 || (*dev_proc(dev, get_page_device))(dev) == 0) {
156
0
            return_error(gs_error_undefined);
157
0
        } else {
158
0
            if (dev->NumCopies_set)
159
0
                return param_write_int(plist, "NumCopies", &dev->NumCopies);
160
0
            else
161
0
                return param_write_null(plist, "NumCopies");
162
0
        }
163
0
    }
164
4.63M
    if (strcmp(Param, "SeparationColorNames") == 0) {
165
0
        gs_param_string_array scna;
166
0
        set_param_array(scna, NULL, 0);
167
0
        return param_write_name_array(plist, "SeparationColorNames", &scna);
168
0
    }
169
4.63M
    if (strcmp(Param, "Separations") == 0) {
170
0
        bool seprs = false;
171
0
        return param_write_bool(plist, "Separations", &seprs);
172
0
    }
173
4.63M
    if (strcmp(Param, "UseCIEColor") == 0) {
174
0
        return param_write_bool(plist, "UseCIEColor", &dev->UseCIEColor);
175
0
    }
176
177
    /* Non-standard parameters */
178
4.63M
    if (strcmp(Param, "HWSize") == 0) {
179
0
        int HWSize[2];
180
0
        gs_param_int_array hwsa;
181
182
0
        HWSize[0] = dev->width;
183
0
        HWSize[1] = dev->height;
184
0
        set_param_array(hwsa, HWSize, 2);
185
0
        return param_write_int_array(plist, "HWSize", &hwsa);
186
0
    }
187
4.63M
    if (strcmp(Param, ".HWMargins") == 0) {
188
0
        gs_param_float_array hwma;
189
0
        set_param_array(hwma, dev->HWMargins, 4);
190
0
        return param_write_float_array(plist, ".HWMargins", &hwma);
191
0
    }
192
4.63M
    if (strcmp(Param, ".MediaSize") == 0) {
193
0
        gs_param_float_array msa;
194
0
        set_param_array(msa, dev->MediaSize, 2);
195
0
        return param_write_float_array(plist, ".MediaSize", &msa);
196
0
    }
197
4.63M
    if (strcmp(Param, "Name") == 0) {
198
0
        gs_param_string dns;
199
0
        param_string_from_string(dns, dev->dname);
200
0
        return param_write_string(plist, "Name", &dns);
201
0
    }
202
4.63M
    if (strcmp(Param, "Colors") == 0) {
203
0
        int colors = dev->color_info.num_components;
204
0
        return param_write_int(plist, "Colors", &colors);
205
0
    }
206
4.63M
    if (strcmp(Param, "BitsPerPixel") == 0) {
207
0
        return param_write_int(plist, "BitsPerPixel", &depth);
208
0
    }
209
4.63M
    if (strcmp(Param, "GrayValues") == 0) {
210
0
        int GrayValues = dev->color_info.max_gray + 1;
211
0
        return param_write_int(plist, "GrayValues", &GrayValues);
212
0
    }
213
4.63M
    if (strcmp(Param, "PageCount") == 0) {
214
0
        return param_write_long(plist, "PageCount", &dev->PageCount);
215
0
    }
216
4.63M
    if (strcmp(Param, ".IgnoreNumCopies") == 0) {
217
0
        return param_write_bool(plist, ".IgnoreNumCopies", &dev->IgnoreNumCopies);
218
0
    }
219
4.63M
    if (strcmp(Param, "TextAlphaBits") == 0) {
220
0
        return param_write_int(plist, "TextAlphaBits",
221
0
                                &dev->color_info.anti_alias.text_bits);
222
0
    }
223
4.63M
    if (strcmp(Param, "GraphicsAlphaBits") == 0) {
224
0
        return param_write_int(plist, "GraphicsAlphaBits",
225
0
                                &dev->color_info.anti_alias.graphics_bits);
226
0
    }
227
4.63M
    if (strcmp(Param, "AntidropoutDownscaler") == 0) {
228
0
        return param_write_bool(plist, "AntidropoutDownscaler",
229
0
                                &dev->color_info.use_antidropout_downscaler);
230
0
    }
231
4.63M
    if (strcmp(Param, ".LockSafetyParams") == 0) {
232
0
        return param_write_bool(plist, ".LockSafetyParams", &dev->LockSafetyParams);
233
0
    }
234
4.63M
    if (strcmp(Param, "MaxPatternBitmap") == 0) {
235
0
        return param_write_size_t(plist, "MaxPatternBitmap", &dev->MaxPatternBitmap);
236
0
    }
237
4.63M
    if (strcmp(Param, "PageUsesTransparency") == 0) {
238
0
        return param_write_bool(plist, "PageUsesTransparency", &dev->page_uses_transparency);
239
0
    }
240
4.63M
    if (strcmp(Param, "PageUsesOverprint") == 0) {
241
0
        return param_write_bool(plist, "PageUsesOverprint", &dev->page_uses_overprint);
242
0
    }
243
4.63M
    if (strcmp(Param, "MaxBitmap") == 0) {
244
0
        return param_write_size_t(plist, "MaxBitmap", &(dev->space_params.MaxBitmap));
245
0
    }
246
4.63M
    if (strcmp(Param, "BandBufferSpace") == 0) {
247
0
        return param_write_size_t(plist, "BandBufferSpace", &dev->space_params.band.BandBufferSpace);
248
0
    }
249
4.63M
    if (strcmp(Param, "BandHeight") == 0) {
250
0
        return param_write_int(plist, "BandHeight", &dev->space_params.band.BandHeight);
251
0
    }
252
4.63M
    if (strcmp(Param, "BandWidth") == 0) {
253
0
        return param_write_int(plist, "BandWidth", &dev->space_params.band.BandWidth);
254
0
    }
255
4.63M
    if (strcmp(Param, "BufferSpace") == 0) {
256
0
        return param_write_size_t(plist, "BufferSpace", &dev->space_params.BufferSpace);
257
0
    }
258
4.63M
    if (strcmp(Param, "InterpolateControl") == 0) {
259
0
        int interpolate_control = dev->interpolate_control;
260
0
        return param_write_int(plist, "InterpolateControl", &interpolate_control);
261
0
    }
262
4.63M
    if (strcmp(Param, "LeadingEdge") == 0) {
263
0
        if (dev->LeadingEdge & LEADINGEDGE_SET_MASK) {
264
0
            int leadingedge = dev->LeadingEdge & LEADINGEDGE_MASK;
265
0
            return param_write_int(plist, "LeadingEdge", &leadingedge);
266
0
        } else
267
0
            return param_write_null(plist, "LeadingEdge");
268
0
    }
269
270
4.63M
    if (dev->color_info.num_components > 1) {
271
3.08M
        int RGBValues = dev->color_info.max_color + 1;
272
3.08M
        long ColorValues = (depth >= 32 ? -1 : 1L << depth); /* value can only be 32 bits */
273
274
3.08M
        if (strcmp(Param, "RedValues") == 0) {
275
0
            return param_write_int(plist, "RedValues", &RGBValues);
276
0
        }
277
3.08M
        if (strcmp(Param, "GreenValues") == 0) {
278
0
            return param_write_int(plist, "GreenValues", &RGBValues);
279
0
        }
280
3.08M
        if (strcmp(Param, "BlueValues") == 0) {
281
0
            return param_write_int(plist, "BlueValues", &RGBValues);
282
0
        }
283
3.08M
        if (strcmp(Param, "ColorValues") == 0) {
284
0
            return param_write_long(plist, "ColorValues", &ColorValues);
285
0
        }
286
3.08M
    }
287
4.63M
    if (strcmp(Param, "HWColorMap") == 0) {
288
0
        byte palette[3 << 8];
289
290
0
        if (param_HWColorMap(dev, palette)) {
291
0
            gs_param_string hwcms;
292
293
0
            hwcms.data = palette, hwcms.size = colors << depth,
294
0
                hwcms.persistent = false;
295
0
            return param_write_string(plist, "HWColorMap", &hwcms);
296
0
        }
297
0
    }
298
299
    /* ICC profiles */
300
    /* Check if the device profile is null.  If it is, then we need to
301
       go ahead and get it set up at this time.  If the proc is not
302
       set up yet then we are not going to do anything yet */
303
    /* Although device methods should not be NULL, they are not completely filled in until
304
     * gx_device_fill_in_procs is called, and its possible for us to get here before this
305
     * happens, so we *must* make sure the method is not NULL before we use it.
306
     */
307
4.63M
    if (dev_proc(dev, get_profile) != NULL) {
308
4.63M
        int code;
309
4.63M
        code = dev_proc(dev, get_profile)(dev,  &dev_profile);
310
4.63M
        if (code < 0)
311
0
            return code;
312
4.63M
        if (dev_profile == NULL) {
313
0
            code = gsicc_init_device_profile_struct(dev, NULL, 0);
314
0
            if (code < 0)
315
0
                return code;
316
0
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
317
0
            if (code < 0)
318
0
                return code;
319
0
        }
320
23.1M
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
321
18.5M
            if (dev_profile->device_profile[k] == NULL
322
18.5M
                || dev_profile->device_profile[k]->name == NULL) {
323
13.8M
                param_string_from_string(profile_array[k], null_str);
324
13.8M
                profile_intents[k] = gsRINOTSPECIFIED;
325
13.8M
                blackptcomps[k] = gsBPNOTSPECIFIED;
326
13.8M
                blackpreserve[k] = gsBKPRESNOTSPECIFIED;
327
13.8M
            } else {
328
4.63M
                param_string_from_transient_string(profile_array[k],
329
4.63M
                    dev_profile->device_profile[k]->name);
330
4.63M
                profile_intents[k] = dev_profile->rendercond[k].rendering_intent;
331
4.63M
                blackptcomps[k] = dev_profile->rendercond[k].black_point_comp;
332
4.63M
                blackpreserve[k] = dev_profile->rendercond[k].preserve_black;
333
4.63M
            }
334
18.5M
        }
335
4.63M
        if (dev_profile->blend_profile == NULL) {
336
4.63M
            param_string_from_string(blend_profile, null_str);
337
4.63M
        } else {
338
0
            param_string_from_transient_string(blend_profile,
339
0
                dev_profile->blend_profile->name);
340
0
        }
341
4.63M
        if (dev_profile->postren_profile == NULL) {
342
4.63M
            param_string_from_string(postren_profile, null_str);
343
4.63M
        } else {
344
0
            param_string_from_transient_string(postren_profile,
345
0
                dev_profile->postren_profile->name);
346
0
        }
347
4.63M
        if (dev_profile->proof_profile == NULL) {
348
4.63M
            param_string_from_string(proof_profile, null_str);
349
4.63M
        } else {
350
0
            param_string_from_transient_string(proof_profile,
351
0
                                     dev_profile->proof_profile->name);
352
0
        }
353
4.63M
        if (dev_profile->link_profile == NULL) {
354
4.63M
            param_string_from_string(link_profile, null_str);
355
4.63M
        } else {
356
0
            param_string_from_transient_string(link_profile,
357
0
                                     dev_profile->link_profile->name);
358
0
        }
359
4.63M
        devicegraytok = dev_profile->devicegraytok;
360
4.63M
        graydetection = dev_profile->graydetection;
361
4.63M
        usefastcolor = dev_profile->usefastcolor;
362
4.63M
        blacktext = dev_profile->blacktext;
363
4.63M
        blackvector = dev_profile->blackvector;
364
4.63M
        blackthresholdC = dev_profile->blackthresholdC;
365
4.63M
        blackthresholdL = dev_profile->blackthresholdL;
366
4.63M
        overprint_control = dev_profile->overprint_control;
367
4.63M
        prebandthreshold = dev_profile->prebandthreshold;
368
        /* With respect to Output profiles that have non-standard colorants,
369
           we rely upon the default profile to give us the colorants if they do
370
           exist. */
371
4.63M
        if (dev_profile->spotnames == NULL) {
372
4.63M
            param_string_from_string(icc_colorants, null_str);
373
4.63M
        } else {
374
0
            char *colorant_names;
375
376
0
            colorant_names =
377
0
                gsicc_get_dev_icccolorants(dev_profile);
378
0
            if (colorant_names != NULL) {
379
0
                param_string_from_transient_string(icc_colorants, colorant_names);
380
0
            } else {
381
0
                param_string_from_string(icc_colorants, null_str);
382
0
            }
383
0
        }
384
4.63M
    } else {
385
0
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
386
0
            param_string_from_string(profile_array[k], null_str);
387
0
            profile_intents[k] = gsRINOTSPECIFIED;
388
0
            blackptcomps[k] = gsBPNOTSPECIFIED;
389
0
            blackpreserve[k] = gsBKPRESNOTSPECIFIED;
390
0
        }
391
0
        param_string_from_string(blend_profile, null_str);
392
0
        param_string_from_string(postren_profile, null_str);
393
0
        param_string_from_string(proof_profile, null_str);
394
0
        param_string_from_string(link_profile, null_str);
395
0
        param_string_from_string(icc_colorants, null_str);
396
0
    }
397
4.63M
    if (strcmp(Param, "DeviceGrayToK") == 0) {
398
0
        return param_write_bool(plist, "DeviceGrayToK", &devicegraytok);
399
0
    }
400
4.63M
    if (strcmp(Param, "GrayDetection") == 0) {
401
0
        return param_write_bool(plist, "GrayDetection", &graydetection);
402
0
    }
403
4.63M
    if (strcmp(Param, "UseFastColor") == 0) {
404
0
        return param_write_bool(plist, "UseFastColor", &usefastcolor);
405
0
    }
406
4.63M
    if (strcmp(Param, "BlackText") == 0) {
407
0
        return param_write_bool(plist, "BlackText", &blacktext);
408
0
    }
409
4.63M
    if (strcmp(Param, "BlackVector") == 0) {
410
0
        return param_write_bool(plist, "BlackVector", &blackvector);
411
0
    }
412
4.63M
    if (strcmp(Param, "BlackThresholdL") == 0) {
413
0
        return param_write_float(plist, "BlackThresholdL", &blackthresholdL);
414
0
    }
415
4.63M
    if (strcmp(Param, "BlackThresholdC") == 0) {
416
0
        return param_write_float(plist, "BlackThresholdC", &blackthresholdC);
417
0
    }
418
4.63M
    if (strcmp(Param, "Overprint") == 0) {
419
0
        gs_param_string opc_name;
420
0
        const char *s = overprint_control_names[(int)overprint_control];
421
422
0
        param_string_from_string(opc_name, s);
423
0
        return param_write_name(plist, "Overprint", &opc_name);
424
0
    }
425
4.63M
    if (strcmp(Param, "PreBandThreshold") == 0) {
426
0
        return param_write_bool(plist, "PreBandThreshold", &prebandthreshold);
427
0
    }
428
4.63M
    if (strcmp(Param, "PostRenderProfile") == 0) {
429
0
        return param_write_string(plist, "PostRenderProfile", &(postren_profile));
430
0
    }
431
4.63M
    if (strcmp(Param, "BlendColorProfile") == 0) {
432
0
        return param_write_string(plist, "BlendColorProfile", &(blend_profile));
433
0
    }
434
4.63M
    if (strcmp(Param, "ProofProfile") == 0) {
435
0
        return param_write_string(plist,"ProofProfile", &(proof_profile));
436
0
    }
437
4.63M
    if (strcmp(Param, "DeviceLinkProfile") == 0) {
438
0
        return param_write_string(plist,"DeviceLinkProfile", &(link_profile));
439
0
    }
440
4.63M
    if (strcmp(Param, "ICCOutputColors") == 0) {
441
0
        return param_write_string(plist,"ICCOutputColors", &(icc_colorants));
442
0
    }
443
4.63M
    if (strcmp(Param, "OutputICCProfile") == 0) {
444
0
        return param_write_string(plist,"OutputICCProfile", &(profile_array[0]));
445
0
    }
446
4.63M
    if (strcmp(Param, "VectorICCProfile") == 0) {
447
0
        return param_write_string(plist,"VectorICCProfile", &(profile_array[1]));
448
0
    }
449
4.63M
    if (strcmp(Param, "ImageICCProfile") == 0) {
450
0
        return param_write_string(plist,"ImageICCProfile", &(profile_array[2]));
451
0
    }
452
4.63M
    if (strcmp(Param, "TextICCProfile") == 0) {
453
0
        return param_write_string(plist,"TextICCProfile", &(profile_array[3]));
454
0
    }
455
4.63M
    if (strcmp(Param, "ColorAccuracy") == 0) {
456
0
        return param_write_int(plist, "ColorAccuracy", (const int *)(&(color_accuracy)));
457
0
    }
458
4.63M
    if (strcmp(Param, "RenderIntent") == 0) {
459
0
        return param_write_int(plist,"RenderIntent", (const int *) (&(profile_intents[0])));
460
0
    }
461
4.63M
    if (strcmp(Param, "VectorIntent") == 0) {
462
0
        return param_write_int(plist,"VectorIntent", (const int *) &(profile_intents[1]));
463
0
    }
464
4.63M
    if (strcmp(Param, "ImageIntent") == 0) {
465
0
        return param_write_int(plist,"ImageIntent", (const int *) &(profile_intents[2]));
466
0
    }
467
4.63M
    if (strcmp(Param, "TextIntent") == 0) {
468
0
        return param_write_int(plist,"TextIntent", (const int *) &(profile_intents[3]));
469
0
    }
470
4.63M
    if (strcmp(Param, "BlackPtComp") == 0) {
471
0
        return param_write_int(plist,"BlackPtComp", (const int *) (&(blackptcomps[0])));
472
0
    }
473
4.63M
    if (strcmp(Param, "VectorBlackPt") == 0) {
474
0
        return param_write_int(plist,"VectorBlackPt", (const int *) &(blackptcomps[1]));
475
0
    }
476
4.63M
    if (strcmp(Param, "ImageBlackPt") == 0) {
477
0
        return param_write_int(plist,"ImageBlackPt", (const int *) &(blackptcomps[2]));
478
0
    }
479
4.63M
    if (strcmp(Param, "TextBlackPt") == 0) {
480
0
        return param_write_int(plist,"TextBlackPt", (const int *) &(blackptcomps[3]));
481
0
    }
482
4.63M
    if (strcmp(Param, "KPreserve") == 0) {
483
0
        return param_write_int(plist,"KPreserve", (const int *) (&(blackpreserve[0])));
484
0
    }
485
4.63M
    if (strcmp(Param, "VectorKPreserve") == 0) {
486
0
        return param_write_int(plist,"VectorKPreserve", (const int *) &(blackpreserve[1]));
487
0
    }
488
4.63M
    if (strcmp(Param, "ImageKPreserve") == 0) {
489
0
        return param_write_int(plist,"ImageKPreserve", (const int *) &(blackpreserve[2]));
490
0
    }
491
4.63M
    if (strcmp(Param, "TextKPreserve") == 0) {
492
0
        return param_write_int(plist,"TextKPreserve", (const int *) &(blackpreserve[3]));
493
0
    }
494
4.63M
    if (strcmp(Param, "FirstPage") == 0) {
495
0
        return param_write_int(plist, "FirstPage", &dev->FirstPage);
496
0
    }
497
4.63M
    if (strcmp(Param, "LastPage") == 0) {
498
0
        return param_write_int(plist, "LastPage", &dev->LastPage);
499
0
    }
500
4.63M
    if (strcmp(Param, "DisablePageHandler") == 0) {
501
0
        temp_bool = dev->DisablePageHandler;
502
0
        return param_write_bool(plist, "DisablePageHandler", &temp_bool);
503
0
    }
504
4.63M
    if (strcmp(Param, "NupControl") == 0){
505
0
        gs_param_string nupcontrol;
506
507
0
        if (dev->NupControl) {
508
0
            gdev_nupcontrol *p = (gdev_nupcontrol *)dev->NupControl;
509
0
            param_string_from_string(nupcontrol, p->nupcontrol_str);
510
0
        }
511
0
        else
512
0
            param_string_from_string(nupcontrol, null_str);
513
0
        return param_write_string(plist, "NupControl", &nupcontrol);
514
0
    }
515
4.63M
    if (strcmp(Param, "PageList") == 0){
516
0
        gs_param_string pagelist;
517
0
        if (dev->PageList) {
518
0
            gdev_pagelist *p = (gdev_pagelist *)dev->PageList;
519
0
            param_string_from_string(pagelist, p->Pages);
520
0
        }
521
0
        else
522
0
            param_string_from_string(pagelist, null_str);
523
0
        return param_write_string(plist, "PageList", &pagelist);
524
0
    }
525
4.63M
    if (strcmp(Param, "FILTERIMAGE") == 0) {
526
0
        temp_bool = dev->ObjectFilter & FILTERIMAGE;
527
0
        return param_write_bool(plist, "FILTERIMAGE", &temp_bool);
528
0
    }
529
4.63M
    if (strcmp(Param, "FILTERTEXT") == 0) {
530
0
        temp_bool = dev->ObjectFilter & FILTERTEXT;
531
0
        return param_write_bool(plist, "FILTERTEXT", &temp_bool);
532
0
    }
533
4.63M
    if (strcmp(Param, "FILTERVECTOR") == 0) {
534
0
        temp_bool = dev->ObjectFilter & FILTERVECTOR;
535
0
        return param_write_bool(plist, "FILTERVECTOR", &temp_bool);
536
0
    }
537
538
4.63M
    return_error(gs_error_undefined);
539
4.63M
}
540
541
/* Get standard parameters. */
542
int
543
gx_default_get_params(gx_device * dev, gs_param_list * plist)
544
1.96M
{
545
1.96M
    int code;
546
547
    /* Standard page device parameters: */
548
549
1.96M
    bool seprs = false;
550
1.96M
    gs_param_string dns, pcms, profile_array[NUM_DEVICE_PROFILES];
551
1.96M
    gs_param_string blend_profile, postren_profile, pagelist, nuplist;
552
1.96M
    gs_param_string proof_profile, link_profile, icc_colorants;
553
1.96M
    gsicc_rendering_intents_t profile_intents[NUM_DEVICE_PROFILES];
554
1.96M
    gsicc_blackptcomp_t blackptcomps[NUM_DEVICE_PROFILES];
555
1.96M
    gsicc_blackpreserve_t blackpreserve[NUM_DEVICE_PROFILES];
556
1.96M
    bool devicegraytok = true;  /* Default if device profile stuct not set */
557
1.96M
    bool graydetection = false;
558
1.96M
    bool usefastcolor = false;  /* set for unmanaged color */
559
1.96M
    bool blacktext = false;
560
1.96M
    bool blackvector = false;
561
1.96M
    float blackthresholdL = BLACKTHRESHOLDL;
562
1.96M
    float blackthresholdC = BLACKTHRESHOLDC;
563
    /* By default, only overprint if the device supports it */
564
1.96M
    gs_overprint_control_t overprint_control = gs_overprint_control_enable;
565
1.96M
    bool prebandthreshold = true, temp_bool;
566
1.96M
    int k;
567
1.96M
    int color_accuracy = MAX_COLOR_ACCURACY;
568
1.96M
    gs_param_float_array msa, ibba, hwra, ma;
569
1.96M
    gs_param_string_array scna;
570
1.96M
    char null_str[1]={'\0'};
571
572
1.96M
#define set_param_array(a, d, s)\
573
13.7M
  (a.data = d, a.size = s, a.persistent = false);
574
575
    /* Non-standard parameters: */
576
1.96M
    int colors = dev->color_info.num_components;
577
1.96M
    int mns = dev->color_info.max_components;
578
1.96M
    int depth = dev->color_info.depth;
579
1.96M
    int GrayValues = dev->color_info.max_gray + 1;
580
1.96M
    int HWSize[2];
581
1.96M
    gs_param_int_array hwsa;
582
1.96M
    gs_param_float_array hwma;
583
1.96M
    cmm_dev_profile_t *dev_profile;
584
585
    /* Fill in page device parameters. */
586
587
1.96M
    param_string_from_string(dns, dev->dname);
588
1.96M
    {
589
1.96M
        const char *cms = get_process_color_model_name(dev);
590
591
        /* We might have an uninitialized device with */
592
        /* color_info.num_components = 0.... */
593
1.96M
        if ((cms != NULL) && (*cms != '\0'))
594
1.96M
            param_string_from_string(pcms, cms);
595
0
        else
596
0
            pcms.data = 0;
597
1.96M
    }
598
599
1.96M
    set_param_array(hwra, dev->HWResolution, 2);
600
1.96M
    set_param_array(msa, dev->MediaSize, 2);
601
1.96M
    set_param_array(ibba, dev->ImagingBBox, 4);
602
1.96M
    set_param_array(ma, dev->Margins, 2);
603
1.96M
    set_param_array(scna, NULL, 0);
604
605
    /* Fill in non-standard parameters. */
606
1.96M
    HWSize[0] = dev->width;
607
1.96M
    HWSize[1] = dev->height;
608
1.96M
    set_param_array(hwsa, HWSize, 2);
609
1.96M
    set_param_array(hwma, dev->HWMargins, 4);
610
    /* Check if the device profile is null.  If it is, then we need to
611
       go ahead and get it set up at this time.  If the proc is not
612
       set up yet then we are not going to do anything yet */
613
    /* Although device methods should not be NULL, they are not completely filled in until
614
     * gx_device_fill_in_procs is called, and its possible for us to get here before this
615
     * happens, so we *must* make sure the method is not NULL before we use it.
616
     */
617
1.96M
    if (dev_proc(dev, get_profile) != NULL) {
618
1.78M
        code = dev_proc(dev, get_profile)(dev,  &dev_profile);
619
1.78M
        if (code < 0)
620
0
            return code;
621
622
1.78M
        if (dev_profile == NULL) {
623
0
            code = gsicc_init_device_profile_struct(dev, NULL, 0);
624
0
            if (code < 0)
625
0
                return code;
626
0
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
627
0
            if (code < 0)
628
0
                return code;
629
0
        }
630
        /* It is possible that the current device profile name is NULL if we
631
           have a pdf14 device in line with a transparency group that is in a
632
           color space specified from a source defined ICC profile. Check for
633
           that here to avoid any access violations.  Bug 692558 */
634
8.94M
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
635
7.15M
            if (dev_profile->device_profile[k] == NULL
636
7.15M
                || dev_profile->device_profile[k]->name == NULL) {
637
5.36M
                param_string_from_string(profile_array[k], null_str);
638
5.36M
                profile_intents[k] = gsRINOTSPECIFIED;
639
5.36M
                blackptcomps[k] = gsBPNOTSPECIFIED;
640
5.36M
                blackpreserve[k] = gsBKPRESNOTSPECIFIED;
641
5.36M
            } else {
642
1.78M
                param_string_from_transient_string(profile_array[k],
643
1.78M
                    dev_profile->device_profile[k]->name);
644
1.78M
                profile_intents[k] = dev_profile->rendercond[k].rendering_intent;
645
1.78M
                blackptcomps[k] = dev_profile->rendercond[k].black_point_comp;
646
1.78M
                blackpreserve[k] = dev_profile->rendercond[k].preserve_black;
647
1.78M
            }
648
7.15M
        }
649
        /* The proof, link and post render profile */
650
1.78M
        if (dev_profile->proof_profile == NULL) {
651
1.78M
            param_string_from_string(proof_profile, null_str);
652
1.78M
        } else {
653
0
            param_string_from_transient_string(proof_profile,
654
0
                                     dev_profile->proof_profile->name);
655
0
        }
656
1.78M
        if (dev_profile->link_profile == NULL) {
657
1.78M
            param_string_from_string(link_profile, null_str);
658
1.78M
        } else {
659
0
            param_string_from_transient_string(link_profile,
660
0
                                     dev_profile->link_profile->name);
661
0
        }
662
1.78M
        if (dev_profile->postren_profile == NULL) {
663
1.78M
            param_string_from_string(postren_profile, null_str);
664
1.78M
        } else {
665
0
            param_string_from_transient_string(postren_profile,
666
0
                dev_profile->postren_profile->name);
667
0
        }
668
1.78M
        if (dev_profile->blend_profile == NULL) {
669
1.78M
            param_string_from_string(blend_profile, null_str);
670
1.78M
        } else {
671
0
            param_string_from_transient_string(blend_profile,
672
0
                dev_profile->blend_profile->name);
673
0
        }
674
1.78M
        devicegraytok = dev_profile->devicegraytok;
675
1.78M
        graydetection = dev_profile->graydetection;
676
1.78M
        usefastcolor = dev_profile->usefastcolor;
677
1.78M
        blacktext = dev_profile->blacktext;
678
1.78M
        blackvector = dev_profile->blackvector;
679
1.78M
        blackthresholdC = dev_profile->blackthresholdC;
680
1.78M
        blackthresholdL = dev_profile->blackthresholdL;
681
1.78M
        overprint_control = dev_profile->overprint_control;
682
1.78M
        prebandthreshold = dev_profile->prebandthreshold;
683
        /* With respect to Output profiles that have non-standard colorants,
684
           we rely upon the default profile to give us the colorants if they do
685
           exist. */
686
1.78M
        if (dev_profile->spotnames == NULL) {
687
1.78M
            param_string_from_string(icc_colorants, null_str);
688
1.78M
        } else {
689
0
            char *colorant_names;
690
691
0
            colorant_names =
692
0
                gsicc_get_dev_icccolorants(dev_profile);
693
0
            if (colorant_names != NULL) {
694
0
                param_string_from_transient_string(icc_colorants, colorant_names);
695
0
            } else {
696
0
                param_string_from_string(icc_colorants, null_str);
697
0
            }
698
0
        }
699
1.78M
    } else {
700
892k
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
701
714k
            param_string_from_string(profile_array[k], null_str);
702
714k
            profile_intents[k] = gsRINOTSPECIFIED;
703
714k
            blackptcomps[k] = gsBPNOTSPECIFIED;
704
714k
            blackpreserve[k] = gsBKPRESNOTSPECIFIED;
705
714k
        }
706
178k
        param_string_from_string(proof_profile, null_str);
707
178k
        param_string_from_string(link_profile, null_str);
708
178k
        param_string_from_string(icc_colorants, null_str);
709
178k
        param_string_from_string(postren_profile, null_str);
710
178k
        param_string_from_string(blend_profile, null_str);
711
178k
    }
712
    /* Transmit the values. */
713
    /* Standard parameters */
714
1.96M
    if (
715
1.96M
        (code = param_write_name(plist, "OutputDevice", &dns)) < 0 ||
716
1.96M
#ifdef PAGESIZE_IS_MEDIASIZE
717
1.96M
        (code = param_write_float_array(plist, "PageSize", &msa)) < 0 ||
718
1.96M
#endif
719
1.96M
        (code = (pcms.data == 0 ? 0 :
720
1.96M
                 param_write_name(plist, "ProcessColorModel", &pcms))) < 0 ||
721
1.96M
        (code = param_write_float_array(plist, "HWResolution", &hwra)) < 0 ||
722
1.96M
        (code = (dev->ImagingBBox_set ?
723
0
                 param_write_float_array(plist, "ImagingBBox", &ibba) :
724
1.96M
                 param_write_null(plist, "ImagingBBox"))) < 0 ||
725
1.96M
        (code = param_write_float_array(plist, "Margins", &ma)) < 0 ||
726
1.96M
        (code = param_write_int(plist, "MaxSeparations", &mns)) < 0 ||
727
1.96M
        (code = (dev->NumCopies_set < 0 ||
728
1.96M
                 (*dev_proc(dev, get_page_device))(dev) == 0 ? 0:
729
1.96M
                 dev->NumCopies_set ?
730
0
                 param_write_int(plist, "NumCopies", &dev->NumCopies) :
731
1.96M
                 param_write_null(plist, "NumCopies"))) < 0 ||
732
1.96M
        (code = param_write_name_array(plist, "SeparationColorNames", &scna)) < 0 ||
733
1.96M
        (code = param_write_bool(plist, "Separations", &seprs)) < 0 ||
734
1.96M
        (code = param_write_bool(plist, "UseCIEColor", &dev->UseCIEColor)) < 0 ||
735
        /* Non-standard parameters */
736
        /* Note:  if change is made in NUM_DEVICE_PROFILES we need to name
737
           that profile here for the device parameter on the command line */
738
1.96M
        (code = param_write_bool(plist, "DeviceGrayToK", &devicegraytok)) < 0 ||
739
1.96M
        (code = param_write_bool(plist, "GrayDetection", &graydetection)) < 0 ||
740
1.96M
        (code = param_write_bool(plist, "UseFastColor", &usefastcolor)) < 0 ||
741
1.96M
        (code = param_write_bool(plist, "BlackText", &blacktext)) < 0 ||
742
1.96M
        (code = param_write_bool(plist, "BlackVector", &blackvector)) < 0 ||
743
1.96M
        (code = param_write_float(plist, "BlackThresholdL", &blackthresholdL)) < 0 ||
744
1.96M
        (code = param_write_float(plist, "BlackThresholdC", &blackthresholdC)) < 0 ||
745
1.96M
        (code = param_write_bool(plist, "PreBandThreshold", &prebandthreshold)) < 0 ||
746
1.96M
        (code = param_write_string(plist,"OutputICCProfile", &(profile_array[0]))) < 0 ||
747
1.96M
        (code = param_write_string(plist,"VectorICCProfile", &(profile_array[1]))) < 0 ||
748
1.96M
        (code = param_write_string(plist,"ImageICCProfile", &(profile_array[2]))) < 0 ||
749
1.96M
        (code = param_write_string(plist,"TextICCProfile", &(profile_array[3]))) < 0 ||
750
1.96M
        (code = param_write_string(plist,"ProofProfile", &(proof_profile))) < 0 ||
751
1.96M
        (code = param_write_string(plist, "PostRenderProfile", &(postren_profile))) < 0 ||
752
1.96M
        (code = param_write_string(plist, "BlendColorProfile", &(blend_profile))) < 0 ||
753
1.96M
        (code = param_write_string(plist,"DeviceLinkProfile", &(link_profile))) < 0 ||
754
1.96M
        (code = param_write_string(plist,"ICCOutputColors", &(icc_colorants))) < 0 ||
755
1.96M
        (code = param_write_int(plist, "RenderIntent", (const int *)(&(profile_intents[0])))) < 0 ||
756
1.96M
        (code = param_write_int(plist, "ColorAccuracy", (const int *)(&(color_accuracy)))) < 0 ||
757
1.96M
        (code = param_write_int(plist,"VectorIntent", (const int *) &(profile_intents[1]))) < 0 ||
758
1.96M
        (code = param_write_int(plist,"ImageIntent", (const int *) &(profile_intents[2]))) < 0 ||
759
1.96M
        (code = param_write_int(plist,"TextIntent", (const int *) &(profile_intents[3]))) < 0 ||
760
1.96M
        (code = param_write_int(plist,"BlackPtComp", (const int *) (&(blackptcomps[0])))) < 0 ||
761
1.96M
        (code = param_write_int(plist,"VectorBlackPt", (const int *) &(blackptcomps[1]))) < 0 ||
762
1.96M
        (code = param_write_int(plist,"ImageBlackPt", (const int *) &(blackptcomps[2]))) < 0 ||
763
1.96M
        (code = param_write_int(plist,"TextBlackPt", (const int *) &(blackptcomps[3]))) < 0 ||
764
1.96M
        (code = param_write_int(plist,"KPreserve", (const int *) (&(blackpreserve[0])))) < 0 ||
765
1.96M
        (code = param_write_int(plist,"VectorKPreserve", (const int *) &(blackpreserve[1]))) < 0 ||
766
1.96M
        (code = param_write_int(plist,"ImageKPreserve", (const int *) &(blackpreserve[2]))) < 0 ||
767
1.96M
        (code = param_write_int(plist,"TextKPreserve", (const int *) &(blackpreserve[3]))) < 0 ||
768
1.96M
        (code = param_write_int_array(plist, "HWSize", &hwsa)) < 0 ||
769
1.96M
        (code = param_write_float_array(plist, ".HWMargins", &hwma)) < 0 ||
770
1.96M
        (code = param_write_float_array(plist, ".MediaSize", &msa)) < 0 ||
771
1.96M
        (code = param_write_string(plist, "Name", &dns)) < 0 ||
772
1.96M
        (code = param_write_int(plist, "Colors", &colors)) < 0 ||
773
1.96M
        (code = param_write_int(plist, "BitsPerPixel", &depth)) < 0 ||
774
1.96M
        (code = param_write_int(plist, "GrayValues", &GrayValues)) < 0 ||
775
1.96M
        (code = param_write_long(plist, "PageCount", &dev->PageCount)) < 0 ||
776
1.96M
        (code = param_write_bool(plist, ".IgnoreNumCopies", &dev->IgnoreNumCopies)) < 0 ||
777
1.96M
        (code = param_write_int(plist, "TextAlphaBits",
778
1.96M
                                &dev->color_info.anti_alias.text_bits)) < 0 ||
779
1.96M
        (code = param_write_int(plist, "GraphicsAlphaBits",
780
1.96M
                                &dev->color_info.anti_alias.graphics_bits)) < 0 ||
781
1.96M
        (code = param_write_bool(plist, "AntidropoutDownscaler",
782
1.96M
                                &dev->color_info.use_antidropout_downscaler)) < 0 ||
783
1.96M
        (code = param_write_bool(plist, ".LockSafetyParams", &dev->LockSafetyParams)) < 0 ||
784
1.96M
        (code = param_write_size_t(plist, "MaxPatternBitmap", &dev->MaxPatternBitmap)) < 0 ||
785
1.96M
        (code = param_write_bool(plist, "PageUsesTransparency", &dev->page_uses_transparency)) < 0 ||
786
1.96M
        (code = param_write_bool(plist, "PageUsesOverprint", &dev->page_uses_overprint)) < 0 ||
787
1.96M
        (code = param_write_size_t(plist, "MaxBitmap", &(dev->space_params.MaxBitmap))) < 0 ||
788
1.96M
        (code = param_write_size_t(plist, "BandBufferSpace", &dev->space_params.band.BandBufferSpace)) < 0 ||
789
1.96M
        (code = param_write_int(plist, "BandHeight", &dev->space_params.band.BandHeight)) < 0 ||
790
1.96M
        (code = param_write_int(plist, "BandWidth", &dev->space_params.band.BandWidth)) < 0 ||
791
1.96M
        (code = param_write_size_t(plist, "BufferSpace", &dev->space_params.BufferSpace)) < 0 ||
792
1.96M
        (code = param_write_int(plist, "InterpolateControl", &dev->interpolate_control)) < 0
793
1.96M
        )
794
0
        return code;
795
1.96M
    {
796
1.96M
        gs_param_string opc_name;
797
1.96M
        const char *s = overprint_control_names[(int)overprint_control];
798
799
1.96M
        param_string_from_string(opc_name, s);
800
1.96M
        param_write_name(plist, "Overprint", &opc_name);
801
1.96M
    }
802
    /* If LeadingEdge was set explicitly, report it here. */
803
1.96M
    if (dev->LeadingEdge & LEADINGEDGE_SET_MASK) {
804
0
        int leadingedge = dev->LeadingEdge & LEADINGEDGE_MASK;
805
0
        code = param_write_int(plist, "LeadingEdge", &leadingedge);
806
0
    } else
807
1.96M
        code = param_write_null(plist, "LeadingEdge");
808
1.96M
    if (code < 0)
809
0
        return code;
810
811
1.96M
    if ((code = param_write_int(plist, "FirstPage", &dev->FirstPage)) < 0)
812
0
        return code;
813
1.96M
    if ((code = param_write_int(plist, "LastPage", &dev->LastPage)) < 0)
814
0
        return code;
815
816
1.96M
    temp_bool = dev->DisablePageHandler;
817
1.96M
    if ((code = param_write_bool(plist, "DisablePageHandler", &temp_bool)) < 0)
818
0
        return code;
819
820
1.96M
    if (dev->NupControl) {
821
0
        gdev_nupcontrol *p = (gdev_nupcontrol *)dev->NupControl;
822
0
        param_string_from_string(nuplist, p->nupcontrol_str);
823
1.96M
    } else {
824
1.96M
        param_string_from_string(nuplist, null_str);
825
1.96M
    }
826
1.96M
    if ((code = param_write_string(plist, "NupControl", &nuplist)) < 0)
827
0
        return code;
828
829
1.96M
    if (dev->PageList) {
830
0
        gdev_pagelist *p = (gdev_pagelist *)dev->PageList;
831
0
        param_string_from_transient_string(pagelist, p->Pages);
832
1.96M
    } else {
833
1.96M
        param_string_from_string(pagelist, null_str);
834
1.96M
    }
835
1.96M
    if ((code = param_write_string(plist, "PageList", &pagelist)) < 0)
836
0
        return code;
837
838
1.96M
    temp_bool = dev->ObjectFilter & FILTERIMAGE;
839
1.96M
    if ((code = param_write_bool(plist, "FILTERIMAGE", &temp_bool)) < 0)
840
0
        return code;
841
1.96M
    temp_bool = dev->ObjectFilter & FILTERTEXT;
842
1.96M
    if ((code = param_write_bool(plist, "FILTERTEXT", &temp_bool)) < 0)
843
0
        return code;
844
1.96M
    temp_bool = dev->ObjectFilter & FILTERVECTOR;
845
1.96M
    if ((code = param_write_bool(plist, "FILTERVECTOR", &temp_bool)) < 0)
846
0
        return code;
847
848
    /* Fill in color information. */
849
850
1.96M
    if (colors > 1) {
851
1.46M
        int RGBValues = dev->color_info.max_color + 1;
852
1.46M
        long ColorValues = (depth >= 32 ? -1 : 1L << depth); /* value can only be 32 bits */
853
854
1.46M
        if ((code = param_write_int(plist, "RedValues", &RGBValues)) < 0 ||
855
1.46M
            (code = param_write_int(plist, "GreenValues", &RGBValues)) < 0 ||
856
1.46M
            (code = param_write_int(plist, "BlueValues", &RGBValues)) < 0 ||
857
1.46M
            (code = param_write_long(plist, "ColorValues", &ColorValues)) < 0
858
1.46M
            )
859
0
            return code;
860
1.46M
    }
861
1.96M
    if (param_requested(plist, "HWColorMap")) {
862
267k
        byte palette[3 << 8];
863
864
267k
        if (param_HWColorMap(dev, palette)) {
865
121k
            gs_param_string hwcms;
866
867
121k
            hwcms.data = palette, hwcms.size = colors << depth,
868
121k
                hwcms.persistent = false;
869
121k
            if ((code = param_write_string(plist, "HWColorMap", &hwcms)) < 0)
870
0
                return code;
871
121k
        }
872
267k
    }
873
874
1.96M
    return 0;
875
1.96M
}
876
877
/* Get the color map for a device.  Return true if there is one. */
878
static bool
879
param_HWColorMap(gx_device * dev, byte * palette /* 3 << 8 */ )
880
267k
{
881
267k
    int depth = dev->color_info.depth;
882
267k
    int colors = dev->color_info.num_components;
883
884
267k
    if (depth <= 8 && colors <= 3) {
885
121k
        byte *p = palette;
886
121k
        gx_color_value rgb[3];
887
121k
        gx_color_index i;
888
889
121k
        fill_dev_proc(dev, map_color_rgb, gx_default_map_color_rgb);
890
11.0M
        for (i = 0; (i >> depth) == 0; i++) {
891
10.9M
            int j;
892
893
10.9M
            if ((*dev_proc(dev, map_color_rgb)) (dev, i, rgb) < 0)
894
0
                return false;
895
22.6M
            for (j = 0; j < colors; j++)
896
11.7M
                *p++ = gx_color_value_to_byte(rgb[j]);
897
10.9M
        }
898
121k
        return true;
899
121k
    }
900
146k
    return false;
901
267k
}
902
903
/* Get hardware-detected parameters. Default action is no hardware params. */
904
int
905
gx_default_get_hardware_params(gx_device * dev, gs_param_list * plist)
906
0
{
907
0
    return 0;
908
0
}
909
910
/* ---------------- Input and output media ---------------- */
911
912
/* Finish defining input or output media. */
913
static int
914
finish_media(gs_param_list * mlist, gs_param_name key, const char *media_type)
915
0
{
916
0
    int code = 0;
917
918
0
    if (media_type != 0) {
919
0
        gs_param_string as;
920
921
0
        param_string_from_string(as, media_type);
922
0
        code = param_write_string(mlist, key, &as);
923
0
    }
924
0
    return code;
925
0
}
926
927
/* Define input media. */
928
929
const gdev_input_media_t gdev_input_media_default =
930
{
931
    gdev_input_media_default_values
932
};
933
934
int
935
gdev_begin_input_media(gs_param_list * mlist, gs_param_dict * pdict,
936
                       int count)
937
0
{
938
0
    pdict->size = count;
939
0
    return param_begin_write_dict(mlist, "InputAttributes", pdict, true);
940
0
}
941
942
int
943
gdev_write_input_media(int index, gs_param_dict * pdict,
944
                       const gdev_input_media_t * pim)
945
0
{
946
0
    char key[25];
947
0
    gs_param_dict mdict;
948
0
    int code;
949
0
    gs_param_string as;
950
951
0
    gs_snprintf(key, sizeof(key), "%d", index);
952
0
    mdict.size = 4;
953
0
    code = param_begin_write_dict(pdict->list, key, &mdict, false);
954
0
    if (code < 0)
955
0
        return code;
956
0
    if ((pim->PageSize[0] != 0 && pim->PageSize[1] != 0) ||
957
0
        (pim->PageSize[2] != 0 && pim->PageSize[3] != 0)
958
0
        ) {
959
0
        gs_param_float_array psa;
960
961
0
        psa.data = pim->PageSize;
962
0
        psa.size =
963
0
            (pim->PageSize[0] == pim->PageSize[2] &&
964
0
             pim->PageSize[1] == pim->PageSize[3] ? 2 : 4);
965
0
        psa.persistent = false;
966
0
        code = param_write_float_array(mdict.list, "PageSize",
967
0
                                       &psa);
968
0
        if (code < 0)
969
0
            return code;
970
0
    }
971
0
    if (pim->MediaColor != 0) {
972
0
        param_string_from_string(as, pim->MediaColor);
973
0
        code = param_write_string(mdict.list, "MediaColor",
974
0
                                  &as);
975
0
        if (code < 0)
976
0
            return code;
977
0
    }
978
0
    if (pim->MediaWeight != 0) {
979
        /*
980
         * We do the following silly thing in order to avoid
981
         * having to work around the 'const' in the arg list.
982
         */
983
0
        float weight = pim->MediaWeight;
984
985
0
        code = param_write_float(mdict.list, "MediaWeight",
986
0
                                 &weight);
987
0
        if (code < 0)
988
0
            return code;
989
0
    }
990
0
    code = finish_media(mdict.list, "MediaType", pim->MediaType);
991
0
    if (code < 0)
992
0
        return code;
993
0
    return param_end_write_dict(pdict->list, key, &mdict);
994
0
}
995
996
int
997
gdev_write_input_page_size(int index, gs_param_dict * pdict,
998
                           double width_points, double height_points)
999
0
{
1000
0
    gdev_input_media_t media;
1001
1002
0
    media.PageSize[0] = media.PageSize[2] = (float) width_points;
1003
0
    media.PageSize[1] = media.PageSize[3] = (float) height_points;
1004
0
    media.MediaColor = 0;
1005
0
    media.MediaWeight = 0;
1006
0
    media.MediaType = 0;
1007
0
    return gdev_write_input_media(index, pdict, &media);
1008
0
}
1009
1010
int
1011
gdev_end_input_media(gs_param_list * mlist, gs_param_dict * pdict)
1012
0
{
1013
0
    return param_end_write_dict(mlist, "InputAttributes", pdict);
1014
0
}
1015
1016
/* Define output media. */
1017
1018
const gdev_output_media_t gdev_output_media_default =
1019
{
1020
    gdev_output_media_default_values
1021
};
1022
1023
int
1024
gdev_begin_output_media(gs_param_list * mlist, gs_param_dict * pdict,
1025
                        int count)
1026
0
{
1027
0
    pdict->size = count;
1028
0
    return param_begin_write_dict(mlist, "OutputAttributes", pdict, true);
1029
0
}
1030
1031
int
1032
gdev_write_output_media(int index, gs_param_dict * pdict,
1033
                        const gdev_output_media_t * pom)
1034
0
{
1035
0
    char key[25];
1036
0
    gs_param_dict mdict;
1037
0
    int code;
1038
1039
0
    gs_snprintf(key, sizeof(key), "%d", index);
1040
0
    mdict.size = 4;
1041
0
    code = param_begin_write_dict(pdict->list, key, &mdict, false);
1042
0
    if (code < 0)
1043
0
        return code;
1044
0
    code = finish_media(mdict.list, "OutputType", pom->OutputType);
1045
0
    if (code < 0)
1046
0
        return code;
1047
0
    return param_end_write_dict(pdict->list, key, &mdict);
1048
0
}
1049
1050
int
1051
gdev_end_output_media(gs_param_list * mlist, gs_param_dict * pdict)
1052
0
{
1053
0
    return param_end_write_dict(mlist, "OutputAttributes", pdict);
1054
0
}
1055
1056
/* ================ Putting parameters ================ */
1057
1058
/* Forward references */
1059
static int param_normalize_anti_alias_bits( uint max_gray, int bits );
1060
static int param_anti_alias_bits(gs_param_list *, gs_param_name, int *);
1061
static int param_MediaSize(gs_param_list *, gs_param_name,
1062
                            const float *, gs_param_float_array *);
1063
1064
static int param_check_bool(gs_param_list *, gs_param_name, bool, bool);
1065
static int param_check_long(gs_param_list *, gs_param_name, long, bool);
1066
#define param_check_int(plist, pname, ival, is_defined)\
1067
4.87M
  param_check_long(plist, pname, (long)(ival), is_defined)
1068
static int param_check_bytes(gs_param_list *, gs_param_name, const byte *,
1069
                              uint, bool);
1070
#define param_check_string(plist, pname, str, is_defined)\
1071
2.43M
  param_check_bytes(plist, pname, (const byte *)(str), \
1072
2.43M
                    (is_defined) ? strlen(str) : 0, is_defined)
1073
1074
/* Set the device parameters. */
1075
/* If the device was open and the put_params procedure closed it, */
1076
/* return 1; otherwise, return 0 or an error code as usual. */
1077
int
1078
gs_putdeviceparams(gx_device * dev, gs_param_list * plist)
1079
902k
{
1080
902k
    bool was_open = dev->is_open;
1081
902k
    int code;
1082
1083
    /* gs_param_list_dump(plist); */
1084
1085
902k
    fill_dev_proc(dev, put_params, gx_default_put_params);
1086
902k
    fill_dev_proc(dev, get_alpha_bits, gx_default_get_alpha_bits);
1087
902k
    code = (*dev_proc(dev, put_params)) (dev, plist);
1088
902k
    return (code < 0 ? code : was_open && !dev->is_open ? 1 : code);
1089
902k
}
1090
1091
static int
1092
gx_default_put_graydetection(bool graydetection, gx_device * dev)
1093
812k
{
1094
812k
    int code = 0;
1095
812k
    cmm_dev_profile_t *profile_struct;
1096
1097
    /* Although device methods should not be NULL, they are not completely filled in until
1098
     * gx_device_fill_in_procs is called, and its possible for us to get here before this
1099
     * happens, so we *must* make sure the method is not NULL before we use it.
1100
     */
1101
812k
    if (dev_proc(dev, get_profile) == NULL) {
1102
        /* This is an odd case where the device has not yet fully been
1103
           set up with its procedures yet.  We want to make sure that
1104
           we catch this so we assume here that we are dealing with
1105
           the target device.  For now allocate the profile structure
1106
           but do not intialize the profile yet as the color info
1107
           may not be fully set up at this time.  */
1108
324k
        if (dev->icc_struct == NULL) {
1109
            /* Allocate at this time the structure */
1110
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1111
0
        }
1112
324k
        dev->icc_struct->graydetection = graydetection;
1113
324k
        dev->icc_struct->pageneutralcolor = graydetection;
1114
487k
    } else {
1115
487k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1116
487k
        if (profile_struct == NULL) {
1117
            /* Create now  */
1118
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1119
0
            profile_struct =  dev->icc_struct;
1120
0
        }
1121
487k
        profile_struct->graydetection = graydetection;
1122
487k
        profile_struct->pageneutralcolor = graydetection;
1123
487k
    }
1124
812k
    return code;
1125
812k
}
1126
1127
static int
1128
gx_default_put_graytok(bool graytok, gx_device * dev)
1129
812k
{
1130
812k
    int code = 0;
1131
812k
    cmm_dev_profile_t *profile_struct;
1132
1133
    /* Although device methods should not be NULL, they are not completely filled in until
1134
     * gx_device_fill_in_procs is called, and its possible for us to get here before this
1135
     * happens, so we *must* make sure the method is not NULL before we use it.
1136
     */
1137
812k
    if (dev_proc(dev, get_profile) == NULL) {
1138
        /* This is an odd case where the device has not yet fully been
1139
           set up with its procedures yet.  We want to make sure that
1140
           we catch this so we assume here that we are dealing with
1141
           the target device.  For now allocate the profile structure
1142
           but do not intialize the profile yet as the color info
1143
           may not be fully set up at this time.  */
1144
324k
        if (dev->icc_struct == NULL) {
1145
            /* Allocate at this time the structure */
1146
143k
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1147
143k
            if (dev->icc_struct == NULL)
1148
0
                return_error(gs_error_VMerror);
1149
143k
        }
1150
324k
        dev->icc_struct->devicegraytok = graytok;
1151
487k
    } else {
1152
487k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1153
487k
        if (profile_struct == NULL) {
1154
            /* Create now  */
1155
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1156
0
            profile_struct =  dev->icc_struct;
1157
0
            if (profile_struct == NULL)
1158
0
                return_error(gs_error_VMerror);
1159
0
        }
1160
487k
        profile_struct->devicegraytok = graytok;
1161
487k
    }
1162
812k
    return code;
1163
812k
}
1164
1165
static int
1166
gx_default_put_prebandthreshold(bool prebandthreshold, gx_device * dev)
1167
812k
{
1168
812k
    int code = 0;
1169
812k
    cmm_dev_profile_t *profile_struct;
1170
1171
    /* Although device methods should not be NULL, they are not completely filled in until
1172
     * gx_device_fill_in_procs is called, and its possible for us to get here before this
1173
     * happens, so we *must* make sure the method is not NULL before we use it.
1174
     */
1175
812k
    if (dev_proc(dev, get_profile) == NULL) {
1176
        /* This is an odd case where the device has not yet fully been
1177
           set up with its procedures yet.  We want to make sure that
1178
           we catch this so we assume here that we are dealing with
1179
           the target device.  For now allocate the profile structure
1180
           but do not intialize the profile yet as the color info
1181
           may not be fully set up at this time.  */
1182
324k
        if (dev->icc_struct == NULL) {
1183
            /* Allocate at this time the structure */
1184
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1185
0
            if (dev->icc_struct == NULL)
1186
0
                return_error(gs_error_VMerror);
1187
0
        }
1188
324k
        dev->icc_struct->prebandthreshold = prebandthreshold;
1189
487k
    } else {
1190
487k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1191
487k
        if (profile_struct == NULL) {
1192
            /* Create now  */
1193
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1194
0
            profile_struct =  dev->icc_struct;
1195
0
            if (profile_struct == NULL)
1196
0
                return_error(gs_error_VMerror);
1197
0
        }
1198
487k
        profile_struct->prebandthreshold = prebandthreshold;
1199
487k
    }
1200
812k
    return code;
1201
812k
}
1202
1203
static int
1204
gx_default_put_usefastcolor(bool fastcolor, gx_device * dev)
1205
812k
{
1206
812k
    int code = 0;
1207
812k
    cmm_dev_profile_t *profile_struct;
1208
1209
    /* Although device methods should not be NULL, they are not completely filled in until
1210
     * gx_device_fill_in_procs is called, and its possible for us to get here before this
1211
     * happens, so we *must* make sure the method is not NULL before we use it.
1212
     */
1213
812k
    if (dev_proc(dev, get_profile) == NULL) {
1214
        /* This is an odd case where the device has not yet fully been
1215
           set up with its procedures yet.  We want to make sure that
1216
           we catch this so we assume here that we are dealing with
1217
           the target device.  For now allocate the profile structure
1218
           but do not intialize the profile yet as the color info
1219
           may not be fully set up at this time.  */
1220
324k
        if (dev->icc_struct == NULL) {
1221
            /* Allocate at this time the structure */
1222
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1223
0
            if (dev->icc_struct == NULL)
1224
0
                return_error(gs_error_VMerror);
1225
0
        }
1226
324k
        dev->icc_struct->usefastcolor = fastcolor;
1227
487k
    } else {
1228
487k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1229
487k
        if (profile_struct == NULL) {
1230
            /* Create now  */
1231
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1232
0
            profile_struct =  dev->icc_struct;
1233
0
            if (profile_struct == NULL)
1234
0
                return_error(gs_error_VMerror);
1235
0
        }
1236
487k
        profile_struct->usefastcolor = fastcolor;
1237
487k
    }
1238
812k
    return code;
1239
812k
}
1240
1241
static int
1242
gx_default_put_blacktext(bool blacktext, gx_device* dev)
1243
812k
{
1244
812k
    int code = 0;
1245
812k
    cmm_dev_profile_t* profile_struct;
1246
1247
812k
    if (dev_proc(dev, get_profile) == NULL) {
1248
324k
        if (dev->icc_struct == NULL) {
1249
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1250
0
            if (dev->icc_struct == NULL)
1251
0
                return_error(gs_error_VMerror);
1252
0
        }
1253
324k
        dev->icc_struct->blacktext = blacktext;
1254
487k
    } else {
1255
487k
        code = dev_proc(dev, get_profile)(dev, &profile_struct);
1256
487k
        if (profile_struct == NULL) {
1257
            /* Create now  */
1258
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1259
0
            profile_struct = dev->icc_struct;
1260
0
            if (profile_struct == NULL)
1261
0
                return_error(gs_error_VMerror);
1262
0
        }
1263
487k
        profile_struct->blacktext = blacktext;
1264
487k
    }
1265
812k
    return code;
1266
812k
}
1267
1268
static int
1269
gx_default_put_blackthresholds(float blackthresholdL, float blackthresholdC, gx_device *dev)
1270
812k
{
1271
812k
    int code = 0;
1272
812k
    cmm_dev_profile_t* profile_struct;
1273
1274
812k
    if (dev_proc(dev, get_profile) == NULL) {
1275
324k
        if (dev->icc_struct == NULL) {
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
324k
        dev->icc_struct->blackthresholdL = blackthresholdL;
1281
324k
        dev->icc_struct->blackthresholdC = blackthresholdC;
1282
487k
    } else {
1283
487k
        code = dev_proc(dev, get_profile)(dev, &profile_struct);
1284
487k
        if (profile_struct == NULL) {
1285
            /* Create now  */
1286
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1287
0
            profile_struct = dev->icc_struct;
1288
0
            if (profile_struct == NULL)
1289
0
                return_error(gs_error_VMerror);
1290
0
        }
1291
487k
        profile_struct->blackthresholdL = blackthresholdL;
1292
487k
        profile_struct->blackthresholdC = blackthresholdC;
1293
487k
    }
1294
812k
    return code;
1295
812k
}
1296
1297
static int
1298
gx_default_put_blackvector(bool blackvector, gx_device* dev)
1299
812k
{
1300
812k
    int code = 0;
1301
812k
    cmm_dev_profile_t* profile_struct;
1302
1303
812k
    if (dev_proc(dev, get_profile) == NULL) {
1304
324k
        if (dev->icc_struct == NULL) {
1305
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1306
0
            if (dev->icc_struct == NULL)
1307
0
                return_error(gs_error_VMerror);
1308
0
        }
1309
324k
        dev->icc_struct->blackvector = blackvector;
1310
487k
    } else {
1311
487k
        code = dev_proc(dev, get_profile)(dev, &profile_struct);
1312
487k
        if (profile_struct == NULL) {
1313
            /* Create now  */
1314
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1315
0
            profile_struct = dev->icc_struct;
1316
0
            if (profile_struct == NULL)
1317
0
                return_error(gs_error_VMerror);
1318
0
        }
1319
487k
        profile_struct->blackvector = blackvector;
1320
487k
    }
1321
812k
    return code;
1322
812k
}
1323
1324
static int
1325
gx_default_put_overprint_control(gs_overprint_control_t overprint_control, gx_device * dev)
1326
812k
{
1327
812k
    int code = 0;
1328
812k
    cmm_dev_profile_t *profile_struct;
1329
1330
    /* Although device methods should not be NULL, they are not completely filled in until
1331
     * gx_device_fill_in_procs is called, and its possible for us to get here before this
1332
     * happens, so we *must* make sure the method is not NULL before we use it.
1333
     */
1334
812k
    if (dev_proc(dev, get_profile) == NULL) {
1335
        /* This is an odd case where the device has not yet fully been
1336
           set up with its procedures yet.  We want to make sure that
1337
           we catch this so we assume here that we are dealing with
1338
           the target device.  For now allocate the profile structure
1339
           but do not intialize the profile yet as the color info
1340
           may not be fully set up at this time.  */
1341
324k
        if (dev->icc_struct == NULL) {
1342
            /* Allocate at this time the structure */
1343
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1344
0
            if (dev->icc_struct == NULL)
1345
0
                return_error(gs_error_VMerror);
1346
0
        }
1347
324k
        dev->icc_struct->overprint_control = overprint_control;
1348
487k
    } else {
1349
487k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1350
487k
        if (profile_struct == NULL) {
1351
            /* Create now  */
1352
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1353
0
            profile_struct =  dev->icc_struct;
1354
0
            if (profile_struct == NULL)
1355
0
                return_error(gs_error_VMerror);
1356
0
        }
1357
487k
        profile_struct->overprint_control = overprint_control;
1358
487k
    }
1359
812k
    return code;
1360
812k
}
1361
1362
static int
1363
gx_default_put_intent(gsicc_rendering_intents_t icc_intent, gx_device * dev,
1364
                   gsicc_profile_types_t index)
1365
2.67M
{
1366
2.67M
    int code;
1367
2.67M
    cmm_dev_profile_t *profile_struct;
1368
1369
    /* Although device methods should not be NULL, they are not completely filled in until
1370
     * gx_device_fill_in_procs is called, and its possible for us to get here before this
1371
     * happens, so we *must* make sure the method is not NULL before we use it.
1372
     */
1373
2.67M
    if (dev_proc(dev, get_profile) == NULL) {
1374
        /* This is an odd case where the device has not yet fully been
1375
           set up with its procedures yet.  We want to make sure that
1376
           we catch this so we assume here that we are dealing with
1377
           the target device */
1378
725k
        if (dev->icc_struct == NULL) {
1379
            /* Intializes the device structure.  Not the profile though for index */
1380
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1381
0
            if (dev->icc_struct == NULL)
1382
0
                return_error(gs_error_VMerror);
1383
0
        }
1384
725k
        code = gsicc_set_device_profile_intent(dev, icc_intent, index);
1385
1.95M
    } else {
1386
1.95M
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1387
1.95M
        if (code < 0)
1388
0
            return code;
1389
1.95M
        if (profile_struct == NULL) {
1390
            /* Create now  */
1391
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1392
0
            if (dev->icc_struct == NULL)
1393
0
                return_error(gs_error_VMerror);
1394
0
        }
1395
1.95M
        code = gsicc_set_device_profile_intent(dev, icc_intent, index);
1396
1.95M
    }
1397
2.67M
    return code;
1398
2.67M
}
1399
1400
static int
1401
gx_default_put_blackpreserve(gsicc_blackpreserve_t blackpreserve, gx_device * dev,
1402
                           gsicc_profile_types_t index)
1403
2.67M
{
1404
2.67M
    int code;
1405
2.67M
    cmm_dev_profile_t *profile_struct;
1406
1407
    /* Although device methods should not be NULL, they are not completely filled in until
1408
     * gx_device_fill_in_procs is called, and its possible for us to get here before this
1409
     * happens, so we *must* make sure the method is not NULL before we use it.
1410
     */
1411
2.67M
    if (dev_proc(dev, get_profile) == NULL) {
1412
        /* This is an odd case where the device has not yet fully been
1413
           set up with its procedures yet.  We want to make sure that
1414
           we catch this so we assume here that we are dealing with
1415
           the target device */
1416
725k
        if (dev->icc_struct == NULL) {
1417
            /* Intializes the device structure.  Not the profile though for index */
1418
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1419
0
            if (dev->icc_struct == NULL)
1420
0
                return_error(gs_error_VMerror);
1421
0
        }
1422
725k
        code = gsicc_set_device_blackpreserve(dev, blackpreserve, index);
1423
1.95M
    } else {
1424
1.95M
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1425
1.95M
        if (code < 0)
1426
0
            return code;
1427
1.95M
        if (profile_struct == NULL) {
1428
            /* Create now  */
1429
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1430
0
            if (dev->icc_struct == NULL)
1431
0
                return_error(gs_error_VMerror);
1432
0
        }
1433
1.95M
        code = gsicc_set_device_blackpreserve(dev, blackpreserve, index);
1434
1.95M
    }
1435
2.67M
    return code;
1436
2.67M
}
1437
1438
1439
1440
1441
static int
1442
gx_default_put_blackptcomp(gsicc_blackptcomp_t blackptcomp, gx_device * dev,
1443
                           gsicc_profile_types_t index)
1444
2.67M
{
1445
2.67M
    int code;
1446
2.67M
    cmm_dev_profile_t *profile_struct;
1447
1448
    /* Although device methods should not be NULL, they are not completely filled in until
1449
     * gx_device_fill_in_procs is called, and its possible for us to get here before this
1450
     * happens, so we *must* make sure the method is not NULL before we use it.
1451
     */
1452
2.67M
    if (dev_proc(dev, get_profile) == NULL) {
1453
        /* This is an odd case where the device has not yet fully been
1454
           set up with its procedures yet.  We want to make sure that
1455
           we catch this so we assume here that we are dealing with
1456
           the target device */
1457
725k
        if (dev->icc_struct == NULL) {
1458
            /* Intializes the device structure.  Not the profile though for index */
1459
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1460
0
            if (dev->icc_struct == NULL)
1461
0
                return_error(gs_error_VMerror);
1462
0
        }
1463
725k
        code = gsicc_set_device_blackptcomp(dev, blackptcomp, index);
1464
1.95M
    } else {
1465
1.95M
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1466
1.95M
        if (code < 0)
1467
0
            return code;
1468
1.95M
        if (profile_struct == NULL) {
1469
            /* Create now  */
1470
0
            dev->icc_struct = gsicc_new_device_profile_array(dev);
1471
0
            if (dev->icc_struct == NULL)
1472
0
                return_error(gs_error_VMerror);
1473
0
        }
1474
1.95M
        code = gsicc_set_device_blackptcomp(dev, blackptcomp, index);
1475
1.95M
    }
1476
2.67M
    return code;
1477
2.67M
}
1478
1479
static int
1480
gx_default_put_icc_colorants(gs_param_string *colorants, gx_device * dev)
1481
28.3k
{
1482
28.3k
    char *tempstr;
1483
28.3k
    int code;
1484
1485
28.3k
    if (colorants->size == 0) return 0;
1486
1487
    /* See below about this device fill proc */
1488
0
    fill_dev_proc(dev, get_profile, gx_default_get_profile);
1489
0
    tempstr = (char *) gs_alloc_bytes(dev->memory, colorants->size+1,
1490
0
                                      "gx_default_put_icc_colorants");
1491
0
    memcpy(tempstr, colorants->data, colorants->size);
1492
    /* Set last position to NULL. */
1493
0
    tempstr[colorants->size] = 0;
1494
0
    code = gsicc_set_device_profile_colorants(dev, tempstr);
1495
0
    gs_free_object(dev->memory, tempstr, "gx_default_put_icc_colorants");
1496
0
    return code;
1497
28.3k
}
1498
1499
static int
1500
gx_default_put_icc(gs_param_string *icc_pro, gx_device * dev,
1501
                   gsicc_profile_types_t index)
1502
226k
{
1503
226k
    char *tempstr;
1504
226k
    int code = 0;
1505
1506
226k
    if (icc_pro->size == 0) return 0;
1507
    /* If this has not yet been set, then set it to the default.
1508
       I don't like doing this here but if we are in here trying to
1509
       set a profile for our device and if the proc for this has not
1510
       yet been set, we are going to lose the chance to set the profile.
1511
       Much like open, this proc should be set early on.  I leave that
1512
       exercise to the device start-up experts */
1513
28.3k
    fill_dev_proc(dev, get_profile, gx_default_get_profile);
1514
28.3k
    if (icc_pro->size < gp_file_name_sizeof) {
1515
28.3k
        tempstr = (char *) gs_alloc_bytes(dev->memory, icc_pro->size+1,
1516
28.3k
                                          "gx_default_put_icc");
1517
28.3k
        if (tempstr == NULL)
1518
0
            return_error(gs_error_VMerror);
1519
28.3k
        memcpy(tempstr, icc_pro->data, icc_pro->size);
1520
        /* Set last position to NULL. */
1521
28.3k
        tempstr[icc_pro->size] = 0;
1522
28.3k
        code = gsicc_init_device_profile_struct(dev, tempstr, index);
1523
28.3k
        gs_free_object(dev->memory, tempstr, "gx_default_put_icc");
1524
28.3k
    }
1525
28.3k
    return code;
1526
28.3k
}
1527
1528
void rc_free_NupControl(gs_memory_t * mem, void *ptr_in, client_name_t cname);  /* silence warning */
1529
/* Exported for use by nup_put_params in gdevnup.c */
1530
void
1531
rc_free_NupControl(gs_memory_t * mem, void *ptr_in, client_name_t cname)
1532
0
{
1533
0
    gdev_nupcontrol *pnupc = (gdev_nupcontrol *)ptr_in;
1534
1535
0
    if (pnupc->rc.ref_count <= 1) {
1536
0
        gs_free(mem->non_gc_memory, pnupc->nupcontrol_str, 1, strlen(pnupc->nupcontrol_str), "free nupcontrol string");
1537
0
        gs_free(mem->non_gc_memory, pnupc, 1, sizeof(gdev_nupcontrol), "free structure to hold nupcontrol string");
1538
0
    }
1539
0
}
1540
1541
static void
1542
rc_free_pages_list(gs_memory_t * mem, void *ptr_in, client_name_t cname)
1543
0
{
1544
0
    gdev_pagelist *PageList = (gdev_pagelist *)ptr_in;
1545
1546
0
    if (PageList->rc.ref_count <= 1) {
1547
0
        gs_free(mem->non_gc_memory, PageList->Pages, 1, strlen(PageList->Pages), "free page list");
1548
0
        gs_free(mem->non_gc_memory, PageList, 1, sizeof(gdev_pagelist), "free structure to hold page list");
1549
0
    }
1550
0
}
1551
1552
/* Set standard parameters. */
1553
/* Note that setting the size or resolution closes the device. */
1554
/* Window devices that don't want this to happen must temporarily */
1555
/* set is_open to false before calling gx_default_put_params, */
1556
/* and then taking appropriate action afterwards. */
1557
int
1558
gx_default_put_params(gx_device * dev, gs_param_list * plist)
1559
813k
{
1560
813k
    int ecode = 0;
1561
813k
    int code;
1562
813k
    gs_param_name param_name;
1563
813k
    gs_param_float_array hwra;
1564
813k
    gs_param_int_array hwsa;
1565
813k
    gs_param_float_array msa;
1566
813k
    gs_param_float_array ma;
1567
813k
    gs_param_float_array hwma;
1568
813k
    gs_param_string_array scna;
1569
813k
    int nci = dev->NumCopies;
1570
813k
    int ncset = dev->NumCopies_set;
1571
813k
    bool ignc = dev->IgnoreNumCopies;
1572
813k
    bool ucc = dev->UseCIEColor;
1573
813k
    gs_param_string icc_pro;
1574
813k
    bool locksafe = dev->LockSafetyParams;
1575
813k
    gs_param_float_array ibba;
1576
813k
    bool ibbnull = false;
1577
813k
    int colors = dev->color_info.num_components;
1578
813k
    int depth = dev->color_info.depth;
1579
813k
    int GrayValues = dev->color_info.max_gray + 1;
1580
813k
    int RGBValues = dev->color_info.max_color + 1;
1581
813k
    long ColorValues = (depth >= 32 ? -1 : 1L << depth);
1582
813k
    int tab = dev->color_info.anti_alias.text_bits;
1583
813k
    int gab = dev->color_info.anti_alias.graphics_bits;
1584
813k
    size_t mpbm = dev->MaxPatternBitmap;
1585
813k
    int ic = dev->interpolate_control;
1586
813k
    bool page_uses_transparency = dev->page_uses_transparency;
1587
813k
    bool page_uses_overprint = dev->page_uses_overprint;
1588
813k
    gdev_space_params sp = dev->space_params;
1589
813k
    gdev_space_params save_sp = dev->space_params;
1590
813k
    int rend_intent[NUM_DEVICE_PROFILES];
1591
813k
    int blackptcomp[NUM_DEVICE_PROFILES];
1592
813k
    int blackpreserve[NUM_DEVICE_PROFILES];
1593
813k
    gs_param_string cms, pagelist, nuplist;
1594
813k
    int leadingedge = dev->LeadingEdge;
1595
813k
    int k;
1596
813k
    int color_accuracy;
1597
813k
    bool devicegraytok = true;
1598
813k
    bool graydetection = false;
1599
813k
    bool usefastcolor = false;
1600
813k
    bool blacktext = false;
1601
813k
    bool blackvector = false;
1602
813k
    float blackthresholdL = BLACKTHRESHOLDL;
1603
813k
    float blackthresholdC = BLACKTHRESHOLDC;
1604
813k
    gs_overprint_control_t overprint_control = gs_overprint_control_enable;
1605
813k
    bool prebandthreshold = false;
1606
813k
    bool use_antidropout = dev->color_info.use_antidropout_downscaler;
1607
813k
    bool temp_bool;
1608
813k
    int  profile_types[NUM_DEVICE_PROFILES] = {gsDEFAULTPROFILE,
1609
813k
                                               gsGRAPHICPROFILE,
1610
813k
                                               gsIMAGEPROFILE,
1611
813k
                                               gsTEXTPROFILE};
1612
1613
813k
    color_accuracy = gsicc_currentcoloraccuracy(dev->memory);
1614
813k
    if (dev->icc_struct != NULL) {
1615
3.32M
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
1616
2.65M
            rend_intent[k] = dev->icc_struct->rendercond[k].rendering_intent;
1617
2.65M
            blackptcomp[k] = dev->icc_struct->rendercond[k].black_point_comp;
1618
2.65M
            blackpreserve[k] = dev->icc_struct->rendercond[k].preserve_black;
1619
2.65M
        }
1620
664k
        graydetection = dev->icc_struct->graydetection;
1621
664k
        devicegraytok = dev->icc_struct->devicegraytok;
1622
664k
        usefastcolor = dev->icc_struct->usefastcolor;
1623
664k
        blacktext = dev->icc_struct->blacktext;
1624
664k
        blackvector = dev->icc_struct->blackvector;
1625
664k
        blackthresholdL = dev->icc_struct->blackthresholdL;
1626
664k
        blackthresholdC = dev->icc_struct->blackthresholdC;
1627
664k
        prebandthreshold = dev->icc_struct->prebandthreshold;
1628
664k
        overprint_control = dev->icc_struct->overprint_control;
1629
664k
    } else {
1630
742k
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
1631
594k
            rend_intent[k] = gsRINOTSPECIFIED;
1632
594k
            blackptcomp[k] = gsBPNOTSPECIFIED;
1633
594k
            blackpreserve[k] = gsBKPRESNOTSPECIFIED;
1634
594k
        }
1635
148k
    }
1636
1637
    /*
1638
     * Template:
1639
     *   BEGIN_ARRAY_PARAM(param_read_xxx_array, "pname", pxxa, size, pxxe) {
1640
     *     ... check value if desired ...
1641
     *     if (success)
1642
     *       break;
1643
     *     ... set ecode ...
1644
     *   } END_ARRAY_PARAM(pxxa, pxxe);
1645
     */
1646
1647
813k
#define BEGIN_ARRAY_PARAM(pread, pname, pa, psize, e)\
1648
5.69M
    BEGIN\
1649
5.69M
    switch (code = pread(plist, (param_name = pname), &(pa))) {\
1650
634k
      case 0:\
1651
634k
        if ((pa).size != psize) {\
1652
0
          ecode = gs_note_error(gs_error_rangecheck);\
1653
0
          (pa).data = 0;  /* mark as not filled */\
1654
0
        } else
1655
813k
#define END_ARRAY_PARAM(pa, e)\
1656
813k
        goto e;\
1657
634k
      default:\
1658
76
        ecode = code;\
1659
76
e:  param_signal_error(plist, param_name, ecode);\
1660
5.05M
      case 1:\
1661
5.05M
        (pa).data = 0;   /* mark as not filled */\
1662
11.3M
    }\
1663
11.3M
    END
1664
1665
    /*
1666
     * The actual value of LeadingEdge must be changed inside this routine,
1667
     * so that we can detect that it has been changed. Thus, instead of a
1668
     * device setting the value itself, it signals a request, which is
1669
     * now executed.
1670
     */
1671
813k
    if (leadingedge & LEADINGEDGE_REQ_BIT) {
1672
0
        leadingedge = (leadingedge & LEADINGEDGE_SET_MASK) |
1673
0
            ((leadingedge >> LEADINGEDGE_REQ_VAL_SHIFT) & LEADINGEDGE_MASK);
1674
0
    }
1675
1676
    /*
1677
     * The HWResolution, HWSize, and MediaSize parameters interact in
1678
     * the following way:
1679
     *      1. Setting HWResolution recomputes HWSize from MediaSize.
1680
     *      2. Setting HWSize recomputes MediaSize from HWResolution.
1681
     *      3. Setting MediaSize recomputes HWSize from HWResolution.
1682
     * If more than one parameter is being set, we apply these rules
1683
     * in the order 1, 2, 3.  This does the right thing in the most
1684
     * common case of setting more than one parameter, namely,
1685
     * setting both HWResolution and HWSize.
1686
     *
1687
     * Changing of LeadingEdge is treated exactly the same as a
1688
     * change in HWResolution. In typical usage, MediaSize is
1689
     * short-edge (MediaSize[0] < MediaSize[1]), so if LeadingEdge
1690
     * is 1 or 3, then HWSize will become long-edge. For nonsquare
1691
     * resolutions, HWResolution[0] always corresponds with width
1692
     * (scan length), and [1] with height (number of scans).
1693
     */
1694
1695
930k
    BEGIN_ARRAY_PARAM(param_read_float_array, "HWResolution", hwra, 2, hwre) {
1696
117k
        if (hwra.data[0] <= 0 || hwra.data[1] <= 0)
1697
0
            ecode = gs_note_error(gs_error_rangecheck);
1698
117k
        else
1699
117k
            break;
1700
117k
    } END_ARRAY_PARAM(hwra, hwre);
1701
841k
    BEGIN_ARRAY_PARAM(param_read_int_array, "HWSize", hwsa, 2, hwsa) {
1702
        /* We need a special check to handle the nullpage device, */
1703
        /* whose size is legitimately [0 0]. */
1704
28.3k
        if ((hwsa.data[0] <= 0 && hwsa.data[0] != dev->width) ||
1705
28.3k
            (hwsa.data[1] <= 0 && hwsa.data[1] != dev->height)
1706
28.3k
        )
1707
0
            ecode = gs_note_error(gs_error_rangecheck);
1708
84.9k
#define max_coord (max_fixed / fixed_1)
1709
28.3k
#if max_coord < max_int
1710
28.3k
        else if (hwsa.data[0] > max_coord || hwsa.data[1] > max_coord)
1711
0
            ecode = gs_note_error(gs_error_limitcheck);
1712
28.3k
#endif
1713
28.3k
#undef max_coord
1714
28.3k
        else
1715
28.3k
            break;
1716
28.3k
    } END_ARRAY_PARAM(hwsa, hwse);
1717
813k
    {
1718
813k
        int t;
1719
1720
813k
        code = param_read_int(plist, "LeadingEdge", &t);
1721
813k
        if (code < 0) {
1722
28.3k
            if (param_read_null(plist, "LeadingEdge") == 0) {
1723
                /* if param is null, clear explicitly-set flag */
1724
28.3k
                leadingedge &= ~LEADINGEDGE_SET_MASK;
1725
28.3k
            } else {
1726
0
                ecode = code;
1727
0
            }
1728
784k
        } else if (code == 0) {
1729
0
            if (t < 0 || t > 3)
1730
0
                param_signal_error(plist, "LeadingEdge",
1731
0
                                   ecode = gs_error_rangecheck);
1732
0
            else
1733
0
                leadingedge = LEADINGEDGE_SET_MASK | t;
1734
0
        }
1735
813k
    }
1736
813k
    {
1737
813k
        const float *res = (hwra.data == 0 ? dev->HWResolution : hwra.data);
1738
1739
813k
#ifdef PAGESIZE_IS_MEDIASIZE
1740
813k
        const float *data;
1741
1742
        /* .MediaSize takes precedence over PageSize, so */
1743
        /* we read PageSize first. */
1744
813k
        code = param_MediaSize(plist, "PageSize", res, &msa);
1745
813k
        if (code < 0)
1746
0
            ecode = code;
1747
        /* Prevent data from being set to 0 if PageSize is specified */
1748
        /* but .MediaSize is not. */
1749
813k
        data = msa.data;
1750
813k
        code = param_MediaSize(plist, ".MediaSize", res, &msa);
1751
813k
        if (code < 0)
1752
76
            ecode = code;
1753
812k
        else if (msa.data == 0)
1754
409k
            msa.data = data;
1755
#else
1756
        code = param_MediaSize(plist, ".MediaSize", res, &msa);
1757
        if (code < 0)
1758
            ecode = code;
1759
#endif
1760
813k
    }
1761
1762
841k
    BEGIN_ARRAY_PARAM(param_read_float_array, "Margins", ma, 2, me) {
1763
28.3k
        break;
1764
28.3k
    } END_ARRAY_PARAM(ma, me);
1765
841k
    BEGIN_ARRAY_PARAM(param_read_float_array, ".HWMargins", hwma, 4, hwme) {
1766
28.3k
        break;
1767
28.3k
    } END_ARRAY_PARAM(hwma, hwme);
1768
813k
    switch (code = param_read_bool(plist, (param_name = ".IgnoreNumCopies"), &ignc)) {
1769
0
        default:
1770
0
            ecode = code;
1771
0
            param_signal_error(plist, param_name, ecode);
1772
28.3k
        case 0:
1773
813k
        case 1:
1774
813k
            break;
1775
813k
    }
1776
813k
    if (dev->NumCopies_set >= 0 &&
1777
813k
        (*dev_proc(dev, get_page_device))(dev) != 0
1778
813k
        ) {
1779
813k
        switch (code = param_read_int(plist, (param_name = "NumCopies"), &nci)) {
1780
0
            case 0:
1781
0
                if (nci < 0)
1782
0
                    ecode = gs_error_rangecheck;
1783
0
                else {
1784
0
                    ncset = 1;
1785
0
                    break;
1786
0
                }
1787
0
                goto nce;
1788
28.3k
            default:
1789
28.3k
                if ((code = param_read_null(plist, param_name)) == 0) {
1790
28.3k
                    ncset = 0;
1791
28.3k
                    break;
1792
28.3k
                }
1793
0
                ecode = code; /* can't be 1 */
1794
0
nce:
1795
0
                param_signal_error(plist, param_name, ecode);
1796
784k
            case 1:
1797
784k
                break;
1798
813k
        }
1799
813k
    }
1800
    /* Set the ICC output colors first */
1801
813k
    if ((code = param_read_string(plist, "ICCOutputColors", &icc_pro)) != 1) {
1802
28.3k
        if ((code = gx_default_put_icc_colorants(&icc_pro, dev)) < 0) {
1803
0
            ecode = code;
1804
0
            param_signal_error(plist, "ICCOutputColors", ecode);
1805
0
        }
1806
28.3k
    }
1807
813k
    if ((code = param_read_string(plist, "DeviceLinkProfile", &icc_pro)) != 1) {
1808
28.3k
        if ((code = gx_default_put_icc(&icc_pro, dev, gsLINKPROFILE)) < 0) {
1809
0
            ecode = code;
1810
0
            param_signal_error(plist, "DeviceLinkProfile", ecode);
1811
0
        }
1812
28.3k
    }
1813
813k
    if ((code = param_read_string(plist, "PostRenderProfile", &icc_pro)) != 1) {
1814
28.3k
        if ((code = gx_default_put_icc(&icc_pro, dev, gsPRPROFILE)) < 0) {
1815
0
            ecode = code;
1816
0
            param_signal_error(plist, "PostRenderProfile", ecode);
1817
0
        }
1818
28.3k
    }
1819
813k
    if ((code = param_read_string(plist, "OutputICCProfile", &icc_pro)) != 1) {
1820
28.3k
        if ((code = gx_default_put_icc(&icc_pro, dev, gsDEFAULTPROFILE)) < 0) {
1821
0
            ecode = code;
1822
0
            param_signal_error(plist, "OutputICCProfile", ecode);
1823
0
        }
1824
28.3k
    }
1825
    /* Note, if a change is made to NUM_DEVICE_PROFILES we need to update
1826
       this with the name of the profile */
1827
813k
    if ((code = param_read_string(plist, "VectorICCProfile", &icc_pro)) != 1) {
1828
28.3k
        if ((code = gx_default_put_icc(&icc_pro, dev, gsGRAPHICPROFILE)) < 0) {
1829
0
            ecode = code;
1830
0
            param_signal_error(plist, "VectorICCProfile", ecode);
1831
0
        }
1832
28.3k
    }
1833
813k
    if ((code = param_read_string(plist, "ImageICCProfile", &icc_pro)) != 1) {
1834
28.3k
        if ((code = gx_default_put_icc(&icc_pro, dev, gsIMAGEPROFILE)) < 0) {
1835
0
            ecode = code;
1836
0
            param_signal_error(plist, "ImageICCProfile", ecode);
1837
0
        }
1838
28.3k
    }
1839
813k
    if ((code = param_read_string(plist, "TextICCProfile", &icc_pro)) != 1) {
1840
28.3k
        if ((code = gx_default_put_icc(&icc_pro, dev, gsTEXTPROFILE)) < 0) {
1841
0
            ecode = code;
1842
0
            param_signal_error(plist, "TextICCProfile", ecode);
1843
0
        }
1844
28.3k
    }
1845
813k
    if ((code = param_read_string(plist, "ProofProfile", &icc_pro)) != 1) {
1846
28.3k
        if ((code = gx_default_put_icc(&icc_pro, dev, gsPROOFPROFILE)) < 0) {
1847
0
            ecode = code;
1848
0
            param_signal_error(plist, "ProofProfile", ecode);
1849
0
        }
1850
28.3k
    }
1851
813k
    if ((code = param_read_string(plist, "BlendColorProfile", &icc_pro)) != 1) {
1852
28.3k
        if ((code = gx_default_put_icc(&icc_pro, dev, gsBLENDPROFILE)) < 0) {
1853
0
            ecode = code;
1854
0
            param_signal_error(plist, "BlendColorProfile", ecode);
1855
0
        }
1856
28.3k
    }
1857
813k
    if ((code = param_read_int(plist, (param_name = "RenderIntent"),
1858
813k
                                                    &(rend_intent[0]))) < 0) {
1859
0
        ecode = code;
1860
0
        param_signal_error(plist, param_name, ecode);
1861
0
    }
1862
813k
    if ((code = param_read_int(plist, (param_name = "VectorIntent"),
1863
813k
                                                    &(rend_intent[1]))) < 0) {
1864
0
        ecode = code;
1865
0
        param_signal_error(plist, param_name, ecode);
1866
0
    }
1867
813k
    if ((code = param_read_int(plist, (param_name = "ImageIntent"),
1868
813k
                                                    &(rend_intent[2]))) < 0) {
1869
0
        ecode = code;
1870
0
        param_signal_error(plist, param_name, ecode);
1871
0
    }
1872
813k
    if ((code = param_read_int(plist, (param_name = "TextIntent"),
1873
813k
                                                    &(rend_intent[3]))) < 0) {
1874
0
        ecode = code;
1875
0
        param_signal_error(plist, param_name, ecode);
1876
0
    }
1877
813k
    if ((code = param_read_int(plist, (param_name = "BlackPtComp"),
1878
813k
                                                    &(blackptcomp[0]))) < 0) {
1879
0
        ecode = code;
1880
0
        param_signal_error(plist, param_name, ecode);
1881
0
    }
1882
813k
    if ((code = param_read_int(plist, (param_name = "VectorBlackPt"),
1883
813k
                                                    &(blackptcomp[1]))) < 0) {
1884
0
        ecode = code;
1885
0
        param_signal_error(plist, param_name, ecode);
1886
0
    }
1887
813k
    if ((code = param_read_int(plist, (param_name = "ImageBlackPt"),
1888
813k
                                                    &(blackptcomp[2]))) < 0) {
1889
0
        ecode = code;
1890
0
        param_signal_error(plist, param_name, ecode);
1891
0
    }
1892
813k
    if ((code = param_read_int(plist, (param_name = "TextBlackPt"),
1893
813k
                                                    &(blackptcomp[3]))) < 0) {
1894
0
        ecode = code;
1895
0
        param_signal_error(plist, param_name, ecode);
1896
0
    }
1897
813k
    if ((code = param_read_int(plist, (param_name = "KPreserve"),
1898
813k
                                                    &(blackpreserve[0]))) < 0) {
1899
0
        ecode = code;
1900
0
        param_signal_error(plist, param_name, ecode);
1901
0
    }
1902
813k
    if ((code = param_read_int(plist, (param_name = "VectorKPreserve"),
1903
813k
                                                    &(blackpreserve[1]))) < 0) {
1904
0
        ecode = code;
1905
0
        param_signal_error(plist, param_name, ecode);
1906
0
    }
1907
813k
    if ((code = param_read_int(plist, (param_name = "ImageKPreserve"),
1908
813k
                                                    &(blackpreserve[2]))) < 0) {
1909
0
        ecode = code;
1910
0
        param_signal_error(plist, param_name, ecode);
1911
0
    }
1912
813k
    if ((code = param_read_int(plist, (param_name = "TextKPreserve"),
1913
813k
                                                    &(blackpreserve[3]))) < 0) {
1914
0
        ecode = code;
1915
0
        param_signal_error(plist, param_name, ecode);
1916
0
    }
1917
813k
    if ((code = param_read_int(plist, (param_name = "ColorAccuracy"),
1918
813k
                                                        &color_accuracy)) < 0) {
1919
0
        ecode = code;
1920
0
        param_signal_error(plist, param_name, ecode);
1921
0
    }
1922
813k
    if ((code = param_read_bool(plist, (param_name = "DeviceGrayToK"),
1923
813k
                                                        &devicegraytok)) < 0) {
1924
0
        ecode = code;
1925
0
        param_signal_error(plist, param_name, ecode);
1926
0
    }
1927
813k
    if ((code = param_read_bool(plist, (param_name = "GrayDetection"),
1928
813k
                                                        &graydetection)) < 0) {
1929
0
        ecode = code;
1930
0
        param_signal_error(plist, param_name, ecode);
1931
0
    }
1932
813k
    if ((code = param_read_bool(plist, (param_name = "UseFastColor"),
1933
813k
                                                        &usefastcolor)) < 0) {
1934
0
        ecode = code;
1935
0
        param_signal_error(plist, param_name, ecode);
1936
0
    }
1937
813k
    if ((code = param_read_bool(plist, (param_name = "BlackText"),
1938
813k
                                                        &blacktext)) < 0) {
1939
0
        ecode = code;
1940
0
        param_signal_error(plist, param_name, ecode);
1941
0
    }
1942
813k
    if ((code = param_read_bool(plist, (param_name = "BlackVector"),
1943
813k
                                                        &blackvector)) < 0) {
1944
0
        ecode = code;
1945
0
        param_signal_error(plist, param_name, ecode);
1946
0
    }
1947
813k
    if ((code = param_read_float(plist, (param_name = "BlackThresholdL"),
1948
813k
                                                        &blackthresholdL)) < 0) {
1949
0
        ecode = code;
1950
0
        param_signal_error(plist, param_name, ecode);
1951
0
    }
1952
813k
    if ((code = param_read_float(plist, (param_name = "BlackThresholdC"),
1953
813k
                                                        &blackthresholdC)) < 0) {
1954
0
        ecode = code;
1955
0
        param_signal_error(plist, param_name, ecode);
1956
0
    }
1957
813k
    if ((code = param_put_enum(plist, "Overprint",
1958
813k
                           (int*)&overprint_control, overprint_control_names, ecode)) < 0) {
1959
76
        ecode = code;
1960
76
        param_signal_error(plist, param_name, ecode);
1961
76
    }
1962
813k
    if ((code = param_read_bool(plist, (param_name = "PreBandThreshold"),
1963
813k
                                                        &prebandthreshold)) < 0) {
1964
0
        ecode = code;
1965
0
        param_signal_error(plist, param_name, ecode);
1966
0
    }
1967
813k
    if ((code = param_read_bool(plist, (param_name = "UseCIEColor"), &ucc)) < 0) {
1968
0
        ecode = code;
1969
0
        param_signal_error(plist, param_name, ecode);
1970
0
    }
1971
813k
    if ((code = param_anti_alias_bits(plist, "TextAlphaBits", &tab)) < 0)
1972
0
        ecode = code;
1973
813k
    if ((code = param_anti_alias_bits(plist, "GraphicsAlphaBits", &gab)) < 0)
1974
0
        ecode = code;
1975
813k
    if ((code = param_read_bool(plist, "AntidropoutDownscaler", &use_antidropout)) < 0)
1976
0
        ecode = code;
1977
813k
    if ((code = param_read_size_t(plist, "MaxPatternBitmap", &mpbm)) < 0)
1978
0
        ecode = code;
1979
813k
    if ((code = param_read_int(plist, "InterpolateControl", &ic)) < 0)
1980
0
        ecode = code;
1981
813k
    if ((code = param_read_bool(plist, (param_name = "PageUsesTransparency"),
1982
813k
                                &page_uses_transparency)) < 0) {
1983
0
        ecode = code;
1984
0
        param_signal_error(plist, param_name, ecode);
1985
0
    }
1986
813k
    if ((code = param_read_bool(plist, (param_name = "PageUsesOverprint"),
1987
813k
                                &page_uses_overprint)) < 0) {
1988
0
        ecode = code;
1989
0
        param_signal_error(plist, param_name, ecode);
1990
0
    }
1991
813k
    if ((code = param_read_size_t(plist, "MaxBitmap", &sp.MaxBitmap)) < 0)
1992
0
        ecode = code;
1993
1994
813k
#define CHECK_PARAM_CASES(member, bad, label)\
1995
813k
    case 0:\
1996
202k
        if ((sp.params_are_read_only ? sp.member != save_sp.member : bad))\
1997
0
            ecode = gs_error_rangecheck;\
1998
0
        else\
1999
202k
            break;\
2000
0
        goto label;\
2001
0
    default:\
2002
0
        ecode = code;\
2003
0
label:\
2004
0
        param_signal_error(plist, param_name, ecode);\
2005
3.04M
    case 1:\
2006
3.04M
        break
2007
2008
813k
    switch (code = param_read_size_t(plist, (param_name = "BufferSpace"), &sp.BufferSpace)) {
2009
813k
        CHECK_PARAM_CASES(BufferSpace, sp.BufferSpace < 10000, bse);
2010
813k
    }
2011
2012
813k
    switch (code = param_read_int(plist, (param_name = "BandWidth"), &sp.band.BandWidth)) {
2013
813k
        CHECK_PARAM_CASES(band.BandWidth, sp.band.BandWidth < 0, bwe);
2014
813k
    }
2015
2016
813k
    switch (code = param_read_int(plist, (param_name = "BandHeight"), &sp.band.BandHeight)) {
2017
813k
        CHECK_PARAM_CASES(band.BandHeight, sp.band.BandHeight < -1, bhe);
2018
813k
    }
2019
813k
    if (sp.band.BandHeight == -1)
2020
0
        sp.band.BandHeight = dev->height; /* 1 band for the page requested */
2021
2022
813k
    switch (code = param_read_size_t(plist, (param_name = "BandBufferSpace"), &sp.band.BandBufferSpace)) {
2023
813k
        CHECK_PARAM_CASES(band.BandBufferSpace, 0, bbse);
2024
813k
    }
2025
2026
2027
813k
    switch (code = param_read_bool(plist, (param_name = ".LockSafetyParams"), &locksafe)) {
2028
28.3k
        case 0:
2029
28.3k
            if (dev->LockSafetyParams && !locksafe)
2030
0
                code = gs_note_error(gs_error_invalidaccess);
2031
28.3k
            else
2032
28.3k
                break;
2033
0
        default:
2034
0
            ecode = code;
2035
0
            param_signal_error(plist, param_name, ecode);
2036
784k
        case 1:
2037
784k
            break;
2038
813k
    }
2039
    /* Ignore parameters that only have meaning for printers. */
2040
813k
#define IGNORE_INT_PARAM(pname)\
2041
3.25M
  { int igni;\
2042
3.25M
    switch ( code = param_read_int(plist, (param_name = pname), &igni) )\
2043
3.25M
      { default:\
2044
0
          ecode = code;\
2045
0
          param_signal_error(plist, param_name, ecode);\
2046
836k
        case 0:\
2047
3.25M
        case 1:\
2048
3.25M
          break;\
2049
3.25M
      }\
2050
3.25M
  }
2051
813k
    IGNORE_INT_PARAM("%MediaSource")
2052
813k
        IGNORE_INT_PARAM("%MediaDestination")
2053
813k
        switch (code = param_read_float_array(plist, (param_name = "ImagingBBox"), &ibba)) {
2054
0
        case 0:
2055
0
            if (ibba.size != 4 ||
2056
0
                ibba.data[2] < ibba.data[0] || ibba.data[3] < ibba.data[1]
2057
0
                )
2058
0
                ecode = gs_note_error(gs_error_rangecheck);
2059
0
            else
2060
0
                break;
2061
0
            goto ibbe;
2062
0
        default:
2063
0
            if ((code = param_read_null(plist, param_name)) == 0) {
2064
0
                ibbnull = true;
2065
0
                ibba.data = 0;
2066
0
                break;
2067
0
            }
2068
0
            ecode = code; /* can't be 1 */
2069
0
          ibbe:param_signal_error(plist, param_name, ecode);
2070
813k
        case 1:
2071
813k
            ibba.data = 0;
2072
813k
            break;
2073
813k
    }
2074
2075
    /* Separation, DeviceN Color, and ProcessColorModel related parameters. */
2076
813k
    {
2077
813k
        const char * pcms = get_process_color_model_name(dev);
2078
        /* the device should have set a process model name at this point */
2079
813k
        if ((code = param_check_string(plist, "ProcessColorModel", pcms, (pcms != NULL))) < 0)
2080
0
            ecode = code;
2081
813k
    }
2082
813k
    IGNORE_INT_PARAM("MaxSeparations")
2083
813k
    if ((code = param_check_bool(plist, "Separations", false, true)) < 0)
2084
0
        ecode = code;
2085
2086
841k
    BEGIN_ARRAY_PARAM(param_read_name_array, "SeparationColorNames", scna, scna.size, scne) {
2087
28.3k
        break;
2088
28.3k
    } END_ARRAY_PARAM(scna, scne);
2089
2090
    /* Now check nominally read-only parameters. */
2091
813k
    if ((code = param_check_string(plist, "OutputDevice", dev->dname, true)) < 0)
2092
0
        ecode = code;
2093
813k
    if ((code = param_check_string(plist, "Name", dev->dname, true)) < 0)
2094
0
        ecode = code;
2095
813k
    if ((code = param_check_int(plist, "Colors", colors, true)) < 0)
2096
0
        ecode = code;
2097
813k
    if ((code = param_check_int(plist, "BitsPerPixel", depth, true)) < 0)
2098
0
        ecode = code;
2099
813k
    if ((code = param_check_int(plist, "GrayValues", GrayValues, true)) < 0)
2100
0
        ecode = code;
2101
2102
    /* with saved-pages, PageCount can't be checked. No harm in letting it change */
2103
813k
    IGNORE_INT_PARAM("PageCount")
2104
2105
813k
    if ((code = param_check_int(plist, "RedValues", RGBValues, true)) < 0)
2106
0
        ecode = code;
2107
813k
    if ((code = param_check_int(plist, "GreenValues", RGBValues, true)) < 0)
2108
0
        ecode = code;
2109
813k
    if ((code = param_check_int(plist, "BlueValues", RGBValues, true)) < 0)
2110
0
        ecode = code;
2111
813k
    if ((code = param_check_long(plist, "ColorValues", ColorValues, true)) < 0)
2112
0
        ecode = code;
2113
813k
    if (param_read_string(plist, "HWColorMap", &cms) != 1) {
2114
0
        byte palette[3 << 8];
2115
2116
0
        if (param_HWColorMap(dev, palette))
2117
0
            code = param_check_bytes(plist, "HWColorMap", palette,
2118
0
                                     colors << depth, true);
2119
0
        else
2120
0
            code = param_check_bytes(plist, "HWColorMap", 0, 0, false);
2121
0
        if (code < 0)
2122
0
            ecode = code;
2123
0
    }
2124
2125
813k
    code = param_read_int(plist, "FirstPage", &dev->FirstPage);
2126
813k
    if (code < 0)
2127
0
        ecode = code;
2128
2129
813k
    code = param_read_int(plist,  "LastPage", &dev->LastPage);
2130
813k
    if (code < 0)
2131
0
        ecode = code;
2132
2133
813k
    code = param_read_bool(plist, "DisablePageHandler", &temp_bool);
2134
813k
    if (code < 0)
2135
0
        ecode = code;
2136
813k
    if (code == 0)
2137
28.3k
        dev->DisablePageHandler = temp_bool;
2138
2139
    /* If we have an NupControl subclass device (N-up) installed, this param will have  */
2140
    /* been handled there, so the check for different will be false, meaning that this  */
2141
    /* code won't end up doing anything. This will catch the first occurence and needs  */
2142
    /* to install the N-up subclass device.           */
2143
813k
    code = param_read_string(plist, "NupControl", &nuplist);
2144
813k
    if (code < 0)
2145
0
        ecode = code;
2146
813k
    if (code == 0) {
2147
28.3k
        if (dev->NupControl && (
2148
0
            nuplist.size == 0 ||
2149
0
            (strncmp(dev->NupControl->nupcontrol_str, (const char *)nuplist.data, nuplist.size) != 0))) {
2150
            /* There was a NupControl, but this one is different -- no longer use the old one */
2151
0
            rc_decrement(dev->NupControl, "default put_params NupControl");
2152
0
            dev->NupControl = NULL;
2153
0
        }
2154
28.3k
    }
2155
813k
    if (dev->NupControl == NULL && code == 0 && nuplist.size > 0) {
2156
0
        gx_device *next_dev;
2157
2158
0
        dev->NupControl = (gdev_nupcontrol *)gs_alloc_bytes(dev->memory->non_gc_memory,
2159
0
                                                          sizeof(gdev_nupcontrol), "structure to hold nupcontrol_str");
2160
0
        if (dev->NupControl == NULL)
2161
0
            return gs_note_error(gs_error_VMerror);
2162
0
        dev->NupControl->nupcontrol_str = (void *)gs_alloc_bytes(dev->memory->non_gc_memory,
2163
0
                                                                 nuplist.size + 1, "nupcontrol string");
2164
0
        if (dev->NupControl->nupcontrol_str == NULL){
2165
0
            gs_free(dev->memory->non_gc_memory, dev->NupControl, 1, sizeof(gdev_nupcontrol),
2166
0
                    "free structure to hold nupcontrol string");
2167
0
            dev->NupControl = 0;
2168
0
            return gs_note_error(gs_error_VMerror);
2169
0
        }
2170
0
        memset(dev->NupControl->nupcontrol_str, 0x00, nuplist.size + 1);
2171
0
        memcpy(dev->NupControl->nupcontrol_str, nuplist.data, nuplist.size);
2172
0
        rc_init_free(dev->NupControl, dev->memory->non_gc_memory, 1, rc_free_NupControl);
2173
2174
        /* Propagate the new NupControl struct to children */
2175
0
        next_dev = dev->child;
2176
0
        while (next_dev != NULL) {
2177
0
            if (next_dev->NupControl)
2178
0
                rc_decrement(next_dev->NupControl, "nup_put_params");
2179
0
            next_dev->NupControl = dev->NupControl;
2180
0
            rc_increment(dev->NupControl);
2181
0
            next_dev = next_dev->child;
2182
0
        }
2183
        /* Propagate the new NupControl struct to parents */
2184
0
        next_dev = dev->parent;
2185
0
        while (next_dev != NULL) {
2186
0
            if (next_dev->NupControl)
2187
0
                rc_decrement(next_dev->NupControl, "nup_put_params");
2188
0
            next_dev->NupControl = dev->NupControl;
2189
0
            rc_increment(dev->NupControl);
2190
0
            next_dev = next_dev->parent;
2191
0
        }
2192
0
    }
2193
2194
813k
    code = param_read_string(plist, "PageList", &pagelist);
2195
813k
    if (code < 0)
2196
0
        ecode = code;
2197
813k
    if (code == 0) {
2198
28.3k
        if (dev->PageList)
2199
28.3k
            rc_decrement(dev->PageList, "default put_params PageList");
2200
28.3k
        dev->PageList = NULL;
2201
28.3k
    }
2202
2203
813k
    if (code == 0 && pagelist.size > 0) {
2204
0
        dev->PageList = (gdev_pagelist *)gs_alloc_bytes(dev->memory->non_gc_memory, sizeof(gdev_pagelist), "structure to hold page list");
2205
0
        if (!dev->PageList)
2206
0
            return gs_note_error(gs_error_VMerror);
2207
0
        dev->PageList->Pages = (void *)gs_alloc_bytes(dev->memory->non_gc_memory, pagelist.size + 1, "String to hold page list");
2208
0
        if (!dev->PageList->Pages){
2209
0
            gs_free(dev->memory->non_gc_memory, dev->PageList, 1, sizeof(gdev_pagelist), "free structure to hold page list");
2210
0
            dev->PageList = 0;
2211
0
            return gs_note_error(gs_error_VMerror);
2212
0
        }
2213
0
        memset(dev->PageList->Pages, 0x00, pagelist.size + 1);
2214
0
        memcpy(dev->PageList->Pages, pagelist.data, pagelist.size);
2215
0
        rc_init_free(dev->PageList, dev->memory->non_gc_memory, 1, rc_free_pages_list);
2216
0
    }
2217
2218
813k
    code = param_read_bool(plist, "FILTERIMAGE", &temp_bool);
2219
813k
    if (code < 0)
2220
0
        ecode = code;
2221
813k
    if (code == 0) {
2222
28.3k
        if (temp_bool)
2223
0
            dev->ObjectFilter |= FILTERIMAGE;
2224
28.3k
        else
2225
28.3k
            dev->ObjectFilter &= ~FILTERIMAGE;
2226
28.3k
    }
2227
2228
813k
    code = param_read_bool(plist, "FILTERTEXT", &temp_bool);
2229
813k
    if (code < 0)
2230
0
        ecode = code;
2231
813k
    if (code == 0) {
2232
28.3k
        if (temp_bool)
2233
0
            dev->ObjectFilter |= FILTERTEXT;
2234
28.3k
        else
2235
28.3k
            dev->ObjectFilter &= ~FILTERTEXT;
2236
28.3k
    }
2237
2238
813k
    code = param_read_bool(plist, "FILTERVECTOR", &temp_bool);
2239
813k
    if (code < 0)
2240
0
        ecode = code;
2241
813k
    if (code == 0) {
2242
28.3k
        if (temp_bool)
2243
0
            dev->ObjectFilter |= FILTERVECTOR;
2244
28.3k
        else
2245
28.3k
            dev->ObjectFilter &= ~FILTERVECTOR;
2246
28.3k
    }
2247
2248
    /* We must 'commit', in order to detect unknown parameters, */
2249
    /* even if there were errors. */
2250
813k
    code = param_commit(plist);
2251
813k
    if (ecode < 0) {
2252
        /* restore_page_device (zdevice2.c) will turn off LockSafetyParams, and relies on putparams
2253
         * to put it back if we are restoring a device. The locksafe value is picked up above from the
2254
         * device we are restoring to, and we *must* make sure it is preserved, even if setting the
2255
         * params failed. Otherwise an attacker can use a failed grestore to reset LockSafetyParams.
2256
         * See bug #699687.
2257
         */
2258
76
        dev->LockSafetyParams = locksafe;
2259
76
        return ecode;
2260
76
    }
2261
812k
    if (code < 0) {
2262
255
        dev->LockSafetyParams = locksafe;
2263
255
        return code;
2264
255
    }
2265
2266
    /*
2267
     * Now actually make the changes. Changing resolution, rotation
2268
     * (through LeadingEdge) or page size requires closing the device,
2269
     * but changing margins or ImagingBBox does not. In order not to
2270
     * close and reopen the device unnecessarily, we check for
2271
     * replacing the values with the same ones.
2272
     */
2273
2274
812k
    dev->color_info.use_antidropout_downscaler = use_antidropout;
2275
2276
812k
    if (hwra.data != 0 &&
2277
812k
        (dev->HWResolution[0] != hwra.data[0] ||
2278
117k
         dev->HWResolution[1] != hwra.data[1])
2279
812k
        ) {
2280
89.2k
        if (dev->is_open)
2281
0
            gs_closedevice(dev);
2282
89.2k
        gx_device_set_resolution(dev, hwra.data[0], hwra.data[1]);
2283
89.2k
    }
2284
812k
    if ((leadingedge & LEADINGEDGE_MASK) !=
2285
812k
        (dev->LeadingEdge & LEADINGEDGE_MASK)) {
2286
        /* If the LeadingEdge_set flag changes but the value of LeadingEdge
2287
           itself does not, don't close device and recompute page size. */
2288
0
        dev->LeadingEdge = leadingedge;
2289
0
        if (dev->is_open)
2290
0
            gs_closedevice(dev);
2291
0
        gx_device_set_resolution(dev, dev->HWResolution[0], dev->HWResolution[1]);
2292
0
    }
2293
    /* clear leadingedge request, preserve "set" flag */
2294
812k
    dev->LeadingEdge &= LEADINGEDGE_MASK;
2295
812k
    dev->LeadingEdge |= (leadingedge & LEADINGEDGE_SET_MASK);
2296
2297
812k
    if (hwsa.data != 0 &&
2298
812k
        (dev->width != hwsa.data[0] ||
2299
28.3k
         dev->height != hwsa.data[1])
2300
812k
        ) {
2301
19.2k
        if (dev->is_open)
2302
0
            gs_closedevice(dev);
2303
19.2k
        gx_device_set_width_height(dev, hwsa.data[0], hwsa.data[1]);
2304
19.2k
    }
2305
812k
    if (msa.data != 0 &&
2306
812k
        (dev->MediaSize[0] != msa.data[0] ||
2307
403k
         dev->MediaSize[1] != msa.data[1])
2308
812k
        ) {
2309
51.6k
        if (dev->is_open)
2310
0
            gs_closedevice(dev);
2311
51.6k
        gx_device_set_page_size(dev, msa.data[0], msa.data[1]);
2312
51.6k
    }
2313
812k
    if (ma.data != 0) {
2314
28.3k
        dev->Margins[0] = ma.data[0];
2315
28.3k
        dev->Margins[1] = ma.data[1];
2316
28.3k
    }
2317
812k
    if (hwma.data != 0) {
2318
28.3k
        dev->HWMargins[0] = hwma.data[0];
2319
28.3k
        dev->HWMargins[1] = hwma.data[1];
2320
28.3k
        dev->HWMargins[2] = hwma.data[2];
2321
28.3k
        dev->HWMargins[3] = hwma.data[3];
2322
28.3k
    }
2323
812k
    dev->NumCopies = nci;
2324
812k
    dev->NumCopies_set = ncset;
2325
812k
    dev->IgnoreNumCopies = ignc;
2326
812k
    if (ibba.data != 0) {
2327
0
        dev->ImagingBBox[0] = ibba.data[0];
2328
0
        dev->ImagingBBox[1] = ibba.data[1];
2329
0
        dev->ImagingBBox[2] = ibba.data[2];
2330
0
        dev->ImagingBBox[3] = ibba.data[3];
2331
0
        dev->ImagingBBox_set = true;
2332
812k
    } else if (ibbnull) {
2333
0
        dev->ImagingBBox_set = false;
2334
0
    }
2335
812k
    dev->UseCIEColor = ucc;
2336
812k
        dev->color_info.anti_alias.text_bits =
2337
812k
                param_normalize_anti_alias_bits(max(dev->color_info.max_gray,
2338
812k
                        dev->color_info.max_color), tab);
2339
812k
        dev->color_info.anti_alias.graphics_bits =
2340
812k
                param_normalize_anti_alias_bits(max(dev->color_info.max_gray,
2341
812k
                        dev->color_info.max_color), gab);
2342
812k
    dev->LockSafetyParams = locksafe;
2343
812k
    dev->MaxPatternBitmap = mpbm;
2344
812k
    dev->interpolate_control = ic;
2345
812k
    dev->space_params = sp;
2346
812k
    dev->page_uses_transparency = page_uses_transparency;
2347
812k
    dev->page_uses_overprint = page_uses_overprint;
2348
812k
    gx_device_decache_colors(dev);
2349
2350
    /* Take care of the rendering intents and blackpts.  For those that
2351
       are not set special, the default provides an override */
2352
812k
    if (dev->icc_struct != NULL) {
2353
        /* Set the default object */
2354
669k
        code = gx_default_put_intent(rend_intent[0], dev, gsDEFAULTPROFILE);
2355
669k
        if (code < 0)
2356
0
            return code;
2357
669k
        code = gx_default_put_blackptcomp(blackptcomp[0], dev, gsDEFAULTPROFILE);
2358
669k
        if (code < 0)
2359
0
            return code;
2360
669k
        code = gx_default_put_blackpreserve(blackpreserve[0], dev, gsDEFAULTPROFILE);
2361
669k
        if (code < 0)
2362
0
            return code;
2363
        /* If the default was specified and not a specialized one (e.g. graphic
2364
           image or text) then the special one will get set to the default.  */
2365
2.67M
        for (k = 1; k < NUM_DEVICE_PROFILES; k++) {
2366
2.00M
            if (rend_intent[0] != gsRINOTSPECIFIED &&
2367
2.00M
                rend_intent[k] == gsRINOTSPECIFIED) {
2368
0
                code = gx_default_put_intent(rend_intent[0], dev, profile_types[k]);
2369
2.00M
            } else {
2370
2.00M
                code = gx_default_put_intent(rend_intent[k], dev, profile_types[k]);
2371
2.00M
            }
2372
2.00M
            if (code < 0)
2373
0
                return code;
2374
2.00M
            if (blackptcomp[0] != gsBPNOTSPECIFIED &&
2375
2.00M
                blackptcomp[k] == gsBPNOTSPECIFIED) {
2376
0
                code = gx_default_put_blackptcomp(blackptcomp[0], dev, profile_types[k]);
2377
2.00M
            } else {
2378
2.00M
                code = gx_default_put_blackptcomp(blackptcomp[k], dev, profile_types[k]);
2379
2.00M
            }
2380
2.00M
            if (code < 0)
2381
0
                return code;
2382
2.00M
            if (blackpreserve[0] != gsBKPRESNOTSPECIFIED &&
2383
2.00M
                blackpreserve[k] == gsBKPRESNOTSPECIFIED) {
2384
0
                code = gx_default_put_blackpreserve(blackpreserve[0], dev, profile_types[k]);
2385
2.00M
            } else {
2386
2.00M
                code = gx_default_put_blackpreserve(blackpreserve[k], dev, profile_types[k]);
2387
2.00M
            }
2388
2.00M
            if (code < 0)
2389
0
                return code;
2390
2.00M
        }
2391
669k
    }
2392
812k
    gsicc_setcoloraccuracy(dev->memory, color_accuracy);
2393
812k
    code = gx_default_put_graytok(devicegraytok, dev);
2394
812k
    if (code < 0)
2395
0
        return code;
2396
812k
    code = gx_default_put_usefastcolor(usefastcolor, dev);
2397
812k
    if (code < 0)
2398
0
        return code;
2399
812k
    code = gx_default_put_blacktext(blacktext, dev);
2400
812k
    if (code < 0)
2401
0
        return code;
2402
812k
    code = gx_default_put_blackvector(blackvector, dev);
2403
812k
    if (code < 0)
2404
0
        return code;
2405
812k
    code = gx_default_put_blackthresholds(blackthresholdL, blackthresholdC, dev);
2406
812k
    if (code < 0)
2407
0
        return code;
2408
812k
    code = gx_default_put_overprint_control(overprint_control, dev);
2409
812k
    if (code < 0)
2410
0
        return code;
2411
812k
    code = gx_default_put_graydetection(graydetection, dev);
2412
812k
    if (code < 0)
2413
0
        return code;
2414
812k
    return gx_default_put_prebandthreshold(prebandthreshold, dev);
2415
812k
}
2416
2417
void
2418
gx_device_request_leadingedge(gx_device *dev, int le_req)
2419
0
{
2420
0
    dev->LeadingEdge = (dev->LeadingEdge & ~LEADINGEDGE_REQ_VAL) |
2421
0
        ((le_req << LEADINGEDGE_REQ_VAL_SHIFT) & LEADINGEDGE_REQ_VAL) |
2422
0
        LEADINGEDGE_REQ_BIT;
2423
0
}
2424
2425
/* Limit the anti-alias bit values to the maximum legal value for the
2426
 * current color depth.
2427
 */
2428
static int
2429
param_normalize_anti_alias_bits( uint max_gray, int bits )
2430
1.62M
{
2431
1.62M
        int max_bits = ilog2( max_gray + 1);
2432
2433
1.62M
        return  (bits > max_bits ? max_bits : bits);
2434
1.62M
}
2435
2436
/* Read TextAlphaBits or GraphicsAlphaBits. */
2437
static int
2438
param_anti_alias_bits(gs_param_list * plist, gs_param_name param_name, int *pa)
2439
1.62M
{
2440
1.62M
    int code = param_read_int(plist, param_name, pa);
2441
2442
1.62M
    switch (code) {
2443
56.6k
    case 0:
2444
56.6k
        switch (*pa) {
2445
56.6k
        case 1: case 2: case 4:
2446
56.6k
            return 0;
2447
0
        default:
2448
0
            code = gs_error_rangecheck;
2449
56.6k
        }
2450
        /* fall through */
2451
0
    default:
2452
0
        param_signal_error(plist, param_name, code);
2453
1.56M
    case 1:
2454
1.56M
        ;
2455
1.62M
    }
2456
1.56M
    return code;
2457
1.62M
}
2458
2459
/* Read .MediaSize or, if supported as a synonym, PageSize. */
2460
static int
2461
param_MediaSize(gs_param_list * plist, gs_param_name pname,
2462
                const float *res, gs_param_float_array * pa)
2463
1.62M
{
2464
1.62M
    gs_param_name param_name;
2465
1.62M
    int ecode = 0;
2466
1.62M
    int code;
2467
2468
2.03M
    BEGIN_ARRAY_PARAM(param_read_float_array, pname, *pa, 2, mse) {
2469
403k
        float width_new = pa->data[0] * res[0] / 72;
2470
403k
        float height_new = pa->data[1] * res[1] / 72;
2471
2472
403k
        if (width_new < 0 || height_new < 0)
2473
0
            ecode = gs_note_error(gs_error_rangecheck);
2474
1.21M
#define max_coord (max_fixed / fixed_1)
2475
403k
#if max_coord < max_int
2476
403k
        else if (width_new > (long)max_coord || height_new > (long)max_coord)
2477
76
            ecode = gs_note_error(gs_error_limitcheck);
2478
403k
#endif
2479
403k
#undef max_coord
2480
403k
        else
2481
403k
            break;
2482
403k
    } END_ARRAY_PARAM(*pa, mse);
2483
1.62M
    return ecode;
2484
1.62M
}
2485
2486
/* Check that a nominally read-only parameter is being set to */
2487
/* its existing value. */
2488
static int
2489
param_check_bool(gs_param_list * plist, gs_param_name pname, bool value,
2490
                 bool is_defined)
2491
813k
{
2492
813k
    int code;
2493
813k
    bool new_value;
2494
2495
813k
    switch (code = param_read_bool(plist, pname, &new_value)) {
2496
28.3k
        case 0:
2497
28.3k
            if (is_defined && new_value == value)
2498
28.3k
                break;
2499
0
            code = gs_note_error(gs_error_rangecheck);
2500
0
            goto e;
2501
0
        default:
2502
0
            if (param_read_null(plist, pname) == 0)
2503
0
                return 1;
2504
0
          e:param_signal_error(plist, pname, code);
2505
784k
        case 1:
2506
784k
            ;
2507
813k
    }
2508
813k
    return code;
2509
813k
}
2510
static int
2511
param_check_long(gs_param_list * plist, gs_param_name pname, long value,
2512
                 bool is_defined)
2513
5.69M
{
2514
5.69M
    int code;
2515
5.69M
    long new_value;
2516
2517
5.69M
    switch (code = param_read_long(plist, pname, &new_value)) {
2518
2.55k
        case 0:
2519
2.55k
            if (is_defined && new_value == value)
2520
2.55k
                break;
2521
0
            code = gs_note_error(gs_error_rangecheck);
2522
0
            goto e;
2523
0
        default:
2524
0
            if (param_read_null(plist, pname) == 0)
2525
0
                return 1;
2526
0
          e:param_signal_error(plist, pname, code);
2527
5.68M
        case 1:
2528
5.68M
            ;
2529
5.69M
    }
2530
5.69M
    return code;
2531
5.69M
}
2532
static int
2533
param_check_bytes(gs_param_list * plist, gs_param_name pname, const byte * str,
2534
                  uint size, bool is_defined)
2535
2.43M
{
2536
2.43M
    int code;
2537
2.43M
    gs_param_string new_value;
2538
2539
2.43M
    switch (code = param_read_string(plist, pname, &new_value)) {
2540
28.3k
        case 0:
2541
28.3k
            if (is_defined && new_value.size == size &&
2542
28.3k
                !memcmp((const char *)str, (const char *)new_value.data,
2543
28.3k
                        size)
2544
28.3k
                )
2545
28.3k
                break;
2546
0
            code = gs_note_error(gs_error_rangecheck);
2547
0
            goto e;
2548
0
        default:
2549
0
            if (param_read_null(plist, pname) == 0)
2550
0
                return 1;
2551
0
          e:param_signal_error(plist, pname, code);
2552
2.41M
        case 1:
2553
2.41M
            ;
2554
2.43M
    }
2555
2.43M
    return code;
2556
2.43M
}