1 /* Copyright (C) 1992, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved. 2 3 This software is provided AS-IS with no warranty, either express or 4 implied. 5 6 This software is distributed under license and may not be copied, 7 modified or distributed except as expressly authorized under the terms 8 of the license contained in the file LICENSE in this distribution. 9 10 For more information about licensing, please refer to 11 http://www.ghostscript.com/licensing/. For information on 12 commercial licensing, go to http://www.artifex.com/licensing/ or 13 contact Artifex Software, Inc., 101 Lucas Valley Road #110, 14 San Rafael, CA 94903, U.S.A., +1(415)492-9861. 15 */ 16 17 /* $Id: zht2.c,v 1.14 2005/10/11 10:04:28 leonardo Exp $ */ 18 /* Level 2 sethalftone operator */ 19 #include "ghost.h" 20 #include "oper.h" 21 #include "gsstruct.h" 22 #include "gxdevice.h" /* for gzht.h */ 23 #include "gzht.h" 24 #include "estack.h" 25 #include "ialloc.h" 26 #include "iddict.h" 27 #include "idparam.h" 28 #include "igstate.h" 29 #include "icolor.h" 30 #include "iht.h" 31 #include "store.h" 32 #include "iname.h" 33 #include "zht2.h" 34 35 /* Forward references */ 36 private int dict_spot_params(const ref *, gs_spot_halftone *, ref *, ref *); 37 private int dict_spot_results(i_ctx_t *, ref *, const gs_spot_halftone *); 38 private int dict_threshold_params(const ref *, gs_threshold_halftone *, 39 ref *); 40 private int dict_threshold2_params(const ref *, gs_threshold2_halftone *, 41 ref *, gs_memory_t *); 42 43 /* 44 * This routine translates a gs_separation_name value into a character string 45 * pointer and a string length. 46 */ 47 int 48 gs_get_colorname_string(const gs_memory_t *mem, gs_separation_name colorname_index, 49 unsigned char **ppstr, unsigned int *pname_size) 50 { 51 ref nref; 52 53 name_index_ref(mem, colorname_index, &nref); 54 name_string_ref(mem, &nref, &nref); 55 return obj_string_data(mem, &nref, (const unsigned char**) ppstr, pname_size); 56 } 57 58 /* Dummy spot function */ 59 private float 60 spot1_dummy(floatp x, floatp y) 61 { 62 return (x + y) / 2; 63 } 64 65 /* <dict> <dict5> .sethalftone5 - */ 66 private int sethalftone_finish(i_ctx_t *); 67 private int sethalftone_cleanup(i_ctx_t *); 68 private int 69 zsethalftone5(i_ctx_t *i_ctx_p) 70 { 71 os_ptr op = osp; 72 uint count; 73 gs_halftone_component *phtc; 74 gs_halftone_component *pc; 75 int code = 0; 76 int j; 77 gs_halftone *pht; 78 gx_device_halftone *pdht; 79 ref sprocs[GS_CLIENT_COLOR_MAX_COMPONENTS + 1]; 80 ref tprocs[GS_CLIENT_COLOR_MAX_COMPONENTS + 1]; 81 gs_memory_t *mem; 82 uint edepth = ref_stack_count(&e_stack); 83 int npop = 2; 84 int dict_enum = dict_first(op); 85 ref rvalue[2]; 86 int cname, colorant_number; 87 byte * pname; 88 uint name_size; 89 int halftonetype, type = 0; 90 gs_state *pgs = igs; 91 int space_index = r_space_index(op - 1); 92 93 mem = (gs_memory_t *) idmemory->spaces_indexed[space_index]; 94 95 check_type(*op, t_dictionary); 96 check_dict_read(*op); 97 check_type(op[-1], t_dictionary); 98 check_dict_read(op[-1]); 99 100 /* 101 * We think that Type 2 and Type 4 halftones, like 102 * screens set by setcolorscreen, adapt automatically to 103 * the device color space, so we need to mark them 104 * with a different internal halftone type. 105 */ 106 dict_int_param(op - 1, "HalftoneType", 1, 5, 0, &type); 107 halftonetype = (type == 2 || type == 4) 108 ? ht_type_multiple_colorscreen 109 : ht_type_multiple; 110 111 /* Count how many components that we will actually use. */ 112 113 for (count = 0; ;) { 114 bool have_default = false; 115 116 /* Move to next element in the dictionary */ 117 if ((dict_enum = dict_next(op, dict_enum, rvalue)) == -1) 118 break; 119 /* 120 * Verify that we have a valid component. We may have a 121 * /HalfToneType entry. 122 */ 123 if (!r_has_type(&rvalue[1], t_dictionary)) 124 continue; 125 126 /* Get the name of the component verify that we will use it. */ 127 cname = name_index(mem, &rvalue[0]); 128 code = gs_get_colorname_string(mem, cname, &pname, &name_size); 129 if (code < 0) 130 break; 131 colorant_number = gs_cname_to_colorant_number(pgs, pname, name_size, 132 halftonetype); 133 if (colorant_number < 0) 134 continue; 135 else if (colorant_number == GX_DEVICE_COLOR_MAX_COMPONENTS) { 136 /* If here then we have the "Default" component */ 137 if (have_default) 138 return_error(e_rangecheck); 139 have_default = true; 140 } 141 142 count++; 143 /* 144 * Check to see if we have already reached the legal number of 145 * components. 146 */ 147 if (count > GS_CLIENT_COLOR_MAX_COMPONENTS + 1) { 148 code = gs_note_error(e_rangecheck); 149 break; 150 } 151 } 152 153 check_estack(5); /* for sampling Type 1 screens */ 154 refset_null(sprocs, count); 155 refset_null(tprocs, count); 156 rc_alloc_struct_0(pht, gs_halftone, &st_halftone, 157 imemory, pht = 0, ".sethalftone5"); 158 phtc = gs_alloc_struct_array(mem, count, gs_halftone_component, 159 &st_ht_component_element, 160 ".sethalftone5"); 161 rc_alloc_struct_0(pdht, gx_device_halftone, &st_device_halftone, 162 imemory, pdht = 0, ".sethalftone5"); 163 if (pht == 0 || phtc == 0 || pdht == 0) { 164 j = 0; /* Quiet the compiler: 165 gs_note_error isn't necessarily identity, 166 so j could be left ununitialized. */ 167 code = gs_note_error(e_VMerror); 168 } else { 169 dict_enum = dict_first(op); 170 for (j = 0, pc = phtc; ;) { 171 int type; 172 173 /* Move to next element in the dictionary */ 174 if ((dict_enum = dict_next(op, dict_enum, rvalue)) == -1) 175 break; 176 /* 177 * Verify that we have a valid component. We may have a 178 * /HalfToneType entry. 179 */ 180 if (!r_has_type(&rvalue[1], t_dictionary)) 181 continue; 182 183 /* Get the name of the component */ 184 cname = name_index(mem, &rvalue[0]); 185 code = gs_get_colorname_string(mem, cname, &pname, &name_size); 186 if (code < 0) 187 break; 188 colorant_number = gs_cname_to_colorant_number(pgs, pname, name_size, 189 halftonetype); 190 if (colorant_number < 0) 191 continue; /* Do not use this component */ 192 pc->cname = cname; 193 pc->comp_number = colorant_number; 194 195 /* Now process the component dictionary */ 196 check_dict_read(rvalue[1]); 197 if (dict_int_param(&rvalue[1], "HalftoneType", 1, 7, 0, &type) < 0) { 198 code = gs_note_error(e_typecheck); 199 break; 200 } 201 switch (type) { 202 default: 203 code = gs_note_error(e_rangecheck); 204 break; 205 case 1: 206 code = dict_spot_params(&rvalue[1], &pc->params.spot, 207 sprocs + j, tprocs + j); 208 pc->params.spot.screen.spot_function = spot1_dummy; 209 pc->type = ht_type_spot; 210 break; 211 case 3: 212 code = dict_threshold_params(&rvalue[1], &pc->params.threshold, 213 tprocs + j); 214 pc->type = ht_type_threshold; 215 break; 216 case 7: 217 code = dict_threshold2_params(&rvalue[1], &pc->params.threshold2, 218 tprocs + j, imemory); 219 pc->type = ht_type_threshold2; 220 break; 221 } 222 if (code < 0) 223 break; 224 pc++; 225 j++; 226 } 227 } 228 if (code >= 0) { 229 pht->type = halftonetype; 230 pht->params.multiple.components = phtc; 231 pht->params.multiple.num_comp = j; 232 pht->params.multiple.get_colorname_string = gs_get_colorname_string; 233 code = gs_sethalftone_prepare(igs, pht, pdht); 234 } 235 if (code >= 0) { 236 /* 237 * Put the actual frequency and angle in the spot function component dictionaries. 238 */ 239 dict_enum = dict_first(op); 240 for (pc = phtc; ; ) { 241 /* Move to next element in the dictionary */ 242 if ((dict_enum = dict_next(op, dict_enum, rvalue)) == -1) 243 break; 244 245 /* Verify that we have a valid component */ 246 if (!r_has_type(&rvalue[1], t_dictionary)) 247 continue; 248 249 /* Get the name of the component and verify that we will use it. */ 250 cname = name_index(mem, &rvalue[0]); 251 code = gs_get_colorname_string(mem, cname, &pname, &name_size); 252 if (code < 0) 253 break; 254 colorant_number = gs_cname_to_colorant_number(pgs, pname, name_size, 255 halftonetype); 256 if (colorant_number < 0) 257 continue; 258 259 if (pc->type == ht_type_spot) { 260 code = dict_spot_results(i_ctx_p, &rvalue[1], &pc->params.spot); 261 if (code < 0) 262 break; 263 } 264 pc++; 265 } 266 } 267 if (code >= 0) { 268 /* 269 * Schedule the sampling of any Type 1 screens, 270 * and any (Type 1 or Type 3) TransferFunctions. 271 * Save the stack depths in case we have to back out. 272 */ 273 uint odepth = ref_stack_count(&o_stack); 274 ref odict, odict5; 275 276 odict = op[-1]; 277 odict5 = *op; 278 pop(2); 279 op = osp; 280 esp += 5; 281 make_mark_estack(esp - 4, es_other, sethalftone_cleanup); 282 esp[-3] = odict; 283 make_istruct(esp - 2, 0, pht); 284 make_istruct(esp - 1, 0, pdht); 285 make_op_estack(esp, sethalftone_finish); 286 for (j = 0; j < count; j++) { 287 gx_ht_order *porder = NULL; 288 289 if (pdht->components == 0) 290 porder = &pdht->order; 291 else { 292 /* Find the component in pdht that matches component j in 293 the pht; gs_sethalftone_prepare() may permute these. */ 294 int k; 295 int comp_number = phtc[j].comp_number; 296 for (k = 0; k < count; k++) { 297 if (pdht->components[k].comp_number == comp_number) { 298 porder = &pdht->components[k].corder; 299 break; 300 } 301 } 302 } 303 switch (phtc[j].type) { 304 case ht_type_spot: 305 code = zscreen_enum_init(i_ctx_p, porder, 306 &phtc[j].params.spot.screen, 307 &sprocs[j], 0, 0, space_index); 308 if (code < 0) 309 break; 310 /* falls through */ 311 case ht_type_threshold: 312 if (!r_has_type(tprocs + j, t__invalid)) { 313 /* Schedule TransferFunction sampling. */ 314 /****** check_xstack IS WRONG ******/ 315 check_ostack(zcolor_remap_one_ostack); 316 check_estack(zcolor_remap_one_estack); 317 code = zcolor_remap_one(i_ctx_p, tprocs + j, 318 porder->transfer, igs, 319 zcolor_remap_one_finish); 320 op = osp; 321 } 322 break; 323 default: /* not possible here, but to keep */ 324 /* the compilers happy.... */ 325 ; 326 } 327 if (code < 0) { /* Restore the stack. */ 328 ref_stack_pop_to(&o_stack, odepth); 329 ref_stack_pop_to(&e_stack, edepth); 330 op = osp; 331 op[-1] = odict; 332 *op = odict5; 333 break; 334 } 335 npop = 0; 336 } 337 } 338 if (code < 0) { 339 gs_free_object(mem, pdht, ".sethalftone5"); 340 gs_free_object(mem, phtc, ".sethalftone5"); 341 gs_free_object(mem, pht, ".sethalftone5"); 342 return code; 343 } 344 pop(npop); 345 return (ref_stack_count(&e_stack) > edepth ? o_push_estack : 0); 346 } 347 348 /* Install the halftone after sampling. */ 349 private int 350 sethalftone_finish(i_ctx_t *i_ctx_p) 351 { 352 gx_device_halftone *pdht = r_ptr(esp, gx_device_halftone); 353 int code; 354 355 if (pdht->components) 356 pdht->order = pdht->components[0].corder; 357 code = gx_ht_install(igs, r_ptr(esp - 1, gs_halftone), pdht); 358 if (code < 0) 359 return code; 360 istate->halftone = esp[-2]; 361 esp -= 4; 362 sethalftone_cleanup(i_ctx_p); 363 return o_pop_estack; 364 } 365 /* Clean up after installing the halftone. */ 366 private int 367 sethalftone_cleanup(i_ctx_t *i_ctx_p) 368 { 369 gx_device_halftone *pdht = r_ptr(&esp[4], gx_device_halftone); 370 gs_halftone *pht = r_ptr(&esp[3], gs_halftone); 371 372 gs_free_object(pdht->rc.memory, pdht, 373 "sethalftone_cleanup(device halftone)"); 374 gs_free_object(pht->rc.memory, pht, 375 "sethalftone_cleanup(halftone)"); 376 return 0; 377 } 378 379 /* ------ Initialization procedure ------ */ 380 381 const op_def zht2_l2_op_defs[] = 382 { 383 op_def_begin_level2(), 384 {"2.sethalftone5", zsethalftone5}, 385 /* Internal operators */ 386 {"0%sethalftone_finish", sethalftone_finish}, 387 op_def_end(0) 388 }; 389 390 /* ------ Internal routines ------ */ 391 392 /* Extract frequency, angle, spot function, and accurate screens flag */ 393 /* from a dictionary. */ 394 private int 395 dict_spot_params(const ref * pdict, gs_spot_halftone * psp, 396 ref * psproc, ref * ptproc) 397 { 398 int code; 399 400 check_dict_read(*pdict); 401 if ((code = dict_float_param(pdict, "Frequency", 0.0, 402 &psp->screen.frequency)) != 0 || 403 (code = dict_float_param(pdict, "Angle", 0.0, 404 &psp->screen.angle)) != 0 || 405 (code = dict_proc_param(pdict, "SpotFunction", psproc, false)) != 0 || 406 (code = dict_bool_param(pdict, "AccurateScreens", 407 gs_currentaccuratescreens(), 408 &psp->accurate_screens)) < 0 || 409 (code = dict_proc_param(pdict, "TransferFunction", ptproc, false)) < 0 410 ) 411 return (code < 0 ? code : e_undefined); 412 psp->transfer = (code > 0 ? (gs_mapping_proc) 0 : gs_mapped_transfer); 413 psp->transfer_closure.proc = 0; 414 psp->transfer_closure.data = 0; 415 return 0; 416 } 417 418 /* Set actual frequency and angle in a dictionary. */ 419 private int 420 dict_real_result(i_ctx_t *i_ctx_p, ref * pdict, const char *kstr, floatp val) 421 { 422 int code = 0; 423 ref *ignore; 424 425 if (dict_find_string(pdict, kstr, &ignore) > 0) { 426 ref rval; 427 428 check_dict_write(*pdict); 429 make_real(&rval, val); 430 code = idict_put_string(pdict, kstr, &rval); 431 } 432 return code; 433 } 434 private int 435 dict_spot_results(i_ctx_t *i_ctx_p, ref * pdict, const gs_spot_halftone * psp) 436 { 437 int code; 438 439 code = dict_real_result(i_ctx_p, pdict, "ActualFrequency", 440 psp->screen.actual_frequency); 441 if (code < 0) 442 return code; 443 return dict_real_result(i_ctx_p, pdict, "ActualAngle", 444 psp->screen.actual_angle); 445 } 446 447 /* Extract Width, Height, and TransferFunction from a dictionary. */ 448 private int 449 dict_threshold_common_params(const ref * pdict, 450 gs_threshold_halftone_common * ptp, 451 ref **pptstring, ref *ptproc) 452 { 453 int code; 454 455 check_dict_read(*pdict); 456 if ((code = dict_int_param(pdict, "Width", 1, 0x7fff, -1, 457 &ptp->width)) < 0 || 458 (code = dict_int_param(pdict, "Height", 1, 0x7fff, -1, 459 &ptp->height)) < 0 || 460 (code = dict_find_string(pdict, "Thresholds", pptstring)) <= 0 || 461 (code = dict_proc_param(pdict, "TransferFunction", ptproc, false)) < 0 462 ) 463 return (code < 0 ? code : e_undefined); 464 ptp->transfer_closure.proc = 0; 465 ptp->transfer_closure.data = 0; 466 return code; 467 } 468 469 /* Extract threshold common parameters + Thresholds. */ 470 private int 471 dict_threshold_params(const ref * pdict, gs_threshold_halftone * ptp, 472 ref * ptproc) 473 { 474 ref *tstring; 475 int code = 476 dict_threshold_common_params(pdict, 477 (gs_threshold_halftone_common *)ptp, 478 &tstring, ptproc); 479 480 if (code < 0) 481 return code; 482 check_read_type_only(*tstring, t_string); 483 if (r_size(tstring) != (long)ptp->width * ptp->height) 484 return_error(e_rangecheck); 485 ptp->thresholds.data = tstring->value.const_bytes; 486 ptp->thresholds.size = r_size(tstring); 487 ptp->transfer = (code > 0 ? (gs_mapping_proc) 0 : gs_mapped_transfer); 488 return 0; 489 } 490 491 /* Extract threshold common parameters + Thresholds, Width2, Height2, */ 492 /* BitsPerSample. */ 493 private int 494 dict_threshold2_params(const ref * pdict, gs_threshold2_halftone * ptp, 495 ref * ptproc, gs_memory_t *mem) 496 { 497 ref *tstring; 498 int code = 499 dict_threshold_common_params(pdict, 500 (gs_threshold_halftone_common *)ptp, 501 &tstring, ptproc); 502 int bps; 503 uint size; 504 int cw2, ch2; 505 506 if (code < 0 || 507 (code = cw2 = dict_int_param(pdict, "Width2", 0, 0x7fff, 0, 508 &ptp->width2)) < 0 || 509 (code = ch2 = dict_int_param(pdict, "Height2", 0, 0x7fff, 0, 510 &ptp->height2)) < 0 || 511 (code = dict_int_param(pdict, "BitsPerSample", 8, 16, -1, &bps)) < 0 512 ) 513 return code; 514 if ((bps != 8 && bps != 16) || cw2 != ch2 || 515 (!cw2 && (ptp->width2 == 0 || ptp->height2 == 0)) 516 ) 517 return_error(e_rangecheck); 518 ptp->bytes_per_sample = bps / 8; 519 switch (r_type(tstring)) { 520 case t_string: 521 size = r_size(tstring); 522 gs_bytestring_from_string(&ptp->thresholds, tstring->value.const_bytes, 523 size); 524 break; 525 case t_astruct: 526 if (gs_object_type(mem, tstring->value.pstruct) != &st_bytes) 527 return_error(e_typecheck); 528 size = gs_object_size(mem, tstring->value.pstruct); 529 gs_bytestring_from_bytes(&ptp->thresholds, r_ptr(tstring, byte), 530 0, size); 531 break; 532 default: 533 return_error(e_typecheck); 534 } 535 check_read(*tstring); 536 if (size != (ptp->width * ptp->height + ptp->width2 * ptp->height2) * 537 ptp->bytes_per_sample) 538 return_error(e_rangecheck); 539 return 0; 540 } 541