Ejemplo n.º 1
0
static int
trap_put_float_param(gs_param_list * plist, gs_param_name param_name,
                     float *pval, bool(*check) (float *pval), int ecode)
{
    int code;

    switch (code = param_read_float(plist, param_name, pval)) {
        case 0:
            if ((*check) (pval))
                return 0;
            code = gs_error_rangecheck;
        default:
            ecode = code;
            param_signal_error(plist, param_name, ecode);
            break;
        case 1:
            break;
    }
    return ecode;
}
Ejemplo n.º 2
0
/* Put parameters, implementation */
static int
gdev_pdf_put_params_impl(gx_device * dev, const gx_device_pdf * save_dev, gs_param_list * plist)
{
    int ecode, code;
    gx_device_pdf *pdev = (gx_device_pdf *) dev;
    float cl = (float)pdev->CompatibilityLevel;
    bool locked = pdev->params.LockDistillerParams;
    gs_param_name param_name;
    enum psdf_color_conversion_strategy save_ccs = pdev->params.ColorConversionStrategy;
  
    pdev->pdf_memory = gs_memory_stable(pdev->memory);
    /*
     * If this is a pseudo-parameter (pdfmark or DSC),
     * don't bother checking for any real ones.
     */

    {
	gs_param_string_array ppa;

	code = param_read_string_array(plist, (param_name = "pdfmark"), &ppa);
	switch (code) {
	    case 0:
		code = pdf_open_document(pdev);
		if (code < 0)
		    return code;
		code = pdfmark_process(pdev, &ppa);
		if (code >= 0)
		    return code;
		/* falls through for errors */
	    default:
		param_signal_error(plist, param_name, code);
		return code;
	    case 1:
		break;
	}

	code = param_read_string_array(plist, (param_name = "DSC"), &ppa);
	switch (code) {
	    case 0:
		code = pdf_open_document(pdev);
		if (code < 0)
		    return code;
		code = pdf_dsc_process(pdev, &ppa);
		if (code >= 0)
		    return code;
		/* falls through for errors */
	    default:
		param_signal_error(plist, param_name, code);
		return code;
	    case 1:
		break;
	}
    }
  
    /*
     * Check for LockDistillerParams before doing anything else.
     * If LockDistillerParams is true and is not being set to false,
     * ignore all resettings of PDF-specific parameters.  Note that
     * LockDistillerParams is read again, and reset if necessary, in
     * psdf_put_params.
     */
    ecode = code = param_read_bool(plist, "LockDistillerParams", &locked);
 
    if (!(locked && pdev->params.LockDistillerParams)) {
	/* General parameters. */

	{
	    int efo = 1;

	    ecode = param_put_int(plist, (param_name = ".EmbedFontObjects"), &efo, ecode);
	    if (efo != 1)
		param_signal_error(plist, param_name, ecode = gs_error_rangecheck);
	}
	{
	    int cdv = CoreDistVersion;

	    ecode = param_put_int(plist, (param_name = "CoreDistVersion"), &cdv, ecode);
	    if (cdv != CoreDistVersion)
		param_signal_error(plist, param_name, ecode = gs_error_rangecheck);
	}

	switch (code = param_read_float(plist, (param_name = "CompatibilityLevel"), &cl)) {
	    default:
		ecode = code;
		param_signal_error(plist, param_name, ecode);
	    case 0:
		/*
		 * Must be 1.2, 1.3, 1.4, or 1.5.  Per Adobe documentation, substitute
		 * the nearest achievable value.
		 */
		if (cl < (float)1.15)
		    cl = (float)1.1;
		else if (cl < (float)1.25)
		    cl = (float)1.2;
		else if (cl < (float)1.35)
		    cl = (float)1.3;
		else if (cl < (float)1.45)
		    cl = (float)1.4;
		else
		    cl = (float)1.5;
	    case 1:
		break;
	}
	{   /* HACK : gs_param_list_s::memory is documented in gsparam.h as
	       "for allocating coerced arrays". Not sure why zputdeviceparams
	       sets it to the current memory space, while the device
	       assumes to store them in the device's memory space.
	       As a hackish workaround we temporary replace it here.
	       Doing so because we don't want to change the global code now
	       because we're unable to test it with all devices.
	       Bug 688531 "Segmentation fault running pdfwrite from 219-01.ps".

	       This solution to be reconsidered after fixing 
	       the bug 688533 "zputdeviceparams specifies a wrong memory space.".
 	    */
	    gs_memory_t *mem = plist->memory;

	    plist->memory = pdev->pdf_memory;
	    code = gs_param_read_items(plist, pdev, pdf_param_items);
	    if (code < 0 ||
		(pdev->is_ps2write && (code = param_read_string(plist, "OPDFReadProcsetPath", &pdev->OPDFReadProcsetPath)) < 0) ||
		(!pdev->is_ps2write && (code = param_read_bool(plist, "ForOPDFRead", &pdev->ForOPDFRead)) < 0)
		);
	    plist->memory = mem;
	}
	if (code < 0)
	    ecode = code;
	{
	    /*
	     * Setting FirstObjectNumber is only legal if the file
	     * has just been opened and nothing has been written,
	     * or if we are setting it to the same value.
	     */
	    long fon = pdev->FirstObjectNumber;

	    if (fon != save_dev->FirstObjectNumber) {
		if (fon <= 0 || fon > 0x7fff0000 ||
		    (pdev->next_id != 0 &&
		     pdev->next_id !=
		     save_dev->FirstObjectNumber + pdf_num_initial_ids)
		    ) {
		    ecode = gs_error_rangecheck;
		    param_signal_error(plist, "FirstObjectNumber", ecode);
		}
	    }
	}
	{
	    /*
	     * Set ProcessColorModel now, because gx_default_put_params checks
	     * it.
	     */
	    static const char *const pcm_names[] = {
		"DeviceGray", "DeviceRGB", "DeviceCMYK", "DeviceN", 0
	    };
	    int pcm = -1;

	    ecode = param_put_enum(plist, "ProcessColorModel", &pcm,
				   pcm_names, ecode);
	    if (pcm >= 0) {
		pdf_set_process_color_model(pdev, pcm);
		pdf_set_initial_color(pdev, &pdev->saved_fill_color, &pdev->saved_stroke_color,
				&pdev->fill_used_process_color, &pdev->stroke_used_process_color);
	    }
	}
    }
    if (ecode < 0)
	goto fail;
    if (pdev->PDFX && pdev->PDFA) {
	ecode = gs_note_error(gs_error_rangecheck);
	param_signal_error(plist, "PDFA", ecode);
	goto fail;
    }
    if (pdev->PDFX && pdev->ForOPDFRead) {
	ecode = gs_note_error(gs_error_rangecheck);
	param_signal_error(plist, "PDFX", ecode);
	goto fail;
    }
    if (pdev->PDFA && pdev->ForOPDFRead) {
	ecode = gs_note_error(gs_error_rangecheck);
	param_signal_error(plist, "PDFA", ecode);
	goto fail;
    }
    if (pdev->PDFA)
	 pdev->HaveTransparency = false;
    /*
     * We have to set version to the new value, because the set of
     * legal parameter values for psdf_put_params varies according to
     * the version.
     */
    if (pdev->PDFX)
	cl = (float)1.3; /* Instead pdev->CompatibilityLevel = 1.2; - see below. */
    if (pdev->PDFA && cl < 1.4)
	cl = (float)1.4;
    pdev->version = (cl < 1.2 ? psdf_version_level2 : psdf_version_ll3);
    if (pdev->ForOPDFRead) {
	pdev->ResourcesBeforeUsage = true;
	pdev->HaveCFF = false;
	pdev->HavePDFWidths = false;
	pdev->HaveStrokeColor = false;
	cl = (float)1.2; /* Instead pdev->CompatibilityLevel = 1.2; - see below. */
	pdev->MaxInlineImageSize = max_long; /* Save printer's RAM from saving temporary image data.
					        Immediate images doen't need buffering. */
	pdev->version = psdf_version_level2;
    } else {
	pdev->ResourcesBeforeUsage = false;
	pdev->HaveCFF = true;
	pdev->HavePDFWidths = true;
	pdev->HaveStrokeColor = true;
    }
    pdev->ParamCompatibilityLevel = cl;
    ecode = gdev_psdf_put_params(dev, plist);
    if (ecode < 0)
	goto fail;
    if ((pdev->params.ColorConversionStrategy == ccs_CMYK &&
	 strcmp(pdev->color_info.cm_name, "DeviceCMYK")) ||
	(pdev->params.ColorConversionStrategy == ccs_sRGB &&
	  strcmp(pdev->color_info.cm_name, "DeviceRGB")) ||
	(pdev->params.ColorConversionStrategy == ccs_Gray &&
	  strcmp(pdev->color_info.cm_name, "DeviceGray"))) {
	eprintf("ColorConversionStrategy is incompatible to ProcessColorModel.\n");
	ecode = gs_note_error(gs_error_rangecheck);
	pdev->params.ColorConversionStrategy = save_ccs;
    }
    if (pdev->params.ColorConversionStrategy == ccs_UseDeviceIndependentColor) {
	if (!pdev->UseCIEColor) {
	    eprintf("Set UseCIEColor for UseDeviceIndependentColor to work properly.\n");
	    ecode = gs_note_error(gs_error_rangecheck);
	    pdev->UseCIEColor = true;
	}
    }
    if (pdev->params.ColorConversionStrategy == ccs_UseDeviceIndependentColorForImages) {
	if (!pdev->UseCIEColor) {
	    eprintf("UseDeviceDependentColorForImages is not supported. Use UseDeviceIndependentColor.\n");
	    pdev->params.ColorConversionStrategy = ccs_UseDeviceIndependentColor;
	    if (!pdev->UseCIEColor) {
		eprintf("Set UseCIEColor for UseDeviceIndependentColor to work properly.\n");
		ecode = gs_note_error(gs_error_rangecheck);
		pdev->UseCIEColor = true;
	    }
	}
    }
    if (pdev->params.ColorConversionStrategy == ccs_UseDeviceDependentColor) {
	if (!strcmp(pdev->color_info.cm_name, "DeviceCMYK")) {
	    eprintf("Replacing the deprecated device parameter value UseDeviceDependentColor with CMYK.\n");
	    pdev->params.ColorConversionStrategy = ccs_CMYK;
	} else if (!strcmp(pdev->color_info.cm_name, "DeviceRGB")) {
	    eprintf("Replacing the deprecated device parameter value UseDeviceDependentColor with sRGB.\n");
	    pdev->params.ColorConversionStrategy = ccs_sRGB;
	} else {
	    eprintf("Replacing the deprecated device parameter value UseDeviceDependentColor with Gray.\n");
	    pdev->params.ColorConversionStrategy = ccs_Gray;
	}
    }
    if (cl < 1.5 && pdev->params.ColorImage.Filter != NULL &&
	    !strcmp(pdev->params.ColorImage.Filter, "JPXEncode")) {
	eprintf("JPXEncode requires CompatibilityLevel >= 1.5 .\n");
	ecode = gs_note_error(gs_error_rangecheck);
    }
    if (cl < 1.5 && pdev->params.GrayImage.Filter != NULL &&
	    !strcmp(pdev->params.GrayImage.Filter, "JPXEncode")) {
	eprintf("JPXEncode requires CompatibilityLevel >= 1.5 .\n");
	ecode = gs_note_error(gs_error_rangecheck);
    }
    if (cl < 1.4  && pdev->params.MonoImage.Filter != NULL &&
	    !strcmp(pdev->params.MonoImage.Filter, "JBIG2Encode")) {
	eprintf("JBIG2Encode requires CompatibilityLevel >= 1.4 .\n");
	ecode = gs_note_error(gs_error_rangecheck);
    }
    if (pdev->HaveTrueTypes && pdev->version == psdf_version_level2) {
	pdev->version = psdf_version_level2_with_TT ;
    }
    /*
     * Acrobat Reader doesn't handle user-space coordinates larger than
     * MAX_USER_COORD.  To compensate for this, reduce the resolution so
     * that the page size in device space (which we equate to user space) is
     * significantly less than MAX_USER_COORD.  Note that this still does
     * not protect us against input files that use coordinates far outside
     * the page boundaries.
     */
#define MAX_EXTENT ((int)(MAX_USER_COORD * 0.9))
    /* Changing resolution or page size requires closing the device, */
    if (dev->height > MAX_EXTENT || dev->width > MAX_EXTENT) {
	double factor =
	    max(dev->height / (double)MAX_EXTENT,
		dev->width / (double)MAX_EXTENT);

	gx_device_set_resolution(dev, dev->HWResolution[0] / factor,
				 dev->HWResolution[1] / factor);
    }
#undef MAX_EXTENT
    if (pdev->FirstObjectNumber != save_dev->FirstObjectNumber) {
	if (pdev->xref.file != 0) {
	    fseek(pdev->xref.file, 0L, SEEK_SET);
	    pdf_initialize_ids(pdev);
	}
    }
    /* Handle the float/double mismatch. */
    pdev->CompatibilityLevel = (int)(cl * 10 + 0.5) / 10.0;
    return 0;
 fail:
    /* Restore all the parameters to their original state. */
    pdev->version = save_dev->version;
    pdf_set_process_color_model(pdev, save_dev->pcm_color_info_index);
    pdev->saved_fill_color = save_dev->saved_fill_color;
    pdev->saved_stroke_color = save_dev->saved_fill_color;
    {
	const gs_param_item_t *ppi = pdf_param_items;

	for (; ppi->key; ++ppi)
	    memcpy((char *)pdev + ppi->offset,
		   (char *)save_dev + ppi->offset,
		   gs_param_type_sizes[ppi->type]);
	pdev->ForOPDFRead = save_dev->ForOPDFRead;
	pdev->OPDFReadProcsetPath = save_dev->OPDFReadProcsetPath;
    }
    return ecode;
}