home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1992, 1993 Aladdin Enterprises. All rights reserved.
-
- This file is part of Aladdin Ghostscript.
-
- Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
- or distributor accepts any responsibility for the consequences of using it,
- or for whether it serves any particular purpose or works at all, unless he
- or she says so in writing. Refer to the Aladdin Ghostscript Free Public
- License (the "License") for full details.
-
- Every copy of Aladdin Ghostscript must include a copy of the License,
- normally in a plain ASCII text file named PUBLIC. The License grants you
- the right to copy, modify and redistribute Aladdin Ghostscript, but only
- under certain conditions described in the License. Among other things, the
- License requires that the copyright notice and this notice be preserved on
- all copies.
- */
-
- /* gscolor2.c */
- /* Level 2 color and halftone operators for Ghostscript library */
- #include "gx.h"
- #include "gserrors.h"
- #include "gxarith.h"
- #include "gxfixed.h" /* ditto */
- #include "gxmatrix.h" /* for gzstate.h */
- #include "gscspace.h" /* for gscolor2.h */
- #include "gxcolor2.h"
- #include "gzstate.h"
- #include "gscie.h"
-
- /* Define the Level 2 color space types. */
- #define cs_procs(scope, remap, install, adjust, enum_p, reloc_p)\
- scope cs_proc_remap_color(remap);\
- scope cs_proc_install_cspace(install);\
- scope cs_proc_adjust_cspace_count(adjust);\
- scope struct_proc_enum_ptrs(enum_p);\
- scope struct_proc_reloc_ptrs(reloc_p)
- cs_procs(extern, gx_remap_CIEBasedABC, gx_install_CIEBasedABC,
- gx_adjust_cspace_CIEBasedABC,
- gx_enum_ptrs_CIEBasedABC, gx_reloc_ptrs_CIEBasedABC);
- cs_procs(extern, gx_remap_CIEBasedA, gx_install_CIEBasedA,
- gx_adjust_cspace_CIEBasedA,
- gx_enum_ptrs_CIEBasedA, gx_reloc_ptrs_CIEBasedA);
- cs_procs(private, gx_remap_Separation, gx_install_Separation,
- gx_adjust_cspace_Separation,
- gx_enum_ptrs_Separation, gx_reloc_ptrs_Separation);
- cs_procs(private, gx_remap_Indexed, gx_install_Indexed,
- gx_adjust_cspace_Indexed,
- gx_enum_ptrs_Indexed, gx_reloc_ptrs_Indexed);
- private cs_proc_init_color(gx_init_Separation);
- const gs_color_space_type
- gs_color_space_type_CIEBasedABC =
- { gs_color_space_index_CIEBasedABC, 3,
- gx_init_paint_3, gx_remap_CIEBasedABC, gx_install_CIEBasedABC,
- gx_adjust_cspace_CIEBasedABC, gx_no_adjust_color_count,
- gx_enum_ptrs_CIEBasedABC, gx_reloc_ptrs_CIEBasedABC
- },
- gs_color_space_type_CIEBasedA =
- { gs_color_space_index_CIEBasedA, 1,
- gx_init_paint_1, gx_remap_CIEBasedA, gx_install_CIEBasedA,
- gx_adjust_cspace_CIEBasedA, gx_no_adjust_color_count,
- gx_enum_ptrs_CIEBasedA, gx_reloc_ptrs_CIEBasedA
- },
- gs_color_space_type_Separation =
- { gs_color_space_index_Separation, 1,
- gx_init_Separation, gx_remap_Separation, gx_install_Separation,
- gx_adjust_cspace_Separation, gx_no_adjust_color_count,
- gx_enum_ptrs_Separation, gx_reloc_ptrs_Separation
- },
- gs_color_space_type_Indexed =
- { gs_color_space_index_Indexed, 1,
- gx_init_paint_1, gx_remap_Indexed, gx_install_Indexed,
- gx_adjust_cspace_Indexed, gx_no_adjust_color_count,
- gx_enum_ptrs_Indexed, gx_reloc_ptrs_Indexed
- };
-
- /* setcolorspace */
- int
- gs_setcolorspace(gs_state *pgs, gs_color_space *pcs)
- { int code;
- gs_color_space cs_old;
- gs_client_color cc_old;
- if ( pgs->in_cachedevice )
- return_error(gs_error_undefined);
- cs_old = *pgs->color_space;
- cc_old = *pgs->ccolor;
- (*pcs->type->adjust_cspace_count)(pcs, pgs, 1);
- *pgs->color_space = *pcs;
- if ( (code = (*pcs->type->install_cspace)(pcs, pgs)) < 0 )
- goto rcs;
- cs_full_init_color(pgs->ccolor, pcs);
- (*cs_old.type->adjust_color_count)(&cc_old, &cs_old, pgs, -1);
- (*cs_old.type->adjust_cspace_count)(&cs_old, pgs, -1);
- gx_unset_dev_color(pgs);
- return code;
- /* Restore the color space if installation failed. */
- rcs: *pgs->color_space = cs_old;
- (*pcs->type->adjust_cspace_count)(pcs, pgs, -1);
- return code;
- }
-
- /* currentcolorspace */
- const gs_color_space *
- gs_currentcolorspace(const gs_state *pgs)
- { return pgs->color_space;
- }
-
- /* setcolor */
- int
- gs_setcolor(gs_state *pgs, const gs_client_color *pcc)
- { gs_color_space *pcs = pgs->color_space;
- if ( pgs->in_cachedevice )
- return_error(gs_error_undefined);
- (*pcs->type->adjust_color_count)(pcc, pcs, pgs, 1);
- (*pcs->type->adjust_color_count)(pgs->ccolor, pcs, pgs, -1);
- *pgs->ccolor = *pcc;
- gx_unset_dev_color(pgs);
- return 0;
- }
-
- /* currentcolor */
- const gs_client_color *
- gs_currentcolor(const gs_state *pgs)
- { return pgs->ccolor;
- }
-
- /* setoverprint */
- void
- gs_setoverprint(gs_state *pgs, int ovp)
- { pgs->overprint = ovp;
- }
-
- /* currentoverprint */
- int
- gs_currentoverprint(const gs_state *pgs)
- { return pgs->overprint;
- }
-
- /* ------ Internal routines ------ */
-
- /* Initialize Level 2 colors. */
-
- private void
- gx_init_Separation(gs_client_color *pcc, const gs_color_space *pcs)
- { pcc->paint.values[0] = 1.0;
- }
-
- /* Color remapping for Level 2 color spaces. */
- /* The CIE-based spaces are handled in gscie.c. */
-
- private int
- gx_remap_Separation(const gs_client_color *pc, const gs_color_space *pcs,
- gx_device_color *pdc, const gs_state *pgs)
- { float tint = pc->paint.values[0];
- int code;
- gs_client_color cc;
- if ( tint < 0 ) tint = 0;
- else if ( tint > 1 ) tint = 1;
- code = (*pcs->params.separation.map->proc.tint_transform)(&pcs->params.separation, tint, &cc.paint.values[0]);
- if ( code < 0 ) return code;
- return (*pcs->params.separation.alt_space.type->remap_color)(&cc,
- (const gs_color_space *)&pcs->params.separation.alt_space,
- pdc, pgs);
- }
-
- private int
- gx_remap_Indexed(const gs_client_color *pc, const gs_color_space *pcs,
- gx_device_color *pdc, const gs_state *pgs)
- { float value = pc->paint.values[0];
- int index =
- (is_fneg(value) ? 0 :
- value >= pcs->params.indexed.hival ?
- pcs->params.indexed.hival :
- (int)value);
- gs_client_color cc;
- if ( pcs->params.indexed.use_proc )
- { int code = (*pcs->params.indexed.lookup.map->proc.lookup_index)(&pcs->params.indexed, index, &cc.paint.values[0]);
- if ( code < 0 ) return code;
- }
- else
- { int m = pcs->params.indexed.base_space.type->num_components;
- const byte *pcomp =
- pcs->params.indexed.lookup.table.data + m * index;
- switch ( m )
- {
- default: return_error(gs_error_rangecheck);
- case 4: cc.paint.values[3] = pcomp[3] * (1.0 / 255.0);
- case 3: cc.paint.values[2] = pcomp[2] * (1.0 / 255.0);
- cc.paint.values[1] = pcomp[1] * (1.0 / 255.0);
- case 1: cc.paint.values[0] = pcomp[0] * (1.0 / 255.0);
- }
- }
- return (*pcs->params.indexed.base_space.type->remap_color)(&cc,
- (const gs_color_space *)&pcs->params.indexed.base_space,
- pdc, pgs);
- }
-
- /* Color space installation ditto. */
-
- private int
- gx_install_Separation(gs_color_space *pcs, gs_state *pgs)
- { return (*pcs->params.separation.alt_space.type->install_cspace)
- ((gs_color_space *)&pcs->params.separation.alt_space, pgs);
- }
-
- private int
- gx_install_Indexed(gs_color_space *pcs, gs_state *pgs)
- { return (*pcs->params.indexed.base_space.type->install_cspace)
- ((gs_color_space *)&pcs->params.indexed.base_space, pgs);
- }
-
- /* Color space reference count adjustment ditto. */
-
- private void
- gx_adjust_cspace_Separation(const gs_color_space *pcs, gs_state *pgs, int delta)
- { rc_adjust_const(pcs->params.separation.map, delta, pgs->memory,
- "gx_adjust_Separation");
- (*pcs->params.separation.alt_space.type->adjust_cspace_count)
- ((const gs_color_space *)&pcs->params.separation.alt_space, pgs, delta);
- }
-
- private void
- gx_adjust_cspace_Indexed(const gs_color_space *pcs, gs_state *pgs, int delta)
- { if ( pcs->params.indexed.use_proc )
- { rc_adjust_const(pcs->params.indexed.lookup.map, delta,
- pgs->memory, "gx_adjust_Indexed");
- }
- (*pcs->params.indexed.base_space.type->adjust_cspace_count)
- ((const gs_color_space *)&pcs->params.indexed.base_space, pgs, delta);
- }
-
- /* GC procedures ditto. */
-
- #define pcs ((gs_color_space *)vptr)
-
- private ENUM_PTRS_BEGIN_PROC(gx_enum_ptrs_Separation) {
- return (*pcs->params.separation.alt_space.type->enum_ptrs)
- (&pcs->params.separation.alt_space,
- sizeof(pcs->params.separation.alt_space), index, pep);
- } ENUM_PTRS_END_PROC
- private RELOC_PTRS_BEGIN(gx_reloc_ptrs_Separation) {
- (*pcs->params.separation.alt_space.type->reloc_ptrs)
- (&pcs->params.separation.alt_space, sizeof(gs_base_color_space), gcst);
- } RELOC_PTRS_END
-
- private ENUM_PTRS_BEGIN(gx_enum_ptrs_Indexed) {
- return (*pcs->params.indexed.base_space.type->enum_ptrs)
- (&pcs->params.indexed.base_space,
- sizeof(pcs->params.indexed.base_space), index-1, pep);
- }
- case 0:
- if ( pcs->params.indexed.use_proc )
- *pep = (void *)pcs->params.indexed.lookup.map;
- else
- { pcs->params.indexed.lookup.table.size =
- (pcs->params.indexed.hival + 1) *
- pcs->params.indexed.base_space.type->num_components;
- *pep = &pcs->params.indexed.lookup.table;
- return ptr_const_string_type;
- }
- break;
- ENUM_PTRS_END
- private RELOC_PTRS_BEGIN(gx_reloc_ptrs_Indexed) {
- (*pcs->params.indexed.base_space.type->reloc_ptrs)
- (&pcs->params.indexed.base_space, sizeof(gs_base_color_space), gcst);
- if ( pcs->params.indexed.use_proc )
- RELOC_PTR(gs_color_space, params.indexed.lookup.map);
- else
- RELOC_CONST_STRING_PTR(gs_color_space, params.indexed.lookup.table);
- } RELOC_PTRS_END
-
- #undef pcs
-