diff options
Diffstat (limited to 'base/gsht.c')
-rw-r--r-- | base/gsht.c | 133 |
1 files changed, 78 insertions, 55 deletions
diff --git a/base/gsht.c b/base/gsht.c index bc72f0e1..2b8567f9 100644 --- a/base/gsht.c +++ b/base/gsht.c @@ -17,6 +17,7 @@ /* setscreen operator for Ghostscript library */ #include "memory_.h" #include "string_.h" +#include "assert_.h" #include <stdlib.h> /* for qsort */ #include "gx.h" #include "gserrors.h" @@ -25,6 +26,7 @@ #include "gxarith.h" /* for igcd */ #include "gzstate.h" #include "gxdevice.h" /* for gzht.h */ +#include "gxdevsop.h" #include "gzht.h" #include "gxfmap.h" /* For effective transfer usage in threshold */ #include "gp.h" @@ -168,12 +170,12 @@ gs_currentscreenlevels(const gs_gstate * pgs) { int gi = 0; - if (pgs->device != 0) + if (pgs->device != NULL) gi = pgs->device->color_info.gray_index; if (gi != GX_CINFO_COMP_NO_INDEX) - return pgs->dev_ht->components[gi].corder.num_levels; + return pgs->dev_ht[HT_OBJTYPE_DEFAULT]->components[gi].corder.num_levels; else - return pgs->dev_ht->components[0].corder.num_levels; + return pgs->dev_ht[HT_OBJTYPE_DEFAULT]->components[0].corder.num_levels; } /* .setscreenphase */ @@ -321,9 +323,9 @@ gx_ht_copy_ht_order(gx_ht_order * pdest, gx_ht_order * psrc, gs_memory_t * mem) psrc->procs, mem); if (code < 0) return code; - if (pdest->levels != 0) + if (pdest->levels != NULL) memcpy(pdest->levels, psrc->levels, psrc->num_levels * sizeof(uint)); - if (pdest->bit_data != 0) + if (pdest->bit_data != NULL) memcpy(pdest->bit_data, psrc->bit_data, (size_t)psrc->num_bits * psrc->procs->bit_data_elt_size); pdest->transfer = psrc->transfer; @@ -576,13 +578,13 @@ gx_ht_order_release(gx_ht_order * porder, gs_memory_t * mem, bool free_cache) { /* "free cache" is a proxy for "differs from default" */ if (free_cache) { - if (porder->cache != 0) + if (porder->cache != NULL) gx_ht_free_cache(mem, porder->cache); } porder->cache = 0; rc_decrement(porder->transfer, "gx_ht_order_release(transfer)"); porder->transfer = 0; - if (porder->data_memory != 0) { + if (porder->data_memory != NULL) { gs_free_object(porder->data_memory, porder->bit_data, "gx_ht_order_release(bit_data)"); gs_free_object(porder->data_memory, porder->levels, @@ -644,53 +646,53 @@ int gs_color_name_component_number(gx_device * dev, const char * pname, int name_size, int halftonetype) { - int num_colorant; + int num_colorant = -1; /* initialize to "unknown" */ + int color_component_type = NO_COMP_NAME_TYPE_HT; + bool devn = dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0); -#define check_colorant_name(dev, name) \ - ((*dev_proc(dev, get_color_comp_index)) (dev, name, strlen(name), NO_COMP_NAME_TYPE_HT)) +#define check_colorant_name(dev, name, component_type) \ + ((*dev_proc(dev, get_color_comp_index)) (dev, name, strlen(name), component_type)) -#define check_colorant_name_length(dev, name, length) \ - ((*dev_proc(dev, get_color_comp_index)) (dev, name, length, NO_COMP_NAME_TYPE_HT)) +#define check_colorant_name_length(dev, name, length, component_type) \ + ((*dev_proc(dev, get_color_comp_index)) (dev, name, length, component_type)) #define check_name(str, pname, length) \ ((strlen(str) == length) && (strncmp(pname, str, length) == 0)) /* - * Check if this is a device colorant. - */ - num_colorant = check_colorant_name_length(dev, pname, name_size); - if (num_colorant >= 0) { - /* - * The device will return GX_DEVICE_COLOR_MAX_COMPONENTS if the - * colorant is logically present in the device but not being used - * because a SeparationOrder parameter is specified. Since we are - * using this value to indicate 'Default', we use -1 to indicate - * that the colorant is not really being used. - */ - if (num_colorant == GX_DEVICE_COLOR_MAX_COMPONENTS) - num_colorant = -1; - return num_colorant; - } - - /* * Check if this is the default component */ if (check_name("Default", pname, name_size)) return GX_DEVICE_COLOR_MAX_COMPONENTS; + if (check_cmyk_color_model_comps(dev)) + color_component_type = SEPARATION_NAME; /* allow separations to be added */ + + /* + * Check if this is a device colorant. + */ /* Halftones set by setcolorscreen, and (we think) */ - /* Type 2 and Type 4 halftones, are supposed to work */ + /* Type 2, 4, and 5 halftones, are supposed to work */ /* for both RGB and CMYK, so we need a special check here. */ if (halftonetype == ht_type_colorscreen || - halftonetype == ht_type_multiple_colorscreen) { + halftonetype == ht_type_multiple_colorscreen || + (halftonetype == ht_type_multiple && devn)) { + /* Note that Red, Green, Blue and/or Gray can be added using setcolorspace */ + /* we just don't automatically add it as a result of sethalftone */ + /* The NO_COMP_NAME_TYPE_HT won't add colorants */ if (check_name("Red", pname, name_size)) - num_colorant = check_colorant_name(dev, "Cyan"); + num_colorant = check_colorant_name(dev, "Cyan", NO_COMP_NAME_TYPE_HT); else if (check_name("Green", pname, name_size)) - num_colorant = check_colorant_name(dev, "Magenta"); + num_colorant = check_colorant_name(dev, "Magenta", NO_COMP_NAME_TYPE_HT); else if (check_name("Blue", pname, name_size)) - num_colorant = check_colorant_name(dev, "Yellow"); + num_colorant = check_colorant_name(dev, "Yellow", NO_COMP_NAME_TYPE_HT); else if (check_name("Gray", pname, name_size)) - num_colorant = check_colorant_name(dev, "Black"); + num_colorant = check_colorant_name(dev, "Black", NO_COMP_NAME_TYPE_HT); + } + if (num_colorant < 0) + num_colorant = check_colorant_name_length(dev, pname, name_size, color_component_type); + + if (num_colorant >= 0) { /* * The device will return GX_DEVICE_COLOR_MAX_COMPONENTS if the * colorant is logically present in the device but not being used @@ -700,12 +702,12 @@ gs_color_name_component_number(gx_device * dev, const char * pname, */ if (num_colorant == GX_DEVICE_COLOR_MAX_COMPONENTS) num_colorant = -1; - + return num_colorant; + } #undef check_colorant_name #undef check_colorant_name_length #undef check_name - } return num_colorant; } @@ -949,7 +951,8 @@ gx_gstate_dev_ht_install( gs_gstate * pgs, gx_device_halftone * pdht, gs_halftone_type type, - const gx_device * dev ) + const gx_device * dev, + gs_HT_objtype_t objtype ) { gx_device_halftone dht; int num_comps = pdht->num_dev_comp; @@ -960,6 +963,8 @@ gx_gstate_dev_ht_install( uint w, h; int dw, dh; + assert(objtype < HT_OBJTYPE_COUNT); + /* construct the new device halftone structure */ memset(&dht.order, 0, sizeof(dht.order)); /* the rc field is filled in later */ @@ -988,7 +993,7 @@ gx_gstate_dev_ht_install( * by clearing the corresponding pointers in the operand halftone's * orders. */ - if (pdht->components != 0) { + if (pdht->components != NULL) { int input_ncomps = pdht->num_comp; for (i = 0; i < input_ncomps && code >= 0; i++) { @@ -1101,27 +1106,28 @@ gx_gstate_dev_ht_install( * we still need. */ if (code >= 0) { - gx_device_halftone * pgsdht = pgs->dev_ht; - rc_header tmp_rc; - - if (pgsdht != 0 && pgsdht->rc.ref_count == 1) { - if (pdht != pgsdht) - gx_device_halftone_release(pgsdht, pgsdht->rc.memory); + gx_device_halftone **ppgsdht; + rc_header tmp_rc; + + /* The pgsdht corresponds to the one we will be installing according to 'objtype' */ + ppgsdht = &(pgs->dev_ht[objtype]); + if (*ppgsdht != NULL && (*ppgsdht)->rc.ref_count == 1) { + if (pdht != *ppgsdht) + gx_device_halftone_release(*ppgsdht, (*ppgsdht)->rc.memory); } else { - rc_unshare_struct( pgs->dev_ht, + rc_unshare_struct( *ppgsdht, gx_device_halftone, &st_device_halftone, pgs->memory, BEGIN code = gs_error_VMerror; goto err; END, "gx_gstate_dev_ht_install" ); - pgsdht = pgs->dev_ht; } /* * Everything worked. "Assume ownership" of the appropriate * portions of the source device halftone by clearing the * associated references. Since we might have - * pdht == pgs->dev_ht, this must done before updating pgs->dev_ht. + * pdht == pgs->dev_ht[], this must done before updating pgs->dev_ht[]. * * If the default order has been used for a device component, and * any of the source component orders share their levels or bit_data @@ -1130,7 +1136,7 @@ gx_gstate_dev_ht_install( * be cleared immediately below, so subsequently it will not be * possible to tell if that this information is being shared. */ - if (pdht->components != 0) { + if (pdht->components != NULL) { int input_ncomps = pdht->num_comp; for (i = 0; i < input_ncomps; i++) { @@ -1150,9 +1156,9 @@ gx_gstate_dev_ht_install( memset(&pdht->order, 0, sizeof(pdht->order)); } - tmp_rc = pgsdht->rc; - *pgsdht = dht; - pgsdht->rc = tmp_rc; + tmp_rc = (*ppgsdht)->rc; + **ppgsdht = dht; + (*ppgsdht)->rc = tmp_rc; /* update the effective transfer function array */ gx_gstate_set_effective_xfer(pgs); @@ -1180,6 +1186,22 @@ gx_gstate_dev_ht_install( } /* + * Copy the dev_ht[HT_OBJTYPE_DEFAULT] to the dev_ht[] for the specified object type. + */ +int +gx_gstate_dev_ht_copy_to_objtype(gs_gstate *pgs, gs_HT_objtype_t objtype) +{ + gx_device_halftone *pdht = pgs->dev_ht[HT_OBJTYPE_DEFAULT]; /* the current dev_ht */ + + if (objtype >= HT_OBJTYPE_COUNT) { + return_error(gs_error_undefined); + } + rc_increment(pdht); + pgs->dev_ht[objtype] = pdht; + return 0; +} + +/* * Install a new halftone in the graphics state. Note that we copy the top * level of the gs_halftone and the gx_device_halftone, and take ownership * of any substructures. @@ -1194,7 +1216,7 @@ gx_ht_install(gs_gstate * pgs, const gs_halftone * pht, int code; pdht->num_dev_comp = pgs->device->color_info.num_components; - if (old_ht != 0 && old_ht->rc.memory == mem && + if (old_ht != NULL && old_ht->rc.memory == mem && old_ht->rc.ref_count == 1 ) new_ht = old_ht; @@ -1203,7 +1225,8 @@ gx_ht_install(gs_gstate * pgs, const gs_halftone * pht, mem, return_error(gs_error_VMerror), "gx_ht_install(new halftone)"); code = gx_gstate_dev_ht_install(pgs, - pdht, pht->type, gs_currentdevice_inline(pgs)); + pdht, pht->type, gs_currentdevice_inline(pgs), + pht->objtype); if (code < 0) { if (new_ht != old_ht) gs_free_object(mem, new_ht, "gx_ht_install(new halftone)"); @@ -1242,7 +1265,7 @@ gx_ht_install(gs_gstate * pgs, const gs_halftone * pht, void gx_gstate_set_effective_xfer(gs_gstate * pgs) { - gx_device_halftone *pdht = pgs->dev_ht; + gx_device_halftone *pdht = pgs->dev_ht[HT_OBJTYPE_DEFAULT]; gx_transfer_map *pmap; gx_ht_order *porder; int i, component_num, non_id_count; |