~ubuntu-branches/ubuntu/vivid/ghostscript/vivid-security

« back to all changes in this revision

Viewing changes to base/gdevpsdp.c

  • Committer: Package Import Robot
  • Author(s): Till Kamppeter
  • Date: 2013-08-09 20:01:36 UTC
  • mfrom: (1.1.37)
  • Revision ID: package-import@ubuntu.com-20130809200136-amb6zrr7hnjb5jq9
Tags: 9.08~rc1~dfsg-0ubuntu1
* New upstream release
   - Ghostscript 9.08rc1.
   - We are using the system's liblcms2 and libopenjpeg now.
* debian/patches/020130401-852e545-pxl-xl-driver-produced-drawing-commands-without-setting-color-space.patch:
  Removed patch backported from upstream.
* debian/patches/ojdk-8007925+8007926.patch,
  debian/patches/ojdk-8007927.patch,
  debian/patches/ojdk-8007929.patch,
  debian/patches/ojdk-8009654.patch: Removed patches on build in liblcms2, we
  use the system's liblcms2 now.
* debian/patches/2001_docdir_fix_for_debian.patch: Manually updated to new
  upstream source code.
* debian/patches/2003_support_multiarch.patch: Refreshed with quilt.
* debian/control: Added build dependencies on liblcms2-dev and
  libopenjpeg-dev.
* debian/rules: Check for removed lcms2/ and openjpeg/ subdirectories in
  the repackaging check again, also set build options for shared liblcms2
  and libopenjpeg libraries.
* debian/rules: Makefile.in and configure.ac are in the root directory of
  the source now and do not need to get linked from base/. Also there is no
  gstoraster and gstopxl CUPS filter in the package any more and no
  "install-cups" make target any more.
* debian/control, debian/rules, debian/ghostscript-cups.install,
  debian/ghostscript-cups.ppd-updater: Removed the ghostscript-cups binary
  package. The files are now provided by cups-filters.
* debian/symbols.common: Updated for new upstream source. Applied patch
  which dpkg-gensymbols generated for debian/libgs9.symbols to this file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2001-2012 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.,  7 Mt. Lassen Drive - Suite A-134, San Rafael,
13
 
   CA  94903, U.S.A., +1(415)492-9861, for further information.
14
 
*/
15
 
 
16
 
 
17
 
/* (Distiller) parameter handling for PostScript and PDF writers */
18
 
#include "string_.h"
19
 
#include "jpeglib_.h"           /* for sdct.h */
20
 
#include "gx.h"
21
 
#include "gserrors.h"
22
 
#include "gsutil.h"
23
 
#include "gxdevice.h"
24
 
#include "gsparamx.h"
25
 
#include "gdevpsdf.h"
26
 
#include "strimpl.h"            /* for short-sighted compilers */
27
 
#include "scfx.h"
28
 
#include "sdct.h"
29
 
#include "slzwx.h"
30
 
#include "srlx.h"
31
 
#include "szlibx.h"
32
 
#ifdef USE_LDF_JB2
33
 
#include "sjbig2_luratech.h"
34
 
#endif
35
 
#ifdef USE_LWF_JP2
36
 
#include "sjpx_luratech.h"
37
 
#endif
38
 
 
39
 
/* Define a (bogus) GC descriptor for gs_param_string. */
40
 
/* The only ones we use are GC-able and not persistent. */
41
 
gs_private_st_composite(st_gs_param_string, gs_param_string, "gs_param_string",
42
 
                        param_string_enum_ptrs, param_string_reloc_ptrs);
43
 
static
44
 
ENUM_PTRS_WITH(param_string_enum_ptrs, gs_param_string *pstr) return 0;
45
 
case 0: return ENUM_CONST_STRING(pstr);
46
 
ENUM_PTRS_END
47
 
static
48
 
RELOC_PTRS_WITH(param_string_reloc_ptrs, gs_param_string *pstr)
49
 
{
50
 
    gs_const_string str;
51
 
 
52
 
    str.data = pstr->data, str.size = pstr->size;
53
 
    RELOC_CONST_STRING_VAR(str);
54
 
    pstr->data = str.data;
55
 
}
56
 
RELOC_PTRS_END
57
 
gs_private_st_element(st_param_string_element, gs_param_string,
58
 
                      "gs_param_string[]", param_string_elt_enum_ptrs,
59
 
                      param_string_elt_reloc_ptrs, st_gs_param_string);
60
 
 
61
 
/* ---------------- Get/put Distiller parameters ---------------- */
62
 
 
63
 
/*
64
 
 * ColorConversionStrategy is supposed to affect output color space
65
 
 * according to the following table.  ****** NOT IMPLEMENTED YET ******
66
 
 
67
 
PS Input:  LeaveCU UseDIC           UseDICFI         sRGB
68
 
Gray art   Gray    CalGray/ICCBased Gray             Gray
69
 
Gray image Gray    CalGray/ICCBased CalGray/ICCBased Gray
70
 
RGB art    RGB     CalGray/ICCBased RGB              CalRGB/sRGB
71
 
RGB image  RGB     CalGray/ICCBased CalRGB/ICCBased  CalRGB/sRGB
72
 
CMYK art   CMYK    LAB/ICCBased     CMYK             CalRGB/sRGB
73
 
CMYK image CMYK    LAB/ICCBased     LAB/ICCBased     CalRGB/sRGB
74
 
CIE art    Cal/ICC Cal/ICC          Cal/ICC          CalRGB/sRGB
75
 
CIE image  Cal/ICC Cal/ICC          Cal/ICC          CalRGB/sRGB
76
 
 
77
 
 */
78
 
 
79
 
/*
80
 
 * The Always/NeverEmbed parameters are defined as being incremental.  Since
81
 
 * this isn't compatible with the general property of page devices that if
82
 
 * you do a currentpagedevice, doing a setpagedevice later will restore the
83
 
 * same state, we actually define the parameters in sets of 3:
84
 
 *      - AlwaysEmbed is used for incremental additions.
85
 
 *      - ~AlwaysEmbed is used for incremental deletions.
86
 
 *      - .AlwaysEmbed is used for the complete list.
87
 
 * and analogously for NeverEmbed.
88
 
 */
89
 
 
90
 
typedef struct psdf_image_filter_name_s {
91
 
    const char *pname;
92
 
    const stream_template *templat;
93
 
    psdf_version min_version;
94
 
} psdf_image_filter_name;
95
 
 
96
 
static const psdf_image_filter_name Poly_filters[] = {
97
 
    {"DCTEncode", &s_DCTE_template},
98
 
    {"FlateEncode", &s_zlibE_template, psdf_version_ll3},
99
 
    {"LZWEncode", &s_LZWE_template},
100
 
#ifdef USE_LWF_JP2
101
 
    {"JPXEncode", &s_jpxe_template},
102
 
#endif
103
 
    {0, 0}
104
 
};
105
 
 
106
 
static const psdf_image_filter_name Mono_filters[] = {
107
 
    {"CCITTFaxEncode", &s_CFE_template},
108
 
    {"FlateEncode", &s_zlibE_template, psdf_version_ll3},
109
 
    {"LZWEncode", &s_LZWE_template},
110
 
    {"RunLengthEncode", &s_RLE_template},
111
 
#ifdef USE_LDF_JB2
112
 
    {"JBIG2Encode", &s_jbig2encode_template},
113
 
#endif
114
 
    {0, 0}
115
 
};
116
 
 
117
 
typedef struct psdf_image_param_names_s {
118
 
    const char *ACSDict;        /* not used for mono */
119
 
    const char *Dict;
120
 
    const char *DownsampleType;
121
 
    float DownsampleThreshold_default;
122
 
    const psdf_image_filter_name *filter_names;
123
 
    const char *Filter;
124
 
    const char *AutoFilterStrategy;
125
 
    gs_param_item_t items[9];   /* AutoFilter (not used for mono), */
126
 
                                /* AntiAlias, */
127
 
                                /* Depth, Downsample, DownsampleThreshold, */
128
 
                                /* Encode, Resolution, AutoFilterStrategy, end marker */
129
 
} psdf_image_param_names_t;
130
 
#define pi(key, type, memb) { key, type, offset_of(psdf_image_params, memb) }
131
 
#define psdf_image_param_names(acs, aa, af, de, di, ds, dt, dst, dstd, e, f, fns, r, afs)\
132
 
    acs, di, dt, dstd, fns, f, afs, {\
133
 
      pi(af, gs_param_type_bool, AutoFilter),\
134
 
      pi(aa, gs_param_type_bool, AntiAlias),\
135
 
      pi(de, gs_param_type_int, Depth),\
136
 
      pi(ds, gs_param_type_bool, Downsample),\
137
 
      pi(dst, gs_param_type_float, DownsampleThreshold),\
138
 
      pi(e, gs_param_type_bool, Encode),\
139
 
      pi(r, gs_param_type_int, Resolution),\
140
 
      pi(afs, gs_param_type_int, AutoFilterStrategy),\
141
 
      gs_param_item_end\
142
 
    }
143
 
 
144
 
static const psdf_image_param_names_t Color_names = {
145
 
    psdf_image_param_names(
146
 
        "ColorACSImageDict", "AntiAliasColorImages", "AutoFilterColorImages",
147
 
        "ColorImageDepth", "ColorImageDict",
148
 
        "DownsampleColorImages", "ColorImageDownsampleType",
149
 
        "ColorImageDownsampleThreshold", 1.5,
150
 
        "EncodeColorImages", "ColorImageFilter", Poly_filters,
151
 
        "ColorImageResolution", 0
152
 
    )
153
 
};
154
 
static const psdf_image_param_names_t Gray_names = {
155
 
    psdf_image_param_names(
156
 
        "GrayACSImageDict", "AntiAliasGrayImages", "AutoFilterGrayImages",
157
 
        "GrayImageDepth", "GrayImageDict",
158
 
        "DownsampleGrayImages", "GrayImageDownsampleType",
159
 
        "GrayImageDownsampleThreshold", 2.0,
160
 
        "EncodeGrayImages", "GrayImageFilter", Poly_filters,
161
 
        "GrayImageResolution", 0
162
 
    )
163
 
};
164
 
static const psdf_image_param_names_t Mono_names = {
165
 
    psdf_image_param_names(
166
 
        0, "AntiAliasMonoImages", 0,
167
 
        "MonoImageDepth", "MonoImageDict",
168
 
        "DownsampleMonoImages", "MonoImageDownsampleType",
169
 
        "MonoImageDownsampleThreshold", 2.0,
170
 
        "EncodeMonoImages", "MonoImageFilter", Mono_filters,
171
 
        "MonoImageResolution", 0
172
 
    )
173
 
};
174
 
static const psdf_image_param_names_t Color_names15 = {
175
 
    psdf_image_param_names(
176
 
        "ColorACSImageDict", "AntiAliasColorImages", "AutoFilterColorImages",
177
 
        "ColorImageDepth", "ColorImageDict",
178
 
        "DownsampleColorImages", "ColorImageDownsampleType",
179
 
        "ColorImageDownsampleThreshold", 1.5,
180
 
        "EncodeColorImages", "ColorImageFilter", Poly_filters,
181
 
        "ColorImageResolution", "ColorAutoFilterStrategy"
182
 
    )
183
 
};
184
 
static const psdf_image_param_names_t Gray_names15 = {
185
 
    psdf_image_param_names(
186
 
        "GrayACSImageDict", "AntiAliasGrayImages", "AutoFilterGrayImages",
187
 
        "GrayImageDepth", "GrayImageDict",
188
 
        "DownsampleGrayImages", "GrayImageDownsampleType",
189
 
        "GrayImageDownsampleThreshold", 2.0,
190
 
        "EncodeGrayImages", "GrayImageFilter", Poly_filters,
191
 
        "GrayImageResolution", "GrayAutoFilterStrategy"
192
 
    )
193
 
};
194
 
#undef pi
195
 
static const char *const AutoRotatePages_names[] = {
196
 
    psdf_arp_names, 0
197
 
};
198
 
static const char *const ColorConversionStrategy_names[] = {
199
 
    psdf_ccs_names, 0
200
 
};
201
 
static const char *const DownsampleType_names[] = {
202
 
    psdf_ds_names, 0
203
 
};
204
 
static const char *const Binding_names[] = {
205
 
    psdf_binding_names, 0
206
 
};
207
 
static const char *const DefaultRenderingIntent_names[] = {
208
 
    psdf_ri_names, 0
209
 
};
210
 
static const char *const TransferFunctionInfo_names[] = {
211
 
    psdf_tfi_names, 0
212
 
};
213
 
static const char *const UCRandBGInfo_names[] = {
214
 
    psdf_ucrbg_names, 0
215
 
};
216
 
static const char *const CannotEmbedFontPolicy_names[] = {
217
 
    psdf_cefp_names, 0
218
 
};
219
 
 
220
 
static const gs_param_item_t psdf_param_items[] = {
221
 
#define pi(key, type, memb) { key, type, offset_of(psdf_distiller_params, memb) }
222
 
 
223
 
    /* General parameters */
224
 
 
225
 
    pi("ASCII85EncodePages", gs_param_type_bool, ASCII85EncodePages),
226
 
    /* (AutoRotatePages) */
227
 
    /* (Binding) */
228
 
    pi("CompressPages", gs_param_type_bool, CompressPages),
229
 
    /* (DefaultRenderingIntent) */
230
 
    pi("DetectBlends", gs_param_type_bool, DetectBlends),
231
 
    pi("DoThumbnails", gs_param_type_bool, DoThumbnails),
232
 
    pi("ImageMemory", gs_param_type_long, ImageMemory),
233
 
    /* (LockDistillerParams) */
234
 
    pi("LZWEncodePages", gs_param_type_bool, LZWEncodePages),
235
 
    pi("OPM", gs_param_type_int, OPM),
236
 
    pi("PreserveHalftoneInfo", gs_param_type_bool, PreserveHalftoneInfo),
237
 
    pi("PreserveOPIComments", gs_param_type_bool, PreserveOPIComments),
238
 
    pi("PreserveOverprintSettings", gs_param_type_bool, PreserveOverprintSettings),
239
 
    /* (TransferFunctionInfo) */
240
 
    /* (UCRandBGInfo) */
241
 
    pi("UseFlateCompression", gs_param_type_bool, UseFlateCompression),
242
 
 
243
 
    /* Color image processing parameters */
244
 
 
245
 
    pi("ConvertCMYKImagesToRGB", gs_param_type_bool, ConvertCMYKImagesToRGB),
246
 
    pi("ConvertImagesToIndexed", gs_param_type_bool, ConvertImagesToIndexed),
247
 
 
248
 
    /* Font embedding parameters */
249
 
 
250
 
    /* (CannotEmbedFontPolicy) */
251
 
    pi("EmbedAllFonts", gs_param_type_bool, EmbedAllFonts),
252
 
    pi("MaxSubsetPct", gs_param_type_int, MaxSubsetPct),
253
 
    pi("SubsetFonts", gs_param_type_bool, SubsetFonts),
254
 
 
255
 
#undef pi
256
 
    gs_param_item_end
257
 
};
258
 
 
259
 
/* -------- Get parameters -------- */
260
 
 
261
 
static int
262
 
psdf_write_name(gs_param_list *plist, const char *key, const char *str)
263
 
{
264
 
    gs_param_string pstr;
265
 
 
266
 
    param_string_from_string(pstr, str);
267
 
    return param_write_name(plist, key, &pstr);
268
 
}
269
 
 
270
 
static int
271
 
psdf_write_string_param(gs_param_list *plist, const char *key,
272
 
                        const gs_const_string *pstr)
273
 
{
274
 
    gs_param_string ps;
275
 
 
276
 
    ps.data = pstr->data;
277
 
    ps.size = pstr->size;
278
 
    ps.persistent = false;
279
 
    return param_write_string(plist, key, &ps);
280
 
}
281
 
 
282
 
/*
283
 
 * Get an image Dict parameter.  Note that we return a default (empty)
284
 
 * dictionary if the parameter has never been set.
285
 
 */
286
 
static int
287
 
psdf_get_image_dict_param(gs_param_list * plist, const gs_param_name pname,
288
 
                          gs_c_param_list *plvalue)
289
 
{
290
 
    gs_param_dict dict;
291
 
    int code;
292
 
 
293
 
    if (pname == 0)
294
 
        return 0;
295
 
    dict.size = 12;             /* enough for all param dicts we know about */
296
 
    if ((code = param_begin_write_dict(plist, pname, &dict, false)) < 0)
297
 
        return code;
298
 
    if (plvalue != 0) {
299
 
        gs_c_param_list_read(plvalue);
300
 
        code = param_list_copy(dict.list, (gs_param_list *)plvalue);
301
 
    }
302
 
    param_end_write_dict(plist, pname, &dict);
303
 
    return code;
304
 
}
305
 
 
306
 
/* Get a set of image-related parameters. */
307
 
static int
308
 
psdf_get_image_params(gs_param_list * plist,
309
 
          const psdf_image_param_names_t * pnames, psdf_image_params * params)
310
 
{
311
 
    /* Skip AutoFilter for mono images. */
312
 
    const gs_param_item_t *items =
313
 
        (pnames->items[0].key == 0 ? pnames->items + 1 : pnames->items);
314
 
    int code;
315
 
 
316
 
    /*
317
 
     * We must actually return a value for every parameter, so that
318
 
     * all parameter names will be recognized as settable by -d or -s
319
 
     * from the command line.
320
 
     */
321
 
    code = gs_param_write_items(plist, params, NULL, items);
322
 
    if (code < 0)
323
 
        return code;
324
 
 
325
 
    code = psdf_get_image_dict_param(plist, pnames->ACSDict, params->ACSDict);
326
 
    if (code < 0)
327
 
        return code;
328
 
 
329
 
           /* (AntiAlias) */
330
 
           /* (AutoFilter) */
331
 
           /* (Depth) */
332
 
    code = psdf_get_image_dict_param(plist, pnames->Dict, params->Dict);
333
 
    if (code < 0)
334
 
        return code;
335
 
 
336
 
           /* (Downsample) */
337
 
    code = psdf_write_name(plist, pnames->DownsampleType,
338
 
                DownsampleType_names[params->DownsampleType]);
339
 
    if (code < 0)
340
 
        return code;
341
 
 
342
 
           /* (DownsampleThreshold) */
343
 
           /* (Encode) */
344
 
    code = psdf_write_name(plist, pnames->Filter,
345
 
                                   (params->Filter == 0 ?
346
 
                                    pnames->filter_names[0].pname :
347
 
                                    params->Filter));
348
 
    if (code < 0)
349
 
        return code;
350
 
 
351
 
           /* (Resolution) */
352
 
#ifdef USE_LWF_JP2
353
 
    if (pnames->AutoFilterStrategy != 0)
354
 
        code = psdf_write_name(plist, pnames->AutoFilterStrategy,
355
 
                                   (params->AutoFilterStrategy == 0 ?
356
 
                                   "JPEG2000" : params->AutoFilterStrategy));
357
 
#endif
358
 
    return code;
359
 
}
360
 
 
361
 
/* Get a font embedding parameter. */
362
 
static int
363
 
psdf_get_embed_param(gs_param_list *plist, gs_param_name allpname,
364
 
                     const gs_param_string_array *psa)
365
 
{
366
 
    int code = param_write_name_array(plist, allpname, psa);
367
 
 
368
 
    if (code >= 0)
369
 
        code = param_write_name_array(plist, allpname + 1, psa);
370
 
    return code;
371
 
}
372
 
 
373
 
/* Get parameters. */
374
 
int
375
 
gdev_psdf_get_params(gx_device * dev, gs_param_list * plist)
376
 
{
377
 
    gx_device_psdf *pdev = (gx_device_psdf *) dev;
378
 
    int code = gdev_vector_get_params(dev, plist);
379
 
    if (code < 0)
380
 
        return code;
381
 
 
382
 
    code = gs_param_write_items(plist, &pdev->params, NULL, psdf_param_items);
383
 
    if (code < 0)
384
 
        return code;
385
 
 
386
 
    /* General parameters */
387
 
 
388
 
    code = psdf_write_name(plist, "AutoRotatePages",
389
 
                AutoRotatePages_names[(int)pdev->params.AutoRotatePages]);
390
 
    if (code < 0)
391
 
        return code;
392
 
 
393
 
    code = psdf_write_name(plist, "Binding",
394
 
                Binding_names[(int)pdev->params.Binding]);
395
 
    if (code < 0)
396
 
        return code;
397
 
 
398
 
    code = psdf_write_name(plist, "DefaultRenderingIntent",
399
 
                DefaultRenderingIntent_names[(int)pdev->params.DefaultRenderingIntent]);
400
 
    if (code < 0)
401
 
        return code;
402
 
 
403
 
    code = psdf_write_name(plist, "TransferFunctionInfo",
404
 
                TransferFunctionInfo_names[(int)pdev->params.TransferFunctionInfo]);
405
 
    if (code < 0)
406
 
        return code;
407
 
 
408
 
    code = psdf_write_name(plist, "UCRandBGInfo",
409
 
                UCRandBGInfo_names[(int)pdev->params.UCRandBGInfo]);
410
 
    if (code < 0)
411
 
        return code;
412
 
 
413
 
    /* Color sampled image parameters */
414
 
 
415
 
    code = psdf_get_image_params(plist,
416
 
                        (pdev->ParamCompatibilityLevel >= 1.5 ? &Color_names15 : &Color_names),
417
 
                        &pdev->params.ColorImage);
418
 
    if (code < 0)
419
 
        return code;
420
 
 
421
 
    code = psdf_write_name(plist, "ColorConversionStrategy",
422
 
                ColorConversionStrategy_names[(int)pdev->params.ColorConversionStrategy]);
423
 
    if (code < 0)
424
 
        return code;
425
 
 
426
 
    code = psdf_write_string_param(plist, "CalCMYKProfile",
427
 
                                        &pdev->params.CalCMYKProfile);
428
 
    if (code < 0)
429
 
        return code;
430
 
 
431
 
    code = psdf_write_string_param(plist, "CalGrayProfile",
432
 
                                        &pdev->params.CalGrayProfile);
433
 
    if (code < 0)
434
 
        return code;
435
 
 
436
 
    code = psdf_write_string_param(plist, "CalRGBProfile",
437
 
                                        &pdev->params.CalRGBProfile);
438
 
    if (code < 0)
439
 
        return code;
440
 
 
441
 
    code = psdf_write_string_param(plist, "sRGBProfile",
442
 
                                        &pdev->params.sRGBProfile);
443
 
    if (code < 0)
444
 
        return code;
445
 
 
446
 
    /* Gray sampled image parameters */
447
 
 
448
 
    code = psdf_get_image_params(plist,
449
 
                        (pdev->ParamCompatibilityLevel >= 1.5 ? &Gray_names15 : &Gray_names),
450
 
                        &pdev->params.GrayImage);
451
 
    if (code < 0)
452
 
        return code;
453
 
 
454
 
    /* Mono sampled image parameters */
455
 
 
456
 
    code = psdf_get_image_params(plist, &Mono_names, &pdev->params.MonoImage);
457
 
    if (code < 0)
458
 
        return code;
459
 
 
460
 
    /* Font embedding parameters */
461
 
 
462
 
    code = psdf_get_embed_param(plist, ".AlwaysEmbed", &pdev->params.AlwaysEmbed);
463
 
    if (code < 0)
464
 
        return code;
465
 
 
466
 
    code = psdf_get_embed_param(plist, ".NeverEmbed", &pdev->params.NeverEmbed);
467
 
    if (code < 0)
468
 
        return code;
469
 
 
470
 
    code = psdf_write_name(plist, "CannotEmbedFontPolicy",
471
 
                CannotEmbedFontPolicy_names[(int)pdev->params.CannotEmbedFontPolicy]);
472
 
 
473
 
    return code;
474
 
}
475
 
 
476
 
/* -------- Put parameters -------- */
477
 
 
478
 
extern stream_state_proc_put_params(s_CF_put_params, stream_CF_state);
479
 
extern stream_state_proc_put_params(s_DCTE_put_params, stream_DCT_state);
480
 
typedef stream_state_proc_put_params((*ss_put_params_t), stream_state);
481
 
 
482
 
static int
483
 
psdf_read_string_param(gs_param_list *plist, const char *key,
484
 
                       gs_const_string *pstr, gs_memory_t *mem, int ecode)
485
 
{
486
 
    gs_param_string ps;
487
 
    int code;
488
 
 
489
 
    switch (code = param_read_string(plist, key, &ps)) {
490
 
    case 0: {
491
 
        uint size = ps.size;
492
 
        byte *data = gs_alloc_string(mem, size, "psdf_read_string_param");
493
 
 
494
 
        if (data == 0)
495
 
            return_error(gs_error_VMerror);
496
 
        memcpy(data, ps.data, size);
497
 
        pstr->data = data;
498
 
        pstr->size = size;
499
 
        break;
500
 
    }
501
 
    default:
502
 
        ecode = code;
503
 
    case 1:
504
 
        break;
505
 
    }
506
 
    return ecode;
507
 
}
508
 
 
509
 
/*
510
 
 * The arguments and return value for psdf_put_enum are different because
511
 
 * we must cast the value both going in and coming out.
512
 
 */
513
 
static int
514
 
psdf_put_enum(gs_param_list *plist, const char *key, int value,
515
 
              const char *const pnames[], int *pecode)
516
 
{
517
 
    *pecode = param_put_enum(plist, key, &value, pnames, *pecode);
518
 
    return value;
519
 
}
520
 
 
521
 
static int
522
 
psdf_CF_put_params(gs_param_list * plist, stream_state * st)
523
 
{
524
 
    stream_CFE_state *const ss = (stream_CFE_state *) st;
525
 
 
526
 
    (*s_CFE_template.set_defaults) (st);
527
 
    ss->K = -1;
528
 
    ss->BlackIs1 = true;
529
 
    return s_CF_put_params(plist, (stream_CF_state *) ss);
530
 
}
531
 
 
532
 
static int
533
 
psdf_DCT_put_params(gs_param_list * plist, stream_state * st)
534
 
{
535
 
    return psdf_DCT_filter(plist, st, 8 /*nominal*/, 8 /*ibid.*/, 3 /*ibid.*/,
536
 
                           NULL);
537
 
}
538
 
 
539
 
/* Put [~](Always|Never)Embed parameters. */
540
 
/* Returns 0 = OK, 1 = no paramewter specified, <0 = error. */
541
 
static int
542
 
param_read_embed_array(gs_param_list * plist, gs_param_name pname,
543
 
                       gs_param_string_array * psa)
544
 
{
545
 
    int code;
546
 
 
547
 
    psa->data = 0, psa->size = 0;
548
 
    switch (code = param_read_name_array(plist, pname, psa)) {
549
 
        default:
550
 
            param_signal_error(plist, pname, code);
551
 
        case 0:
552
 
        case 1:
553
 
            break;
554
 
    }
555
 
    return code;
556
 
}
557
 
static bool
558
 
param_string_eq(const gs_param_string *ps1, const gs_param_string *ps2)
559
 
{
560
 
    return !bytes_compare(ps1->data, ps1->size, ps2->data, ps2->size);
561
 
}
562
 
static int
563
 
add_embed(gs_param_string_array *prsa, const gs_param_string_array *psa,
564
 
          gs_memory_t *mem)
565
 
{
566
 
    uint i;
567
 
    gs_param_string *const rdata =
568
 
        (gs_param_string *)prsa->data; /* break const */
569
 
    uint count = prsa->size;
570
 
 
571
 
    for (i = 0; i < psa->size; ++i) {
572
 
        uint j;
573
 
 
574
 
        for (j = 0; j < count; ++j)
575
 
            if (param_string_eq(&psa->data[i], &rdata[j]))
576
 
                    break;
577
 
        if (j == count) {
578
 
            uint size = psa->data[i].size;
579
 
            byte *data = gs_alloc_string(mem, size, "add_embed");
580
 
 
581
 
            if (data == 0)
582
 
                return_error(gs_error_VMerror);
583
 
            memcpy(data, psa->data[i].data, size);
584
 
            rdata[count].data = data;
585
 
            rdata[count].size = size;
586
 
            rdata[count].persistent = false;
587
 
            count++;
588
 
        }
589
 
    }
590
 
    prsa->size = count;
591
 
    return 0;
592
 
}
593
 
static void
594
 
delete_embed(gs_param_string_array *prsa, const gs_param_string_array *pnsa,
595
 
             gs_memory_t *mem)
596
 
{
597
 
    uint i;
598
 
    gs_param_string *const rdata =
599
 
        (gs_param_string *)prsa->data; /* break const */
600
 
    uint count = prsa->size;
601
 
 
602
 
    for (i = pnsa->size; i-- > 0;) {
603
 
        uint j;
604
 
 
605
 
        for (j = count; j-- > 0;)
606
 
            if (param_string_eq(&pnsa->data[i], &rdata[j]))
607
 
                break;
608
 
        if (j + 1 != 0) {
609
 
            gs_free_const_string(mem, rdata[j].data, rdata[j].size,
610
 
                                 "delete_embed");
611
 
            rdata[j] = rdata[--count];
612
 
        }
613
 
    }
614
 
    prsa->size = count;
615
 
}
616
 
static int merge_embed(gs_param_string_array * psa, gs_param_string_array * asa,
617
 
                     gs_memory_t *mem)
618
 
{
619
 
    gs_param_string_array rsa;
620
 
    gs_param_string *rdata;
621
 
    int code;
622
 
 
623
 
    rdata = gs_alloc_struct_array(mem, psa->size + asa->size,
624
 
                                  gs_param_string,
625
 
                                  &st_param_string_element,
626
 
                                  "psdf_put_embed_param(update)");
627
 
    if (rdata == 0)
628
 
        return_error(gs_error_VMerror);
629
 
    memcpy(rdata, psa->data, psa->size * sizeof(*psa->data));
630
 
    rsa.data = rdata;
631
 
    rsa.size = psa->size;
632
 
    rsa.persistent = false;
633
 
    code = add_embed(&rsa, asa, mem);
634
 
    if (code < 0) {
635
 
        gs_free_object(mem, rdata, "psdf_put_embed_param(update)");
636
 
        return code;
637
 
    }
638
 
    gs_free_const_object(mem, psa->data, "psdf_put_embed_param(free)");
639
 
    *psa = rsa;
640
 
    return 0;
641
 
}
642
 
 
643
 
static int
644
 
psdf_put_embed_param(gs_param_list * plist, gs_param_name notpname,
645
 
                     gs_param_name pname, gs_param_string_array * psa,
646
 
                     gs_memory_t *mem, int ecode)
647
 
{
648
 
    gs_param_name allpname = pname + 1;
649
 
    gs_param_string_array sa, nsa, asa;
650
 
    int code;
651
 
 
652
 
    mem = gs_memory_stable(mem);
653
 
    code  = param_read_embed_array(plist, pname, &sa);
654
 
    if (code < 0)
655
 
        return code;
656
 
    if (code == 0) {
657
 
        /* Optimize for sa == *psa. */
658
 
        int i;
659
 
 
660
 
        if (sa.size == psa->size) {
661
 
            for (i = 0; i < sa.size; ++i) {
662
 
                if (!param_string_eq(&sa.data[i], &psa->data[i]))
663
 
                    break;
664
 
     }
665
 
        } else
666
 
            i = -1;
667
 
        if (i == sa.size) {
668
 
            /* equal, no-op. */
669
 
        } else {
670
 
            delete_embed(psa, psa, mem);
671
 
            code = merge_embed(psa, &sa, mem);
672
 
            if (code < 0)
673
 
                return code;
674
 
        }
675
 
    }
676
 
    code = param_read_embed_array(plist, notpname, &nsa);
677
 
    if (code < 0)
678
 
        return code;
679
 
    if (nsa.data != 0)
680
 
        delete_embed(psa, &nsa, mem);
681
 
    code = param_read_embed_array(plist, allpname, &asa);
682
 
    if (code < 0)
683
 
        return code;
684
 
    if (asa.data != 0) {
685
 
        code = merge_embed(psa, &asa, mem);
686
 
        if (code < 0)
687
 
            return code;
688
 
    }
689
 
    if (psa->data)
690
 
        psa->data = gs_resize_object(mem, (gs_param_string *)psa->data, psa->size,
691
 
                                        "psdf_put_embed_param(resize)");
692
 
    return 0;
693
 
}
694
 
 
695
 
/* Put an image Dict parameter. */
696
 
static int
697
 
psdf_put_image_dict_param(gs_param_list * plist, const gs_param_name pname,
698
 
                          gs_c_param_list **pplvalue,
699
 
                          const stream_template * templat,
700
 
                          ss_put_params_t put_params, gs_memory_t * mem)
701
 
{
702
 
    gs_param_dict dict;
703
 
    gs_c_param_list *plvalue = *pplvalue;
704
 
    int code;
705
 
 
706
 
    mem = gs_memory_stable(mem);
707
 
    switch (code = param_begin_read_dict(plist, pname, &dict, false)) {
708
 
        default:
709
 
            param_signal_error(plist, pname, code);
710
 
            return code;
711
 
        case 1:
712
 
            return 0;
713
 
        case 0: {
714
 
            /* Check the parameter values now. */
715
 
            stream_state *ss = s_alloc_state(mem, templat->stype, pname);
716
 
 
717
 
            if (ss == 0)
718
 
                return_error(gs_error_VMerror);
719
 
            ss->templat = templat;
720
 
            if (templat->set_defaults)
721
 
                templat->set_defaults(ss);
722
 
            code = put_params(dict.list, ss);
723
 
            if (templat->release)
724
 
                templat->release(ss);
725
 
            gs_free_object(mem, ss, pname);
726
 
            if (code < 0) {
727
 
                param_signal_error(plist, pname, code);
728
 
            } else {
729
 
                plvalue = gs_c_param_list_alloc(mem, pname);
730
 
                if (plvalue == 0)
731
 
                    return_error(gs_error_VMerror);
732
 
                gs_c_param_list_write(plvalue, mem);
733
 
                code = param_list_copy((gs_param_list *)plvalue,
734
 
                                       dict.list);
735
 
                if (code < 0) {
736
 
                    gs_c_param_list_release(plvalue);
737
 
                    gs_free_object(mem, plvalue, pname);
738
 
                    plvalue = *pplvalue;
739
 
                }
740
 
            }
741
 
        }
742
 
        param_end_read_dict(plist, pname, &dict);
743
 
        break;
744
 
    }
745
 
    if (plvalue != *pplvalue) {
746
 
        if (*pplvalue)
747
 
            gs_c_param_list_release(*pplvalue);
748
 
        *pplvalue = plvalue;
749
 
    }
750
 
    return code;
751
 
}
752
 
 
753
 
/* Put a set of image-related parameters. */
754
 
static int
755
 
psdf_put_image_params(const gx_device_psdf * pdev, gs_param_list * plist,
756
 
                      const psdf_image_param_names_t * pnames,
757
 
                      psdf_image_params * params, int ecode)
758
 
{
759
 
    gs_param_string fs;
760
 
    /*
761
 
     * Since this procedure can be called before the device is open,
762
 
     * we must use pdev->memory rather than pdev->v_memory.
763
 
     */
764
 
    gs_memory_t *mem = pdev->memory;
765
 
    gs_param_name pname;
766
 
    /* Skip AutoFilter for mono images. */
767
 
    const gs_param_item_t *items =
768
 
        (pnames->items[0].key == 0 ? pnames->items + 1 : pnames->items);
769
 
    int code = gs_param_read_items(plist, params, items);
770
 
 
771
 
    if ((pname = pnames->ACSDict) != 0) {
772
 
        code = psdf_put_image_dict_param(plist, pname, &params->ACSDict,
773
 
                                         &s_DCTE_template,
774
 
                                         psdf_DCT_put_params, mem);
775
 
        if (code < 0)
776
 
            ecode = code;
777
 
    }
778
 
    /* (AntiAlias) */
779
 
    /* (AutoFilter) */
780
 
    /* (Depth) */
781
 
    if ((pname = pnames->Dict) != 0) {
782
 
        const stream_template *templat;
783
 
        ss_put_params_t put_params;
784
 
 
785
 
        /* Hack to determine what kind of a Dict we want: */
786
 
        if (pnames->Dict[0] == 'M')
787
 
            templat = &s_CFE_template,
788
 
                put_params = psdf_CF_put_params;
789
 
        else
790
 
            templat = &s_DCTE_template,
791
 
                put_params = psdf_DCT_put_params;
792
 
        code = psdf_put_image_dict_param(plist, pname, &params->Dict,
793
 
                                         templat, put_params, mem);
794
 
        if (code < 0)
795
 
            ecode = code;
796
 
    }
797
 
    /* (Downsample) */
798
 
    params->DownsampleType = (enum psdf_downsample_type)
799
 
        psdf_put_enum(plist, pnames->DownsampleType,
800
 
                      (int)params->DownsampleType, DownsampleType_names,
801
 
                      &ecode);
802
 
    /* (DownsampleThreshold) */
803
 
    /* (Encode) */
804
 
#ifdef USE_LWF_JP2
805
 
    /* Process AutoFilterStrategy before Filter, because it sets defaults
806
 
       for the latter. */
807
 
    if (pnames->AutoFilterStrategy != NULL) {
808
 
        switch (code = param_read_string(plist, pnames->AutoFilterStrategy, &fs)) {
809
 
            case 0:
810
 
                {
811
 
                    const psdf_image_filter_name *pn = pnames->filter_names;
812
 
                    const char *param_name = 0;
813
 
 
814
 
                    if (gs_param_string_eq(&fs, "/JPEG")) {
815
 
                        params->AutoFilterStrategy = "/JPEG";
816
 
                        param_name = "DCTEncode";
817
 
                    } if (gs_param_string_eq(&fs, "/JPEG2000")) {
818
 
                        params->AutoFilterStrategy = "/JPEG2000";
819
 
                        param_name = "JPXEncode";
820
 
                    } else {
821
 
                        ecode = gs_error_rangecheck;
822
 
                        goto ipe1;
823
 
                    }
824
 
                    while (pn->pname != 0 && !gs_param_string_eq(&fs, param_name))
825
 
                        pn++;
826
 
                    if (pn->pname != 0 && pn->min_version <= pdev->version) {
827
 
                        params->Filter = pn->pname;
828
 
                        params->filter_template = pn->templat;
829
 
                    }
830
 
                    break;
831
 
                }
832
 
            default:
833
 
                ecode = code;
834
 
            ipe1:param_signal_error(plist, pnames->AutoFilterStrategy, ecode);
835
 
            case 1:
836
 
                break;
837
 
        }
838
 
    }
839
 
#endif
840
 
    switch (code = param_read_string(plist, pnames->Filter, &fs)) {
841
 
        case 0:
842
 
            {
843
 
                const psdf_image_filter_name *pn = pnames->filter_names;
844
 
 
845
 
                while (pn->pname != 0 && !gs_param_string_eq(&fs, pn->pname))
846
 
                    pn++;
847
 
                if (pn->pname == 0 || pn->min_version > pdev->version) {
848
 
                    ecode = gs_error_rangecheck;
849
 
                    goto ipe;
850
 
                }
851
 
                params->Filter = pn->pname;
852
 
                params->filter_template = pn->templat;
853
 
                break;
854
 
            }
855
 
        default:
856
 
            ecode = code;
857
 
          ipe:param_signal_error(plist, pnames->Filter, ecode);
858
 
        case 1:
859
 
            break;
860
 
    }
861
 
    /* (Resolution) */
862
 
    if (ecode >= 0) {           /* Force parameters to acceptable values. */
863
 
        if (params->Resolution < 1)
864
 
            params->Resolution = 1;
865
 
        if (params->DownsampleThreshold < 1 ||
866
 
            params->DownsampleThreshold > 10)
867
 
            params->DownsampleThreshold = pnames->DownsampleThreshold_default;
868
 
        switch (params->Depth) {
869
 
            default:
870
 
                params->Depth = -1;
871
 
            case 1:
872
 
            case 2:
873
 
            case 4:
874
 
            case 8:
875
 
            case -1:
876
 
                break;
877
 
        }
878
 
    }
879
 
    return ecode;
880
 
}
881
 
 
882
 
/* Put parameters. */
883
 
int
884
 
gdev_psdf_put_params(gx_device * dev, gs_param_list * plist)
885
 
{
886
 
    gx_device_psdf *pdev = (gx_device_psdf *) dev;
887
 
    gs_memory_t *mem =
888
 
        (pdev->v_memory ? pdev->v_memory : dev->memory);
889
 
    int ecode, code;
890
 
    psdf_distiller_params params;
891
 
 
892
 
    params = pdev->params;
893
 
 
894
 
    /*
895
 
     * If LockDistillerParams was true and isn't being set to false,
896
 
     * ignore all other psdf parameters.  However, do not ignore the
897
 
     * standard device parameters.
898
 
     */
899
 
    ecode = code = param_read_bool(plist, "LockDistillerParams",
900
 
                                   &params.LockDistillerParams);
901
 
    if (!(pdev->params.LockDistillerParams && params.LockDistillerParams)) {
902
 
 
903
 
        /* General parameters. */
904
 
 
905
 
        code = gs_param_read_items(plist, &params, psdf_param_items);
906
 
        if (code < 0)
907
 
            ecode = code;
908
 
        params.AutoRotatePages = (enum psdf_auto_rotate_pages)
909
 
            psdf_put_enum(plist, "AutoRotatePages", (int)params.AutoRotatePages,
910
 
                          AutoRotatePages_names, &ecode);
911
 
        params.Binding = (enum psdf_binding)
912
 
            psdf_put_enum(plist, "Binding", (int)params.Binding,
913
 
                          Binding_names, &ecode);
914
 
        params.DefaultRenderingIntent = (enum psdf_default_rendering_intent)
915
 
            psdf_put_enum(plist, "DefaultRenderingIntent",
916
 
                          (int)params.DefaultRenderingIntent,
917
 
                          DefaultRenderingIntent_names, &ecode);
918
 
        params.TransferFunctionInfo = (enum psdf_transfer_function_info)
919
 
            psdf_put_enum(plist, "TransferFunctionInfo",
920
 
                          (int)params.TransferFunctionInfo,
921
 
                          TransferFunctionInfo_names, &ecode);
922
 
        params.UCRandBGInfo = (enum psdf_ucr_and_bg_info)
923
 
            psdf_put_enum(plist, "UCRandBGInfo", (int)params.UCRandBGInfo,
924
 
                          UCRandBGInfo_names, &ecode);
925
 
        ecode = param_put_bool(plist, "UseFlateCompression",
926
 
                               &params.UseFlateCompression, ecode);
927
 
 
928
 
        /* Color sampled image parameters */
929
 
 
930
 
        ecode = psdf_put_image_params(pdev, plist,
931
 
                        (pdev->ParamCompatibilityLevel >= 1.5 ? &Color_names15 : &Color_names),
932
 
                                      &params.ColorImage, ecode);
933
 
        params.ColorConversionStrategy = (enum psdf_color_conversion_strategy)
934
 
            psdf_put_enum(plist, "ColorConversionStrategy",
935
 
                          (int)params.ColorConversionStrategy,
936
 
                          ColorConversionStrategy_names, &ecode);
937
 
        ecode = psdf_read_string_param(plist, "CalCMYKProfile",
938
 
                                       &params.CalCMYKProfile, mem, ecode);
939
 
        ecode = psdf_read_string_param(plist, "CalGrayProfile",
940
 
                                       &params.CalGrayProfile, mem, ecode);
941
 
        ecode = psdf_read_string_param(plist, "CalRGBProfile",
942
 
                                       &params.CalRGBProfile, mem, ecode);
943
 
        ecode = psdf_read_string_param(plist, "sRGBProfile",
944
 
                                       &params.sRGBProfile, mem, ecode);
945
 
 
946
 
        /* Gray sampled image parameters */
947
 
 
948
 
        ecode = psdf_put_image_params(pdev, plist,
949
 
                        (pdev->ParamCompatibilityLevel >= 1.5 ? &Gray_names15 : &Gray_names),
950
 
                                      &params.GrayImage, ecode);
951
 
 
952
 
        /* Mono sampled image parameters */
953
 
 
954
 
        ecode = psdf_put_image_params(pdev, plist, &Mono_names,
955
 
                                      &params.MonoImage, ecode);
956
 
 
957
 
        /* Font embedding parameters */
958
 
 
959
 
        ecode = psdf_put_embed_param(plist, "~AlwaysEmbed", ".AlwaysEmbed",
960
 
                                     &params.AlwaysEmbed, mem, ecode);
961
 
        ecode = psdf_put_embed_param(plist, "~NeverEmbed", ".NeverEmbed",
962
 
                                     &params.NeverEmbed, mem, ecode);
963
 
        params.CannotEmbedFontPolicy = (enum psdf_cannot_embed_font_policy)
964
 
            psdf_put_enum(plist, "CannotEmbedFontPolicy",
965
 
                          (int)params.CannotEmbedFontPolicy,
966
 
                          CannotEmbedFontPolicy_names, &ecode);
967
 
    }
968
 
    if (ecode < 0)
969
 
        return ecode;
970
 
    code = gdev_vector_put_params(dev, plist);
971
 
    if (code < 0)
972
 
        return code;
973
 
 
974
 
    pdev->params = params;      /* OK to update now */
975
 
    return 0;
976
 
}