gscolor.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. /* Copyright (C) 1989, 1992, 1993, 1994, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
  2. This software is provided AS-IS with no warranty, either express or
  3. implied.
  4. This software is distributed under license and may not be copied,
  5. modified or distributed except as expressly authorized under the terms
  6. of the license contained in the file LICENSE in this distribution.
  7. For more information about licensing, please refer to
  8. http://www.ghostscript.com/licensing/. For information on
  9. commercial licensing, go to http://www.artifex.com/licensing/ or
  10. contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  11. San Rafael, CA 94903, U.S.A., +1(415)492-9861.
  12. */
  13. /* $Id: gscolor.c,v 1.14 2004/08/04 19:36:12 stefan Exp $ */
  14. /* Color and halftone operators for Ghostscript library */
  15. #include "gx.h"
  16. #include "gserrors.h"
  17. #include "gsstruct.h"
  18. #include "gsutil.h" /* for gs_next_ids */
  19. #include "gsccolor.h"
  20. #include "gxcspace.h"
  21. #include "gxdcconv.h"
  22. #include "gxdevice.h" /* for gx_color_index */
  23. #include "gxcmap.h"
  24. #include "gscolor2.h"
  25. #include "gzstate.h"
  26. /* Imported from gsht.c */
  27. void gx_set_effective_transfer(gs_state *);
  28. /* Structure descriptors */
  29. public_st_client_color();
  30. public_st_transfer_map();
  31. /* GC procedures */
  32. private
  33. ENUM_PTRS_WITH(transfer_map_enum_ptrs, gx_transfer_map *mptr) return 0;
  34. case 0: ENUM_RETURN((mptr->proc == 0 ? mptr->closure.data : 0));
  35. ENUM_PTRS_END
  36. private RELOC_PTRS_WITH(transfer_map_reloc_ptrs, gx_transfer_map *mptr)
  37. {
  38. if (mptr->proc == 0)
  39. RELOC_PTR(gx_transfer_map, closure.data);
  40. }
  41. RELOC_PTRS_END
  42. /* Initialize colors with 1, or 3, or 4 paint components. */
  43. /* (These are only used by setcolorspace.) */
  44. void
  45. gx_init_paint_1(gs_client_color * pcc, const gs_color_space * pcs)
  46. {
  47. pcc->paint.values[0] = 0.0;
  48. }
  49. void
  50. gx_init_paint_3(gs_client_color * pcc, const gs_color_space * pcs)
  51. {
  52. pcc->paint.values[2] = 0.0;
  53. pcc->paint.values[1] = 0.0;
  54. pcc->paint.values[0] = 0.0;
  55. }
  56. void
  57. gx_init_paint_4(gs_client_color * pcc, const gs_color_space * pcs)
  58. {
  59. /* DeviceCMYK and CIEBasedDEFG spaces initialize to 0,0,0,1. */
  60. pcc->paint.values[3] = 1.0;
  61. gx_init_paint_3(pcc, pcs);
  62. }
  63. /* Force a value into the range [0.0..1.0]. */
  64. #define FORCE_UNIT(p) (p <= 0.0 ? 0.0 : p >= 1.0 ? 1.0 : p)
  65. /* Restrict colors with 1, 3, or 4 components to the range (0,1). */
  66. void
  67. gx_restrict01_paint_1(gs_client_color * pcc, const gs_color_space * pcs)
  68. {
  69. pcc->paint.values[0] = FORCE_UNIT(pcc->paint.values[0]);
  70. }
  71. void
  72. gx_restrict01_paint_3(gs_client_color * pcc, const gs_color_space * pcs)
  73. {
  74. pcc->paint.values[2] = FORCE_UNIT(pcc->paint.values[2]);
  75. pcc->paint.values[1] = FORCE_UNIT(pcc->paint.values[1]);
  76. pcc->paint.values[0] = FORCE_UNIT(pcc->paint.values[0]);
  77. }
  78. void
  79. gx_restrict01_paint_4(gs_client_color * pcc, const gs_color_space * pcs)
  80. {
  81. pcc->paint.values[3] = FORCE_UNIT(pcc->paint.values[3]);
  82. gx_restrict01_paint_3(pcc, pcs);
  83. }
  84. /* Null reference count adjustment procedure. */
  85. void
  86. gx_no_adjust_color_count(const gs_client_color * pcc,
  87. const gs_color_space * pcs, int delta)
  88. {
  89. }
  90. /* Forward declarations */
  91. void load_transfer_map(gs_state *, gx_transfer_map *, floatp);
  92. /* setgray */
  93. int
  94. gs_setgray(gs_state * pgs, floatp gray)
  95. {
  96. gs_color_space cs;
  97. int code;
  98. gs_cspace_init_DeviceGray(pgs->memory, &cs);
  99. if ((code = gs_setcolorspace(pgs, &cs)) >= 0) {
  100. gs_client_color * pcc = pgs->ccolor;
  101. cs_adjust_color_count(pgs, -1); /* not strictly necessary */
  102. pcc->paint.values[0] = FORCE_UNIT(gray);
  103. pcc->pattern = 0; /* for GC */
  104. gx_unset_dev_color(pgs);
  105. }
  106. return code;
  107. }
  108. /* setrgbcolor */
  109. int
  110. gs_setrgbcolor(gs_state * pgs, floatp r, floatp g, floatp b)
  111. {
  112. gs_color_space cs;
  113. int code;
  114. gs_cspace_init_DeviceRGB(pgs->memory, &cs);
  115. if ((code = gs_setcolorspace(pgs, &cs)) >= 0) {
  116. gs_client_color * pcc = pgs->ccolor;
  117. cs_adjust_color_count(pgs, -1); /* not strictly necessary */
  118. pcc->paint.values[0] = FORCE_UNIT(r);
  119. pcc->paint.values[1] = FORCE_UNIT(g);
  120. pcc->paint.values[2] = FORCE_UNIT(b);
  121. pcc->pattern = 0; /* for GC */
  122. gx_unset_dev_color(pgs);
  123. }
  124. return code;
  125. }
  126. /* setnullcolor */
  127. int
  128. gs_setnullcolor(gs_state * pgs)
  129. {
  130. if (pgs->in_cachedevice)
  131. return_error(gs_error_undefined);
  132. gs_setgray(pgs, 0.0); /* set color space to something harmless */
  133. color_set_null(pgs->dev_color);
  134. return 0;
  135. }
  136. /* settransfer */
  137. /* Remap=0 is used by the interpreter. */
  138. int
  139. gs_settransfer(gs_state * pgs, gs_mapping_proc tproc)
  140. {
  141. return gs_settransfer_remap(pgs, tproc, true);
  142. }
  143. int
  144. gs_settransfer_remap(gs_state * pgs, gs_mapping_proc tproc, bool remap)
  145. {
  146. gx_transfer *ptran = &pgs->set_transfer;
  147. /*
  148. * We can safely decrement the reference counts
  149. * of the non-default transfer maps, because
  150. * if any of them get freed, the rc_unshare can't fail.
  151. */
  152. rc_decrement(ptran->red, "gs_settransfer");
  153. rc_decrement(ptran->green, "gs_settransfer");
  154. rc_decrement(ptran->blue, "gs_settransfer");
  155. rc_unshare_struct(ptran->gray, gx_transfer_map, &st_transfer_map,
  156. pgs->memory, goto fail, "gs_settransfer");
  157. ptran->gray->proc = tproc;
  158. ptran->gray->id = gs_next_ids(pgs->memory, 1);
  159. ptran->red = 0;
  160. ptran->green = 0;
  161. ptran->blue = 0;
  162. if (remap) {
  163. load_transfer_map(pgs, ptran->gray, 0.0);
  164. gx_set_effective_transfer(pgs);
  165. gx_unset_dev_color(pgs);
  166. } else
  167. gx_set_effective_transfer(pgs);
  168. return 0;
  169. fail:
  170. rc_increment(ptran->red);
  171. rc_increment(ptran->green);
  172. rc_increment(ptran->blue);
  173. rc_increment(ptran->gray);
  174. return_error(gs_error_VMerror);
  175. }
  176. /* currenttransfer */
  177. gs_mapping_proc
  178. gs_currenttransfer(const gs_state * pgs)
  179. {
  180. return pgs->set_transfer.gray->proc;
  181. }
  182. /* ------ Non-operator routines ------ */
  183. /* Set device color = 1 for writing into the character cache. */
  184. void
  185. gx_set_device_color_1(gs_state * pgs)
  186. {
  187. gs_color_space cs;
  188. gs_setoverprint(pgs, false);
  189. gs_setoverprintmode(pgs, 0);
  190. gs_cspace_init_DeviceGray(pgs->memory, &cs);
  191. gs_setcolorspace(pgs, &cs);
  192. set_nonclient_dev_color(pgs->dev_color, 1);
  193. pgs->log_op = lop_default;
  194. /*
  195. * In the unlikely event that overprint mode is in effect,
  196. * update the overprint information.
  197. */
  198. if (pgs->effective_overprint_mode == 1)
  199. (void)gs_do_set_overprint(pgs);
  200. }
  201. /* ------ Internal routines ------ */
  202. /*
  203. * Load one cached transfer map. We export this for gscolor1.c.
  204. * Note that we must deal with both old (proc) and new (closure) maps.
  205. */
  206. private float
  207. transfer_use_proc(floatp value, const gx_transfer_map * pmap,
  208. const void *ignore_proc_data)
  209. {
  210. return (*pmap->proc) (value, pmap);
  211. }
  212. void
  213. load_transfer_map(gs_state * pgs, gx_transfer_map * pmap, floatp min_value)
  214. {
  215. gs_mapping_closure_proc_t proc;
  216. const void *proc_data;
  217. frac *values = pmap->values;
  218. frac fmin = float2frac(min_value);
  219. int i;
  220. if (pmap->proc == 0) /* use closure */
  221. proc = pmap->closure.proc, proc_data = pmap->closure.data;
  222. else /* use proc */
  223. proc = transfer_use_proc, proc_data = 0 /* not used */;
  224. for (i = 0; i < transfer_map_size; i++) {
  225. float fval =
  226. (*proc) ((float)i / (transfer_map_size - 1), pmap, proc_data);
  227. values[i] =
  228. (fval < min_value ? fmin :
  229. fval >= 1.0 ? frac_1 :
  230. float2frac(fval));
  231. }
  232. }