home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1996 February / PCWK0296.iso / sharewar / dos / program / gs300sr1 / gs300sr1.exe / ZCSPACE2.C < prev    next >
C/C++ Source or Header  |  1994-07-31  |  9KB  |  270 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. /* zcspace2.c */
  20. /* Level 2 color space operators */
  21. #include "string_.h"            /* for strlen */
  22. #include "ghost.h"
  23. #include "errors.h"
  24. #include "oper.h"
  25. #include "gscolor.h"
  26. #include "gscspace.h"
  27. #include "gscolor2.h"
  28. #include "dstack.h"        /* for systemdict */
  29. #include "estack.h"
  30. #include "idict.h"
  31. #include "idparam.h"
  32. #include "igstate.h"
  33. #include "iname.h"        /* for name_eq */
  34. #include "store.h"
  35.  
  36. /* Imported from gscolor2.c */
  37. extern const gs_color_space_type
  38.     gs_color_space_type_Separation,
  39.     gs_color_space_type_Pattern;
  40.  
  41. /* Imported from zcie.c */
  42. extern int
  43.     zcolorspace_CIEBasedABC(P3(const ref *, gs_color_space *, ref_cie_procs *)),
  44.     zcolorspace_CIEBasedA(P3(const ref *, gs_color_space *, ref_cie_procs *));
  45. /* Imported from zcsindex.c */
  46. extern int zcolorspace_Indexed(P3(const ref *, gs_color_space *, ref *));
  47. extern int zcolorspace_Separation(P3(const ref *, gs_color_space *,
  48.                                      ref_separation_params *));
  49.  
  50. /* Forward references */
  51. typedef enum { cs_allow_base, cs_allow_paint, cs_allow_all } cs_allowed;
  52. private int cspace_param(P4(const ref *, gs_color_space *, ref_color_procs *, cs_allowed));
  53.  
  54. /* Initialization */
  55. private void
  56. zcspace2_init(void)
  57. {    /* Create the names of the color spaces. */
  58.     ref csna;
  59.     typedef struct { const char _ds *s; int i; } csni;
  60.     static const csni nia[] = {
  61.         {"DeviceGray", (int)gs_color_space_index_DeviceGray},
  62.         {"DeviceRGB", (int)gs_color_space_index_DeviceRGB},
  63.         {"DeviceCMYK", (int)gs_color_space_index_DeviceCMYK},
  64.         {"CIEBasedABC", (int)gs_color_space_index_CIEBasedABC},
  65.         {"CIEBasedA", (int)gs_color_space_index_CIEBasedA},
  66.         {"Separation", (int)gs_color_space_index_Separation},
  67.         {"Indexed", (int)gs_color_space_index_Indexed},
  68.         {"Pattern", (int)gs_color_space_index_Pattern}
  69.     };
  70.     int i;
  71.     ialloc_ref_array(&csna, a_readonly, countof(nia), "ColorSpaceNames");
  72.     for ( i = 0; i < countof(nia); i++ )
  73.     {    const char _ds *str = nia[i].s;
  74.         name_ref((const byte *)str, strlen(str), csna.value.refs + nia[i].i, 0);
  75.     }
  76.     dict_put_string(systemdict, "ColorSpaceNames", &csna);
  77. }
  78.  
  79.  
  80. /* - currentcolorspace <cspace> */
  81. int
  82. zcurrentcolorspace(register os_ptr op)
  83. {    push(1);
  84.     if ( r_has_type(&istate->colorspace.array, t_null) )
  85.     {    /* Create the 1-element array on the fly. */
  86.         const gs_color_space *pcs = gs_currentcolorspace(igs);
  87.         ref *pcsna;
  88.         dict_find_string(systemdict, "ColorSpaceNames", &pcsna);
  89.         make_tasv(op, t_array, a_readonly, 1, refs,
  90.               pcsna->value.refs + (int)pcs->type->index);
  91.     }
  92.     else
  93.         *op = istate->colorspace.array;
  94.     return 0;
  95. }
  96.  
  97. /* <cspace> setcolorspace - */
  98. int
  99. zsetcolorspace(register os_ptr op)
  100. {    gs_color_space cs;
  101.     ref_color_procs procs;
  102.     ref_colorspace cspace_old;
  103.     es_ptr ep = esp;
  104.     int code;
  105.     procs = istate->colorspace.procs;
  106.     code = cspace_param((const ref *)op, &cs, &procs, cs_allow_all);
  107.     if ( code < 0 )
  108.     {    esp = ep;
  109.         return code;
  110.     }
  111.     /* The color space installation procedure may refer to */
  112.     /* istate->colorspace.procs. */
  113.     cspace_old = istate->colorspace;
  114.     if ( r_has_type(op, t_name) )
  115.         make_null(&istate->colorspace.array);    /* no params */
  116.     else
  117.         istate->colorspace.array = *op;
  118.     istate->colorspace.procs = procs;
  119.     code = gs_setcolorspace(igs, &cs);
  120.     if ( code < 0 )
  121.     {    istate->colorspace = cspace_old;
  122.         esp = ep;
  123.         return code;
  124.     }
  125.     pop(1);
  126.     return (esp == ep ? 0 : o_push_estack);
  127. }
  128.  
  129. /* ------ Initialization procedure ------ */
  130.  
  131. op_def zcspace2_l2_op_defs[] = {
  132.         op_def_begin_level2(),
  133.     {"0currentcolorspace", zcurrentcolorspace},
  134.     {"1setcolorspace", zsetcolorspace},
  135.     op_def_end(zcspace2_init)
  136. };
  137.  
  138. /* ------ Internal procedures ------ */
  139.  
  140. /* Extract the parameters for a color space. */
  141. private int
  142. cspace_param(const ref *pcsref, gs_color_space *pcs,
  143.   ref_color_procs *pcprocs, cs_allowed allow)
  144. {    const ref *pcsa;
  145.     uint asize;
  146.     ref *pcsna;
  147.     int csi;
  148.     int code;
  149.     if ( r_has_type(pcsref, t_array) )
  150.     {    check_read(*pcsref);
  151.         pcsa = pcsref->value.const_refs;
  152.         asize = r_size(pcsref);
  153.         if ( asize == 0 )
  154.             return_error(e_rangecheck);
  155.     }
  156.     else
  157.     {    pcsa = pcsref;
  158.         asize = 1;
  159.     }
  160.     check_type(*pcsa, t_name);
  161.     dict_find_string(systemdict, "ColorSpaceNames", &pcsna);
  162.     for ( csi = 0; !name_eq(pcsa, pcsna->value.refs + csi); )
  163.     {    if ( ++csi == r_size(pcsna) )
  164.             return_error(e_rangecheck);
  165.     }
  166.     pcsa++;
  167.     asize--;
  168.     /* Note: to avoid having to undo allocations, we should make all */
  169.     /* checks before any recursive calls of cspace_params. */
  170.     /* Unfortunately, we can't do this in the case of Indexed spaces. */
  171.     switch ( (gs_color_space_index)csi )
  172.     {
  173.     case gs_color_space_index_DeviceGray:
  174.         if ( asize != 0 )
  175.             return_error(e_rangecheck);
  176.         pcs->type = &gs_color_space_type_DeviceGray;
  177.         break;
  178.     case gs_color_space_index_DeviceRGB:
  179.         if ( asize != 0 )
  180.             return_error(e_rangecheck);
  181.         pcs->type = &gs_color_space_type_DeviceRGB;
  182.         break;
  183.     case gs_color_space_index_DeviceCMYK:
  184.         if ( asize != 0 )
  185.             return_error(e_rangecheck);
  186.         pcs->type = &gs_color_space_type_DeviceCMYK;
  187.         break;
  188.     case gs_color_space_index_CIEBasedABC:
  189.         if ( asize != 1 )
  190.             return_error(e_rangecheck);
  191.         code = zcolorspace_CIEBasedABC(pcsa, pcs, &pcprocs->cie);
  192.         if ( code < 0 )
  193.             return code;
  194.         /*pcs->type = &gs_color_space_type_CIEBasedABC;*/    /* set by zcolorspace... */
  195.         break;
  196.     case gs_color_space_index_CIEBasedA:
  197.         if ( asize != 1 )
  198.             return_error(e_rangecheck);
  199.         code = zcolorspace_CIEBasedA(pcsa, pcs, &pcprocs->cie);
  200.         if ( code < 0 )
  201.             return code;
  202.         /*pcs->type = &gs_color_space_type_CIEBasedA;*/    /* set by zcolorspace... */
  203.         break;
  204.     case gs_color_space_index_Separation:
  205.         if ( allow == cs_allow_base )
  206.             return_error(e_rangecheck);
  207.         if ( asize != 3 )
  208.             return_error(e_rangecheck);
  209.         switch ( r_type(pcsa) )
  210.         {
  211.         default:
  212.             return_error(e_typecheck);
  213.         case t_string:
  214.         case t_name:
  215.             ;
  216.         }
  217.         check_proc(pcsa[2]);
  218.         code = cspace_param(pcsa + 1, (gs_color_space *)&pcs->params.separation.alt_space, pcprocs, cs_allow_base);
  219.         if ( code < 0 )
  220.             return code;
  221.         code = zcolorspace_Separation(pcsa, pcs, &pcprocs->special.separation);
  222.         if ( code < 0 )
  223.             return code;
  224.         /*pcs->type = &gs_color_space_type_Separation;*/    /* set by zcolorspace... */
  225.         break;
  226.     case gs_color_space_index_Indexed:
  227.         if ( allow == cs_allow_base )
  228.             return_error(e_rangecheck);
  229.         if ( asize != 3 )
  230.             return_error(e_rangecheck);
  231.         check_type(pcsa[1], t_integer);
  232.         if ( pcsa[1].value.intval < 0 || pcsa[1].value.intval > 4095 )
  233.             return_error(e_rangecheck);
  234.         /* We must get the base space now, rather than later, */
  235.         /* so we can check the length of the table against */
  236.         /* the num_components of the base space. */
  237.         code = cspace_param(pcsa, (gs_color_space *)&pcs->params.indexed.base_space, pcprocs, cs_allow_base);
  238.         if ( code < 0 )
  239.             return code;
  240.         code = zcolorspace_Indexed(pcsa, pcs, &pcprocs->special.index_proc);
  241.         if ( code < 0 )
  242.             return code;
  243.         /*pcs->type = &gs_color_space_type_Indexed;*/    /* set by zcolorspace... */
  244.         break;
  245.     case gs_color_space_index_Pattern:
  246.         if ( allow != cs_allow_all )
  247.             return_error(e_rangecheck);
  248.         switch ( asize )
  249.         {
  250.         case 0:        /* no base space */
  251.             pcs->params.pattern.has_base_space = false;
  252.             break;
  253.         default:
  254.             return_error(e_rangecheck);
  255.         case 1:
  256.             pcs->params.pattern.has_base_space = true;
  257.             code = cspace_param(pcsa,
  258.               (gs_color_space *)&pcs->params.pattern.base_space,
  259.               pcprocs, cs_allow_paint);
  260.             if ( code < 0 )
  261.                 return code;
  262.         }
  263.         pcs->type = &gs_color_space_type_Pattern;
  264.         break;
  265.     default:
  266.         return_error(e_typecheck);
  267.     }
  268.     return 0;
  269. }
  270.