コード例 #1
0
/*
 * Convert a DeviceN color (with PANTONE colorants) into device color.
 */
static int
client_pantone_remap_DeviceN(client_custom_color_params_t * pparam,
	const frac * pconc, const gs_color_space * pcs, gx_device_color * pdc,
       	const gs_imager_state * pis, gx_device * dev, gs_color_select_t select)
{
   	return client_pantone_remap_color(pparam, pconc,
	(demo_color_space_data_t *)(pcs->pclient_color_space_data),
	pdc, pis, dev, select, gs_color_space_num_components(pcs));
}
コード例 #2
0
static int
gx_concretize_DeviceN(const gs_client_color * pc, const gs_color_space * pcs,
		      frac * pconc, const gs_imager_state * pis)
{
    int code, tcode = 0;
    gs_client_color cc;
    const gs_color_space *pacs = pcs->base_space;
    gs_device_n_map *map = pcs->params.device_n.map;

#ifdef DEBUG
    /* 
     * Verify that the color space and imager state info match.
     */
    if (pcs->id != pis->color_component_map.cspace_id)
	dprintf("gx_concretize_DeviceN: color space id mismatch");
#endif

    /*
     * Check if we need to map into the alternate color space.
     * We must preserve tcode for implementing a semi-hack in the interpreter.
     */
    if (pis->color_component_map.use_alt_cspace) {
	    /* Check the 1-element cache first. */
	if (map->cache_valid) {
	    int i;

	    for (i = pcs->params.device_n.num_components; --i >= 0;) {
		if (map->tint[i] != pc->paint.values[i])
		    break;
	    }
	    if (i < 0) {
		int num_out = gs_color_space_num_components(pacs);

		for (i = 0; i < num_out; ++i)
		    pconc[i] = map->conc[i];
		return 0;
	    }
	}
        tcode = (*pcs->params.device_n.map->tint_transform)
	     (pc->paint.values, &cc.paint.values[0],
	     pis, pcs->params.device_n.map->tint_transform_data);
        if (tcode < 0)
	    return tcode;
	code = cs_concretize_color(&cc, pacs, pconc, pis);
    }
    else {
	float ftemp;
	int i;

	for (i = pcs->params.device_n.num_components; --i >= 0;)
	    pconc[i] = unit_frac(pc->paint.values[i], ftemp);
	return 0;
    }
    return (code < 0 || tcode == 0 ? code : tcode);
}
コード例 #3
0
ファイル: gxhldevc.c プロジェクト: carriercomm/legacy
/*
 * Get the number of components in the current color space.
 *
 * More description in src/gxhldevc.h
 */
int
gx_hld_get_number_color_components(const gs_imager_state * pis)
{
    const gs_state * pgs = gx_hld_get_gstate_ptr(pis);

    if (pgs != NULL) {
        const gs_color_space * pcs = pgs->color_space;
	int n = gs_color_space_num_components(pcs);

	return (n >= 0 ? n : -n - 1);
    } else
	return -1;
}
コード例 #4
0
ファイル: gdevvec.c プロジェクト: hackqiang/gs
/* Initialize for enumerating an image. */
int
gdev_vector_begin_image(gx_device_vector * vdev,
                        const gs_imager_state * pis, const gs_image_t * pim,
                        gs_image_format_t format, const gs_int_rect * prect,
              const gx_drawing_color * pdcolor, const gx_clip_path * pcpath,
                    gs_memory_t * mem, const gx_image_enum_procs_t * pprocs,
                        gdev_vector_image_enum_t * pie)
{
    const gs_color_space *pcs = pim->ColorSpace;
    int num_components;
    int bits_per_pixel;
    int code;

    if (pim->ImageMask)
        bits_per_pixel = num_components = 1;
    else
        num_components = gs_color_space_num_components(pcs),
            bits_per_pixel = pim->BitsPerComponent;
    code = gx_image_enum_common_init((gx_image_enum_common_t *) pie,
                                     (const gs_data_image_t *)pim,
                                     pprocs, (gx_device *) vdev,
                                     num_components, format);
    if (code < 0)
        return code;
    pie->bits_per_pixel = bits_per_pixel * num_components /
        pie->num_planes;
    pie->default_info = 0;
    pie->bbox_info = 0;
    if ((code = gdev_vector_update_log_op(vdev, pis->log_op)) < 0 ||
        (code = gdev_vector_update_clip_path(vdev, pcpath)) < 0 ||
        ((pim->ImageMask ||
          (pim->CombineWithColor && rop3_uses_T(pis->log_op))) &&
         (code = gdev_vector_update_fill_color(vdev, pis, pdcolor)) < 0) ||
        (vdev->bbox_device &&
         (code = (*dev_proc(vdev->bbox_device, begin_image))
          ((gx_device *) vdev->bbox_device, pis, pim, format, prect,
           pdcolor, pcpath, mem, &pie->bbox_info)) < 0)
        )
        return code;
    pie->memory = mem;
    if (prect)
        pie->width = prect->q.x - prect->p.x,
            pie->height = prect->q.y - prect->p.y;
    else
        pie->width = pim->Width, pie->height = pim->Height;
    pie->bits_per_row = pie->width * pie->bits_per_pixel;
    pie->y = 0;
    return 0;
}
コード例 #5
0
ファイル: gscsepr.c プロジェクト: SynEmira/ruby-ghostscript
/*
 * Set the Separation tint transformation procedure to a Function.
 */
int
gs_cspace_set_sepr_function(const gs_color_space *pcspace, gs_function_t *pfn)
{
    gs_device_n_map *pimap;

    if (gs_color_space_get_index(pcspace) != gs_color_space_index_Separation ||
        pfn->params.m != 1 || pfn->params.n !=
          gs_color_space_num_components(pcspace->base_space)
        )
        return_error(gs_error_rangecheck);
    pimap = pcspace->params.separation.map;
    pimap->tint_transform = map_devn_using_function;
    pimap->tint_transform_data = pfn;
    pimap->cache_valid = false;
    return 0;
}
コード例 #6
0
ファイル: gximage.c プロジェクト: ststeiger/ghostsvg
void
gs_pixel_image_t_init(gs_pixel_image_t * pim,
		      gs_color_space * color_space)
{
    int num_components;

    if (color_space == 0 ||
	(num_components =
	 gs_color_space_num_components(color_space)) < 0
	)
	num_components = 0;
    gs_data_image_t_init((gs_data_image_t *) pim, num_components);
    pim->format = gs_image_format_chunky;
    pim->ColorSpace = color_space;
    pim->CombineWithColor = false;
}
コード例 #7
0
/* Transform a CIEBased color to XYZ. */
static int
cie_to_xyz(const double *in, double out[3], const gs_color_space *pcs,
	   const gs_imager_state *pis)
{
    gs_client_color cc;
    frac xyz[3];
    int ncomp = gs_color_space_num_components(pcs);
    int i;

    for (i = 0; i < ncomp; ++i)
	cc.paint.values[i] = in[i];
    cs_concretize_color(&cc, pcs, xyz, pis);
    out[0] = frac2float(xyz[0]);
    out[1] = frac2float(xyz[1]);
    out[2] = frac2float(xyz[2]);
    return 0;
}
コード例 #8
0
/*
 * Save the device color information including the color space id and
 * client color data (if available).
 *
 * More description in src/gxhldevc.h
 */
bool
gx_hld_save_color(const gs_imager_state * pis, const gx_device_color * pdevc,
		gx_hl_saved_color * psc)
{
    const gs_state * pgs = gx_hld_get_gstate_ptr(pis);
    memset(psc, 0, sizeof(*psc));	/* clear the entire structure */

    if (pdevc == NULL) {
        /* No device color given, should not happen */
        gx_hld_saved_color_init(psc);	/* revert to unknown color */
	return false;
    } else if (pgs == NULL) {
        /* No color space, simply save device color specific info */
        psc->color_space_id = psc->pattern_id = gs_no_id;
        pdevc->type->save_dc(pdevc, &(psc->saved_dev_color));
	return false;
    } else {
        /*
	 * Have color space, save id,  ccolor, & device color specific info.
	 * Also save the high level colors since two gx_color_index values
	 * may be the same but for differing high level colors (due to the
	 * usual lower resolution of the gx_color_index values.
	 */
        const gs_color_space * pcs = pgs->color_space;
        int i = gs_color_space_num_components(pcs);

        psc->color_space_id = pcs->id;
        pdevc->type->save_dc(pdevc, &(psc->saved_dev_color));
	if (pdevc->type == gx_dc_type_pattern2)
	    i = 0;
        else if (i < 0)
	    i = -i - 1; /* See gx_num_components_Pattern. */
        for (i--; i >= 0; i--)
	    psc->ccolor.paint.values[i] = pdevc->ccolor.paint.values[i];

	/* Save the pattern id - if present */
	if ((pdevc->type == gx_dc_type_pattern 
	   || pdevc->type == gx_dc_type_pattern2) && pdevc->ccolor_valid)
            psc->pattern_id = pdevc->ccolor.pattern->pattern_id;
	else
            psc->pattern_id = gs_no_id;
	return true;
    }
}
コード例 #9
0
ファイル: zimage3.c プロジェクト: BorodaZizitopa/ghostscript
/* <dict> .image4 - */
static int
zimage4(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    gs_image4_t image;
    image_params ip;
    int num_components =
        gs_color_space_num_components(gs_currentcolorspace(igs));
    int colors[countof(image.MaskColor)];
    int code;
    int i;

    gs_image4_t_init(&image, NULL);
    code = pixel_image_params(i_ctx_p, op, (gs_pixel_image_t *)&image, &ip,
                              12, false, gs_currentcolorspace(igs));
    if (code < 0)
        return code;
    code = dict_int_array_check_param(imemory, op, "MaskColor",
       num_components * 2, colors, 0, e_rangecheck);
    /* Clamp the color values to the unsigned range. */
    if (code == num_components) {
        image.MaskColor_is_range = false;
        for (i = 0; i < code; ++i)
            image.MaskColor[i] = (colors[i] < 0 ? ~(uint)0 : colors[i]);
    }
    else if (code == num_components * 2) {
        image.MaskColor_is_range = true;
        for (i = 0; i < code; i += 2) {
            if (colors[i+1] < 0) /* no match possible */
                image.MaskColor[i] = 1, image.MaskColor[i+1] = 0;
            else {
                image.MaskColor[i+1] = colors[i+1];
                image.MaskColor[i] = max(colors[i], 0);
            }
        }
    } else
        return_error(code < 0 ? code : gs_note_error(e_rangecheck));
    return zimage_setup(i_ctx_p, (gs_pixel_image_t *)&image, &ip.DataSource[0],
                        image.CombineWithColor, 1);
}
コード例 #10
0
/* Common code for .image1 and .alphaimage operators */
int
image1_setup(i_ctx_t * i_ctx_p, bool has_alpha)
{
    os_ptr          op = osp;
    gs_image_t      image;
    image_params    ip;
    int             code;
    gs_color_space *csp = gs_currentcolorspace(igs);
    extern bool CPSI_mode;

    /* Adobe interpreters accept sampled images when the current color
     * space is a pattern color space using the base color space instead
     * of the pattern space. CET 12-07a-12
     * If all conditions are not met the pattern color space goes through
     * triggering a rangecheck error.
     */
    if (CPSI_mode && gs_color_space_num_components(csp) < 1) {
       gs_color_space *bsp = csp->base_space;
       if (bsp)
         csp = bsp;
    }

    gs_image_t_init(&image, csp);
    code = pixel_image_params( i_ctx_p,
                               op,
                               (gs_pixel_image_t *)&image,
                               &ip,
			       (level2_enabled ? 16 : 8),
                               has_alpha, csp);
    if (code < 0)
	return code;

    image.Alpha = (has_alpha ? gs_image_alpha_last : gs_image_alpha_none);
    return zimage_setup( i_ctx_p,
                         (gs_pixel_image_t *)&image,
                         &ip.DataSource[0],
			 image.CombineWithColor,
                         1 );
}
コード例 #11
0
/* Extract and check the parameters for a gs_pixel_image_t. */
int
pixel_image_params(i_ctx_t *i_ctx_p, const ref *op, gs_pixel_image_t *pim,
		   image_params *pip, int max_bits_per_component,
		   bool has_alpha, gs_color_space *csp)
{
    int num_components =
	gs_color_space_num_components(csp);
    int code;

    if (num_components < 1)
	return_error(e_rangecheck);	/* Pattern space not allowed */
    pim->ColorSpace = csp;
    code = data_image_params(imemory, op, (gs_data_image_t *) pim, pip, true,
			     num_components, max_bits_per_component,
			     has_alpha);
    if (code < 0)
	return code;
    pim->format =
	(pip->MultipleDataSources ? gs_image_format_component_planar :
	 gs_image_format_chunky);
    return dict_bool_param(op, "CombineWithColor", false,
			   &pim->CombineWithColor);
}
コード例 #12
0
/* Create a PDF Lab color space corresponding to a CIEBased color space. */
static int
lab_range(gs_range range_out[3] /* only [1] and [2] used */,
	  const gs_color_space *pcs, const gs_cie_common *pciec,
	  const gs_range *ranges, gs_memory_t *mem)
{
    /*
     * Determine the range of a* and b* by evaluating the color space
     * mapping at all of its extrema.
     */
    int ncomp = gs_color_space_num_components(pcs);
    gs_imager_state *pis;
    int code = gx_cie_to_xyz_alloc(&pis, pcs, mem);
    int i, j;

    if (code < 0)
	return code;
    for (j = 1; j < 3; ++j)
	range_out[j].rmin = 1000.0, range_out[j].rmax = -1000.0;
    for (i = 0; i < 1 << ncomp; ++i) {
	double in[4], xyz[3];

	for (j = 0; j < ncomp; ++j)
	    in[j] = (i & (1 << j) ? ranges[j].rmax : ranges[j].rmin);
	if (cie_to_xyz(in, xyz, pcs, pis) >= 0) {
	    double lab[3];

	    xyz_to_lab(xyz, lab, pciec);
	    for (j = 1; j < 3; ++j) {
		range_out[j].rmin = min(range_out[j].rmin, lab[j]);
		range_out[j].rmax = max(range_out[j].rmax, lab[j]);
	    }
	}
    }
    gx_cie_to_xyz_free(pis);
    return 0;
}
コード例 #13
0
ファイル: zshade.c プロジェクト: computersforpeace/ghostpdl
/* Collect parameters for a mesh shading. */
static int
build_mesh_shading(i_ctx_t *i_ctx_p, const ref * op,
                   gs_shading_mesh_params_t * params,
                   float **pDecode, gs_function_t ** pFunction,
                   gs_memory_t *mem)
{
    int code;
    float *data = 0;
    ref *pDataSource;

    *pDecode = 0;
    *pFunction = 0;
    if (dict_find_string(op, "DataSource", &pDataSource) <= 0)
        return_error(gs_error_rangecheck);
    if (r_is_array(pDataSource)) {
        uint size = r_size(pDataSource);

        data = (float *)gs_alloc_byte_array(mem, size, sizeof(float),
                                            "build_mesh_shading");
        if (data == 0)
            return_error(gs_error_VMerror);
        code = process_float_array(mem, pDataSource, size, data);
        if (code < 0) {
            gs_free_object(mem, data, "build_mesh_shading");
            return code;
        }
        data_source_init_floats(&params->DataSource, data, size);
    } else
        switch (r_type(pDataSource)) {
            case t_file: {
                stream *s;

                check_read_file(i_ctx_p, s, pDataSource);
                data_source_init_stream(&params->DataSource, s);
                break;
            }
            case t_string:
                check_read(*pDataSource);
                data_source_init_string2(&params->DataSource,
                                         pDataSource->value.bytes,
                                         r_size(pDataSource));
                break;
            default:
                return_error(gs_error_typecheck);
        }
    code = build_shading_function(i_ctx_p, op, pFunction, 1, mem, NULL);
    if (code < 0) {
        gs_free_object(mem, data, "build_mesh_shading");
        return code;
    }
    if (data_source_is_array(params->DataSource)) {
        params->BitsPerCoordinate = 0;
        params->BitsPerComponent = 0;
    } else {
        int num_decode = 4 +
            (*pFunction != 0 ? 1 :
             gs_color_space_num_components(params->ColorSpace)) * 2;

        if ((code = dict_int_param(op, "BitsPerCoordinate", 1, 32, 0,
                                   &params->BitsPerCoordinate)) >= 0 &&
            (code = dict_int_param(op, "BitsPerComponent", 1, 16, 0,
                                   &params->BitsPerComponent)) >= 0
            ) {
            *pDecode = (float *)
                gs_alloc_byte_array(mem, num_decode, sizeof(float),
                                    "build_mesh_shading");
            if (*pDecode == 0)
                code = gs_note_error(gs_error_VMerror);
            else {
                code = dict_floats_param(mem, op, "Decode", num_decode, *pDecode, NULL);
                if (code < 0) {
                    gs_free_object(mem, *pDecode, "build_mesh_shading");
                    *pDecode = 0;
                }
            }
        }
    }
    if (code < 0) {
        if (*pFunction != 0) {
            gs_function_free(*pFunction, true, mem);
            *pFunction = 0;
        }
        gs_free_object(mem, data, "build_mesh_shading");
    }
    return code;
}
コード例 #14
0
ファイル: gximage3.c プロジェクト: sicsiksix/aaa_website
int
gx_begin_image3_generic(gx_device * dev,
                        const gs_imager_state *pis, const gs_matrix *pmat,
                        const gs_image_common_t *pic, const gs_int_rect *prect,
                        const gx_drawing_color *pdcolor,
                        const gx_clip_path *pcpath, gs_memory_t *mem,
                        image3_make_mid_proc_t make_mid,
                        image3_make_mcde_proc_t make_mcde,
                        gx_image_enum_common_t **pinfo)
{
    const gs_image3_t *pim = (const gs_image3_t *)pic;
    gx_image3_enum_t *penum;
    gs_int_rect mask_rect, data_rect;
    gx_device *mdev = 0;
    gx_device *pcdev = 0;
    gs_image_t i_pixel, i_mask;
    gs_matrix mi_pixel, mi_mask, mat;
    gs_rect mrect;
    gs_int_point origin;
    int code;

    /* Validate the parameters. */
    if (pim->Height <= 0 || pim->MaskDict.Height <= 0)
        return_error(gs_error_rangecheck);
    switch (pim->InterleaveType) {
        default:
            return_error(gs_error_rangecheck);
        case interleave_chunky:
            if (pim->MaskDict.Width != pim->Width ||
                pim->MaskDict.Height != pim->Height ||
                pim->MaskDict.BitsPerComponent != pim->BitsPerComponent ||
                pim->format != gs_image_format_chunky
                )
                return_error(gs_error_rangecheck);
            break;
        case interleave_scan_lines:
            if (pim->MaskDict.Height % pim->Height != 0 &&
                pim->Height % pim->MaskDict.Height != 0
                )
                return_error(gs_error_rangecheck);
            /* falls through */
        case interleave_separate_source:
            if (pim->MaskDict.BitsPerComponent != 1)
                return_error(gs_error_rangecheck);
    }
    if (!check_image3_extent(pim->ImageMatrix.xx,
                             pim->MaskDict.ImageMatrix.xx) ||
        !check_image3_extent(pim->ImageMatrix.xy,
                             pim->MaskDict.ImageMatrix.xy) ||
        !check_image3_extent(pim->ImageMatrix.yx,
                             pim->MaskDict.ImageMatrix.yx) ||
        !check_image3_extent(pim->ImageMatrix.yy,
                             pim->MaskDict.ImageMatrix.yy)
        )
        return_error(gs_error_rangecheck);
    if ((code = gs_matrix_invert(&pim->ImageMatrix, &mi_pixel)) < 0 ||
        (code = gs_matrix_invert(&pim->MaskDict.ImageMatrix, &mi_mask)) < 0
        )
        return code;
    if (fabs(mi_pixel.tx - mi_mask.tx) >= 0.5 ||
        fabs(mi_pixel.ty - mi_mask.ty) >= 0.5
        )
        return_error(gs_error_rangecheck);
#ifdef DEBUG
    {
        /* Although the PLRM says that the Mask and Image *must* be the same size,  */
        /* Adobe CPSI (and other RIPS) ignore this and process anyway. Note that we */
        /* are not compatible if the Mask Height than the Data (pixel) Height. CPSI */
        /* de-interleaves the mask from the data image and stops at the Mask Height */
        /* Problem detected with Genoa 468-03 (part of file 468-01.ps)              */
        /*****           fixme: When Data Image Height > Mask Height            *****/
        gs_point ep, em;

        if ((code = gs_point_transform(pim->Width, pim->Height, &mi_pixel,
                                       &ep)) < 0 ||
            (code = gs_point_transform(pim->MaskDict.Width,
                                       pim->MaskDict.Height, &mi_mask,
                                       &em)) < 0
            )
            return code;
        if (fabs(ep.x - em.x) >= 0.5 || fabs(ep.y - em.y) >= 0.5)
            code = gs_error_rangecheck;	/* leave the check in for debug breakpoint */
    }
#endif /* DEBUG */
    penum = gs_alloc_struct(mem, gx_image3_enum_t, &st_image3_enum,
                            "gx_begin_image3");
    if (penum == 0)
        return_error(gs_error_VMerror);
    penum->num_components =
        gs_color_space_num_components(pim->ColorSpace);
    gx_image_enum_common_init((gx_image_enum_common_t *) penum,
                              (const gs_data_image_t *)pim,
                              &image3_enum_procs, dev,
                              1 + penum->num_components,
                              pim->format);
    /* Initialize pointers now in case we bail out. */
    penum->mask_data = 0;
    penum->pixel_data = 0;
    if (prect) {
        long lmw = pim->MaskDict.Width, lmh = pim->MaskDict.Height;

        data_rect = *prect;
        mask_rect.p.x = (int)(data_rect.p.x * lmw / pim->Width);
        mask_rect.p.y = (int)(data_rect.p.y * lmh / pim->Height);
        mask_rect.q.x = (int)((data_rect.q.x + pim->Width - 1) * lmw /
                              pim->Width);
        mask_rect.q.y = (int)((data_rect.q.y + pim->Height - 1) * lmh /
                              pim->Height);
    } else {
        mask_rect.p.x = mask_rect.p.y = 0;
        mask_rect.q.x = pim->MaskDict.Width;
        mask_rect.q.y = pim->MaskDict.Height;
        data_rect.p.x = data_rect.p.y = 0;
        data_rect.q.x = pim->Width;
        data_rect.q.y = pim->Height;
    }
    penum->mask_width = mask_rect.q.x - mask_rect.p.x;
    penum->mask_height = mask_rect.q.y - mask_rect.p.y;
    penum->mask_full_height = pim->MaskDict.Height;
    penum->mask_y = 0;
    penum->mask_skip = 0;
    penum->pixel_width = data_rect.q.x - data_rect.p.x;
    penum->pixel_height = data_rect.q.y - data_rect.p.y;
    penum->pixel_full_height = pim->Height;
    penum->pixel_y = 0;
    penum->mask_info = 0;
    penum->pixel_info = 0;
    if (pim->InterleaveType == interleave_chunky) {
        /* Allocate row buffers for the mask and pixel data. */
        penum->pixel_data =
            gs_alloc_bytes(mem,
                           (penum->pixel_width * pim->BitsPerComponent *
                            penum->num_components + 7) >> 3,
                           "gx_begin_image3(pixel_data)");
        penum->mask_data =
            gs_alloc_bytes(mem, (penum->mask_width + 7) >> 3,
                           "gx_begin_image3(mask_data)");
        if (penum->pixel_data == 0 || penum->mask_data == 0) {
            code = gs_note_error(gs_error_VMerror);
            goto out1;
        }
    }
コード例 #15
0
ファイル: gximage.c プロジェクト: ststeiger/ghostsvg
/*
 * Read generic pixel image parameters.
 */
int
gx_pixel_image_sget(gs_pixel_image_t *pim, stream *s,
		    gs_color_space *pcs)
{
    uint control;
    float decode_default_1 = 1;
    int num_components, num_decode;
    int i;
    int code;
    uint ignore;

    if ((code = sget_variable_uint(s, &control)) < 0 ||
	(code = sget_variable_uint(s, (uint *)&pim->Width)) < 0 ||
	(code = sget_variable_uint(s, (uint *)&pim->Height)) < 0
	)
	return code;
    if_debug3('b', "[b]get control=0x%x, Width=%d, Height=%d\n",
	      control, pim->Width, pim->Height);
    if (control & PI_ImageMatrix) {
	if ((code = sget_matrix(s, &pim->ImageMatrix)) < 0)
	    return code;
	debug_b_print_matrix(pim);
    } else
	gx_image_matrix_set_default((gs_data_image_t *)pim);
    pim->BitsPerComponent = ((control >> PI_BPC_SHIFT) & PI_BPC_MASK) + 1;
    pim->format = (control >> PI_FORMAT_SHIFT) & PI_FORMAT_MASK;
    pim->ColorSpace = pcs;
    num_components = gs_color_space_num_components(pcs);
    num_decode = num_components * 2;
    if (gs_color_space_get_index(pcs) == gs_color_space_index_Indexed)
	decode_default_1 = (float)pcs->params.indexed.hival;
    if (control & PI_Decode) {
	uint dflags = 0x10000;
	float *dp = pim->Decode;

	for (i = 0; i < num_decode; i += 2, dp += 2, dflags <<= 2) {
	    if (dflags >= 0x10000) {
		dflags = sgetc(s) + 0x100;
		if (dflags < 0x100)
		    return_error(gs_error_ioerror);
	    }
	    switch (dflags & 0xc0) {
	    case 0x00:
		dp[0] = 0, dp[1] = DECODE_DEFAULT(i + 1, decode_default_1);
		break;
	    case 0x40:
		dp[0] = DECODE_DEFAULT(i + 1, decode_default_1), dp[1] = 0;
		break;
	    case 0x80:
		dp[0] = 0;
		if (sgets(s, (byte *)(dp + 1), sizeof(float), &ignore) < 0)
		    return_error(gs_error_ioerror);
		break;
	    case 0xc0:
		if (sgets(s, (byte *)dp, sizeof(float) * 2, &ignore) < 0)
		    return_error(gs_error_ioerror);
		break;
	    }
	}
	debug_b_print_decode(pim, num_decode);
    } else {
        for (i = 0; i < num_decode; ++i)
	    pim->Decode[i] = DECODE_DEFAULT(i, decode_default_1);
    }
    pim->Interpolate = (control & PI_Interpolate) != 0;
    pim->CombineWithColor = (control & PI_CombineWithColor) != 0;
    return control >> PI_BITS;
}
コード例 #16
0
ファイル: gximage.c プロジェクト: ststeiger/ghostsvg
/*
 *	Width, encoded as a variable-length uint
 *	Height, encoded ditto
 *	ImageMatrix (if A = 1), per gs_matrix_store/fetch
 *	Decode (if D = 1): blocks of up to 4 components
 *	    aabbccdd, where each xx is decoded as:
 *		00 = default, 01 = swapped default,
 *		10 = (0,V), 11 = (U,V)
 *	    non-defaulted components (up to 8 floats)
 */
int
gx_pixel_image_sput(const gs_pixel_image_t *pim, stream *s,
		    const gs_color_space **ppcs, int extra)
{
    const gs_color_space *pcs = pim->ColorSpace;
    int bpc = pim->BitsPerComponent;
    int num_components = gs_color_space_num_components(pcs);
    int num_decode;
    uint control = extra << PI_BITS;
    float decode_default_1 = 1;
    int i;
    uint ignore;

    /* Construct the control word. */

    if (!gx_image_matrix_is_default((const gs_data_image_t *)pim))
	control |= PI_ImageMatrix;
    switch (pim->format) {
    case gs_image_format_chunky:
    case gs_image_format_component_planar:
	switch (bpc) {
	case 1: case 2: case 4: case 8: case 12: break;
	default: return_error(gs_error_rangecheck);
	}
	break;
    case gs_image_format_bit_planar:
	if (bpc < 1 || bpc > 8)
	    return_error(gs_error_rangecheck);
    }
    control |= (bpc - 1) << PI_BPC_SHIFT;
    control |= pim->format << PI_FORMAT_SHIFT;
    num_decode = num_components * 2;
    if (gs_color_space_get_index(pcs) == gs_color_space_index_Indexed)
	decode_default_1 = (float)pcs->params.indexed.hival;
    for (i = 0; i < num_decode; ++i)
	if (pim->Decode[i] != DECODE_DEFAULT(i, decode_default_1)) {
	    control |= PI_Decode;
	    break;
	}
    if (pim->Interpolate)
	control |= PI_Interpolate;
    if (pim->CombineWithColor)
	control |= PI_CombineWithColor;

    /* Write the encoding on the stream. */

    if_debug3('b', "[b]put control=0x%x, Width=%d, Height=%d\n",
	      control, pim->Width, pim->Height);
    sput_variable_uint(s, control);
    sput_variable_uint(s, (uint)pim->Width);
    sput_variable_uint(s, (uint)pim->Height);
    if (control & PI_ImageMatrix) {
	debug_b_print_matrix(pim);
	sput_matrix(s, &pim->ImageMatrix);
    }
    if (control & PI_Decode) {
	int i;
	uint dflags = 1;
	float decode[8];
	int di = 0;

	debug_b_print_decode(pim, num_decode);
	for (i = 0; i < num_decode; i += 2) {
	    float u = pim->Decode[i], v = pim->Decode[i + 1];
	    float dv = DECODE_DEFAULT(i + 1, decode_default_1);

	    if (dflags >= 0x100) {
		sputc(s, (byte)(dflags & 0xff));
		sputs(s, (const byte *)decode, di * sizeof(float), &ignore);
		dflags = 1;
		di = 0;
	    }
	    dflags <<= 2;
	    if (u == 0 && v == dv)
		DO_NOTHING;
	    else if (u == dv && v == 0)
		dflags += 1;
	    else {
		if (u != 0) {
		    dflags++;
		    decode[di++] = u;
		}
		dflags += 2;
		decode[di++] = v;
	    }
	}
	sputc(s, (byte)((dflags << (8 - num_decode)) & 0xff));
	sputs(s, (const byte *)decode, di * sizeof(float), &ignore);
    }
    *ppcs = pcs;
    return 0;
}
コード例 #17
0
ファイル: zshade.c プロジェクト: computersforpeace/ghostpdl
/* Common framework for building shadings. */
static int
build_shading(i_ctx_t *i_ctx_p, build_shading_proc_t proc)
{
    os_ptr op = osp;
    int code;
    float box[4];
    gs_shading_params_t params;
    gs_shading_t *psh;
    ref *pvalue;

    check_type(*op, t_dictionary);
    params.ColorSpace = 0;
    params.cie_joint_caches = 0;
    params.Background = 0;
    /* Collect parameters common to all shading types. */
    {
        gs_color_space *pcs = gs_currentcolorspace(igs);
        int num_comp = gs_color_space_num_components(pcs);

        if (num_comp < 0) {	/* Pattern color space */
            gs_errorinfo_put_pair_from_dict(i_ctx_p, op, "ColorSpace");
            return_error(gs_error_typecheck);
        }
        params.ColorSpace = pcs;
        rc_increment_cs(pcs);
        if (dict_find_string(op, "Background", &pvalue) > 0) {
            gs_client_color *pcc =
                ialloc_struct(gs_client_color, &st_client_color,
                              "build_shading");

            if (pcc == 0) {
                code = gs_note_error(gs_error_VMerror);
                goto fail;
            }
            pcc->pattern = 0;
            params.Background = pcc;
            code = dict_floats_param(imemory, op, "Background",
                                     gs_color_space_num_components(pcs),
                                     pcc->paint.values, NULL);
            if (code < 0) {
                gs_errorinfo_put_pair_from_dict(i_ctx_p, op, "Background");
                goto fail;
            }
        }
    }
    if (dict_find_string(op, "BBox", &pvalue) <= 0)
        params.have_BBox = false;
    else if ((code = dict_floats_param(imemory, op, "BBox",
                                       4, box, NULL)) == 4) {
        /* Adobe Interpreters accept denormalised BBox - bug 688937 */
        if (box[0] <= box[2]) {
            params.BBox.p.x = box[0];
            params.BBox.q.x = box[2];
        } else {
            params.BBox.p.x = box[2];
            params.BBox.q.x = box[0];
        }
        if (box[1] <= box[3]) {
            params.BBox.p.y = box[1];
            params.BBox.q.y = box[3];
        } else {
            params.BBox.p.y = box[3];
            params.BBox.q.y = box[1];
        }
        params.have_BBox = true;
    } else {
        gs_errorinfo_put_pair_from_dict(i_ctx_p, op, "BBox");
        goto fail;
    }
    code = dict_bool_param(op, "AntiAlias", false, &params.AntiAlias);
    if (code < 0) {
        gs_errorinfo_put_pair_from_dict(i_ctx_p, op, "AntiAlias");
        goto fail;
    }
    /* Finish building the shading. */
    code = (*proc)(i_ctx_p, op, &params, &psh, imemory);
    if (code < 0)
        goto fail;
    if (gx_color_space_needs_cie_caches(psh->params.ColorSpace)) {
        rc_decrement(psh->params.cie_joint_caches, "build_shading");
        psh->params.cie_joint_caches = gx_currentciecaches(igs);
        rc_increment(psh->params.cie_joint_caches);
    }
    make_istruct_new(op, 0, psh);
    return code;
fail:
    gs_free_object(imemory, params.Background, "Background");
    if (params.ColorSpace) {
        rc_decrement_only_cs(params.ColorSpace, "build_shading");
    }
    return (code < 0 ? code : gs_note_error(gs_error_rangecheck));
}
コード例 #18
0
ファイル: gscdevn.c プロジェクト: computersforpeace/ghostpdl
static int
gx_concretize_DeviceN(const gs_client_color * pc, const gs_color_space * pcs,
                      frac * pconc, const gs_imager_state * pis, gx_device *dev)
{
    int code, tcode = 0;
    gs_client_color cc;
    gs_color_space *pacs = (gs_color_space*) (pcs->base_space);
    gs_device_n_map *map = pcs->params.device_n.map;
    bool is_lab;
    int num_src_comps = pcs->params.device_n.num_components;

#ifdef DEBUG
    /*
     * Verify that the color space and imager state info match.
     */
    if (pcs->id != pis->color_component_map.cspace_id)
        dmprintf(dev->memory, "gx_concretize_DeviceN: color space id mismatch");
#endif

    /*
     * Check if we need to map into the alternate color space.
     * We must preserve tcode for implementing a semi-hack in the interpreter.
     */

    if (pis->color_component_map.use_alt_cspace) {
        /* Check the 1-element cache first. */
        if (map->cache_valid) {
            int i;

            for (i = pcs->params.device_n.num_components; --i >= 0;) {
                if (map->tint[i] != pc->paint.values[i])
                    break;
            }
            if (i < 0) {
                int num_out = gs_color_space_num_components(pacs);

                for (i = 0; i < num_out; ++i)
                    pconc[i] = map->conc[i];
                return 0;
            }
        }
        tcode = (*pcs->params.device_n.map->tint_transform)
             (pc->paint.values, &cc.paint.values[0],
             pis, pcs->params.device_n.map->tint_transform_data);
        (*pacs->type->restrict_color)(&cc, pacs);
        if (tcode < 0)
            return tcode;
        /* First check if this was PS based. */
        if (gs_color_space_is_PSCIE(pacs)) {
            /* We may have to rescale data to 0 to 1 range */
            rescale_cie_colors(pacs, &cc);
            /* If we have not yet created the profile do that now */
            if (pacs->icc_equivalent == NULL) {
                gs_colorspace_set_icc_equivalent(pacs, &(is_lab), pis->memory);
            }
            /* Use the ICC equivalent color space */
            pacs = pacs->icc_equivalent;
        }
        if (pacs->cmm_icc_profile_data->data_cs == gsCIELAB ||
            pacs->cmm_icc_profile_data->islab) {
            /* Get the data in a form that is concrete for the CMM */
            cc.paint.values[0] /= 100.0;
            cc.paint.values[1] = (cc.paint.values[1]+128)/255.0;
            cc.paint.values[2] = (cc.paint.values[2]+128)/255.0;
        }
        code = cs_concretize_color(&cc, pacs, pconc, pis, dev);
    }
    else {
        int i;

        for (i = num_src_comps; --i >= 0;)
            pconc[i] = gx_unit_frac(pc->paint.values[i]);
        return 0;
    }
    return (code < 0 || tcode == 0 ? code : tcode);
}
コード例 #19
0
/*
 * Create a PDF color space corresponding to a PostScript color space.
 * For parameterless color spaces, set *pvalue to a (literal) string with
 * the color space name; for other color spaces, create a cos_array_t if
 * necessary and set *pvalue to refer to it.  In the latter case, if
 * by_name is true, return a string /Rxxxx rather than a reference to
 * the actual object.
 *
 * If ppranges is not NULL, then if  the domain of the color space had
 * to be scaled (to convert a CIEBased space to ICCBased), store a pointer
 * to the ranges in *ppranges, otherwise set *ppranges to 0.
 */
int
pdf_color_space_named(gx_device_pdf *pdev, cos_value_t *pvalue,
		const gs_range_t **ppranges,
		const gs_color_space *pcs,
		const pdf_color_space_names_t *pcsn,
		bool by_name, const byte *res_name, int name_length)
{
    gs_color_space_index csi = gs_color_space_get_index(pcs);
    cos_array_t *pca;
    cos_dict_t *pcd;
    cos_value_t v;
    const gs_cie_common *pciec;
    gs_function_t *pfn;
    const gs_range_t *ranges = 0;
    uint serialized_size;
    byte *serialized = NULL, serialized0[100];
    pdf_resource_t *pres = NULL;
    int code;

    if (ppranges)
	*ppranges = 0;		/* default */
    switch (csi) {
    case gs_color_space_index_DeviceGray:
	cos_c_string_value(pvalue, pcsn->DeviceGray);
	return 0;
    case gs_color_space_index_DeviceRGB:
	cos_c_string_value(pvalue, pcsn->DeviceRGB);
	return 0;
    case gs_color_space_index_DeviceCMYK:
	cos_c_string_value(pvalue, pcsn->DeviceCMYK);
	return 0;
    case gs_color_space_index_Pattern:
	if (!pcs->params.pattern.has_base_space) {
	    cos_c_string_value(pvalue, "/Pattern");
	    return 0;
	}
	break;
    case gs_color_space_index_CIEICC:
        /*
	 * Take a special early exit for unrecognized ICCBased color spaces,
	 * or for PDF 1.2 output (ICCBased color spaces date from PDF 1.3).
	 */
        if (pcs->params.icc.picc_info->picc == 0 ||
	    pdev->CompatibilityLevel < 1.3
	    ) {
	    if (res_name != NULL)
		return 0; /* Ignore .includecolorspace */
            return pdf_color_space( pdev, pvalue, ppranges,
                                    pcs->base_space,
                                    pcsn, by_name);
	}
        break;
    default:
	break;
    }
    if (pdev->params.ColorConversionStrategy == ccs_CMYK && 
	    csi != gs_color_space_index_DeviceCMYK &&
	    csi != gs_color_space_index_DeviceGray &&
	    csi != gs_color_space_index_Pattern)
	return_error(gs_error_rangecheck);
    if (pdev->params.ColorConversionStrategy == ccs_sRGB && 
	    csi != gs_color_space_index_DeviceRGB && 
	    csi != gs_color_space_index_DeviceGray &&
	    csi != gs_color_space_index_Pattern)
	return_error(gs_error_rangecheck);
    if (pdev->params.ColorConversionStrategy == ccs_Gray && 
	    csi != gs_color_space_index_DeviceGray &&
	    csi != gs_color_space_index_Pattern)
	return_error(gs_error_rangecheck);
    /* Check whether we already have a PDF object for this color space. */
    if (pcs->id != gs_no_id)
	pres = pdf_find_resource_by_gs_id(pdev, resourceColorSpace, pcs->id);
    if (pres == NULL) {
	stream s;

	s_init(&s, pdev->memory);
	swrite_position_only(&s);
	code = cs_serialize(pcs, &s);
	if (code < 0)
	    return_error(gs_error_unregistered); /* Must not happen. */
	serialized_size = stell(&s);
	sclose(&s);
	if (serialized_size <= sizeof(serialized0))
	    serialized = serialized0;
	else {
	    serialized = gs_alloc_bytes(pdev->pdf_memory, serialized_size, "pdf_color_space");
	    if (serialized == NULL)
		return_error(gs_error_VMerror);
	}
	swrite_string(&s, serialized, serialized_size);
	code = cs_serialize(pcs, &s);
	if (code < 0)
	    return_error(gs_error_unregistered); /* Must not happen. */
	if (stell(&s) != serialized_size) 
	    return_error(gs_error_unregistered); /* Must not happen. */
	sclose(&s);
	pres = pdf_find_cspace_resource(pdev, serialized, serialized_size);
	if (pres != NULL) {
	    if (serialized != serialized0)
		gs_free_object(pdev->pdf_memory, serialized, "pdf_color_space");
	    serialized = NULL;
	}
    }
    if (pres) {
	const pdf_color_space_t *const ppcs =
	    (const pdf_color_space_t *)pres;

	if (ppranges != 0 && ppcs->ranges != 0)
	    *ppranges = ppcs->ranges;
	pca = (cos_array_t *)pres->object;
	goto ret;
    }

    /* Space has parameters -- create an array. */
    pca = cos_array_alloc(pdev, "pdf_color_space");
    if (pca == 0)
	return_error(gs_error_VMerror);

    switch (csi) {

    case gs_color_space_index_CIEICC:
	code = pdf_iccbased_color_space(pdev, pvalue, pcs, pca);
        break;

    case gs_color_space_index_CIEA: {
	/* Check that we can represent this as a CalGray space. */
	const gs_cie_a *pcie = pcs->params.a;
	bool unitary = cie_ranges_are_0_1(&pcie->RangeA, 1);
	bool identityA = (pcie->MatrixA.u == 1 && pcie->MatrixA.v == 1 && 
	                  pcie->MatrixA.w == 1);
	gs_vector3 expts;

	pciec = (const gs_cie_common *)pcie;
	if (!pcie->common.MatrixLMN.is_identity) {
	    code = pdf_convert_cie_space(pdev, pca, pcs, "GRAY", pciec,
					 &pcie->RangeA, ONE_STEP_NOT, NULL,
					 &ranges);
	    break;
	}
	if (unitary && identityA &&
	    CIE_CACHE_IS_IDENTITY(&pcie->caches.DecodeA) &&
	    CIE_SCALAR3_CACHE_IS_EXPONENTIAL(pcie->common.caches.DecodeLMN, expts) &&
	    expts.v == expts.u && expts.w == expts.u
	    ) {
	    DO_NOTHING;
	} else if (unitary && identityA &&
		   CIE_CACHE3_IS_IDENTITY(pcie->common.caches.DecodeLMN) &&
		   cie_vector_cache_is_exponential(&pcie->caches.DecodeA, &expts.u)
		   ) {
	    DO_NOTHING;
	} else {
	    code = pdf_convert_cie_space(pdev, pca, pcs, "GRAY", pciec,
					 &pcie->RangeA, ONE_STEP_NOT, NULL,
					 &ranges);
	    break;
	}
	code = cos_array_add(pca, cos_c_string_value(&v, "/CalGray"));
	if (code < 0)
	    return code;
	pcd = cos_dict_alloc(pdev, "pdf_color_space(dict)");
	if (pcd == 0)
	    return_error(gs_error_VMerror);
	if (expts.u != 1) {
	    code = cos_dict_put_c_key_real(pcd, "/Gamma", expts.u);
	    if (code < 0)
		return code;
	}
    }
    cal:
    /* Finish handling a CIE-based color space (Calxxx or Lab). */
    if (code < 0)
	return code;
    code = pdf_finish_cie_space(pca, pcd, pciec);
    break;

    case gs_color_space_index_CIEABC: {
	/* Check that we can represent this as a CalRGB space. */
	const gs_cie_abc *pcie = pcs->params.abc;
	bool unitary = cie_ranges_are_0_1(pcie->RangeABC.ranges, 3);
	gs_vector3 expts;
	const gs_matrix3 *pmat = NULL;
	cie_cache_one_step_t one_step =
	    cie_cached_abc_is_one_step(pcie, &pmat);

	pciec = (const gs_cie_common *)pcie;
	if (unitary) {
	    switch (one_step) {
	    case ONE_STEP_ABC:
		if (CIE_VECTOR3_CACHE_IS_EXPONENTIAL(pcie->caches.DecodeABC.caches, expts))
		    goto calrgb;
		break;
	    case ONE_STEP_LMN:
		if (CIE_SCALAR3_CACHE_IS_EXPONENTIAL(pcie->common.caches.DecodeLMN, expts))
		    goto calrgb;
	    default:
		break;
	    }
	}
	if (cie_is_lab(pcie)) {
	    /* Represent this as a Lab space. */
	    pcd = cos_dict_alloc(pdev, "pdf_color_space(dict)");
	    if (pcd == 0)
		return_error(gs_error_VMerror);
	    code = pdf_put_lab_color_space(pca, pcd, pcie->RangeABC.ranges);
	    goto cal;
	} else {
	    code = pdf_convert_cie_space(pdev, pca, pcs, "RGB ", pciec,
					 pcie->RangeABC.ranges,
					 one_step, pmat, &ranges);
	    break;
	}
    calrgb:
	code = cos_array_add(pca, cos_c_string_value(&v, "/CalRGB"));
	if (code < 0)
	    return code;
	pcd = cos_dict_alloc(pdev, "pdf_color_space(dict)");
	if (pcd == 0)
	    return_error(gs_error_VMerror);
	if (expts.u != 1 || expts.v != 1 || expts.w != 1) {
	    code = cos_dict_put_c_key_vector3(pcd, "/Gamma", &expts);
	    if (code < 0)
		return code;
	}
	if (!pmat->is_identity) {
	    cos_array_t *pcma =
		cos_array_alloc(pdev, "pdf_color_space(Matrix)");

	    if (pcma == 0)
		return_error(gs_error_VMerror);
	    if ((code = cos_array_add_vector3(pcma, &pmat->cu)) < 0 ||
		(code = cos_array_add_vector3(pcma, &pmat->cv)) < 0 ||
		(code = cos_array_add_vector3(pcma, &pmat->cw)) < 0 ||
		(code = cos_dict_put(pcd, (const byte *)"/Matrix", 7,
				     COS_OBJECT_VALUE(&v, pcma))) < 0
		)
		return code;
	}
    }
    goto cal;

    case gs_color_space_index_CIEDEF:
	code = pdf_convert_cie_space(pdev, pca, pcs, "RGB ",
				     (const gs_cie_common *)pcs->params.def,
				     pcs->params.def->RangeDEF.ranges,
				     ONE_STEP_NOT, NULL, &ranges);
	break;

    case gs_color_space_index_CIEDEFG:
	code = pdf_convert_cie_space(pdev, pca, pcs, "CMYK",
				     (const gs_cie_common *)pcs->params.defg,
				     pcs->params.defg->RangeDEFG.ranges,
				     ONE_STEP_NOT, NULL, &ranges);
	break;

    case gs_color_space_index_Indexed:
	code = pdf_indexed_color_space(pdev, pvalue, pcs, pca);
	break;

    case gs_color_space_index_DeviceN:
        if (pdev->CompatibilityLevel < 1.3)
	    return_error(gs_error_rangecheck);
	pfn = gs_cspace_get_devn_function(pcs);
	/****** CURRENTLY WE ONLY HANDLE Functions ******/
	if (pfn == 0)
	    return_error(gs_error_rangecheck);
	{
	    cos_array_t *psna = 
		cos_array_alloc(pdev, "pdf_color_space(DeviceN)");
	    int i;
	    byte *name_string;
	    uint name_string_length;
	    cos_value_t v_attriburtes, *va = NULL;

	    if (psna == 0)
		return_error(gs_error_VMerror);
	    for (i = 0; i < pcs->params.device_n.num_components; ++i) {
	 	if ((code = pcs->params.device_n.get_colorname_string(
				  pdev->memory,
				  pcs->params.device_n.names[i], &name_string, 
				  &name_string_length)) < 0 ||
		    (code = pdf_string_to_cos_name(pdev, name_string, 
				  name_string_length, &v)) < 0 ||
		    (code = cos_array_add_no_copy(psna, &v)) < 0)
		    return code;
	    }
	    COS_OBJECT_VALUE(&v, psna);
	    if (pcs->params.device_n.colorants != NULL) {
		cos_dict_t *colorants  = cos_dict_alloc(pdev, "pdf_color_space(DeviceN)");
		cos_value_t v_colorants, v_separation, v_colorant_name;
		const gs_device_n_attributes *csa;
		pdf_resource_t *pres_attributes;

		if (colorants == NULL)
		    return_error(gs_error_VMerror);
		code = pdf_alloc_resource(pdev, resourceOther, 0, &pres_attributes, -1);
		if (code < 0)
		    return code;
		cos_become(pres_attributes->object, cos_type_dict);
		COS_OBJECT_VALUE(&v_colorants, colorants);
		code = cos_dict_put((cos_dict_t *)pres_attributes->object, 
		    (const byte *)"/Colorants", 10, &v_colorants);
		if (code < 0)
		    return code;
		for (csa = pcs->params.device_n.colorants; csa != NULL; csa = csa->next) {
	 	    code = pcs->params.device_n.get_colorname_string(pdev->memory,
				  csa->colorant_name, &name_string, &name_string_length);
		    if (code < 0)
			return code;
		    code = pdf_color_space(pdev, &v_separation, NULL, csa->cspace, pcsn, false);
		    if (code < 0)
			return code;
		    code = pdf_string_to_cos_name(pdev, name_string, name_string_length, &v_colorant_name);
		    if (code < 0)
			return code;
		    code = cos_dict_put(colorants, v_colorant_name.contents.chars.data, 
					v_colorant_name.contents.chars.size, &v_separation);
		    if (code < 0)
			return code;
		}
    		code = pdf_substitute_resource(pdev, &pres_attributes, resourceOther, NULL, true);
		if (code < 0)
		    return code;
		va = &v_attriburtes;
		COS_OBJECT_VALUE(va, pres_attributes->object);
	    }
	    if ((code = pdf_separation_color_space(pdev, pca, "/DeviceN", &v,
						   pcs->base_space,
					pfn, &pdf_color_space_names, va)) < 0)
		return code;
	}
	break;

    case gs_color_space_index_Separation:
	pfn = gs_cspace_get_sepr_function(pcs);
	/****** CURRENTLY WE ONLY HANDLE Functions ******/
	if (pfn == 0)
	    return_error(gs_error_rangecheck);
	{
	    byte *name_string;
	    uint name_string_length;
	    if ((code = pcs->params.separation.get_colorname_string(
				  pdev->memory, 
				  pcs->params.separation.sep_name, &name_string, 
				  &name_string_length)) < 0 ||
		(code = pdf_string_to_cos_name(pdev, name_string, 
				      name_string_length, &v)) < 0 ||
		(code = pdf_separation_color_space(pdev, pca, "/Separation", &v,
					    pcs->base_space,
					    pfn, &pdf_color_space_names, NULL)) < 0)
		return code;
	}
	break;

    case gs_color_space_index_Pattern:
	if ((code = pdf_color_space(pdev, pvalue, ppranges,
				    pcs->base_space,
				    &pdf_color_space_names, false)) < 0 ||
	    (code = cos_array_add(pca,
				  cos_c_string_value(&v, "/Pattern"))) < 0 ||
	    (code = cos_array_add(pca, pvalue)) < 0
	    )
	    return code;
	break;

    default:
	return_error(gs_error_rangecheck);
    }
    /*
     * Register the color space as a resource, since it must be referenced
     * by name rather than directly.
     */
    {
	pdf_color_space_t *ppcs;

	if (code < 0 ||
	    (code = pdf_alloc_resource(pdev, resourceColorSpace, pcs->id,
				       &pres, -1)) < 0
	    ) {
	    COS_FREE(pca, "pdf_color_space");
	    return code;
	}
	pdf_reserve_object_id(pdev, pres, 0);
	if (res_name != NULL) {
	    int l = min(name_length, sizeof(pres->rname) - 1);
	    
	    memcpy(pres->rname, res_name, l);
	    pres->rname[l] = 0;
	}
	ppcs = (pdf_color_space_t *)pres;
	if (serialized == serialized0) {
	    serialized = gs_alloc_bytes(pdev->pdf_memory, serialized_size, "pdf_color_space");
	    if (serialized == NULL)
		return_error(gs_error_VMerror);
	    memcpy(serialized, serialized0, serialized_size);
	}
	ppcs->serialized = serialized;
	ppcs->serialized_size = serialized_size;
	if (ranges) {
	    int num_comp = gs_color_space_num_components(pcs);
	    gs_range_t *copy_ranges = (gs_range_t *)
		gs_alloc_byte_array(pdev->pdf_memory, num_comp,
				    sizeof(gs_range_t), "pdf_color_space");

	    if (copy_ranges == 0) {
		COS_FREE(pca, "pdf_color_space");
		return_error(gs_error_VMerror);
	    }
	    memcpy(copy_ranges, ranges, num_comp * sizeof(gs_range_t));
	    ppcs->ranges = copy_ranges;
	    if (ppranges)
		*ppranges = copy_ranges;
	} else
	    ppcs->ranges = 0;
	pca->id = pres->object->id;
	COS_FREE(pres->object, "pdf_color_space");
	pres->object = (cos_object_t *)pca;
	cos_write_object(COS_OBJECT(pca), pdev);
    }
 ret:
    if (by_name) {
	/* Return a resource name rather than an object reference. */
	discard(COS_RESOURCE_VALUE(pvalue, pca));
    } else
	discard(COS_OBJECT_VALUE(pvalue, pca));
    if (pres != NULL) {
	pres->where_used |= pdev->used_mask;
	code = pdf_add_resource(pdev, pdev->substream_Resources, "/ColorSpace", pres);
	if (code < 0)
	    return code;
    }
    return 0;
}
コード例 #20
0
/*
 * Create an Indexed color space.  This is a single-use procedure,
 * broken out only for readability.
 */
static int
pdf_indexed_color_space(gx_device_pdf *pdev, cos_value_t *pvalue,
			const gs_color_space *pcs, cos_array_t *pca)
{
    const gs_indexed_params *pip = &pcs->params.indexed;
    const gs_color_space *base_space = pcs->base_space;
    int num_entries = pip->hival + 1;
    int num_components = gs_color_space_num_components(base_space);
    uint table_size = num_entries * num_components;
    /* Guess at the extra space needed for PS string encoding. */
    uint string_size = 2 + table_size * 4;
    uint string_used;
    byte buf[100];		/* arbitrary */
    stream_AXE_state st;
    stream s, es;
    gs_memory_t *mem = pdev->pdf_memory;
    byte *table;
    byte *palette;
    cos_value_t v;
    int code;

    /* PDF doesn't support Indexed color spaces with more than 256 entries. */
    if (num_entries > 256)
	return_error(gs_error_rangecheck);
    if (pdev->CompatibilityLevel < 1.3) {
	switch (gs_color_space_get_index(pcs)) {
	    case gs_color_space_index_Pattern:
	    case gs_color_space_index_Separation:
	    case gs_color_space_index_Indexed:
	    case gs_color_space_index_DeviceN:
		return_error(gs_error_rangecheck);
	    default: DO_NOTHING; 
	}

    }
    table = gs_alloc_string(mem, string_size, "pdf_color_space(table)");
    palette = gs_alloc_string(mem, table_size, "pdf_color_space(palette)");
    if (table == 0 || palette == 0) {
	gs_free_string(mem, palette, table_size,
		       "pdf_color_space(palette)");
	gs_free_string(mem, table, string_size,
		       "pdf_color_space(table)");
	return_error(gs_error_VMerror);
    }
    s_init(&s, mem);
    swrite_string(&s, table, string_size);
    s_init(&es, mem);
    s_init_state((stream_state *)&st, &s_PSSE_template, NULL);
    s_init_filter(&es, (stream_state *)&st, buf, sizeof(buf), &s);
    sputc(&s, '(');
    if (pcs->params.indexed.use_proc) {
	gs_client_color cmin, cmax;
	byte *pnext = palette;
	int i, j;

	/* Find the legal range for the color components. */
	for (j = 0; j < num_components; ++j)
	    cmin.paint.values[j] = (float)min_long,
		cmax.paint.values[j] = (float)max_long;
	gs_color_space_restrict_color(&cmin, base_space);
	gs_color_space_restrict_color(&cmax, base_space);
	/*
	 * Compute the palette values, with the legal range for each
	 * one mapped to [0 .. 255].
	 */
	for (i = 0; i < num_entries; ++i) {
	    gs_client_color cc;

	    gs_cspace_indexed_lookup(pcs, i, &cc);
	    for (j = 0; j < num_components; ++j) {
		float v = (cc.paint.values[j] - cmin.paint.values[j])
		    * 255 / (cmax.paint.values[j] - cmin.paint.values[j]);

		*pnext++ = (v <= 0 ? 0 : v >= 255 ? 255 : (byte)v);
	    }
	}
    } else
	memcpy(palette, pip->lookup.table.data, table_size);
    if (gs_color_space_get_index(base_space) ==
	gs_color_space_index_DeviceRGB
	) {
	/* Check for an all-gray palette3. */
	int i;

	for (i = table_size; (i -= 3) >= 0; )
	    if (palette[i] != palette[i + 1] ||
		palette[i] != palette[i + 2]
		)
		break;
	if (i < 0) {
	    /* Change the color space to DeviceGray. */
	    for (i = 0; i < num_entries; ++i)
		palette[i] = palette[i * 3];
	    table_size = num_entries;
	    base_space = gs_cspace_new_DeviceGray(mem);
	}
    }
    stream_write(&es, palette, table_size);
    gs_free_string(mem, palette, table_size, "pdf_color_space(palette)");
    sclose(&es);
    sflush(&s);
    string_used = (uint)stell(&s);
    table = gs_resize_string(mem, table, string_size, string_used,
			     "pdf_color_space(table)");
    /*
     * Since the array is always referenced by name as a resource
     * rather than being written as a value, even for in-line images,
     * always use the full name for the color space.
     *
     * We don't have to worry about the range of the base space:
     * in PDF, unlike PostScript, the values from the lookup table are
     * scaled automatically.
     */
    if ((code = pdf_color_space(pdev, pvalue, NULL, base_space,
				&pdf_color_space_names, false)) < 0 ||
	(code = cos_array_add(pca,
			      cos_c_string_value(&v, 
						 pdf_color_space_names.Indexed
						 /*pcsn->Indexed*/))) < 0 ||
	(code = cos_array_add(pca, pvalue)) < 0 ||
	(code = cos_array_add_int(pca, pip->hival)) < 0 ||
	(code = cos_array_add_no_copy(pca,
				      cos_string_value(&v, table,
						       string_used))) < 0
	)
	return code;
    return 0;
}
コード例 #21
0
ファイル: gscdevn.c プロジェクト: kinsigne/Motif-Scan-Plus
static int
gx_concretize_DeviceN(const gs_client_color * pc, const gs_color_space * pcs,
                      frac * pconc, const gs_imager_state * pis, gx_device *dev)
{
    int code, tcode = 0;
    gs_client_color cc;
    gs_color_space *pacs = (gs_color_space*) (pcs->base_space);
    gs_device_n_map *map = pcs->params.device_n.map;
    bool is_lab;
    int k;
    int num_des_comps = dev->color_info.num_components;
    gsicc_namedcolor_t *named_color;
    const gs_separation_name *names = pcs->params.device_n.names;
    int num_src_comps = pcs->params.device_n.num_components;

#ifdef DEBUG
    /*
     * Verify that the color space and imager state info match.
     */
    if (pcs->id != pis->color_component_map.cspace_id)
        dmprintf(dev->memory, "gx_concretize_DeviceN: color space id mismatch");
#endif

    /*
     * Check if we need to map into the alternate color space.
     * We must preserve tcode for implementing a semi-hack in the interpreter.
     */

    if (pis->color_component_map.use_alt_cspace) {
        /* First see if we have a named color object that we can use to try
           to map from the spot color into device values.  */
        if (pis->icc_manager->device_named != NULL) {
            /* There is a table present.  If we have the colorant name
               then get the device values */
            gx_color_value device_values[GX_DEVICE_COLOR_MAX_COMPONENTS];
            byte *pname;
            uint name_size;
            gsicc_rendering_param_t rendering_params;

            /* Define the rendering intents. */
            rendering_params.black_point_comp = pis->blackptcomp;
            rendering_params.graphics_type_tag = dev->graphics_type_tag;
            rendering_params.override_icc = false;
            rendering_params.preserve_black = gsBKPRESNOTSPECIFIED;
            rendering_params.rendering_intent = pis->renderingintent;
            rendering_params.cmm = gsCMM_DEFAULT;

            /* Allocate and initialize name structure */
            named_color = 
                (gsicc_namedcolor_t*) gs_alloc_bytes(dev->memory,
                    num_src_comps * sizeof(gsicc_namedcolor_t),
                    "gx_remap_concrete_DeviceN");

            for (k = 0; k < num_src_comps; k++) {
                pcs->params.device_n.get_colorname_string(dev->memory, names[k], 
                                                          &pname, &name_size);
                named_color[k].colorant_name = (char*) pname;
                named_color[k].name_size = name_size;
            }
            code = gsicc_transform_named_color(pc->paint.values, named_color,
                                               num_src_comps, device_values, 
                                               pis, dev, NULL, 
                                               &rendering_params);
            gs_free_object(dev->memory, named_color, 
                           "gx_remap_concrete_DeviceN");
            if (code == 0) {
                for (k = 0; k < num_des_comps; k++){
                    pconc[k] = float2frac(((float) device_values[k])/65535.0);
                }
                return(0);
            }
        }
        /* Check the 1-element cache first. */
        if (map->cache_valid) {
            int i;

            for (i = pcs->params.device_n.num_components; --i >= 0;) {
                if (map->tint[i] != pc->paint.values[i])
                    break;
            }
            if (i < 0) {
                int num_out = gs_color_space_num_components(pacs);

                for (i = 0; i < num_out; ++i)
                    pconc[i] = map->conc[i];
                return 0;
            }
        }
        tcode = (*pcs->params.device_n.map->tint_transform)
             (pc->paint.values, &cc.paint.values[0],
             pis, pcs->params.device_n.map->tint_transform_data);
        (*pacs->type->restrict_color)(&cc, pacs);
        if (tcode < 0)
            return tcode;
        /* First check if this was PS based. */
        if (gs_color_space_is_PSCIE(pacs)) {
            /* We may have to rescale data to 0 to 1 range */
            rescale_cie_colors(pacs, &cc);
            /* If we have not yet created the profile do that now */
            if (pacs->icc_equivalent == NULL) {
                gs_colorspace_set_icc_equivalent(pacs, &(is_lab), pis->memory);
            }
            /* Use the ICC equivalent color space */
            pacs = pacs->icc_equivalent;
        }
        if (pacs->cmm_icc_profile_data->data_cs == gsCIELAB ||
            pacs->cmm_icc_profile_data->islab) {
            /* Get the data in a form that is concrete for the CMM */
            cc.paint.values[0] /= 100.0;
            cc.paint.values[1] = (cc.paint.values[1]+128)/255.0;
            cc.paint.values[2] = (cc.paint.values[2]+128)/255.0;
        }
        code = cs_concretize_color(&cc, pacs, pconc, pis, dev);
    }
    else {
        int i;

        for (i = num_src_comps; --i >= 0;)
            pconc[i] = gx_unit_frac(pc->paint.values[i]);
        return 0;
    }
    return (code < 0 || tcode == 0 ? code : tcode);
}
コード例 #22
0
ファイル: gscsepr.c プロジェクト: SynEmira/ruby-ghostscript
static int
gx_concretize_Separation(const gs_client_color *pc, const gs_color_space *pcs,
                         frac *pconc, const gs_imager_state *pis, gx_device *dev)
{
    int code;
    gs_client_color cc;
    gs_color_space *pacs = pcs->base_space;
    bool is_lab;
    int k;
    int num_des_comps = dev->color_info.num_components;

    if (pcs->params.separation.sep_type == SEP_OTHER &&
        pcs->params.separation.use_alt_cspace) {
        gs_device_n_map *map = pcs->params.separation.map;
        /* First see if we have a named color object that we can use to try
           to map from the spot color into device values.  */
        if (pis->icc_manager->device_named != NULL) {
            /* There is a table present.  If we have the colorant name
               then get the device values */
            gx_color_value device_values[GX_DEVICE_COLOR_MAX_COMPONENTS];
            const gs_separation_name name = pcs->params.separation.sep_name;
            byte *pname;
            uint name_size;
            gsicc_rendering_param_t rendering_params;

            /* Define the rendering intents. */
            rendering_params.black_point_comp = BP_ON;
            rendering_params.graphics_type_tag = GS_PATH_TAG;
            rendering_params.rendering_intent = pis->renderingintent;

            pcs->params.separation.get_colorname_string(pis->memory, name,
                                                &pname, &name_size);
            code = gsicc_transform_named_color(pc->paint.values[0], pname,
                            name_size, device_values, pis, dev, NULL,
                            &rendering_params);
            if (code == 0) {
                for (k = 0; k < num_des_comps; k++){
                    pconc[k] = float2frac(((float) device_values[k])/65535.0);
                }
                return(0);
            }
        }
        /* Check the 1-element cache first. */
        if (map->cache_valid && map->tint[0] == pc->paint.values[0]) {
            int i, num_out = gs_color_space_num_components(pacs);

            for (i = 0; i < num_out; ++i)
                pconc[i] = map->conc[i];
            return 0;
        }
        code = (*pcs->params.separation.map->tint_transform)
            (pc->paint.values, &cc.paint.values[0],
             pis, pcs->params.separation.map->tint_transform_data);
        if (code < 0)
            return code;
        /* First check if this was PS based. */
        if (gs_color_space_is_PSCIE(pacs)) {
            /* If we have not yet create the profile do that now */
            if (pacs->icc_equivalent == NULL) {
                gs_colorspace_set_icc_equivalent(pacs, &(is_lab), pis->memory);
            }
            /* Use the ICC equivalent color space */
            pacs = pacs->icc_equivalent;
        }
        if (pacs->cmm_icc_profile_data->data_cs == gsCIELAB) {
            /* Get the data in a form that is concrete for the CMM */
            cc.paint.values[0] /= 100.0;
            cc.paint.values[1] = (cc.paint.values[1]+128)/255.0;
            cc.paint.values[2] = (cc.paint.values[2]+128)/255.0;
        }
        return cs_concretize_color(&cc, pacs, pconc, pis, dev);
    }
    else {
        pconc[0] = gx_unit_frac(pc->paint.values[0]);
    }
    return 0;
}
コード例 #23
0
ファイル: pxgstate.c プロジェクト: ststeiger/ghostsvg
static bool
px_is_currentcolor_pattern(const gs_state *pgs)
{
    return (gs_color_space_num_components(gs_currentcolorspace(pgs)) < 1);
}