/* * 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)); }
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); }
/* * 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; }
/* 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; }
/* * 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; }
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; }
/* 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; }
/* * 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; } }
/* <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); }
/* 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 ); }
/* 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); }
/* 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; }
/* 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(¶ms->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(¶ms->DataSource, s); break; } case t_string: check_read(*pDataSource); data_source_init_string2(¶ms->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, ¶ms->BitsPerCoordinate)) >= 0 && (code = dict_int_param(op, "BitsPerComponent", 1, 16, 0, ¶ms->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; }
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; } }
/* * 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; }
/* * 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; }
/* 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, ¶ms.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, ¶ms, &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)); }
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); }
/* * 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; }
/* * 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; }
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); }
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; }
static bool px_is_currentcolor_pattern(const gs_state *pgs) { return (gs_color_space_num_components(gs_currentcolorspace(pgs)) < 1); }