static int check_for_nontrans_pattern(gs_state *pgs, unsigned char *comp_name) { gx_device * dev = pgs->device; bool is_patt_clist = (strcmp("pattern-clist",dev->dname) == 0); bool is_patt_acum = (strcmp("pattern accumulator",dev->dname) == 0); /* Check if we are collecting data for a pattern that has no transparency. In that case, we need to ignore the state changes */ if (is_patt_clist || is_patt_acum) { if (is_patt_clist) { gx_device_clist_writer *clwdev = (gx_device_clist_writer*) dev; const gs_pattern1_instance_t *pinst = clwdev->pinst; if (!(pinst->templat.uses_transparency)) { if_debug1('v', "[v]%s NOT sending in pattern\n",comp_name); return(1); } } if (is_patt_acum) { gx_device_pattern_accum *padev = (gx_device_pattern_accum*) dev; const gs_pattern1_instance_t *pinst = padev->instance; if (!(pinst->templat.uses_transparency)) { if_debug1('v', "[v]%s NOT sending in pattern\n",comp_name); return(1); } } } return(0); }
/* Render a CIEBasedA color. */ int gx_concretize_CIEA(const gs_client_color * pc, const gs_color_space * pcs_in, frac * pconc, const gs_imager_state * pis, gx_device *dev) { int code; gs_color_space *pcs_icc; gs_client_color scale_pc; gs_color_space *pcs = (gs_color_space *) pcs_in; if_debug1('c', "[c]concretize CIEA %g\n", pc->paint.values[0]); /* If we are comming in here then we have not completed the conversion of the CIE A space to an ICC type. We will finish that process now. */ if (pcs->icc_equivalent == NULL) { code = gx_ciea_to_icc(&pcs_icc, pcs, pis->memory->stable_memory); } else { /* Once the ICC color space is set, we should be doing all the remaps through the ICC equivalent */ pcs_icc = pcs->icc_equivalent; } /* Rescale the input based upon the input range since profile is created to remap this range from 0 to 1 */ if (check_range(&(pcs->params.a->RangeA), 1)) { return((pcs_icc->type->concretize_color)(pc, pcs_icc, pconc, pis, dev)); } /* Do the rescale from 0 to 1 */ rescale_input_color(&(pcs->params.a->RangeA), 1, pc, &scale_pc); /* Now the icc remap */ return((pcs_icc->type->concretize_color)(&scale_pc, pcs_icc, pconc, pis, dev)); }
int gx_remap_CIEA(const gs_client_color * pc, const gs_color_space * pcs_in, gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev, gs_color_select_t select) { int code; gs_color_space *pcs_icc; gs_client_color scale_pc; gs_color_space *pcs = (gs_color_space *) pcs_in; if_debug1('c', "[c]remap CIEA [%g]\n",pc->paint.values[0]); /* If we are coming in here then we may have not completed the conversion of the CIE A space to an ICC type. We will finish that process now. */ if (pcs->icc_equivalent == NULL) { code = gx_ciea_to_icc(&pcs_icc, pcs, pis->memory->stable_memory); } else { /* Once the ICC color space is set, we should be doing all the remaps through the ICC equivalent */ pcs_icc = pcs->icc_equivalent; } /* Rescale the input based upon the input range since profile is created to remap this range from 0 to 1 */ if (check_range(&(pcs->params.a->RangeA), 1)) { return((pcs_icc->type->remap_color)(pc,pcs_icc,pdc,pis,dev,select)); } /* Do the rescale from 0 to 1 */ rescale_input_color(&(pcs->params.a->RangeA), 1, pc, &scale_pc); /* Now the icc remap */ code = (pcs_icc->type->remap_color)(&scale_pc,pcs_icc,pdc,pis,dev,select); /* Save unscaled data for high level device (e.g. pdfwrite) */ pdc->ccolor.paint.values[0] = pc->paint.values[0]; pdc->ccolor_valid = true; return(code); }
gx_color_index eprn_map_rgb_color_for_RGB(gx_device *device, const gx_color_value cv[]) { gx_color_value red = cv[0], green = cv[1], blue = cv[2]; static const gx_color_value half = gx_max_color_value/2; gx_color_index value = 0; const eprn_Device *dev = (eprn_Device *)device; #ifdef EPRN_TRACE if_debug3(EPRN_TRACE_CHAR, "! eprn_map_rgb_color_for_RGB() called for RGB = (%hu, %hu, %hu),\n", red, green, blue); #endif assert(dev->eprn.colour_model == eprn_DeviceRGB); if (red > half) value |= RED_BIT; if (green > half) value |= GREEN_BIT; if (blue > half) value |= BLUE_BIT; #ifdef EPRN_TRACE if_debug1(EPRN_TRACE_CHAR, " returning 0x%lX.\n", (unsigned long)value); #endif return value; }
gx_color_index eprn_map_rgb_color_for_CMY_or_K(gx_device *device, const gx_color_value cv[]) { gx_color_value red = cv[0], green = cv[1], blue = cv[2]; static const gx_color_value half = gx_max_color_value/2; gx_color_index value = (CYAN_BIT | MAGENTA_BIT | YELLOW_BIT); const eprn_Device *dev = (eprn_Device *)device; #ifdef EPRN_TRACE if_debug3(EPRN_TRACE_CHAR, "! eprn_map_rgb_color_for_CMY_or_K() called for RGB = (%hu, %hu, %hu),\n", red, green, blue); #endif assert(dev->eprn.colour_model == eprn_DeviceGray && red == green && green == blue && (blue == 0 || blue == gx_max_color_value) || dev->eprn.colour_model == eprn_DeviceCMY || dev->eprn.colour_model == eprn_DeviceCMY_plus_K); /* Map to CMY */ if (red > half) value &= ~CYAN_BIT; if (green > half) value &= ~MAGENTA_BIT; if (blue > half) value &= ~YELLOW_BIT; /* Remap composite black to true black if available */ if (dev->eprn.colour_model != eprn_DeviceCMY && value == (CYAN_BIT | MAGENTA_BIT | YELLOW_BIT)) value = BLACK_BIT; #ifdef EPRN_TRACE if_debug1(EPRN_TRACE_CHAR, " returning 0x%lX.\n", (unsigned long)value); #endif return value; }
gx_color_index eprn_map_rgb_color_for_RGB_flex(gx_device *device, const gx_color_value cv[]) { gx_color_value red = cv[0], green = cv[1], blue = cv[2]; gx_color_index value = 0; gx_color_value step; unsigned int level; const eprn_Eprn *eprn = &((eprn_Device *)device)->eprn; #ifdef EPRN_TRACE if_debug3(EPRN_TRACE_CHAR, "! eprn_map_rgb_color_for_RGB_flex() called for RGB = (%hu, %hu, %hu),\n", red, green, blue); #endif /* See the discussion in eprn_map_cmyk_color_flex() below. */ step = gx_max_color_value/eprn->non_black_levels; /* The order has to be BGR from left to right */ level = blue/step; if (level >= eprn->non_black_levels) level = eprn->non_black_levels - 1; value = level << eprn->bits_per_colorant; level = green/step; if (level >= eprn->non_black_levels) level = eprn->non_black_levels - 1; value = (value | level) << eprn->bits_per_colorant; level = red/step; if (level >= eprn->non_black_levels) level = eprn->non_black_levels - 1; value = (value | level) << eprn->bits_per_colorant; #ifdef EPRN_TRACE if_debug1(EPRN_TRACE_CHAR, " returning 0x%lX.\n", (unsigned long)value); #endif return value; }
static int c_alpha_write(const gs_composite_t * pcte, byte * data, uint * psize) { uint size = *psize; uint used; if_debug1('v', "[v]c_alpha_write(%d)\n", pacte->params.op); if (pacte->params.op == composite_Dissolve) { used = 1 + sizeof(pacte->params.delta); if (size < used) { *psize = used; return_error(gs_error_rangecheck); } memcpy(data + 1, &pacte->params.delta, sizeof(pacte->params.delta)); } else { used = 1; if (size < used) { *psize = used; return_error(gs_error_rangecheck); } } *data = (byte) pacte->params.op; *psize = used; return 0; }
int eprn_output_page(gx_device *dev, int num_copies, int flush) { eprn_Eprn *eprn = &((eprn_Device *)dev)->eprn; int rc; #ifdef EPRN_TRACE clock_t start_time = clock(); if_debug0(EPRN_TRACE_CHAR, "! eprn_output_page()...\n"); #endif /* Initialize eprn_get_planes() data */ eprn->next_y = 0; if (eprn->intensity_rendering == eprn_IR_FloydSteinberg) { /* Fetch the first line and store it in 'next_scan_line'. */ if (eprn_fetch_scan_line((eprn_Device *)dev, &eprn->next_scan_line) == 0) eprn->next_y++; } /* Ship out */ rc = gdev_prn_output_page(dev, num_copies, flush); /* CUPS page accounting message. The CUPS documentation is not perfectly clear on whether one should generate this message before printing a page or after printing has been successful. The rasterto* filters generate it before sending the page, but as the scheduler uses these messages for accounting, this seems unfair. */ if (rc == 0 && eprn->CUPS_accounting) eprintf2("PAGE: %ld %d\n", dev->ShowpageCount, num_copies); /* The arguments are the number of the page, starting at 1, and the number of copies of that page. */ #ifndef EPRN_NO_PAGECOUNTFILE /* On success, record the number of pages printed */ if (rc == 0 && eprn->pagecount_file != NULL) { assert(num_copies > 0); /* because of signed/unsigned */ if (pcf_inccount(eprn->pagecount_file, num_copies) != 0) { /* pcf_inccount() has issued an error message. */ eprintf( " No further attempts will be made to access the page count file.\n"); gs_free(dev->memory->non_gc_memory, eprn->pagecount_file, strlen(eprn->pagecount_file) + 1, sizeof(char), "eprn_output_page"); eprn->pagecount_file = NULL; } } #endif /* !EPRN_NO_PAGECOUNTFILE */ /* If soft tumble has been demanded, ensure the get_initial_matrix procedure is consulted for the next page */ if (eprn->soft_tumble) eprn_forget_defaultmatrix(dev->memory->non_gc_memory); #ifdef EPRN_TRACE if_debug1(EPRN_TRACE_CHAR, "! eprn_output_page() terminates after %f s.\n", ((float)(clock() - start_time))/CLOCKS_PER_SEC); #endif return rc; }
/* * Copy from tmp to dst, taking into account PixelOut vs. PixelIn sizes * We do the conversion from PixelIn to PixelOut here (if needed) * since if the Y is scaled down we will convert less often. * This is simpler because we can treat all columns identically * without regard to the number of samples per pixel. */ static void idownscale_y(void /*PixelOut */ *dst, const void /* PixelIn */ *tmp, stream_ISpecialDownScale_state *const ss) { int kn = ss->params.WidthOut * ss->params.spp_interp; int kc; float scale = (float) ss->params.MaxValueOut/255.0; if_debug0('W', "[W]idownscale_y: "); if (ss->sizeofPixelOut == 1) { if (ss->sizeofPixelIn == 1) { const byte *pp = (byte *)tmp; for ( kc = 0; kc < kn; ++kc, pp++ ) { if_debug1('W', " %d", *pp); ((byte *)dst)[kc] = *pp; } } else { /* sizeofPixelIn == 2 */ const bits16 *pp = (bits16 *)tmp; for ( kc = 0; kc < kn; ++kc, pp++ ) { if_debug1('W', " %d", *pp); ((byte *)dst)[kc] = frac2byte(*pp); } } } else { /* sizeofPixelOut == 2 */ if (ss->sizeofPixelIn == 1) { const byte *pp = (byte *)tmp; for ( kc = 0; kc < kn; ++kc, pp++ ) { if_debug1('W', " %d", *pp); ((bits16 *)dst)[kc] = (bits16)((*pp)*scale); } } else { /* sizeofPixelIn == 2 */ const bits16 *pp = (bits16 *)tmp; for ( kc = 0; kc < kn; ++kc, pp++ ) { if_debug1('W', " %d", *pp); ((bits16 *)dst)[kc] = *pp; } } } if_debug0('W', "n"); }
/* Report an error by storing it in the stream's error_string. */ int filter_report_error(stream_state * st, const char *str) { if_debug1('s', "[s]stream error: %s\n", str); strncpy(st->error_string, str, STREAM_MAX_ERROR_STRING); /* Ensure null termination. */ st->error_string[STREAM_MAX_ERROR_STRING] = 0; return 0; }
/* time to actually transfer the data. */ int gp_read_macresource(byte *buf, const char *fname, const uint type, const ushort id) { Handle resource = NULL; SInt32 size = 0; FSSpec spec; SInt16 fileref; OSErr result; /* open file */ result = convertPathToSpec(fname, strlen(fname), &spec); if (result != noErr) goto fin; fileref = FSpOpenResFile(&spec, fsRdPerm); if (fileref == -1) goto fin; if_debug1('s', "[s] loading resource from fileref %d\n", fileref); /* load resource */ resource = Get1Resource((ResType)type, (SInt16)id); if (resource == NULL) goto fin; /* allocate res */ /* GetResourceSize() is probably good enough */ //size = GetResourceSizeOnDisk(resource); size = GetMaxResourceSize(resource); if_debug1('s', "[s] resource size on disk is %d bytes\n", size); /* if we don't have a buffer to fill, just return */ if (buf == NULL) goto fin; /* otherwise, copy resource into res from handle */ HLock(resource); memcpy(buf, *resource, size); HUnlock(resource); fin: /* free resource, if necessary */ ReleaseResource(resource); CloseResFile(fileref); return (size); }
/* Page management */ static int svg_beginpage(gx_device_vector *vdev) { gx_device_svg *svg = (gx_device_svg *)vdev; svg_write_header(svg); if_debug1('_', "svg_beginpage (page count %d)\n", svg->page_count); return 0; }
void pcl_define_escape_command(int /*char */ chr, const pcl_command_definition_t * pcmd, pcl_parser_state_t * pcl_parser_state) { #ifdef DEBUG if (chr < min_escape_2char || chr > max_escape_2char) if_debug1('I', "Invalid escape character %c\n", chr); else if ( #endif pcl_register_command(&pcl_parser_state-> definitions->pcl_escape_command_indices [chr - min_escape_2char], pcmd, pcl_parser_state) #ifdef DEBUG ) if_debug1('I', "Redefining ESC %c\n", chr) #endif ; }
/* Define a command or list of commands. */ void pcl_define_control_command(int /*char */ chr, const pcl_command_definition_t * pcmd, pcl_parser_state_t * pcl_parser_state) { #ifdef DEBUG if (chr < 0 || chr >= countof(pcl_parser_state->definitions->pcl_control_command_indices)) if_debug1('I', "Invalid control character %d\n", chr); else if ( #endif pcl_register_command(&pcl_parser_state-> definitions->pcl_control_command_indices [chr], pcmd, pcl_parser_state) #ifdef DEBUG ) if_debug1('I', "Redefining control character %d\n", chr); #endif ; }
static int svg_print_path_type(gx_device_svg *svg, gx_path_type_t type) { const char *path_type_names[] = {"winding number", "fill", "stroke", "fill and stroke", "clip"}; if (type <= 4) if_debug2('_', "type %d (%s)", type, path_type_names[type]); else if_debug1('_', "type %d", type); return 0; }
/* Imager state */ static int svg_setlinewidth(gx_device_vector *vdev, floatp width) { gx_device_svg *svg = (gx_device_svg *)vdev; if_debug1('_', "svg_setlinewidth(%lf)\n", width); svg->linewidth = width; svg->dirty++; return 0; }
int gs_discard_transparency_layer(gs_state *pgs) { /****** NYI, DUMMY ******/ gs_transparency_state_t *pts = pgs->transparency_stack; if_debug1('v', "[v](0x%lx)gs_discard_transparency_layer\n", (ulong)pgs); if (!pts) return_error(gs_error_rangecheck); pop_transparency_stack(pgs, "gs_discard_transparency_layer"); return 0; }
/* <cid9font> <cid> .type9mapcid <charstring> <font_index> */ int ztype9mapcid(i_ctx_t *i_ctx_p) { os_ptr op = osp; gs_font *pfont; gs_font_cid0 *pfcid; int code = font_param(op - 1, &pfont); gs_glyph_data_t gdata; int fidx; if (code < 0) return code; if (pfont->FontType != ft_CID_encrypted) return_error(e_invalidfont); check_type(*op, t_integer); pfcid = (gs_font_cid0 *)pfont; gdata.memory = pfont->memory; code = pfcid->cidata.glyph_data((gs_font_base *)pfcid, (gs_glyph)(gs_min_cid_glyph + op->value.intval), &gdata, &fidx); /* return code; original error-sensitive & fragile code */ if (code < 0) { /* failed to load glyph data, put CID 0 */ int default_fallback_CID = 0 ; if_debug2('J', "[J]ztype9cidmap() use CID %d instead of glyph-missing CID %d\n", default_fallback_CID, op->value.intval); op->value.intval = default_fallback_CID; /* reload glyph for default_fallback_CID */ code = pfcid->cidata.glyph_data((gs_font_base *)pfcid, (gs_glyph)(gs_min_cid_glyph + default_fallback_CID), &gdata, &fidx); if (code < 0) { if_debug1('J', "[J]ztype9cidmap() could not load default glyph (CID %d)\n", op->value.intval); return_error(e_invalidfont); } } /****** FOLLOWING IS NOT GENERAL W.R.T. ALLOCATION OF GLYPH DATA ******/ make_const_string(op - 1, a_readonly | imemory_space((gs_ref_memory_t *)pfont->memory), gdata.bits.size, gdata.bits.data); make_int(op, fidx); return code; }
static int svg_setlinecap(gx_device_vector *vdev, gs_line_cap cap) { gx_device_svg *svg = (gx_device_svg *)vdev; const char *linecap_names[] = {"butt", "round", "square", "triangle", "unknown"}; if (cap < 0 || cap > gs_cap_unknown) return gs_throw_code(gs_error_rangecheck); if_debug1('_', "svg_setlinecap(%s)\n", linecap_names[cap]); svg->linecap = cap; svg->dirty++; return 0; }
int eprn_map_color_rgb(gx_device *device, gx_color_index color, gx_color_value rgb[]) { #ifdef EPRN_TRACE if_debug1(EPRN_TRACE_CHAR, "! eprn_map_color_rgb() called for 0x%lX.\n", (unsigned long)color); #endif /* Just to be safe we return defined values (white) */ if (((eprn_Device *)device)->eprn.colour_model == eprn_DeviceRGB) rgb[0] = rgb[1] = rgb[2] = gx_max_color_value; else rgb[0] = rgb[1] = rgb[2] = 0; return -1; }
static int svg_setlinejoin(gx_device_vector *vdev, gs_line_join join) { gx_device_svg *svg = (gx_device_svg *)vdev; const char *linejoin_names[] = {"miter", "round", "bevel", "none", "triangle", "unknown"}; if (join < 0 || join > gs_join_unknown) return gs_throw_code(gs_error_rangecheck); if_debug1('_', "svg_setlinejoin(%s)\n", linejoin_names[join]); svg->linejoin = join; svg->dirty++; return 0; }
static int c_alpha_read(gs_composite_t ** ppcte, const byte * data, uint size, gs_memory_t * mem) { gs_composite_alpha_params_t params; int code, nbytes = 1; if (size < 1 || *data > composite_op_last) return_error(gs_error_rangecheck); params.op = *data; if_debug1('v', "[v]c_alpha_read(%d)\n", params.op); if (params.op == composite_Dissolve) { if (size < 1 + sizeof(params.delta)) return_error(gs_error_rangecheck); memcpy(¶ms.delta, data + 1, sizeof(params.delta)); nbytes += sizeof(params.delta); } code = gs_create_composite_alpha(ppcte, ¶ms, mem); return code < 0 ? code : nbytes; }
/* Clear the relocation for a ref object. */ static void refs_clear_reloc(obj_header_t *hdr, uint size) { ref_packed *rp = (ref_packed *) (hdr + 1); ref_packed *end = (ref_packed *) ((byte *) rp + size); while (rp < end) { if (r_is_packed(rp)) rp++; else { /* Full-size ref. Store the relocation here if possible. */ ref *const pref = (ref *)rp; if (!ref_type_uses_size_or_null(r_type(pref))) { if_debug1('8', " [8]clearing reloc at 0x%lx\n", (ulong) rp); r_set_size(pref, 0); } rp += packed_per_ref; } } }
gx_color_index eprn_map_rgb_color_for_RGB_max(gx_device *device, const gx_color_value cv[]) { gx_color_value red = cv[0], green = cv[1], blue = cv[2]; gx_color_index value; #ifdef EPRN_TRACE if_debug3(EPRN_TRACE_CHAR, "! eprn_map_rgb_color_for_RGB_max() called for RGB = (%hu, %hu, %hu),\n", red, green, blue); #endif value = dominant_8bits(red) << 8; value |= dominant_8bits(green) << 16; value |= dominant_8bits(blue) << 24; #ifdef EPRN_TRACE if_debug1(EPRN_TRACE_CHAR, " returning 0x%08lX.\n", (unsigned long)value); #endif return value; }
gx_color_index eprn_map_cmyk_color_max(gx_device *device, const gx_color_value cv[]) { gx_color_value cyan = cv[0], magenta = cv[1], yellow = cv[2], black = cv[3]; gx_color_index value; #ifdef EPRN_TRACE if_debug4(EPRN_TRACE_CHAR, "! eprn_map_cmyk_color_max() called for CMYK = (%hu, %hu, %hu, %hu),\n", cyan, magenta, yellow, black); #endif value = dominant_8bits(black); value |= dominant_8bits(cyan) << 8; value |= dominant_8bits(magenta) << 16; value |= dominant_8bits(yellow) << 24; #ifdef EPRN_TRACE if_debug1(EPRN_TRACE_CHAR, " returning 0x%08lX.\n", (unsigned long)value); #endif return value; }
gx_color_index eprn_map_cmyk_color(gx_device *device, const gx_color_value cv[]) { gx_color_value cyan = cv[0], magenta = cv[1], yellow = cv[2], black = cv[3]; gx_color_index value = 0; static const gx_color_value threshold = gx_max_color_value/2; #ifdef EPRN_TRACE if_debug4(EPRN_TRACE_CHAR, "! eprn_map_cmyk_color() called for CMYK = (%hu, %hu, %hu, %hu),\n", cyan, magenta, yellow, black); #endif if (cyan > threshold) value |= CYAN_BIT; if (magenta > threshold) value |= MAGENTA_BIT; if (yellow > threshold) value |= YELLOW_BIT; if (black > threshold) value |= BLACK_BIT; #ifdef EPRN_TRACE if_debug1(EPRN_TRACE_CHAR, " returning 0x%lX.\n", (unsigned long)value); #endif return value; }
int gs_end_transparency_mask(gs_state *pgs, gs_transparency_channel_selector_t csel) { gs_pdf14trans_params_t params = { 0 }; gs_pdf14trans_params_t params_color = { 0 }; gs_imager_state * pis = (gs_imager_state *)pgs; int code; if (check_for_nontrans_pattern(pgs, (unsigned char *)"gs_end_transparency_mask")) { return(0); } /* If we have done a q then set a flag to watch for any Qs */ /* if (pis->trans_flags.xstate_pending) pis->trans_flags.xstate_change = true; */ /* This should not depend upon if we have encountered a q operation. We could be setting a softmask, before there is any q operation. Unlikely but it could happen. Then if we encouter a q operation (and this flag is true) we will need to push the mask graphic state (PDF14_PUSH_TRANS_STATE). */ pis->trans_flags.xstate_change = true; if_debug1('v', "[v]xstate_changed set true, gstate level is %d\n", pgs->level); if_debug2('v', "[v](0x%lx)gs_end_transparency_mask(%d)\n", (ulong)pgs, (int)csel); params.pdf14_op = PDF14_END_TRANS_MASK; /* Other parameters not used */ params.csel = csel; /* If this is the outer end then return us to our normal defaults */ if_debug0('v', "[v]popping soft mask color sending\n"); params_color.pdf14_op = PDF14_POP_SMASK_COLOR; code = gs_state_update_pdf14trans(pgs, ¶ms_color); if (code < 0) return(code); return gs_state_update_pdf14trans(pgs, ¶ms); }
/* Used for when we have to mash entire transform to CIEXYZ */ int gx_psconcretize_CIEA(const gs_client_color * pc, const gs_color_space * pcs, frac * pconc, const gs_imager_state * pis) { const gs_cie_a *pcie = pcs->params.a; cie_cached_value a = float2cie_cached(pc->paint.values[0]); cie_cached_vector3 vlmn; int code; if_debug1('c', "[c]concretize CIEA %g\n", pc->paint.values[0]); code = gx_cie_check_rendering_inline(pcs, pconc, pis); if (code < 0) return code; if (code == 1) return 0; /* Apply DecodeA and MatrixA. */ if (!pis->cie_joint_caches->skipDecodeABC) vlmn = *LOOKUP_ENTRY(a, &pcie->caches.DecodeA); else vlmn.u = vlmn.v = vlmn.w = a; GX_CIE_REMAP_FINISH(vlmn, pconc, pis, pcs); return 0; }
gx_color_index eprn_map_cmyk_color_flex(gx_device *device, const gx_color_value cv[]) { gx_color_value cyan = cv[0], magenta = cv[1], yellow = cv[2], black = cv[3]; gx_color_index value = 0; gx_color_value step; unsigned int level; const eprn_Eprn *eprn = &((eprn_Device *)device)->eprn; #ifdef EPRN_TRACE if_debug4(EPRN_TRACE_CHAR, "! eprn_map_cmyk_color_flex() called for CMYK = (%hu, %hu, %hu, %hu),\n", cyan, magenta, yellow, black); #endif /* I can think of three linear methods to extract discrete values from a continuous intensity in the range [0, 1]: (a) multiply by the number of levels minus 1 and truncate, (b) multiply by the number of levels minus 1 and round, and (c) multiply by the number of levels and truncate, except for an intensity of 1 in which case one returns the number of levels minus 1. For intensity values which can be represented exactly, i.e., intensity = i/(levels-1) for some non-negative i < levels, these three methods are identical. (a) is however inappropriate here because for less than 32 levels ghostscript already provides intensity values which have been adjusted to a representable level. A rounding error could now result in a level which is too small by one. I prefer (c) because it gives equal shares to all levels. I'm using integer arithmetic here although floating point numbers would be more accurate. This routine may, however, be called quite frequently, and the loss in accuray is acceptable as long as the values determined for 'step' are large compared to the number of levels. If you consider "large" as meaning "10 times as large", the critical boundary is at about 81 levels. The highest number of intensity levels at present supported by HP DeskJets is apparently 4. A more accurate implementation would determine 'step' as a floating point value, divide the intensity by it, and take the floor (entier) of the result as the component intensity. */ /* The order has to be (YMC)(K) from left to right */ if (eprn->colour_model != eprn_DeviceGray) { step = gx_max_color_value/eprn->non_black_levels; level = yellow/step; if (level >= eprn->non_black_levels) level = eprn->non_black_levels - 1; value = level << eprn->bits_per_colorant; level = magenta/step; if (level >= eprn->non_black_levels) level = eprn->non_black_levels - 1; value = (value | level) << eprn->bits_per_colorant; level = cyan/step; if (level >= eprn->non_black_levels) level = eprn->non_black_levels - 1; value = (value | level) << eprn->bits_per_colorant; } if (eprn->colour_model != eprn_DeviceCMY) { step = gx_max_color_value/eprn->black_levels; level = black/step; if (level >= eprn->black_levels) level = eprn->black_levels - 1; value |= level; } #ifdef EPRN_TRACE if_debug1(EPRN_TRACE_CHAR, " returning 0x%lX.\n", (unsigned long)value); #endif return value; }
/* <source> <dict> /JPXDecode <file> */ static int z_jpx_decode(i_ctx_t * i_ctx_p) { os_ptr op = osp; ref *sop = NULL; ref *csname = NULL; stream_jpxd_state state; /* it's our responsibility to call set_defaults() */ state.memory = imemory->non_gc_memory; if (s_jpxd_template.set_defaults) (*s_jpxd_template.set_defaults)((stream_state *)&state); state.jpx_memory = imemory->non_gc_memory; if (r_has_type(op, t_dictionary)) { check_dict_read(*op); if ( dict_find_string(op, "Alpha", &sop) > 0) { check_type(*sop, t_boolean); if (sop->value.boolval) state.alpha = true; } if ( dict_find_string(op, "ColorSpace", &sop) > 0) { /* parse the value */ if (r_is_array(sop)) { /* assume it's the first array element */ csname = sop->value.refs; } else if (r_has_type(sop,t_name)) { /* use the name directly */ csname = sop; } else { dprintf("warning: JPX ColorSpace value is an unhandled type!\n"); } if (csname != NULL) { ref sref; /* get a reference to the name's string value */ name_string_ref(imemory, csname, &sref); /* request raw index values if the colorspace is /Indexed */ if (!ISTRCMP(&sref, "Indexed")) state.colorspace = gs_jpx_cs_indexed; /* tell the filter what output we want for other spaces */ else if (!ISTRCMP(&sref, "DeviceGray")) state.colorspace = gs_jpx_cs_gray; else if (!ISTRCMP(&sref, "DeviceRGB")) state.colorspace = gs_jpx_cs_rgb; else if (!ISTRCMP(&sref, "DeviceCMYK")) state.colorspace = gs_jpx_cs_cmyk; else if (!ISTRCMP(&sref, "ICCBased")) { /* The second array element should be the profile's stream dict */ ref *csdict = sop->value.refs + 1; ref *nref; ref altname; if (r_is_array(sop) && (r_size(sop) > 1) && r_has_type(csdict, t_dictionary)) { check_dict_read(*csdict); /* try to look up the alternate space */ if (dict_find_string(csdict, "Alternate", &nref) > 0) { name_string_ref(imemory, csname, &altname); if (!ISTRCMP(&altname, "DeviceGray")) state.colorspace = gs_jpx_cs_gray; else if (!ISTRCMP(&altname, "DeviceRGB")) state.colorspace = gs_jpx_cs_rgb; else if (!ISTRCMP(&altname, "DeviceCMYK")) state.colorspace = gs_jpx_cs_cmyk; } /* else guess based on the number of components */ if (state.colorspace == gs_jpx_cs_unset && dict_find_string(csdict, "N", &nref) > 0) { if_debug1('w', "[w] JPX image has an external %d" " channel colorspace\n", nref->value.intval); switch (nref->value.intval) { case 1: state.colorspace = gs_jpx_cs_gray; break; case 3: state.colorspace = gs_jpx_cs_rgb; break; case 4: state.colorspace = gs_jpx_cs_cmyk; break; } } } } } else { if_debug0('w', "[w] Couldn't read JPX ColorSpace key!\n"); } } } /* we pass npop=0, since we've no arguments left to consume */ /* we pass 0 instead of the usual rspace(sop) which will allocate storage for filter state from the same memory pool as the stream it's coding. this causes no trouble because we maintain no pointers */ return filter_read(i_ctx_p, 0, &s_jpxd_template, (stream_state *) & state, 0); }