~ubuntu-branches/ubuntu/jaunty/ghostscript/jaunty-updates

« back to all changes in this revision

Viewing changes to src/gdevpdfp.c

  • Committer: Bazaar Package Importer
  • Author(s): Till Kamppeter
  • Date: 2009-01-20 16:40:45 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20090120164045-lnfhi0n30o5lwhwa
Tags: 8.64.dfsg.1~svn9377-0ubuntu1
* New upstream release (SVN rev 9377)
   o Fixes many bugs concerning PDF rendering, to make the PDF printing
     workflow correctly working.
   o Fixes long-standing bugs in many drivers, like input paper tray and
     duplex options not working for the built-in PCL 4, 5, 5c, 5e, and
     6/XL drivers, PDF input not working for bjc600, bjc800, and cups
     output devices, several options not working and uninitialized
     memory with cups output device.
   o Merged nearly all patches of the Ubuntu and Debian packages upstream.
   o Fixes LP: #317810, LP: #314439, LP: #314018.
* debian/patches/03_libpaper_support.dpatch,
  debian/patches/11_gs-cjk_font_glyph_handling_fix.dpatch,
  debian/patches/12_gs-cjk_vertical_writing_metrics_fix.dpatch,
  debian/patches/13_gs-cjk_cjkps_examples.dpatch,
  debian/patches/20_bbox_segv_fix.dpatch,
  debian/patches/21_brother_7x0_gdi_fix.dpatch,
  debian/patches/22_epsn_margin_workaround.dpatch,
  debian/patches/24_gs_man_fix.dpatch,
  debian/patches/25_toolbin_insecure_tmp_usage_fix.dpatch,
  debian/patches/26_assorted_script_fixes.dpatch,
  debian/patches/29_gs_css_fix.dpatch,
  debian/patches/30_ps2pdf_man_improvement.dpatch,
  debian/patches/31_fix-gc-sigbus.dpatch,
  debian/patches/34_ftbfs-on-hurd-fix.dpatch,
  debian/patches/35_disable_libcairo.dpatch,
  debian/patches/38_pxl-duplex.dpatch,
  debian/patches/39_pxl-resolution.dpatch,
  debian/patches/42_gs-init-ps-delaybind-fix.dpatch,
  debian/patches/45_bjc600-bjc800-pdf-input.dpatch,
  debian/patches/48_cups-output-device-pdf-duplex-uninitialized-memory-fix.dpatch,
  debian/patches/50_lips4-floating-point-exception.dpatch,
  debian/patches/52_cups-device-logging.dpatch,
  debian/patches/55_pcl-input-slot-fix.dpatch,
  debian/patches/57_pxl-input-slot-fix.dpatch,
  debian/patches/60_pxl-cups-driver-pdf.dpatch,
  debian/patches/62_onebitcmyk-pdf.dpatch,
  debian/patches/65_too-big-temp-files-1.dpatch,
  debian/patches/67_too-big-temp-files-2.dpatch,
  debian/patches/70_take-into-account-data-in-stream-buffer-before-refill.dpatch:
  Removed, applied upstream.
* debian/patches/01_docdir_fix_for_debian.dpatch,
  debian/patches/02_gs_man_fix_debian.dpatch,
  debian/patches/01_docdir-fix-for-debian.dpatch,
  debian/patches/02_docdir-fix-for-debian.dpatch: Renamed patches to
  make merging with Debian easier.
* debian/patches/32_improve-handling-of-media-size-changes-from-gv.dpatch, 
  debian/patches/33_bad-params-to-xinitimage-on-large-bitmaps.dpatch:
  regenerated for new source directory structure.
* debian/rules: Corrected paths to remove cidfmap (it is in Resource/Init/
  in GS 8.64) and to install headers (source paths are psi/ and base/ now).
* debian/rules: Remove all fontmaps, as DeFoMa replaces them.
* debian/local/pdftoraster/pdftoraster.c,
  debian/local/pdftoraster/pdftoraster.convs, debian/rules: Removed
  added pdftoraster filter and use the one which comes with Ghostscript.
* debian/ghostscript.links: s/8.63/8.64/

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2001-2006 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, modified
8
 
   or distributed except as expressly authorized under the terms of that
9
 
   license.  Refer to licensing information at http://www.artifex.com/
10
 
   or contact Artifex Software, Inc.,  7 Mt. Lassen Drive - Suite A-134,
11
 
   San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
12
 
*/
13
 
 
14
 
/* $Id: gdevpdfp.c 8250 2007-09-25 13:31:24Z giles $ */
15
 
/* Get/put parameters for PDF-writing driver */
16
 
#include "memory_.h"
17
 
#include "string_.h"
18
 
#include "gx.h"
19
 
#include "gserrors.h"
20
 
#include "gdevpdfx.h"
21
 
#include "gdevpdfo.h"
22
 
#include "gdevpdfg.h"
23
 
#include "gsparamx.h"
24
 
 
25
 
/*
26
 
 * The pdfwrite device supports the following "real" parameters:
27
 
 *      OutputFile <string>
28
 
 *      all the Distiller parameters (also see gdevpsdp.c)
29
 
 * Only some of the Distiller parameters actually have any effect.
30
 
 *
31
 
 * The device also supports the following write-only pseudo-parameters that
32
 
 * serve only to communicate other information from the PostScript file.
33
 
 * Their "value" is an array of strings, some of which may be the result
34
 
 * of converting arbitrary PostScript objects to string form.
35
 
 *      pdfmark - see gdevpdfm.c
36
 
 *      DSC - processed in this file
37
 
 */
38
 
static int pdf_dsc_process(gx_device_pdf * pdev,
39
 
                            const gs_param_string_array * pma);
40
 
 
41
 
static const int CoreDistVersion = 5000;        /* Distiller 5.0 */
42
 
static const gs_param_item_t pdf_param_items[] = {
43
 
#define pi(key, type, memb) { key, type, offset_of(gx_device_pdf, memb) }
44
 
 
45
 
        /* Acrobat Distiller 4 parameters */
46
 
 
47
 
    /*
48
 
     * EndPage and StartPage are renamed because EndPage collides with
49
 
     * a page device parameter.
50
 
     */
51
 
    pi("PDFEndPage", gs_param_type_int, EndPage),
52
 
    pi("PDFStartPage", gs_param_type_int, StartPage),
53
 
    pi("Optimize", gs_param_type_bool, Optimize),
54
 
    pi("ParseDSCCommentsForDocInfo", gs_param_type_bool,
55
 
       ParseDSCCommentsForDocInfo),
56
 
    pi("ParseDSCComments", gs_param_type_bool, ParseDSCComments),
57
 
    pi("EmitDSCWarnings", gs_param_type_bool, EmitDSCWarnings),
58
 
    pi("CreateJobTicket", gs_param_type_bool, CreateJobTicket),
59
 
    pi("PreserveEPSInfo", gs_param_type_bool, PreserveEPSInfo),
60
 
    pi("AutoPositionEPSFiles", gs_param_type_bool, AutoPositionEPSFiles),
61
 
    pi("PreserveCopyPage", gs_param_type_bool, PreserveCopyPage),
62
 
    pi("UsePrologue", gs_param_type_bool, UsePrologue),
63
 
 
64
 
        /* Acrobat Distiller 5 parameters */
65
 
 
66
 
    pi("OffOptimizations", gs_param_type_int, OffOptimizations),
67
 
 
68
 
        /* Ghostscript-specific parameters */
69
 
 
70
 
    pi("ReAssignCharacters", gs_param_type_bool, ReAssignCharacters),
71
 
    pi("ReEncodeCharacters", gs_param_type_bool, ReEncodeCharacters),
72
 
    pi("FirstObjectNumber", gs_param_type_long, FirstObjectNumber),
73
 
    pi("CompressFonts", gs_param_type_bool, CompressFonts),
74
 
    pi("PrintStatistics", gs_param_type_bool, PrintStatistics),
75
 
    pi("MaxInlineImageSize", gs_param_type_long, MaxInlineImageSize),
76
 
    pi("DSCEncodingToUnicode", gs_param_type_int_array, DSCEncodingToUnicode),
77
 
 
78
 
        /* PDF Encryption */
79
 
    pi("OwnerPassword", gs_param_type_string, OwnerPassword),
80
 
    pi("UserPassword", gs_param_type_string, UserPassword),
81
 
    pi("KeyLength", gs_param_type_int, KeyLength),
82
 
    pi("Permissions", gs_param_type_int, Permissions),
83
 
    pi("EncryptionR", gs_param_type_int, EncryptionR),
84
 
    pi("NoEncrypt", gs_param_type_string, NoEncrypt),
85
 
 
86
 
        /* Target viewer capabilities (Ghostscript-specific)  */
87
 
 /* pi("ForOPDFRead", gs_param_type_bool, ForOPDFRead),                     pdfwrite-only */
88
 
    pi("PatternImagemask", gs_param_type_bool, PatternImagemask),
89
 
    pi("MaxClipPathSize", gs_param_type_int, MaxClipPathSize),
90
 
    pi("MaxShadingBitmapSize", gs_param_type_int, MaxShadingBitmapSize),
91
 
    pi("MaxViewerMemorySize", gs_param_type_int, MaxViewerMemorySize),
92
 
    pi("HaveTrueTypes", gs_param_type_bool, HaveTrueTypes),
93
 
    pi("HaveCIDSystem", gs_param_type_bool, HaveCIDSystem),
94
 
    pi("HaveTransparency", gs_param_type_bool, HaveTransparency),
95
 
 /* pi("OPDFReadProcsetPath", gs_param_type_string, OPDFReadProcsetPath),   ps2write-only */
96
 
    pi("CompressEntireFile", gs_param_type_bool, CompressEntireFile),
97
 
    pi("PDFX", gs_param_type_bool, PDFX),
98
 
    pi("PDFA", gs_param_type_bool, PDFA),
99
 
    pi("DocumentUUID", gs_param_type_string, DocumentUUID),
100
 
    pi("InstanceUUID", gs_param_type_string, InstanceUUID),
101
 
    pi("DocumentTimeSeq", gs_param_type_int, DocumentTimeSeq),
102
 
 
103
 
    /* PDF/X parameters */
104
 
    pi("PDFXTrimBoxToMediaBoxOffset", gs_param_type_float_array, PDFXTrimBoxToMediaBoxOffset),
105
 
    pi("PDFXSetBleedBoxToMediaBox", gs_param_type_bool, PDFXSetBleedBoxToMediaBox),
106
 
    pi("PDFXBleedBoxToTrimBoxOffset", gs_param_type_float_array, PDFXBleedBoxToTrimBoxOffset),
107
 
#undef pi
108
 
    gs_param_item_end
109
 
};
110
 
  
111
 
/*
112
 
  Notes on implementing the remaining Distiller functionality
113
 
  ===========================================================
114
 
 
115
 
  Architectural issues
116
 
  --------------------
117
 
 
118
 
  Must optionally disable application of TR, BG, UCR similarly.  Affects:
119
 
    PreserveHalftoneInfo
120
 
    PreserveOverprintSettings
121
 
    TransferFunctionInfo
122
 
    UCRandBGInfo
123
 
 
124
 
  Current limitations
125
 
  -------------------
126
 
 
127
 
  Non-primary elements in HalftoneType 5 are not written correctly
128
 
 
129
 
  Acrobat Distiller 3
130
 
  -------------------
131
 
 
132
 
  ---- Image parameters ----
133
 
 
134
 
  AntiAlias{Color,Gray,Mono}Images
135
 
 
136
 
  ---- Other parameters ----
137
 
 
138
 
  CompressPages
139
 
    Compress things other than page contents
140
 
  * PreserveHalftoneInfo
141
 
  PreserveOPIComments
142
 
    ? see OPI spec?
143
 
  * PreserveOverprintSettings
144
 
  * TransferFunctionInfo
145
 
  * UCRandBGInfo
146
 
  ColorConversionStrategy
147
 
    Select color space for drawing commands
148
 
  ConvertImagesToIndexed
149
 
    Postprocess image data *after* downsampling (requires an extra pass)
150
 
 
151
 
  Acrobat Distiller 4
152
 
  -------------------
153
 
 
154
 
  ---- Other functionality ----
155
 
 
156
 
  Document structure pdfmarks
157
 
 
158
 
  ---- Parameters ----
159
 
 
160
 
  xxxDownsampleType = /Bicubic
161
 
    Add new filter (or use siscale?) & to setup (gdevpsdi.c)
162
 
  DetectBlends
163
 
    Idiom recognition?  PatternType 2 patterns / shfill?  (see AD4)
164
 
  DoThumbnails
165
 
    Also output to memory device -- resolution issue
166
 
 
167
 
  ---- Job-level control ----
168
 
 
169
 
  EmitDSCWarnings
170
 
    Require DSC parser / interceptor
171
 
  CreateJobTicket
172
 
    ?
173
 
  AutoPositionEPSFiles
174
 
    Require DSC parsing
175
 
  PreserveCopyPage
176
 
    Concatenate Contents streams
177
 
  UsePrologue
178
 
    Needs hack in top-level control?
179
 
 
180
 
*/
181
 
 
182
 
/* ---------------- Get parameters ---------------- */
183
 
 
184
 
/* Get parameters. */
185
 
int
186
 
gdev_pdf_get_params(gx_device * dev, gs_param_list * plist)
187
 
{
188
 
    gx_device_pdf *pdev = (gx_device_pdf *) dev;
189
 
    float cl = (float)pdev->CompatibilityLevel;
190
 
    int code;
191
 
    int cdv = CoreDistVersion;
192
 
    int EmbedFontObjects = 1;
193
 
 
194
 
    pdev->ParamCompatibilityLevel = cl;
195
 
    code = gdev_psdf_get_params(dev, plist);
196
 
    if (code < 0 ||
197
 
        (code = param_write_int(plist, ".EmbedFontObjects", &EmbedFontObjects)) < 0 ||
198
 
        (code = param_write_int(plist, "CoreDistVersion", &cdv)) < 0 ||
199
 
        (code = param_write_float(plist, "CompatibilityLevel", &cl)) < 0 ||
200
 
        (pdev->is_ps2write && (code = param_write_string(plist, "OPDFReadProcsetPath", &pdev->OPDFReadProcsetPath)) < 0) ||
201
 
        (!pdev->is_ps2write && (code = param_write_bool(plist, "ForOPDFRead", &pdev->ForOPDFRead)) < 0) ||
202
 
        /* Indicate that we can process pdfmark and DSC. */
203
 
        (param_requested(plist, "pdfmark") > 0 &&
204
 
         (code = param_write_null(plist, "pdfmark")) < 0) ||
205
 
        (param_requested(plist, "DSC") > 0 &&
206
 
         (code = param_write_null(plist, "DSC")) < 0) ||
207
 
        (code = gs_param_write_items(plist, pdev, NULL, pdf_param_items)) < 0
208
 
        );
209
 
    return code;
210
 
}
211
 
 
212
 
/* ---------------- Put parameters ---------------- */
213
 
 
214
 
/* Put parameters, implementation */
215
 
static int
216
 
gdev_pdf_put_params_impl(gx_device * dev, const gx_device_pdf * save_dev, gs_param_list * plist)
217
 
{
218
 
    int ecode, code;
219
 
    gx_device_pdf *pdev = (gx_device_pdf *) dev;
220
 
    float cl = (float)pdev->CompatibilityLevel;
221
 
    bool locked = pdev->params.LockDistillerParams;
222
 
    gs_param_name param_name;
223
 
    enum psdf_color_conversion_strategy save_ccs = pdev->params.ColorConversionStrategy;
224
 
  
225
 
    pdev->pdf_memory = gs_memory_stable(pdev->memory);
226
 
    /*
227
 
     * If this is a pseudo-parameter (pdfmark or DSC),
228
 
     * don't bother checking for any real ones.
229
 
     */
230
 
 
231
 
    {
232
 
        gs_param_string_array ppa;
233
 
 
234
 
        code = param_read_string_array(plist, (param_name = "pdfmark"), &ppa);
235
 
        switch (code) {
236
 
            case 0:
237
 
                code = pdf_open_document(pdev);
238
 
                if (code < 0)
239
 
                    return code;
240
 
                code = pdfmark_process(pdev, &ppa);
241
 
                if (code >= 0)
242
 
                    return code;
243
 
                /* falls through for errors */
244
 
            default:
245
 
                param_signal_error(plist, param_name, code);
246
 
                return code;
247
 
            case 1:
248
 
                break;
249
 
        }
250
 
 
251
 
        code = param_read_string_array(plist, (param_name = "DSC"), &ppa);
252
 
        switch (code) {
253
 
            case 0:
254
 
                code = pdf_open_document(pdev);
255
 
                if (code < 0)
256
 
                    return code;
257
 
                code = pdf_dsc_process(pdev, &ppa);
258
 
                if (code >= 0)
259
 
                    return code;
260
 
                /* falls through for errors */
261
 
            default:
262
 
                param_signal_error(plist, param_name, code);
263
 
                return code;
264
 
            case 1:
265
 
                break;
266
 
        }
267
 
    }
268
 
  
269
 
    /*
270
 
     * Check for LockDistillerParams before doing anything else.
271
 
     * If LockDistillerParams is true and is not being set to false,
272
 
     * ignore all resettings of PDF-specific parameters.  Note that
273
 
     * LockDistillerParams is read again, and reset if necessary, in
274
 
     * psdf_put_params.
275
 
     */
276
 
    ecode = code = param_read_bool(plist, "LockDistillerParams", &locked);
277
 
 
278
 
    if (!(locked && pdev->params.LockDistillerParams)) {
279
 
        /* General parameters. */
280
 
 
281
 
        {
282
 
            int efo = 1;
283
 
 
284
 
            ecode = param_put_int(plist, (param_name = ".EmbedFontObjects"), &efo, ecode);
285
 
            if (efo != 1)
286
 
                param_signal_error(plist, param_name, ecode = gs_error_rangecheck);
287
 
        }
288
 
        {
289
 
            int cdv = CoreDistVersion;
290
 
 
291
 
            ecode = param_put_int(plist, (param_name = "CoreDistVersion"), &cdv, ecode);
292
 
            if (cdv != CoreDistVersion)
293
 
                param_signal_error(plist, param_name, ecode = gs_error_rangecheck);
294
 
        }
295
 
 
296
 
        switch (code = param_read_float(plist, (param_name = "CompatibilityLevel"), &cl)) {
297
 
            default:
298
 
                ecode = code;
299
 
                param_signal_error(plist, param_name, ecode);
300
 
            case 0:
301
 
                /*
302
 
                 * Must be 1.2, 1.3, 1.4, or 1.5.  Per Adobe documentation, substitute
303
 
                 * the nearest achievable value.
304
 
                 */
305
 
                if (cl < (float)1.15)
306
 
                    cl = (float)1.1;
307
 
                else if (cl < (float)1.25)
308
 
                    cl = (float)1.2;
309
 
                else if (cl < (float)1.35)
310
 
                    cl = (float)1.3;
311
 
                else if (cl < (float)1.45)
312
 
                    cl = (float)1.4;
313
 
                else
314
 
                    cl = (float)1.5;
315
 
            case 1:
316
 
                break;
317
 
        }
318
 
        {   /* HACK : gs_param_list_s::memory is documented in gsparam.h as
319
 
               "for allocating coerced arrays". Not sure why zputdeviceparams
320
 
               sets it to the current memory space, while the device
321
 
               assumes to store them in the device's memory space.
322
 
               As a hackish workaround we temporary replace it here.
323
 
               Doing so because we don't want to change the global code now
324
 
               because we're unable to test it with all devices.
325
 
               Bug 688531 "Segmentation fault running pdfwrite from 219-01.ps".
326
 
 
327
 
               This solution to be reconsidered after fixing 
328
 
               the bug 688533 "zputdeviceparams specifies a wrong memory space.".
329
 
            */
330
 
            gs_memory_t *mem = plist->memory;
331
 
 
332
 
            plist->memory = pdev->pdf_memory;
333
 
            code = gs_param_read_items(plist, pdev, pdf_param_items);
334
 
            if (code < 0 ||
335
 
                (pdev->is_ps2write && (code = param_read_string(plist, "OPDFReadProcsetPath", &pdev->OPDFReadProcsetPath)) < 0) ||
336
 
                (!pdev->is_ps2write && (code = param_read_bool(plist, "ForOPDFRead", &pdev->ForOPDFRead)) < 0)
337
 
                );
338
 
            plist->memory = mem;
339
 
        }
340
 
        if (code < 0)
341
 
            ecode = code;
342
 
        {
343
 
            /*
344
 
             * Setting FirstObjectNumber is only legal if the file
345
 
             * has just been opened and nothing has been written,
346
 
             * or if we are setting it to the same value.
347
 
             */
348
 
            long fon = pdev->FirstObjectNumber;
349
 
 
350
 
            if (fon != save_dev->FirstObjectNumber) {
351
 
                if (fon <= 0 || fon > 0x7fff0000 ||
352
 
                    (pdev->next_id != 0 &&
353
 
                     pdev->next_id !=
354
 
                     save_dev->FirstObjectNumber + pdf_num_initial_ids)
355
 
                    ) {
356
 
                    ecode = gs_error_rangecheck;
357
 
                    param_signal_error(plist, "FirstObjectNumber", ecode);
358
 
                }
359
 
            }
360
 
        }
361
 
        {
362
 
            /*
363
 
             * Set ProcessColorModel now, because gx_default_put_params checks
364
 
             * it.
365
 
             */
366
 
            static const char *const pcm_names[] = {
367
 
                "DeviceGray", "DeviceRGB", "DeviceCMYK", "DeviceN", 0
368
 
            };
369
 
            int pcm = -1;
370
 
 
371
 
            ecode = param_put_enum(plist, "ProcessColorModel", &pcm,
372
 
                                   pcm_names, ecode);
373
 
            if (pcm >= 0) {
374
 
                pdf_set_process_color_model(pdev, pcm);
375
 
                pdf_set_initial_color(pdev, &pdev->saved_fill_color, &pdev->saved_stroke_color,
376
 
                                &pdev->fill_used_process_color, &pdev->stroke_used_process_color);
377
 
            }
378
 
        }
379
 
    }
380
 
    if (ecode < 0)
381
 
        goto fail;
382
 
    if (pdev->PDFX && pdev->PDFA) {
383
 
        ecode = gs_note_error(gs_error_rangecheck);
384
 
        param_signal_error(plist, "PDFA", ecode);
385
 
        goto fail;
386
 
    }
387
 
    if (pdev->PDFX && pdev->ForOPDFRead) {
388
 
        ecode = gs_note_error(gs_error_rangecheck);
389
 
        param_signal_error(plist, "PDFX", ecode);
390
 
        goto fail;
391
 
    }
392
 
    if (pdev->PDFA && pdev->ForOPDFRead) {
393
 
        ecode = gs_note_error(gs_error_rangecheck);
394
 
        param_signal_error(plist, "PDFA", ecode);
395
 
        goto fail;
396
 
    }
397
 
    if (pdev->PDFA)
398
 
         pdev->HaveTransparency = false;
399
 
    /*
400
 
     * We have to set version to the new value, because the set of
401
 
     * legal parameter values for psdf_put_params varies according to
402
 
     * the version.
403
 
     */
404
 
    if (pdev->PDFX)
405
 
        cl = (float)1.3; /* Instead pdev->CompatibilityLevel = 1.2; - see below. */
406
 
    if (pdev->PDFA && cl < 1.4)
407
 
        cl = (float)1.4;
408
 
    pdev->version = (cl < 1.2 ? psdf_version_level2 : psdf_version_ll3);
409
 
    if (pdev->ForOPDFRead) {
410
 
        pdev->ResourcesBeforeUsage = true;
411
 
        pdev->HaveCFF = false;
412
 
        pdev->HavePDFWidths = false;
413
 
        pdev->HaveStrokeColor = false;
414
 
        cl = (float)1.2; /* Instead pdev->CompatibilityLevel = 1.2; - see below. */
415
 
        pdev->MaxInlineImageSize = max_long; /* Save printer's RAM from saving temporary image data.
416
 
                                                Immediate images doen't need buffering. */
417
 
        pdev->version = psdf_version_level2;
418
 
    } else {
419
 
        pdev->ResourcesBeforeUsage = false;
420
 
        pdev->HaveCFF = true;
421
 
        pdev->HavePDFWidths = true;
422
 
        pdev->HaveStrokeColor = true;
423
 
    }
424
 
    pdev->ParamCompatibilityLevel = cl;
425
 
    ecode = gdev_psdf_put_params(dev, plist);
426
 
    if (ecode < 0)
427
 
        goto fail;
428
 
    if ((pdev->params.ColorConversionStrategy == ccs_CMYK &&
429
 
         strcmp(pdev->color_info.cm_name, "DeviceCMYK")) ||
430
 
        (pdev->params.ColorConversionStrategy == ccs_sRGB &&
431
 
          strcmp(pdev->color_info.cm_name, "DeviceRGB")) ||
432
 
        (pdev->params.ColorConversionStrategy == ccs_Gray &&
433
 
          strcmp(pdev->color_info.cm_name, "DeviceGray"))) {
434
 
        eprintf("ColorConversionStrategy is incompatible to ProcessColorModel.\n");
435
 
        ecode = gs_note_error(gs_error_rangecheck);
436
 
        pdev->params.ColorConversionStrategy = save_ccs;
437
 
    }
438
 
    if (pdev->params.ColorConversionStrategy == ccs_UseDeviceIndependentColor) {
439
 
        if (!pdev->UseCIEColor) {
440
 
            eprintf("Set UseCIEColor for UseDeviceIndependentColor to work properly.\n");
441
 
            ecode = gs_note_error(gs_error_rangecheck);
442
 
            pdev->UseCIEColor = true;
443
 
        }
444
 
    }
445
 
    if (pdev->params.ColorConversionStrategy == ccs_UseDeviceIndependentColorForImages) {
446
 
        if (!pdev->UseCIEColor) {
447
 
            eprintf("UseDeviceDependentColorForImages is not supported. Use UseDeviceIndependentColor.\n");
448
 
            pdev->params.ColorConversionStrategy = ccs_UseDeviceIndependentColor;
449
 
            if (!pdev->UseCIEColor) {
450
 
                eprintf("Set UseCIEColor for UseDeviceIndependentColor to work properly.\n");
451
 
                ecode = gs_note_error(gs_error_rangecheck);
452
 
                pdev->UseCIEColor = true;
453
 
            }
454
 
        }
455
 
    }
456
 
    if (pdev->params.ColorConversionStrategy == ccs_UseDeviceDependentColor) {
457
 
        if (!strcmp(pdev->color_info.cm_name, "DeviceCMYK")) {
458
 
            eprintf("Replacing the deprecated device parameter value UseDeviceDependentColor with CMYK.\n");
459
 
            pdev->params.ColorConversionStrategy = ccs_CMYK;
460
 
        } else if (!strcmp(pdev->color_info.cm_name, "DeviceRGB")) {
461
 
            eprintf("Replacing the deprecated device parameter value UseDeviceDependentColor with sRGB.\n");
462
 
            pdev->params.ColorConversionStrategy = ccs_sRGB;
463
 
        } else {
464
 
            eprintf("Replacing the deprecated device parameter value UseDeviceDependentColor with Gray.\n");
465
 
            pdev->params.ColorConversionStrategy = ccs_Gray;
466
 
        }
467
 
    }
468
 
    if (cl < 1.5 && pdev->params.ColorImage.Filter != NULL &&
469
 
            !strcmp(pdev->params.ColorImage.Filter, "JPXEncode")) {
470
 
        eprintf("JPXEncode requires CompatibilityLevel >= 1.5 .\n");
471
 
        ecode = gs_note_error(gs_error_rangecheck);
472
 
    }
473
 
    if (cl < 1.5 && pdev->params.GrayImage.Filter != NULL &&
474
 
            !strcmp(pdev->params.GrayImage.Filter, "JPXEncode")) {
475
 
        eprintf("JPXEncode requires CompatibilityLevel >= 1.5 .\n");
476
 
        ecode = gs_note_error(gs_error_rangecheck);
477
 
    }
478
 
    if (cl < 1.4  && pdev->params.MonoImage.Filter != NULL &&
479
 
            !strcmp(pdev->params.MonoImage.Filter, "JBIG2Encode")) {
480
 
        eprintf("JBIG2Encode requires CompatibilityLevel >= 1.4 .\n");
481
 
        ecode = gs_note_error(gs_error_rangecheck);
482
 
    }
483
 
    if (pdev->HaveTrueTypes && pdev->version == psdf_version_level2) {
484
 
        pdev->version = psdf_version_level2_with_TT ;
485
 
    }
486
 
    /*
487
 
     * Acrobat Reader doesn't handle user-space coordinates larger than
488
 
     * MAX_USER_COORD.  To compensate for this, reduce the resolution so
489
 
     * that the page size in device space (which we equate to user space) is
490
 
     * significantly less than MAX_USER_COORD.  Note that this still does
491
 
     * not protect us against input files that use coordinates far outside
492
 
     * the page boundaries.
493
 
     */
494
 
#define MAX_EXTENT ((int)(MAX_USER_COORD * 0.9))
495
 
    /* Changing resolution or page size requires closing the device, */
496
 
    if (dev->height > MAX_EXTENT || dev->width > MAX_EXTENT) {
497
 
        double factor =
498
 
            max(dev->height / (double)MAX_EXTENT,
499
 
                dev->width / (double)MAX_EXTENT);
500
 
 
501
 
        gx_device_set_resolution(dev, dev->HWResolution[0] / factor,
502
 
                                 dev->HWResolution[1] / factor);
503
 
    }
504
 
#undef MAX_EXTENT
505
 
    if (pdev->FirstObjectNumber != save_dev->FirstObjectNumber) {
506
 
        if (pdev->xref.file != 0) {
507
 
            fseek(pdev->xref.file, 0L, SEEK_SET);
508
 
            pdf_initialize_ids(pdev);
509
 
        }
510
 
    }
511
 
    /* Handle the float/double mismatch. */
512
 
    pdev->CompatibilityLevel = (int)(cl * 10 + 0.5) / 10.0;
513
 
    return 0;
514
 
 fail:
515
 
    /* Restore all the parameters to their original state. */
516
 
    pdev->version = save_dev->version;
517
 
    pdf_set_process_color_model(pdev, save_dev->pcm_color_info_index);
518
 
    pdev->saved_fill_color = save_dev->saved_fill_color;
519
 
    pdev->saved_stroke_color = save_dev->saved_fill_color;
520
 
    {
521
 
        const gs_param_item_t *ppi = pdf_param_items;
522
 
 
523
 
        for (; ppi->key; ++ppi)
524
 
            memcpy((char *)pdev + ppi->offset,
525
 
                   (char *)save_dev + ppi->offset,
526
 
                   gs_param_type_sizes[ppi->type]);
527
 
        pdev->ForOPDFRead = save_dev->ForOPDFRead;
528
 
        pdev->OPDFReadProcsetPath = save_dev->OPDFReadProcsetPath;
529
 
    }
530
 
    return ecode;
531
 
}
532
 
 
533
 
/* Put parameters */
534
 
int
535
 
gdev_pdf_put_params(gx_device * dev, gs_param_list * plist)
536
 
{
537
 
    int code;
538
 
    gx_device_pdf *pdev = (gx_device_pdf *) dev;
539
 
    gs_memory_t *mem = gs_memory_stable(pdev->memory);
540
 
    gx_device_pdf *save_dev = gs_malloc(mem, sizeof(gx_device_pdf), 1,
541
 
        "saved gx_device_pdf");
542
 
 
543
 
    if (!save_dev)
544
 
        return_error(gs_error_VMerror);
545
 
    memcpy(save_dev, pdev, sizeof(gx_device_pdf));
546
 
    code = gdev_pdf_put_params_impl(dev, save_dev, plist);
547
 
    gs_free(mem, save_dev, sizeof(gx_device_pdf), 1, "saved gx_device_pdf");
548
 
    return code;
549
 
}
550
 
 
551
 
/* ---------------- Process DSC comments ---------------- */
552
 
 
553
 
static int
554
 
pdf_dsc_process(gx_device_pdf * pdev, const gs_param_string_array * pma)
555
 
{
556
 
    /*
557
 
     * The Adobe "Distiller Parameters" documentation says that Distiller
558
 
     * looks at DSC comments, but it doesn't say which ones.  We look at
559
 
     * the ones that we see how to map directly to obvious PDF constructs.
560
 
     */
561
 
    int code = 0;
562
 
    uint i;
563
 
 
564
 
    /*
565
 
     * If ParseDSCComments is false, all DSC comments are ignored, even if
566
 
     * ParseDSCComentsForDocInfo or PreserveEPSInfo is true.
567
 
     */
568
 
    if (!pdev->ParseDSCComments)
569
 
        return 0;
570
 
 
571
 
    for (i = 0; i + 1 < pma->size && code >= 0; i += 2) {
572
 
        const gs_param_string *pkey = &pma->data[i];
573
 
        const gs_param_string *pvalue = &pma->data[i + 1];
574
 
        const char *key;
575
 
        int code;
576
 
 
577
 
        /*
578
 
         * %%For, %%Creator, and %%Title are recognized only if either
579
 
         * ParseDSCCommentsForDocInfo or PreserveEPSInfo is true.
580
 
         * The other DSC comments are always recognized.
581
 
         *
582
 
         * Acrobat Distiller sets CreationDate and ModDate to the current
583
 
         * time, not the value of %%CreationDate.  We think this is wrong,
584
 
         * but we do the same -- we ignore %%CreationDate here.
585
 
         */
586
 
 
587
 
        if (pdf_key_eq(pkey, "Creator"))
588
 
            key = "/Creator";
589
 
        else if (pdf_key_eq(pkey, "Title"))
590
 
            key = "/Title";
591
 
        else if (pdf_key_eq(pkey, "For"))
592
 
            key = "/Author";
593
 
        else {
594
 
            pdf_page_dsc_info_t *ppdi;
595
 
            char scan_buf[200]; /* arbitrary */
596
 
 
597
 
            if ((ppdi = &pdev->doc_dsc_info,
598
 
                 pdf_key_eq(pkey, "Orientation")) ||
599
 
                (ppdi = &pdev->page_dsc_info,
600
 
                 pdf_key_eq(pkey, "PageOrientation"))
601
 
                ) {
602
 
                if (pvalue->size == 1 && pvalue->data[0] >= '0' &&
603
 
                    pvalue->data[0] <= '3'
604
 
                    )
605
 
                    ppdi->orientation = pvalue->data[0] - '0';
606
 
                else
607
 
                    ppdi->orientation = -1;
608
 
            } else if ((ppdi = &pdev->doc_dsc_info,
609
 
                        pdf_key_eq(pkey, "ViewingOrientation")) ||
610
 
                       (ppdi = &pdev->page_dsc_info,
611
 
                        pdf_key_eq(pkey, "PageViewingOrientation"))
612
 
                       ) {
613
 
                gs_matrix mat;
614
 
                int orient;
615
 
 
616
 
                if(pvalue->size >= sizeof(scan_buf) - 1)
617
 
                    continue;   /* error */
618
 
                memcpy(scan_buf, pvalue->data, pvalue->size);
619
 
                scan_buf[pvalue->size] = 0;
620
 
                if (sscanf(scan_buf, "[%g %g %g %g]",
621
 
                           &mat.xx, &mat.xy, &mat.yx, &mat.yy) != 4
622
 
                    )
623
 
                    continue;   /* error */
624
 
                for (orient = 0; orient < 4; ++orient) {
625
 
                    if (mat.xx == 1 && mat.xy == 0 && mat.yx == 0 && mat.yy == 1)
626
 
                        break;
627
 
                    gs_matrix_rotate(&mat, -90.0, &mat);
628
 
                }
629
 
                if (orient == 4) /* error */
630
 
                    orient = -1;
631
 
                ppdi->viewing_orientation = orient;
632
 
            } else {
633
 
                gs_rect box;
634
 
 
635
 
                if (pdf_key_eq(pkey, "EPSF")) {
636
 
                    pdev->is_EPS = (pvalue->size >= 1 && pvalue->data[0] != '0');
637
 
                    continue;
638
 
                }
639
 
                /*
640
 
                 * We only parse the BoundingBox for the sake of
641
 
                 * AutoPositionEPSFiles.
642
 
                 */
643
 
                if (pdf_key_eq(pkey, "BoundingBox"))
644
 
                    ppdi = &pdev->doc_dsc_info;
645
 
                else if (pdf_key_eq(pkey, "PageBoundingBox"))
646
 
                    ppdi = &pdev->page_dsc_info;
647
 
                else
648
 
                    continue;
649
 
                if(pvalue->size >= sizeof(scan_buf) - 1)
650
 
                    continue;   /* error */
651
 
                memcpy(scan_buf, pvalue->data, pvalue->size);
652
 
                scan_buf[pvalue->size] = 0;
653
 
                if (sscanf(scan_buf, "[%lg %lg %lg %lg]",
654
 
                           &box.p.x, &box.p.y, &box.q.x, &box.q.y) != 4
655
 
                    )
656
 
                    continue;   /* error */
657
 
                ppdi->bounding_box = box;
658
 
            }
659
 
            continue;
660
 
        }
661
 
 
662
 
        if (pdev->ParseDSCCommentsForDocInfo || pdev->PreserveEPSInfo)
663
 
            code = cos_dict_put_c_key_string(pdev->Info, key,
664
 
                                             pvalue->data, pvalue->size);
665
 
    }
666
 
    return code;
667
 
}