1*7dd7cddfSDavid du Colombier /* Copyright (C) 1992, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved. 2*7dd7cddfSDavid du Colombier 3*7dd7cddfSDavid du Colombier This file is part of Aladdin Ghostscript. 4*7dd7cddfSDavid du Colombier 5*7dd7cddfSDavid du Colombier Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author 6*7dd7cddfSDavid du Colombier or distributor accepts any responsibility for the consequences of using it, 7*7dd7cddfSDavid du Colombier or for whether it serves any particular purpose or works at all, unless he 8*7dd7cddfSDavid du Colombier or she says so in writing. Refer to the Aladdin Ghostscript Free Public 9*7dd7cddfSDavid du Colombier License (the "License") for full details. 10*7dd7cddfSDavid du Colombier 11*7dd7cddfSDavid du Colombier Every copy of Aladdin Ghostscript must include a copy of the License, 12*7dd7cddfSDavid du Colombier normally in a plain ASCII text file named PUBLIC. The License grants you 13*7dd7cddfSDavid du Colombier the right to copy, modify and redistribute Aladdin Ghostscript, but only 14*7dd7cddfSDavid du Colombier under certain conditions described in the License. Among other things, the 15*7dd7cddfSDavid du Colombier License requires that the copyright notice and this notice be preserved on 16*7dd7cddfSDavid du Colombier all copies. 17*7dd7cddfSDavid du Colombier */ 18*7dd7cddfSDavid du Colombier 19*7dd7cddfSDavid du Colombier /*$Id: zht2.c,v 1.1 2000/03/09 08:40:45 lpd Exp $ */ 20*7dd7cddfSDavid du Colombier /* Level 2 sethalftone operator */ 21*7dd7cddfSDavid du Colombier #include "ghost.h" 22*7dd7cddfSDavid du Colombier #include "oper.h" 23*7dd7cddfSDavid du Colombier #include "gsstruct.h" 24*7dd7cddfSDavid du Colombier #include "gxdevice.h" /* for gzht.h */ 25*7dd7cddfSDavid du Colombier #include "gzht.h" 26*7dd7cddfSDavid du Colombier #include "estack.h" 27*7dd7cddfSDavid du Colombier #include "ialloc.h" 28*7dd7cddfSDavid du Colombier #include "iddict.h" 29*7dd7cddfSDavid du Colombier #include "idparam.h" 30*7dd7cddfSDavid du Colombier #include "igstate.h" 31*7dd7cddfSDavid du Colombier #include "icolor.h" 32*7dd7cddfSDavid du Colombier #include "iht.h" 33*7dd7cddfSDavid du Colombier #include "store.h" 34*7dd7cddfSDavid du Colombier 35*7dd7cddfSDavid du Colombier /* Forward references */ 36*7dd7cddfSDavid du Colombier private int dict_spot_params(P4(const ref *, gs_spot_halftone *, 37*7dd7cddfSDavid du Colombier ref *, ref *)); 38*7dd7cddfSDavid du Colombier private int dict_spot_results(P3(i_ctx_t *, ref *, const gs_spot_halftone *)); 39*7dd7cddfSDavid du Colombier private int dict_threshold_params(P3(const ref *, gs_threshold_halftone *, 40*7dd7cddfSDavid du Colombier ref *)); 41*7dd7cddfSDavid du Colombier private int dict_threshold2_params(P4(const ref *, gs_threshold2_halftone *, 42*7dd7cddfSDavid du Colombier ref *, gs_memory_t *)); 43*7dd7cddfSDavid du Colombier 44*7dd7cddfSDavid du Colombier /* Dummy spot function */ 45*7dd7cddfSDavid du Colombier private float 46*7dd7cddfSDavid du Colombier spot1_dummy(floatp x, floatp y) 47*7dd7cddfSDavid du Colombier { 48*7dd7cddfSDavid du Colombier return (x + y) / 2; 49*7dd7cddfSDavid du Colombier } 50*7dd7cddfSDavid du Colombier 51*7dd7cddfSDavid du Colombier /* <dict> <dict5> .sethalftone5 - */ 52*7dd7cddfSDavid du Colombier private int sethalftone_finish(P1(i_ctx_t *)); 53*7dd7cddfSDavid du Colombier private int sethalftone_cleanup(P1(i_ctx_t *)); 54*7dd7cddfSDavid du Colombier private int 55*7dd7cddfSDavid du Colombier zsethalftone5(i_ctx_t *i_ctx_p) 56*7dd7cddfSDavid du Colombier { 57*7dd7cddfSDavid du Colombier os_ptr op = osp; 58*7dd7cddfSDavid du Colombier uint count; 59*7dd7cddfSDavid du Colombier gs_halftone_component *phtc; 60*7dd7cddfSDavid du Colombier gs_halftone_component *pc; 61*7dd7cddfSDavid du Colombier int code = 0; 62*7dd7cddfSDavid du Colombier int i, j; 63*7dd7cddfSDavid du Colombier gs_halftone *pht; 64*7dd7cddfSDavid du Colombier gx_device_halftone *pdht; 65*7dd7cddfSDavid du Colombier static const char *const color_names[] = { 66*7dd7cddfSDavid du Colombier gs_ht_separation_name_strings 67*7dd7cddfSDavid du Colombier }; 68*7dd7cddfSDavid du Colombier ref sprocs[countof(color_names)]; 69*7dd7cddfSDavid du Colombier ref tprocs[countof(color_names)]; 70*7dd7cddfSDavid du Colombier gs_memory_t *mem; 71*7dd7cddfSDavid du Colombier uint edepth = ref_stack_count(&e_stack); 72*7dd7cddfSDavid du Colombier int npop = 2; 73*7dd7cddfSDavid du Colombier 74*7dd7cddfSDavid du Colombier check_type(*op, t_dictionary); 75*7dd7cddfSDavid du Colombier check_dict_read(*op); 76*7dd7cddfSDavid du Colombier check_type(op[-1], t_dictionary); 77*7dd7cddfSDavid du Colombier check_dict_read(op[-1]); 78*7dd7cddfSDavid du Colombier count = 0; 79*7dd7cddfSDavid du Colombier for (i = 0; i < countof(color_names); i++) { 80*7dd7cddfSDavid du Colombier ref *pvalue; 81*7dd7cddfSDavid du Colombier 82*7dd7cddfSDavid du Colombier if (dict_find_string(op, color_names[i], &pvalue) > 0) 83*7dd7cddfSDavid du Colombier count++; 84*7dd7cddfSDavid du Colombier else if (i == gs_ht_separation_Default) 85*7dd7cddfSDavid du Colombier return_error(e_typecheck); 86*7dd7cddfSDavid du Colombier } 87*7dd7cddfSDavid du Colombier mem = (gs_memory_t *) idmemory->spaces_indexed[r_space_index(op - 1)]; 88*7dd7cddfSDavid du Colombier check_estack(5); /* for sampling Type 1 screens */ 89*7dd7cddfSDavid du Colombier refset_null(sprocs, countof(sprocs)); 90*7dd7cddfSDavid du Colombier refset_null(tprocs, countof(tprocs)); 91*7dd7cddfSDavid du Colombier rc_alloc_struct_0(pht, gs_halftone, &st_halftone, 92*7dd7cddfSDavid du Colombier imemory, pht = 0, ".sethalftone5"); 93*7dd7cddfSDavid du Colombier phtc = gs_alloc_struct_array(mem, count, gs_halftone_component, 94*7dd7cddfSDavid du Colombier &st_ht_component_element, 95*7dd7cddfSDavid du Colombier ".sethalftone5"); 96*7dd7cddfSDavid du Colombier rc_alloc_struct_0(pdht, gx_device_halftone, &st_device_halftone, 97*7dd7cddfSDavid du Colombier imemory, pdht = 0, ".sethalftone5"); 98*7dd7cddfSDavid du Colombier if (pht == 0 || phtc == 0 || pdht == 0) 99*7dd7cddfSDavid du Colombier code = gs_note_error(e_VMerror); 100*7dd7cddfSDavid du Colombier else 101*7dd7cddfSDavid du Colombier for (i = 0, j = 0, pc = phtc; i < countof(color_names); i++) { 102*7dd7cddfSDavid du Colombier int type; 103*7dd7cddfSDavid du Colombier ref *pvalue; 104*7dd7cddfSDavid du Colombier 105*7dd7cddfSDavid du Colombier if (dict_find_string(op, color_names[i], &pvalue) > 0) { 106*7dd7cddfSDavid du Colombier check_type_only(*pvalue, t_dictionary); 107*7dd7cddfSDavid du Colombier check_dict_read(*pvalue); 108*7dd7cddfSDavid du Colombier if (dict_int_param(pvalue, "HalftoneType", 1, 7, 0, 109*7dd7cddfSDavid du Colombier &type) < 0 110*7dd7cddfSDavid du Colombier ) { 111*7dd7cddfSDavid du Colombier code = gs_note_error(e_typecheck); 112*7dd7cddfSDavid du Colombier break; 113*7dd7cddfSDavid du Colombier } 114*7dd7cddfSDavid du Colombier switch (type) { 115*7dd7cddfSDavid du Colombier default: 116*7dd7cddfSDavid du Colombier code = gs_note_error(e_rangecheck); 117*7dd7cddfSDavid du Colombier break; 118*7dd7cddfSDavid du Colombier case 1: 119*7dd7cddfSDavid du Colombier code = dict_spot_params(pvalue, 120*7dd7cddfSDavid du Colombier &pc->params.spot, sprocs + j, 121*7dd7cddfSDavid du Colombier tprocs + j); 122*7dd7cddfSDavid du Colombier pc->params.spot.screen.spot_function = spot1_dummy; 123*7dd7cddfSDavid du Colombier pc->type = ht_type_spot; 124*7dd7cddfSDavid du Colombier break; 125*7dd7cddfSDavid du Colombier case 3: 126*7dd7cddfSDavid du Colombier code = dict_threshold_params(pvalue, 127*7dd7cddfSDavid du Colombier &pc->params.threshold, tprocs + j); 128*7dd7cddfSDavid du Colombier pc->type = ht_type_threshold; 129*7dd7cddfSDavid du Colombier break; 130*7dd7cddfSDavid du Colombier case 7: 131*7dd7cddfSDavid du Colombier code = dict_threshold2_params(pvalue, 132*7dd7cddfSDavid du Colombier &pc->params.threshold2, tprocs + j, 133*7dd7cddfSDavid du Colombier imemory); 134*7dd7cddfSDavid du Colombier pc->type = ht_type_threshold2; 135*7dd7cddfSDavid du Colombier break; 136*7dd7cddfSDavid du Colombier } 137*7dd7cddfSDavid du Colombier if (code < 0) 138*7dd7cddfSDavid du Colombier break; 139*7dd7cddfSDavid du Colombier pc->cname = (gs_ht_separation_name) i; 140*7dd7cddfSDavid du Colombier pc++, j++; 141*7dd7cddfSDavid du Colombier } 142*7dd7cddfSDavid du Colombier } 143*7dd7cddfSDavid du Colombier if (code >= 0) { 144*7dd7cddfSDavid du Colombier /* 145*7dd7cddfSDavid du Colombier * We think that Type 2 and Type 4 halftones, like 146*7dd7cddfSDavid du Colombier * screens set by setcolorscreen, adapt automatically to 147*7dd7cddfSDavid du Colombier * the device color space, so we need to mark them 148*7dd7cddfSDavid du Colombier * with a different internal halftone type. 149*7dd7cddfSDavid du Colombier */ 150*7dd7cddfSDavid du Colombier int type = 0; 151*7dd7cddfSDavid du Colombier 152*7dd7cddfSDavid du Colombier dict_int_param(op - 1, "HalftoneType", 1, 5, 0, &type); 153*7dd7cddfSDavid du Colombier pht->type = 154*7dd7cddfSDavid du Colombier (type == 2 || type == 4 ? ht_type_multiple_colorscreen : 155*7dd7cddfSDavid du Colombier ht_type_multiple); 156*7dd7cddfSDavid du Colombier pht->params.multiple.components = phtc; 157*7dd7cddfSDavid du Colombier pht->params.multiple.num_comp = count; 158*7dd7cddfSDavid du Colombier code = gs_sethalftone_prepare(igs, pht, pdht); 159*7dd7cddfSDavid du Colombier } 160*7dd7cddfSDavid du Colombier if (code >= 0) 161*7dd7cddfSDavid du Colombier for (j = 0, pc = phtc; j < count; j++, pc++) { 162*7dd7cddfSDavid du Colombier if (pc->type == ht_type_spot) { 163*7dd7cddfSDavid du Colombier ref *pvalue; 164*7dd7cddfSDavid du Colombier 165*7dd7cddfSDavid du Colombier dict_find_string(op, color_names[pc->cname], &pvalue); 166*7dd7cddfSDavid du Colombier code = dict_spot_results(i_ctx_p, pvalue, &pc->params.spot); 167*7dd7cddfSDavid du Colombier if (code < 0) 168*7dd7cddfSDavid du Colombier break; 169*7dd7cddfSDavid du Colombier } 170*7dd7cddfSDavid du Colombier } 171*7dd7cddfSDavid du Colombier if (code >= 0) { 172*7dd7cddfSDavid du Colombier /* 173*7dd7cddfSDavid du Colombier * Schedule the sampling of any Type 1 screens, 174*7dd7cddfSDavid du Colombier * and any (Type 1 or Type 3) TransferFunctions. 175*7dd7cddfSDavid du Colombier * Save the stack depths in case we have to back out. 176*7dd7cddfSDavid du Colombier */ 177*7dd7cddfSDavid du Colombier uint odepth = ref_stack_count(&o_stack); 178*7dd7cddfSDavid du Colombier ref odict, odict5; 179*7dd7cddfSDavid du Colombier 180*7dd7cddfSDavid du Colombier odict = op[-1]; 181*7dd7cddfSDavid du Colombier odict5 = *op; 182*7dd7cddfSDavid du Colombier pop(2); 183*7dd7cddfSDavid du Colombier op = osp; 184*7dd7cddfSDavid du Colombier esp += 5; 185*7dd7cddfSDavid du Colombier make_mark_estack(esp - 4, es_other, sethalftone_cleanup); 186*7dd7cddfSDavid du Colombier esp[-3] = odict; 187*7dd7cddfSDavid du Colombier make_istruct(esp - 2, 0, pht); 188*7dd7cddfSDavid du Colombier make_istruct(esp - 1, 0, pdht); 189*7dd7cddfSDavid du Colombier make_op_estack(esp, sethalftone_finish); 190*7dd7cddfSDavid du Colombier for (j = 0; j < count; j++) { 191*7dd7cddfSDavid du Colombier gx_ht_order *porder = 192*7dd7cddfSDavid du Colombier (pdht->components == 0 ? &pdht->order : 193*7dd7cddfSDavid du Colombier &pdht->components[j].corder); 194*7dd7cddfSDavid du Colombier 195*7dd7cddfSDavid du Colombier switch (phtc[j].type) { 196*7dd7cddfSDavid du Colombier case ht_type_spot: 197*7dd7cddfSDavid du Colombier code = zscreen_enum_init(i_ctx_p, porder, 198*7dd7cddfSDavid du Colombier &phtc[j].params.spot.screen, 199*7dd7cddfSDavid du Colombier &sprocs[j], 0, 0, mem); 200*7dd7cddfSDavid du Colombier if (code < 0) 201*7dd7cddfSDavid du Colombier break; 202*7dd7cddfSDavid du Colombier /* falls through */ 203*7dd7cddfSDavid du Colombier case ht_type_threshold: 204*7dd7cddfSDavid du Colombier if (!r_has_type(tprocs + j, t__invalid)) { 205*7dd7cddfSDavid du Colombier /* Schedule TransferFunction sampling. */ 206*7dd7cddfSDavid du Colombier /****** check_xstack IS WRONG ******/ 207*7dd7cddfSDavid du Colombier check_ostack(zcolor_remap_one_ostack); 208*7dd7cddfSDavid du Colombier check_estack(zcolor_remap_one_estack); 209*7dd7cddfSDavid du Colombier code = zcolor_remap_one(i_ctx_p, tprocs + j, 210*7dd7cddfSDavid du Colombier porder->transfer, igs, 211*7dd7cddfSDavid du Colombier zcolor_remap_one_finish); 212*7dd7cddfSDavid du Colombier op = osp; 213*7dd7cddfSDavid du Colombier } 214*7dd7cddfSDavid du Colombier break; 215*7dd7cddfSDavid du Colombier default: /* not possible here, but to keep */ 216*7dd7cddfSDavid du Colombier /* the compilers happy.... */ 217*7dd7cddfSDavid du Colombier ; 218*7dd7cddfSDavid du Colombier } 219*7dd7cddfSDavid du Colombier if (code < 0) { /* Restore the stack. */ 220*7dd7cddfSDavid du Colombier ref_stack_pop_to(&o_stack, odepth); 221*7dd7cddfSDavid du Colombier ref_stack_pop_to(&e_stack, edepth); 222*7dd7cddfSDavid du Colombier op = osp; 223*7dd7cddfSDavid du Colombier op[-1] = odict; 224*7dd7cddfSDavid du Colombier *op = odict5; 225*7dd7cddfSDavid du Colombier break; 226*7dd7cddfSDavid du Colombier } 227*7dd7cddfSDavid du Colombier npop = 0; 228*7dd7cddfSDavid du Colombier } 229*7dd7cddfSDavid du Colombier } 230*7dd7cddfSDavid du Colombier if (code < 0) { 231*7dd7cddfSDavid du Colombier gs_free_object(mem, pdht, ".sethalftone5"); 232*7dd7cddfSDavid du Colombier gs_free_object(mem, phtc, ".sethalftone5"); 233*7dd7cddfSDavid du Colombier gs_free_object(mem, pht, ".sethalftone5"); 234*7dd7cddfSDavid du Colombier return code; 235*7dd7cddfSDavid du Colombier } 236*7dd7cddfSDavid du Colombier pop(npop); 237*7dd7cddfSDavid du Colombier return (ref_stack_count(&e_stack) > edepth ? o_push_estack : 0); 238*7dd7cddfSDavid du Colombier } 239*7dd7cddfSDavid du Colombier /* Install the halftone after sampling. */ 240*7dd7cddfSDavid du Colombier private int 241*7dd7cddfSDavid du Colombier sethalftone_finish(i_ctx_t *i_ctx_p) 242*7dd7cddfSDavid du Colombier { 243*7dd7cddfSDavid du Colombier gx_device_halftone *pdht = r_ptr(esp, gx_device_halftone); 244*7dd7cddfSDavid du Colombier int code; 245*7dd7cddfSDavid du Colombier 246*7dd7cddfSDavid du Colombier if (pdht->components) 247*7dd7cddfSDavid du Colombier pdht->order = pdht->components[0].corder; 248*7dd7cddfSDavid du Colombier code = gx_ht_install(igs, r_ptr(esp - 1, gs_halftone), pdht); 249*7dd7cddfSDavid du Colombier if (code < 0) 250*7dd7cddfSDavid du Colombier return code; 251*7dd7cddfSDavid du Colombier istate->halftone = esp[-2]; 252*7dd7cddfSDavid du Colombier esp -= 4; 253*7dd7cddfSDavid du Colombier sethalftone_cleanup(i_ctx_p); 254*7dd7cddfSDavid du Colombier return o_pop_estack; 255*7dd7cddfSDavid du Colombier } 256*7dd7cddfSDavid du Colombier /* Clean up after installing the halftone. */ 257*7dd7cddfSDavid du Colombier private int 258*7dd7cddfSDavid du Colombier sethalftone_cleanup(i_ctx_t *i_ctx_p) 259*7dd7cddfSDavid du Colombier { 260*7dd7cddfSDavid du Colombier gx_device_halftone *pdht = r_ptr(&esp[4], gx_device_halftone); 261*7dd7cddfSDavid du Colombier gs_halftone *pht = r_ptr(&esp[3], gs_halftone); 262*7dd7cddfSDavid du Colombier 263*7dd7cddfSDavid du Colombier gs_free_object(pdht->rc.memory, pdht, 264*7dd7cddfSDavid du Colombier "sethalftone_cleanup(device halftone)"); 265*7dd7cddfSDavid du Colombier gs_free_object(pht->rc.memory, pht, 266*7dd7cddfSDavid du Colombier "sethalftone_cleanup(halftone)"); 267*7dd7cddfSDavid du Colombier return 0; 268*7dd7cddfSDavid du Colombier } 269*7dd7cddfSDavid du Colombier 270*7dd7cddfSDavid du Colombier /* ------ Initialization procedure ------ */ 271*7dd7cddfSDavid du Colombier 272*7dd7cddfSDavid du Colombier const op_def zht2_l2_op_defs[] = 273*7dd7cddfSDavid du Colombier { 274*7dd7cddfSDavid du Colombier op_def_begin_level2(), 275*7dd7cddfSDavid du Colombier {"2.sethalftone5", zsethalftone5}, 276*7dd7cddfSDavid du Colombier /* Internal operators */ 277*7dd7cddfSDavid du Colombier {"0%sethalftone_finish", sethalftone_finish}, 278*7dd7cddfSDavid du Colombier op_def_end(0) 279*7dd7cddfSDavid du Colombier }; 280*7dd7cddfSDavid du Colombier 281*7dd7cddfSDavid du Colombier /* ------ Internal routines ------ */ 282*7dd7cddfSDavid du Colombier 283*7dd7cddfSDavid du Colombier /* Extract frequency, angle, spot function, and accurate screens flag */ 284*7dd7cddfSDavid du Colombier /* from a dictionary. */ 285*7dd7cddfSDavid du Colombier private int 286*7dd7cddfSDavid du Colombier dict_spot_params(const ref * pdict, gs_spot_halftone * psp, 287*7dd7cddfSDavid du Colombier ref * psproc, ref * ptproc) 288*7dd7cddfSDavid du Colombier { 289*7dd7cddfSDavid du Colombier int code; 290*7dd7cddfSDavid du Colombier 291*7dd7cddfSDavid du Colombier check_dict_read(*pdict); 292*7dd7cddfSDavid du Colombier if ((code = dict_float_param(pdict, "Frequency", 0.0, 293*7dd7cddfSDavid du Colombier &psp->screen.frequency)) != 0 || 294*7dd7cddfSDavid du Colombier (code = dict_float_param(pdict, "Angle", 0.0, 295*7dd7cddfSDavid du Colombier &psp->screen.angle)) != 0 || 296*7dd7cddfSDavid du Colombier (code = dict_proc_param(pdict, "SpotFunction", psproc, false)) != 0 || 297*7dd7cddfSDavid du Colombier (code = dict_bool_param(pdict, "AccurateScreens", 298*7dd7cddfSDavid du Colombier gs_currentaccuratescreens(), 299*7dd7cddfSDavid du Colombier &psp->accurate_screens)) < 0 || 300*7dd7cddfSDavid du Colombier (code = dict_proc_param(pdict, "TransferFunction", ptproc, false)) < 0 301*7dd7cddfSDavid du Colombier ) 302*7dd7cddfSDavid du Colombier return (code < 0 ? code : e_undefined); 303*7dd7cddfSDavid du Colombier psp->transfer = (code > 0 ? (gs_mapping_proc) 0 : gs_mapped_transfer); 304*7dd7cddfSDavid du Colombier psp->transfer_closure.proc = 0; 305*7dd7cddfSDavid du Colombier psp->transfer_closure.data = 0; 306*7dd7cddfSDavid du Colombier return 0; 307*7dd7cddfSDavid du Colombier } 308*7dd7cddfSDavid du Colombier 309*7dd7cddfSDavid du Colombier /* Set actual frequency and angle in a dictionary. */ 310*7dd7cddfSDavid du Colombier private int 311*7dd7cddfSDavid du Colombier dict_real_result(i_ctx_t *i_ctx_p, ref * pdict, const char *kstr, floatp val) 312*7dd7cddfSDavid du Colombier { 313*7dd7cddfSDavid du Colombier int code = 0; 314*7dd7cddfSDavid du Colombier ref *ignore; 315*7dd7cddfSDavid du Colombier 316*7dd7cddfSDavid du Colombier if (dict_find_string(pdict, kstr, &ignore) > 0) { 317*7dd7cddfSDavid du Colombier ref rval; 318*7dd7cddfSDavid du Colombier 319*7dd7cddfSDavid du Colombier check_dict_write(*pdict); 320*7dd7cddfSDavid du Colombier make_real(&rval, val); 321*7dd7cddfSDavid du Colombier code = idict_put_string(pdict, kstr, &rval); 322*7dd7cddfSDavid du Colombier } 323*7dd7cddfSDavid du Colombier return code; 324*7dd7cddfSDavid du Colombier } 325*7dd7cddfSDavid du Colombier private int 326*7dd7cddfSDavid du Colombier dict_spot_results(i_ctx_t *i_ctx_p, ref * pdict, const gs_spot_halftone * psp) 327*7dd7cddfSDavid du Colombier { 328*7dd7cddfSDavid du Colombier int code; 329*7dd7cddfSDavid du Colombier 330*7dd7cddfSDavid du Colombier code = dict_real_result(i_ctx_p, pdict, "ActualFrequency", 331*7dd7cddfSDavid du Colombier psp->screen.actual_frequency); 332*7dd7cddfSDavid du Colombier if (code < 0) 333*7dd7cddfSDavid du Colombier return code; 334*7dd7cddfSDavid du Colombier return dict_real_result(i_ctx_p, pdict, "ActualAngle", 335*7dd7cddfSDavid du Colombier psp->screen.actual_angle); 336*7dd7cddfSDavid du Colombier } 337*7dd7cddfSDavid du Colombier 338*7dd7cddfSDavid du Colombier /* Extract Width, Height, and TransferFunction from a dictionary. */ 339*7dd7cddfSDavid du Colombier private int 340*7dd7cddfSDavid du Colombier dict_threshold_common_params(const ref * pdict, 341*7dd7cddfSDavid du Colombier gs_threshold_halftone_common * ptp, 342*7dd7cddfSDavid du Colombier ref **pptstring, ref *ptproc) 343*7dd7cddfSDavid du Colombier { 344*7dd7cddfSDavid du Colombier int code; 345*7dd7cddfSDavid du Colombier 346*7dd7cddfSDavid du Colombier check_dict_read(*pdict); 347*7dd7cddfSDavid du Colombier if ((code = dict_int_param(pdict, "Width", 1, 0x7fff, -1, 348*7dd7cddfSDavid du Colombier &ptp->width)) < 0 || 349*7dd7cddfSDavid du Colombier (code = dict_int_param(pdict, "Height", 1, 0x7fff, -1, 350*7dd7cddfSDavid du Colombier &ptp->height)) < 0 || 351*7dd7cddfSDavid du Colombier (code = dict_find_string(pdict, "Thresholds", pptstring)) <= 0 || 352*7dd7cddfSDavid du Colombier (code = dict_proc_param(pdict, "TransferFunction", ptproc, false)) < 0 353*7dd7cddfSDavid du Colombier ) 354*7dd7cddfSDavid du Colombier return (code < 0 ? code : e_undefined); 355*7dd7cddfSDavid du Colombier ptp->transfer_closure.proc = 0; 356*7dd7cddfSDavid du Colombier ptp->transfer_closure.data = 0; 357*7dd7cddfSDavid du Colombier return code; 358*7dd7cddfSDavid du Colombier } 359*7dd7cddfSDavid du Colombier 360*7dd7cddfSDavid du Colombier /* Extract threshold common parameters + Thresholds. */ 361*7dd7cddfSDavid du Colombier private int 362*7dd7cddfSDavid du Colombier dict_threshold_params(const ref * pdict, gs_threshold_halftone * ptp, 363*7dd7cddfSDavid du Colombier ref * ptproc) 364*7dd7cddfSDavid du Colombier { 365*7dd7cddfSDavid du Colombier ref *tstring; 366*7dd7cddfSDavid du Colombier int code = 367*7dd7cddfSDavid du Colombier dict_threshold_common_params(pdict, 368*7dd7cddfSDavid du Colombier (gs_threshold_halftone_common *)ptp, 369*7dd7cddfSDavid du Colombier &tstring, ptproc); 370*7dd7cddfSDavid du Colombier 371*7dd7cddfSDavid du Colombier if (code < 0) 372*7dd7cddfSDavid du Colombier return code; 373*7dd7cddfSDavid du Colombier check_read_type_only(*tstring, t_string); 374*7dd7cddfSDavid du Colombier if (r_size(tstring) != (long)ptp->width * ptp->height) 375*7dd7cddfSDavid du Colombier return_error(e_rangecheck); 376*7dd7cddfSDavid du Colombier ptp->thresholds.data = tstring->value.const_bytes; 377*7dd7cddfSDavid du Colombier ptp->thresholds.size = r_size(tstring); 378*7dd7cddfSDavid du Colombier ptp->transfer = (code > 0 ? (gs_mapping_proc) 0 : gs_mapped_transfer); 379*7dd7cddfSDavid du Colombier return 0; 380*7dd7cddfSDavid du Colombier } 381*7dd7cddfSDavid du Colombier 382*7dd7cddfSDavid du Colombier /* Extract threshold common parameters + Thresholds, Width2, Height2, */ 383*7dd7cddfSDavid du Colombier /* BitsPerSample. */ 384*7dd7cddfSDavid du Colombier private int 385*7dd7cddfSDavid du Colombier dict_threshold2_params(const ref * pdict, gs_threshold2_halftone * ptp, 386*7dd7cddfSDavid du Colombier ref * ptproc, gs_memory_t *mem) 387*7dd7cddfSDavid du Colombier { 388*7dd7cddfSDavid du Colombier ref *tstring; 389*7dd7cddfSDavid du Colombier int code = 390*7dd7cddfSDavid du Colombier dict_threshold_common_params(pdict, 391*7dd7cddfSDavid du Colombier (gs_threshold_halftone_common *)ptp, 392*7dd7cddfSDavid du Colombier &tstring, ptproc); 393*7dd7cddfSDavid du Colombier int bps; 394*7dd7cddfSDavid du Colombier uint size; 395*7dd7cddfSDavid du Colombier int cw2, ch2; 396*7dd7cddfSDavid du Colombier 397*7dd7cddfSDavid du Colombier if (code < 0 || 398*7dd7cddfSDavid du Colombier (code = cw2 = dict_int_param(pdict, "Width2", 0, 0x7fff, 0, 399*7dd7cddfSDavid du Colombier &ptp->width2)) < 0 || 400*7dd7cddfSDavid du Colombier (code = ch2 = dict_int_param(pdict, "Height2", 0, 0x7fff, 0, 401*7dd7cddfSDavid du Colombier &ptp->height2)) < 0 || 402*7dd7cddfSDavid du Colombier (code = dict_int_param(pdict, "BitsPerSample", 8, 16, -1, &bps)) < 0 403*7dd7cddfSDavid du Colombier ) 404*7dd7cddfSDavid du Colombier return code; 405*7dd7cddfSDavid du Colombier if ((bps != 8 && bps != 16) || cw2 != ch2 || 406*7dd7cddfSDavid du Colombier (!cw2 && (ptp->width2 == 0 || ptp->height2 == 0)) 407*7dd7cddfSDavid du Colombier ) 408*7dd7cddfSDavid du Colombier return_error(e_rangecheck); 409*7dd7cddfSDavid du Colombier ptp->bytes_per_sample = bps / 8; 410*7dd7cddfSDavid du Colombier switch (r_type(tstring)) { 411*7dd7cddfSDavid du Colombier case t_string: 412*7dd7cddfSDavid du Colombier size = r_size(tstring); 413*7dd7cddfSDavid du Colombier gs_bytestring_from_string(&ptp->thresholds, tstring->value.const_bytes, 414*7dd7cddfSDavid du Colombier size); 415*7dd7cddfSDavid du Colombier break; 416*7dd7cddfSDavid du Colombier case t_astruct: 417*7dd7cddfSDavid du Colombier if (gs_object_type(mem, tstring->value.pstruct) != &st_bytes) 418*7dd7cddfSDavid du Colombier return_error(e_typecheck); 419*7dd7cddfSDavid du Colombier size = gs_object_size(mem, tstring->value.pstruct); 420*7dd7cddfSDavid du Colombier gs_bytestring_from_bytes(&ptp->thresholds, r_ptr(tstring, byte), 421*7dd7cddfSDavid du Colombier 0, size); 422*7dd7cddfSDavid du Colombier break; 423*7dd7cddfSDavid du Colombier default: 424*7dd7cddfSDavid du Colombier return_error(e_typecheck); 425*7dd7cddfSDavid du Colombier } 426*7dd7cddfSDavid du Colombier check_read(*tstring); 427*7dd7cddfSDavid du Colombier if (size != (ptp->width * ptp->height + ptp->width2 * ptp->height2) * 428*7dd7cddfSDavid du Colombier ptp->bytes_per_sample) 429*7dd7cddfSDavid du Colombier return_error(e_rangecheck); 430*7dd7cddfSDavid du Colombier return 0; 431*7dd7cddfSDavid du Colombier } 432