home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1996 February / PCWK0296.iso / sharewar / dos / program / gs300sr1 / gs300sr1.exe / GSCOLOR2.C < prev    next >
C/C++ Source or Header  |  1994-07-27  |  10KB  |  273 lines

  1. /* Copyright (C) 1992, 1993 Aladdin Enterprises.  All rights reserved.
  2.   
  3.   This file is part of Aladdin Ghostscript.
  4.   
  5.   Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
  6.   or distributor accepts any responsibility for the consequences of using it,
  7.   or for whether it serves any particular purpose or works at all, unless he
  8.   or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
  9.   License (the "License") for full details.
  10.   
  11.   Every copy of Aladdin Ghostscript must include a copy of the License,
  12.   normally in a plain ASCII text file named PUBLIC.  The License grants you
  13.   the right to copy, modify and redistribute Aladdin Ghostscript, but only
  14.   under certain conditions described in the License.  Among other things, the
  15.   License requires that the copyright notice and this notice be preserved on
  16.   all copies.
  17. */
  18.  
  19. /* gscolor2.c */
  20. /* Level 2 color and halftone operators for Ghostscript library */
  21. #include "gx.h"
  22. #include "gserrors.h"
  23. #include "gxarith.h"
  24. #include "gxfixed.h"            /* ditto */
  25. #include "gxmatrix.h"            /* for gzstate.h */
  26. #include "gscspace.h"            /* for gscolor2.h */
  27. #include "gxcolor2.h"
  28. #include "gzstate.h"
  29. #include "gscie.h"
  30.  
  31. /* Define the Level 2 color space types. */
  32. #define cs_procs(scope, remap, install, adjust, enum_p, reloc_p)\
  33.   scope cs_proc_remap_color(remap);\
  34.   scope cs_proc_install_cspace(install);\
  35.   scope cs_proc_adjust_cspace_count(adjust);\
  36.   scope struct_proc_enum_ptrs(enum_p);\
  37.   scope struct_proc_reloc_ptrs(reloc_p)
  38. cs_procs(extern, gx_remap_CIEBasedABC, gx_install_CIEBasedABC,
  39.   gx_adjust_cspace_CIEBasedABC,
  40.   gx_enum_ptrs_CIEBasedABC, gx_reloc_ptrs_CIEBasedABC);
  41. cs_procs(extern, gx_remap_CIEBasedA, gx_install_CIEBasedA,
  42.   gx_adjust_cspace_CIEBasedA,
  43.   gx_enum_ptrs_CIEBasedA, gx_reloc_ptrs_CIEBasedA);
  44. cs_procs(private, gx_remap_Separation, gx_install_Separation,
  45.   gx_adjust_cspace_Separation,
  46.   gx_enum_ptrs_Separation, gx_reloc_ptrs_Separation);
  47. cs_procs(private, gx_remap_Indexed, gx_install_Indexed,
  48.   gx_adjust_cspace_Indexed,
  49.   gx_enum_ptrs_Indexed, gx_reloc_ptrs_Indexed);
  50. private cs_proc_init_color(gx_init_Separation);
  51. const gs_color_space_type
  52.     gs_color_space_type_CIEBasedABC =
  53.      { gs_color_space_index_CIEBasedABC, 3,
  54.        gx_init_paint_3, gx_remap_CIEBasedABC, gx_install_CIEBasedABC,
  55.        gx_adjust_cspace_CIEBasedABC, gx_no_adjust_color_count,
  56.        gx_enum_ptrs_CIEBasedABC, gx_reloc_ptrs_CIEBasedABC
  57.      },
  58.     gs_color_space_type_CIEBasedA =
  59.      { gs_color_space_index_CIEBasedA, 1,
  60.        gx_init_paint_1, gx_remap_CIEBasedA, gx_install_CIEBasedA,
  61.        gx_adjust_cspace_CIEBasedA, gx_no_adjust_color_count,
  62.        gx_enum_ptrs_CIEBasedA, gx_reloc_ptrs_CIEBasedA
  63.      },
  64.     gs_color_space_type_Separation =
  65.      { gs_color_space_index_Separation, 1,
  66.        gx_init_Separation, gx_remap_Separation, gx_install_Separation,
  67.        gx_adjust_cspace_Separation, gx_no_adjust_color_count,
  68.        gx_enum_ptrs_Separation, gx_reloc_ptrs_Separation
  69.      },
  70.     gs_color_space_type_Indexed =
  71.      { gs_color_space_index_Indexed, 1,
  72.        gx_init_paint_1, gx_remap_Indexed, gx_install_Indexed,
  73.        gx_adjust_cspace_Indexed, gx_no_adjust_color_count,
  74.        gx_enum_ptrs_Indexed, gx_reloc_ptrs_Indexed
  75.      };
  76.  
  77. /* setcolorspace */
  78. int
  79. gs_setcolorspace(gs_state *pgs, gs_color_space *pcs)
  80. {    int code;
  81.     gs_color_space cs_old;
  82.     gs_client_color cc_old;
  83.     if ( pgs->in_cachedevice )
  84.         return_error(gs_error_undefined);
  85.     cs_old = *pgs->color_space;
  86.     cc_old = *pgs->ccolor;
  87.     (*pcs->type->adjust_cspace_count)(pcs, pgs, 1);
  88.     *pgs->color_space = *pcs;
  89.     if ( (code = (*pcs->type->install_cspace)(pcs, pgs)) < 0 )
  90.         goto rcs;
  91.     cs_full_init_color(pgs->ccolor, pcs);
  92.     (*cs_old.type->adjust_color_count)(&cc_old, &cs_old, pgs, -1);
  93.     (*cs_old.type->adjust_cspace_count)(&cs_old, pgs, -1);
  94.     gx_unset_dev_color(pgs);
  95.     return code;
  96.     /* Restore the color space if installation failed. */
  97. rcs:    *pgs->color_space = cs_old;
  98.     (*pcs->type->adjust_cspace_count)(pcs, pgs, -1);
  99.     return code;
  100. }
  101.  
  102. /* currentcolorspace */
  103. const gs_color_space *
  104. gs_currentcolorspace(const gs_state *pgs)
  105. {    return pgs->color_space;
  106. }
  107.  
  108. /* setcolor */
  109. int
  110. gs_setcolor(gs_state *pgs, const gs_client_color *pcc)
  111. {    gs_color_space *pcs = pgs->color_space;
  112.     if ( pgs->in_cachedevice )
  113.         return_error(gs_error_undefined);
  114.     (*pcs->type->adjust_color_count)(pcc, pcs, pgs, 1);
  115.     (*pcs->type->adjust_color_count)(pgs->ccolor, pcs, pgs, -1);
  116.     *pgs->ccolor = *pcc;
  117.     gx_unset_dev_color(pgs);
  118.     return 0;
  119. }
  120.  
  121. /* currentcolor */
  122. const gs_client_color *
  123. gs_currentcolor(const gs_state *pgs)
  124. {    return pgs->ccolor;
  125. }
  126.  
  127. /* setoverprint */
  128. void
  129. gs_setoverprint(gs_state *pgs, int ovp)
  130. {    pgs->overprint = ovp;
  131. }
  132.  
  133. /* currentoverprint */
  134. int
  135. gs_currentoverprint(const gs_state *pgs)
  136. {    return pgs->overprint;
  137. }
  138.  
  139. /* ------ Internal routines ------ */
  140.  
  141. /* Initialize Level 2 colors. */
  142.  
  143. private void
  144. gx_init_Separation(gs_client_color *pcc, const gs_color_space *pcs)
  145. {    pcc->paint.values[0] = 1.0;
  146. }
  147.  
  148. /* Color remapping for Level 2 color spaces. */
  149. /* The CIE-based spaces are handled in gscie.c. */
  150.  
  151. private int
  152. gx_remap_Separation(const gs_client_color *pc, const gs_color_space *pcs,
  153.   gx_device_color *pdc, const gs_state *pgs)
  154. {    float tint = pc->paint.values[0];
  155.     int code;
  156.     gs_client_color cc;
  157.     if ( tint < 0 ) tint = 0;
  158.     else if ( tint > 1 ) tint = 1;
  159.     code = (*pcs->params.separation.map->proc.tint_transform)(&pcs->params.separation, tint, &cc.paint.values[0]);
  160.     if ( code < 0 ) return code;
  161.     return (*pcs->params.separation.alt_space.type->remap_color)(&cc,
  162.         (const gs_color_space *)&pcs->params.separation.alt_space,
  163.          pdc, pgs);
  164. }
  165.  
  166. private int
  167. gx_remap_Indexed(const gs_client_color *pc, const gs_color_space *pcs,
  168.   gx_device_color *pdc, const gs_state *pgs)
  169. {    float value = pc->paint.values[0];
  170.     int index =
  171.         (is_fneg(value) ? 0 :
  172.          value >= pcs->params.indexed.hival ?
  173.            pcs->params.indexed.hival :
  174.          (int)value);
  175.     gs_client_color cc;
  176.     if ( pcs->params.indexed.use_proc )
  177.     {    int code = (*pcs->params.indexed.lookup.map->proc.lookup_index)(&pcs->params.indexed, index, &cc.paint.values[0]);
  178.         if ( code < 0 ) return code;
  179.     }
  180.     else
  181.     {    int m = pcs->params.indexed.base_space.type->num_components;
  182.         const byte *pcomp =
  183.           pcs->params.indexed.lookup.table.data + m * index;
  184.         switch ( m )
  185.         {
  186.         default: return_error(gs_error_rangecheck);
  187.         case 4: cc.paint.values[3] = pcomp[3] * (1.0 / 255.0);
  188.         case 3: cc.paint.values[2] = pcomp[2] * (1.0 / 255.0);
  189.             cc.paint.values[1] = pcomp[1] * (1.0 / 255.0);
  190.         case 1: cc.paint.values[0] = pcomp[0] * (1.0 / 255.0);
  191.         }
  192.     }
  193.     return (*pcs->params.indexed.base_space.type->remap_color)(&cc,
  194.         (const gs_color_space *)&pcs->params.indexed.base_space,
  195.          pdc, pgs);
  196. }
  197.  
  198. /* Color space installation ditto. */
  199.  
  200. private int
  201. gx_install_Separation(gs_color_space *pcs, gs_state *pgs)
  202. {    return (*pcs->params.separation.alt_space.type->install_cspace)
  203.         ((gs_color_space *)&pcs->params.separation.alt_space, pgs);
  204. }
  205.  
  206. private int
  207. gx_install_Indexed(gs_color_space *pcs, gs_state *pgs)
  208. {    return (*pcs->params.indexed.base_space.type->install_cspace)
  209.         ((gs_color_space *)&pcs->params.indexed.base_space, pgs);
  210. }
  211.  
  212. /* Color space reference count adjustment ditto. */
  213.  
  214. private void
  215. gx_adjust_cspace_Separation(const gs_color_space *pcs, gs_state *pgs, int delta)
  216. {    rc_adjust_const(pcs->params.separation.map, delta, pgs->memory,
  217.             "gx_adjust_Separation");
  218.     (*pcs->params.separation.alt_space.type->adjust_cspace_count)
  219.      ((const gs_color_space *)&pcs->params.separation.alt_space, pgs, delta);
  220. }
  221.  
  222. private void
  223. gx_adjust_cspace_Indexed(const gs_color_space *pcs, gs_state *pgs, int delta)
  224. {    if ( pcs->params.indexed.use_proc )
  225.     {    rc_adjust_const(pcs->params.indexed.lookup.map, delta,
  226.                 pgs->memory, "gx_adjust_Indexed");
  227.     }
  228.     (*pcs->params.indexed.base_space.type->adjust_cspace_count)
  229.      ((const gs_color_space *)&pcs->params.indexed.base_space, pgs, delta);
  230. }
  231.  
  232. /* GC procedures ditto. */
  233.  
  234. #define pcs ((gs_color_space *)vptr)
  235.  
  236. private ENUM_PTRS_BEGIN_PROC(gx_enum_ptrs_Separation) {
  237.     return (*pcs->params.separation.alt_space.type->enum_ptrs)
  238.          (&pcs->params.separation.alt_space,
  239.           sizeof(pcs->params.separation.alt_space), index, pep);
  240. } ENUM_PTRS_END_PROC
  241. private RELOC_PTRS_BEGIN(gx_reloc_ptrs_Separation) {
  242.     (*pcs->params.separation.alt_space.type->reloc_ptrs)
  243.       (&pcs->params.separation.alt_space, sizeof(gs_base_color_space), gcst);
  244. } RELOC_PTRS_END
  245.  
  246. private ENUM_PTRS_BEGIN(gx_enum_ptrs_Indexed) {
  247.     return (*pcs->params.indexed.base_space.type->enum_ptrs)
  248.          (&pcs->params.indexed.base_space,
  249.           sizeof(pcs->params.indexed.base_space), index-1, pep);
  250.     }
  251.     case 0:
  252.         if ( pcs->params.indexed.use_proc )
  253.           *pep = (void *)pcs->params.indexed.lookup.map;
  254.         else
  255.           {    pcs->params.indexed.lookup.table.size =
  256.               (pcs->params.indexed.hival + 1) *
  257.                 pcs->params.indexed.base_space.type->num_components;
  258.             *pep = &pcs->params.indexed.lookup.table;
  259.             return ptr_const_string_type;
  260.           }
  261.         break;
  262. ENUM_PTRS_END
  263. private RELOC_PTRS_BEGIN(gx_reloc_ptrs_Indexed) {
  264.     (*pcs->params.indexed.base_space.type->reloc_ptrs)
  265.       (&pcs->params.indexed.base_space, sizeof(gs_base_color_space), gcst);
  266.     if ( pcs->params.indexed.use_proc )
  267.       RELOC_PTR(gs_color_space, params.indexed.lookup.map);
  268.     else
  269.       RELOC_CONST_STRING_PTR(gs_color_space, params.indexed.lookup.table);
  270. } RELOC_PTRS_END
  271.  
  272. #undef pcs
  273.