diff options
author | Michael Vrhel <michael.vrhel@artifex.com> | 2012-05-03 12:13:06 -0700 |
---|---|---|
committer | Michael Vrhel <michael.vrhel@artifex.com> | 2012-05-05 22:24:29 -0700 |
commit | 7b81312d205a2f9b89f40da4b4f6b67bcacd8ef1 (patch) | |
tree | 59a9ebf6d6b0424eb4b18e7c2e6a4d657f095afc /gs | |
parent | c5f91f9fa29922713d3751654dda09ccc8518801 (diff) |
Fix for issues in use of /SeparationOrder and /SeparationColorNames
Several issues and quite a bit of confusion in the code with respect
to this option. I believe this should clear some things up.
Documentation still needs to be updated as to how this option functions
and what devices it actually works with. Note that
SeparationOrder and SeparationColorNames really only works for the
tiffsep device. The psdcmyk device was never really set up for use
with this option. Not sure if we want to add it. Also, I discovered
that with the disabling of compressed color encoding, the tiffsep1
device renders incorrectly. I had not converted this device to planar
as I had thought that it performed halftoning during rendering. I
did not realize it was rendering 8 bit data and then doing
a thresholding operation. We may want to just move this to a planar
based device. In that case, we could use the fast planar halftoning.
Note that with this fix, the device will only create output for the
colorants listed in /SeparationOrder. The psdcmyk device was not
making use of the /SeparationOrder information properly. It is now
which makes for some different renderings in the ps3cet/29-07*.ps test
files which exercise /SeparationOrder changes. In such a case, the
device will not output any missing colorants, which previously
it was doing.
Diffstat (limited to 'gs')
-rw-r--r-- | gs/base/gdevdevn.c | 17 | ||||
-rw-r--r-- | gs/base/gdevpsd.c | 234 | ||||
-rw-r--r-- | gs/base/gdevtsep.c | 317 |
3 files changed, 220 insertions, 348 deletions
diff --git a/gs/base/gdevdevn.c b/gs/base/gdevdevn.c index fd30bbaea..9229306d7 100644 --- a/gs/base/gdevdevn.c +++ b/gs/base/gdevdevn.c @@ -391,8 +391,7 @@ devn_put_params(gx_device * pdev, gs_param_list * plist, int num_names = scna.size; fixed_colorant_names_list pcomp_names = pdevn_params->std_colorant_names; - /* Start the num_spot count after the std. colorants */ - num_spot = pdevn_params->num_std_colorant_names; + num_spot = pdevn_params->separations.num_separations; for (i = 0; i < num_names; i++) { /* Verify that the name is not one of our process colorants */ if (!check_process_color_names(pcomp_names, &scna.data[i])) { @@ -413,10 +412,11 @@ devn_put_params(gx_device * pdev, gs_param_list * plist, num_spot++; } } - pdevn_params->separations.num_separations = num_spot - npcmcolors; num_spot_changed = true; - for (i = npcmcolors; i < num_spot; i++) - pdevn_params->separation_order_map[i] = i; + for (i = pdevn_params->separations.num_separations; i < num_spot; i++) + pdevn_params->separation_order_map[i + pdevn_params->num_std_colorant_names] = + i + pdevn_params->num_std_colorant_names; + pdevn_params->separations.num_separations = num_spot; } /* * Process the SeparationOrder names. @@ -430,11 +430,12 @@ devn_put_params(gx_device * pdev, gs_param_list * plist, * Check if names match either the process color model or * SeparationColorNames. If not then error. */ - if ((comp_num = check_pcm_and_separation_names(pdev, pdevn_params, - (const char *)sona.data[i].data, sona.data[i].size, 0)) < 0) { + if ((comp_num = (*dev_proc(pdev, get_color_comp_index)) + (pdev, (const char *)sona.data[i].data, + sona.data[i].size, SEPARATION_NAME)) < 0) { return_error(gs_error_rangecheck); } - pdevn_params->separation_order_map[comp_num] = comp_num; + pdevn_params->separation_order_map[i] = comp_num; } } /* diff --git a/gs/base/gdevpsd.c b/gs/base/gdevpsd.c index 226f291fd..71e36770d 100644 --- a/gs/base/gdevpsd.c +++ b/gs/base/gdevpsd.c @@ -31,8 +31,6 @@ #include "gxgetbit.h" #include "gdevppla.h" -#define PSD_PLANAR 1 - #ifndef cmm_gcmmhlink_DEFINED #define cmm_gcmmhlink_DEFINED typedef void* gcmmhlink_t; @@ -68,13 +66,8 @@ static dev_proc_map_color_rgb(psd_map_color_rgb); static dev_proc_get_color_mapping_procs(get_psdrgb_color_mapping_procs); static dev_proc_get_color_mapping_procs(get_psd_color_mapping_procs); static dev_proc_get_color_comp_index(psd_get_color_comp_index); -#if PSD_PLANAR static dev_proc_encode_color(psd_encode_color); static dev_proc_decode_color(psd_decode_color); -#else -static dev_proc_encode_color(psd_encode_compressed_color); -static dev_proc_decode_color(psd_decode_compressed_color); -#endif static dev_proc_update_spot_equivalent_colors(psd_update_spot_equivalent_colors); static dev_proc_ret_devn_params(psd_ret_devn_params); @@ -304,17 +297,10 @@ const psd_device gs_psdrgb_device = * compressed encoding is not separable. If we do not have 64 bits then we * use a simple non-compressable encoding. */ -#if USE_COMPRESSED_ENCODING -#define NC GX_DEVICE_COLOR_MAX_COMPONENTS -#define SL GX_CINFO_SEP_LIN_NONE -#define ENCODE_COLOR psd_encode_compressed_color -#define DECODE_COLOR psd_decode_compressed_color -#else #define NC ARCH_SIZEOF_GX_COLOR_INDEX #define SL GX_CINFO_SEP_LIN #define ENCODE_COLOR psd_encode_color #define DECODE_COLOR psd_decode_color -#endif #define GCIB (ARCH_SIZEOF_GX_COLOR_INDEX * 8) /* @@ -350,9 +336,9 @@ const psd_device gs_psdcmyk_device = int psd_prn_open(gx_device * pdev) { -#if PSD_PLANAR psd_device *pdev_psd = (psd_device *) pdev; int code; + int k; pdev_psd->warning_given = false; /* With planar the depth can be more than 64. Update the color @@ -375,28 +361,17 @@ psd_prn_open(gx_device * pdev) pdev->color_info.num_components = GS_CLIENT_COLOR_MAX_COMPONENTS; pdev->color_info.max_components = GS_CLIENT_COLOR_MAX_COMPONENTS; } + /* Push this to the max amount as a default if someone has not set it */ + if (pdev_psd->devn_params.num_separation_order_names == 0) + for (k = 0; k < GS_CLIENT_COLOR_MAX_COMPONENTS; k++) { + pdev_psd->devn_params.separation_order_map[k] = k; + } pdev->color_info.depth = pdev->color_info.num_components * pdev_psd->devn_params.bitspercomponent; pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN; pdev->icc_struct->supports_devn = true; code = gdev_prn_open_planar(pdev, true); return code; -#else - int code = gdev_prn_open(pdev); - psd_device *pdev_psd = (psd_device *) pdev; - - pdev_psd->warning_given = false; -#endif - -#if !USE_COMPRESSED_ENCODING - /* - * If we are using the compressed encoding scheme, then set the separable - * and linear info. - */ - set_linear_color_bits_mask_shift(pdev); - pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN; -#endif - return code; } /* 2007/05/04 @@ -482,9 +457,33 @@ static void cmyk_cs_to_psdcmyk_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) { - int * map = ((psd_device *) dev)->devn_params.separation_order_map; - - cmyk_cs_to_devn_cm(dev, map, c, m, y, k, out); + const gs_devn_params *devn = psd_ret_devn_params(dev); + const int *map = devn->separation_order_map; + int j; + + if (devn->num_separation_order_names > 0) { + /* This is to set only those that we are using */ + for (j = 0; j < devn->num_separation_order_names; j++) { + switch (map[j]) { + case 0 : + out[0] = c; + break; + case 1: + out[1] = m; + break; + case 2: + out[2] = y; + break; + case 3: + out[3] = k; + break; + default: + break; + } + } + } else { + cmyk_cs_to_devn_cm(dev, map, c, m, y, k, out); + } } static void @@ -611,7 +610,6 @@ get_psd_color_mapping_procs(const gx_device * dev) return NULL; } -#if PSD_PLANAR /* * Encode a list of colorant values into a gx_color_index_value. */ @@ -651,31 +649,8 @@ psd_decode_color(gx_device * dev, gx_color_index color, gx_color_value * out) } return 0; } -#else -/* - * Encode a list of colorant values into a gx_color_index_value. - * With 64 bit gx_color_index values, we compress the colorant values. This - * allows us to handle more than 8 colorants. - */ -static gx_color_index -psd_encode_compressed_color(gx_device *dev, const gx_color_value colors[]) -{ - return devn_encode_compressed_color(dev, colors, &(((psd_device *)dev)->devn_params)); -} /* - * Decode a gx_color_index value back to a list of colorant values. - * With 64 bit gx_color_index values, we compress the colorant values. This - * allows us to handle more than 8 colorants. - */ -static int -psd_decode_compressed_color(gx_device * dev, gx_color_index color, gx_color_value * out) -{ - return devn_decode_compressed_color(dev, color, out, - &(((psd_device *)dev)->devn_params)); -} -#endif -/* * Convert a gx_color_index to RGB. */ static int @@ -982,9 +957,12 @@ psd_get_color_comp_index(gx_device * dev, const char * pname, /* This is a one shot deal. That is it will simply post a notice once that some colorants will be converted due to a limit being reached. It will not list names of colorants since then I would need to keep track of - which ones I have already mentioned */ + which ones I have already mentioned. Also, if someone is fooling with + num_order, then this warning is not given since they should know what + is going on already */ if (index < 0 && component_type == SEPARATION_NAME && - pdev->warning_given == false) { + pdev->warning_given == false && + pdev->devn_params.num_separation_order_names == 0) { dlprintf("**** Max spot colorants reached.\n"); dlprintf("**** Some colorants will be converted to equivalent CMYK values.\n"); pdev->warning_given = true; @@ -1024,38 +1002,50 @@ static int psd_setup(psd_write_ctx *xc, psd_device *dev) { int i; + int spot_count; #define NUM_CMYK_COMPONENTS 4 xc->base_bytes_pp = dev->devn_params.num_std_colorant_names; xc->num_channels = xc->base_bytes_pp; - xc->n_extra_channels = dev->devn_params.separations.num_separations; + if (dev->devn_params.num_separation_order_names == 0) { + xc->n_extra_channels = dev->devn_params.separations.num_separations; + } else { + /* Have to figure out how many in the order list were not std + colorants */ + spot_count = 0; + for (i = 0; i < dev->devn_params.num_separation_order_names; i++) { + if (dev->devn_params.separation_order_map[i] >= NUM_CMYK_COMPONENTS) { + spot_count++; + } + } + xc->n_extra_channels = spot_count; + } xc->width = dev->width; xc->height = dev->height; - /* * Determine the order of the output components. This is based upon * the SeparationOrder parameter. This parameter can be used to select * which planes are actually imaged. For the process color model channels * we image the channels which are requested. Non requested process color * model channels are simply filled with white. For spot colors we only - * image the requested channels. Note: There are no spot colors with - * the RGB color model. + * image the requested channels. */ - for (i = 0; i < xc->base_bytes_pp + xc->n_extra_channels; i++) - xc->chnl_to_position[i] = -1; for (i = 0; i < xc->base_bytes_pp + xc->n_extra_channels; i++) { - int sep_order_num = dev->devn_params.separation_order_map[i]; - - if (sep_order_num != GX_DEVICE_COLOR_MAX_COMPONENTS) { - if (i < NUM_CMYK_COMPONENTS) /* Do not rearrange CMYK */ - xc->chnl_to_position[i] = sep_order_num; - else { /* Re arrange separations */ + xc->chnl_to_position[i] = i; + xc->chnl_to_orig_sep[i] = i; + } + /* If we had a specify order name, then we may need to adjust things */ + if (dev->devn_params.num_separation_order_names > 0) { + for (i = 0; i < dev->devn_params.num_separation_order_names; i++) { + int sep_order_num = dev->devn_params.separation_order_map[i]; + if (sep_order_num >= NUM_CMYK_COMPONENTS) { xc->chnl_to_position[xc->num_channels] = sep_order_num; - xc->chnl_to_orig_sep[xc->num_channels++] = i; + xc->chnl_to_orig_sep[xc->num_channels++] = sep_order_num; } } + } else { + xc->num_channels += dev->devn_params.separations.num_separations; } - return 0; } @@ -1189,36 +1179,9 @@ psd_write_header(psd_write_ctx *xc, psd_device *pdev) return code; } -static void -psd_calib_row(gx_device *dev, psd_write_ctx *xc, byte **tile_data, const byte *row, - int channel, gcmmhlink_t link, int inn, int outn) -{ - int base_bytes_pp = xc->base_bytes_pp; - int n_extra_channels = xc->n_extra_channels; - int channels = base_bytes_pp + n_extra_channels; - int x; - unsigned char in[MAX_CHAN]; - - for (x = 0; x < xc->width; x++) { - if (channel < outn) { - int plane_idx; - - for (plane_idx = 0; plane_idx < inn; plane_idx++) - in[plane_idx] = row[x*channels+plane_idx]; - - gscms_transform_color(dev, link, &(in[0]), - &((*tile_data)[x]), 1); - - } else { - (*tile_data)[x] = 255 ^ row[x*channels+base_bytes_pp+channel]; - } - } -} - /* * Close device and clean up ICC structures. */ - static int psd_prn_close(gx_device *dev) { @@ -1262,7 +1225,6 @@ psd_prn_close(gx_device *dev) * SeparationOrder data. */ -#if PSD_PLANAR static int psd_write_image_data(psd_write_ctx *xc, gx_device_printer *pdev) { @@ -1348,74 +1310,6 @@ psd_write_image_data(psd_write_ctx *xc, gx_device_printer *pdev) } return code; } -#else -static int -psd_write_image_data(psd_write_ctx *xc, gx_device_printer *pdev) -{ - int code = 0; - int raster = gdev_prn_raster(pdev); - int i, j; - byte *line, *sep_line; - int base_bytes_pp = xc->base_bytes_pp; - int chan_idx; - psd_device *xdev = (psd_device *)pdev; - gcmmhlink_t link = xdev->output_icc_link; - byte * row, * unpacked; - int width = pdev->width; - int non_encodable_count = 0; - int num_comp = xc->num_channels; - - psd_write_16(xc, 0); /* Compression */ - - line = gs_alloc_bytes(pdev->memory, raster, "psd_write_image_data"); - sep_line = gs_alloc_bytes(pdev->memory, xc->width, "psd_write_sep_line"); - unpacked = gs_alloc_bytes(pdev->memory, width *num_comp, - "psd_write_image"); - if (line == NULL || sep_line == NULL || unpacked == NULL) - return_error(gs_error_VMerror); - - /* Print the output planes */ - for (chan_idx = 0; chan_idx < num_comp; chan_idx++) { - for (j = 0; j < xc->height; ++j) { - int data_pos = xc->chnl_to_position[chan_idx]; - - /* Check if the separation is present in the SeparationOrder */ - if (data_pos >= 0) { - code = gdev_prn_get_bits(pdev, j, line, &row); - /* Unpack the encoded color info */ - non_encodable_count += devn_unpack_row((gx_device *)pdev, - num_comp, &(xdev->devn_params), width, row, unpacked); - if (link == NULL) { - for (i = 0; i < xc->width; ++i) { - if (base_bytes_pp == 3) { - /* RGB */ - sep_line[i] = unpacked[i * num_comp + data_pos]; - } else { - /* CMYK */ - sep_line[i] = 255 - unpacked[i * num_comp + data_pos]; - } - } - } else { - psd_calib_row((gx_device*) xdev, xc, &sep_line, unpacked, data_pos, - link, xdev->output_profile->num_comps, - xdev->output_profile->num_comps_out); - } - psd_write(xc, sep_line, xc->width); - } else { - if (chan_idx < NUM_CMYK_COMPONENTS) { - /* Write empty process color */ - for (i = 0; i < xc->width; ++i) - sep_line[i] = 255; - psd_write(xc, sep_line, xc->width); - } - } - } - } - gs_free_object(pdev->memory, sep_line, "psd_write_sep_line"); - gs_free_object(pdev->memory, line, "psd_write_image_data"); - return code; -} -#endif static int psd_print_page(gx_device_printer *pdev, FILE *file) diff --git a/gs/base/gdevtsep.c b/gs/base/gdevtsep.c index a50557a41..9f19d614d 100644 --- a/gs/base/gdevtsep.c +++ b/gs/base/gdevtsep.c @@ -37,8 +37,6 @@ #include "gxgetbit.h" #include "gdevppla.h" -#define TIFFSEP_PLANAR 1 - /* * Some of the code in this module is based upon the gdevtfnx.c module. * gdevtfnx.c has the following message: @@ -391,12 +389,11 @@ static dev_proc_put_params(tiffsep_put_params); static dev_proc_print_page(tiffsep_print_page); static dev_proc_get_color_mapping_procs(tiffsep_get_color_mapping_procs); static dev_proc_get_color_comp_index(tiffsep_get_color_comp_index); -#if USE_COMPRESSED_ENCODING +#if USE_COMPRESSED_ENCODING /* Still needed for tiffsep1 */ static dev_proc_encode_color(tiffsep_encode_compressed_color); static dev_proc_decode_color(tiffsep_decode_compressed_color); -#else -static dev_proc_encode_color(tiffsep_encode_color); #endif +static dev_proc_encode_color(tiffsep_encode_color); static dev_proc_decode_color(tiffsep_decode_color); static dev_proc_update_spot_equivalent_colors(tiffsep_update_spot_equivalent_colors); static dev_proc_ret_devn_params(tiffsep_ret_devn_params); @@ -600,6 +597,7 @@ gs_private_st_composite_final(st_tiffsep_device, tiffsep_device, * compressed encoding is not separable. If we do not have 64 bits then we * use a simple non-compressable encoding. */ +/* Compressed color encoding only needed for tiffsep1 */ #if USE_COMPRESSED_ENCODING # define NC GX_DEVICE_COLOR_MAX_COMPONENTS # define SL GX_CINFO_SEP_LIN_NONE @@ -617,7 +615,7 @@ gs_private_st_composite_final(st_tiffsep_device, tiffsep_device, * TIFF devices with CMYK process color model and spot color support. */ static const gx_device_procs spot_cmyk_procs = - sep_device_procs(tiffsep_prn_open, tiffsep_prn_close, ENCODE_COLOR, DECODE_COLOR, + sep_device_procs(tiffsep_prn_open, tiffsep_prn_close, tiffsep_encode_color, tiffsep_decode_color, tiffsep_update_spot_equivalent_colors, tiffsep_put_params, NULL); static const gx_device_procs spot1_cmyk_procs = @@ -626,7 +624,7 @@ static const gx_device_procs spot1_cmyk_procs = const tiffsep_device gs_tiffsep_device = { - tiffsep_devices_body(tiffsep_device, spot_cmyk_procs, "tiffsep", NC, GX_CINFO_POLARITY_SUBTRACTIVE, GCIB, MAX_COLOR_VALUE, MAX_COLOR_VALUE, SL, "DeviceCMYK", tiffsep_print_page, tiffseps_print_page_copies, COMPRESSION_LZW), + tiffsep_devices_body(tiffsep_device, spot_cmyk_procs, "tiffsep", ARCH_SIZEOF_GX_COLOR_INDEX, GX_CINFO_POLARITY_SUBTRACTIVE, GCIB, MAX_COLOR_VALUE, MAX_COLOR_VALUE, GX_CINFO_SEP_LIN, "DeviceCMYK", tiffsep_print_page, tiffseps_print_page_copies, COMPRESSION_LZW), /* devn_params specific parameters */ { 8, /* Not used - Bits per color */ DeviceCMYKComponents, /* Names of color model colorants */ @@ -702,9 +700,33 @@ static void tiffsep_cmyk_cs_to_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) { - int * map = ((tiffsep_device *) dev)->devn_params.separation_order_map; - - cmyk_cs_to_devn_cm(dev, map, c, m, y, k, out); + const gs_devn_params *devn = tiffsep_ret_devn_params(dev); + const int *map = devn->separation_order_map; + int j; + + if (devn->num_separation_order_names > 0) { + /* This is to set only those that we are using */ + for (j = 0; j < devn->num_separation_order_names; j++) { + switch (map[j]) { + case 0 : + out[0] = c; + break; + case 1: + out[1] = m; + break; + case 2: + out[2] = y; + break; + case 3: + out[3] = k; + break; + default: + break; + } + } + } else { + cmyk_cs_to_devn_cm(dev, map, c, m, y, k, out); + } } static const gx_cm_color_map_procs tiffsep_cm_procs = { @@ -746,7 +768,8 @@ tiffsep_decode_compressed_color(gx_device * dev, gx_color_index color, gx_color_ return devn_decode_compressed_color(dev, color, out, &(((tiffsep_device *)dev)->devn_params)); } -#else +#endif + /* * Encode a list of colorant values into a gx_color_index_value. * With 32 bit gx_color_index values, we simply pack values. @@ -767,7 +790,6 @@ tiffsep_encode_color(gx_device *dev, const gx_color_value colors[]) } return (color == gx_no_color_index ? color ^ 1 : color); } -#endif /* * Decode a gx_color_index value back to a list of colorant values. @@ -1120,9 +1142,12 @@ tiffsep_get_color_comp_index(gx_device * dev, const char * pname, /* This is a one shot deal. That is it will simply post a notice once that some colorants will be converted due to a limit being reached. It will not list names of colorants since then I would need to keep track of - which ones I have already mentioned */ + which ones I have already mentioned. Also, if someone is fooling with + num_order, then this warning is not given since they should know what + is going on already */ if (index < 0 && component_type == SEPARATION_NAME && - pdev->warning_given == false) { + pdev->warning_given == false && + pdev->devn_params.num_separation_order_names == 0) { dlprintf("**** Max spot colorants reached.\n"); dlprintf("**** Some colorants will be converted to equivalent CMYK values.\n"); pdev->warning_given = true; @@ -1308,13 +1333,10 @@ tiffsep_prn_open(gx_device * pdev) { gx_device_printer * const ppdev = (gx_device_printer *)pdev; tiffsep_device *pdev_sep = (tiffsep_device *) pdev; - int code; - -#if TIFFSEP_PLANAR + int code, k; /* With planar the depth can be more than 64. Update the color info to reflect the proper depth and number of planes */ - pdev_sep->warning_given = false; if (pdev_sep->devn_params.page_spot_colors >= 0) { pdev->color_info.num_components = @@ -1331,27 +1353,17 @@ tiffsep_prn_open(gx_device * pdev) pdev->color_info.num_components = GS_CLIENT_COLOR_MAX_COMPONENTS; pdev->color_info.max_components = GS_CLIENT_COLOR_MAX_COMPONENTS; } + /* Push this to the max amount as a default if someone has not set it */ + if (pdev_sep->devn_params.num_separation_order_names == 0) + for (k = 0; k < GS_CLIENT_COLOR_MAX_COMPONENTS; k++) { + pdev_sep->devn_params.separation_order_map[k] = k; + } pdev->color_info.depth = pdev->color_info.num_components * pdev_sep->devn_params.bitspercomponent; pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN; code = gdev_prn_open_planar(pdev, true); ppdev->file = NULL; - pdev->icc_struct->supports_devn = true; -#else - code = tiff_open(pdev); - pdev_sep->warning_given = false; - -#if !USE_COMPRESSED_ENCODING - /* - * If we are using the compressed encoding scheme, then set the separable - * and linear info. - */ - set_linear_color_bits_mask_shift(pdev); - pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN; -#endif -#endif - return code; } @@ -1403,7 +1415,6 @@ tiffsep_prn_close(gx_device * pdev) int num_spot = pdevn->devn_params.separations.num_separations; char name[MAX_FILE_NAME_SIZE]; int code; - short map_comp_to_sep[GX_DEVICE_COLOR_MAX_COMPONENTS]; int comp_num; int num_comp = number_output_separations(num_dev_comp, num_std_colorants, num_order, num_spot); @@ -1417,14 +1428,13 @@ tiffsep_prn_close(gx_device * pdev) return code; if (pdevn->close_files) { - build_comp_to_sep_map(pdevn, map_comp_to_sep); /* Close the separation files */ for (comp_num = 0; comp_num < num_comp; comp_num++ ) { if (pdevn->sep_file[comp_num] != NULL) { - int sep_num = map_comp_to_sep[comp_num]; - + int sep_num = pdevn->devn_params.separation_order_map[comp_num]; + code = create_separation_file_name(pdevn, name, - MAX_FILE_NAME_SIZE, sep_num, false); + MAX_FILE_NAME_SIZE, sep_num, true); if (code < 0) return code; code = tiffsep_close_sep_file(pdevn, name, comp_num); @@ -1449,13 +1459,13 @@ typedef struct cmyk_composite_map_s { * device components. */ static void -build_cmyk_map(tiffsep_device * pdev, int num_comp, - short *map_comp_to_sep, cmyk_composite_map * cmyk_map) +build_cmyk_map(tiffsep_device * pdev, int num_comp, + cmyk_composite_map * cmyk_map) { int comp_num; for (comp_num = 0; comp_num < num_comp; comp_num++ ) { - int sep_num = map_comp_to_sep[comp_num]; + int sep_num = pdev->devn_params.separation_order_map[comp_num]; cmyk_map[comp_num].c = cmyk_map[comp_num].m = cmyk_map[comp_num].y = cmyk_map[comp_num].k = frac_0; @@ -1480,59 +1490,14 @@ build_cmyk_map(tiffsep_device * pdev, int num_comp, } } -#if TIFFSEP_PLANAR /* * Build a CMYK equivalent to a raster line from planar buffer */ static void -build_cmyk_raster_line_fromplanar(gs_get_bits_params_t params, byte * dest, int width, - int num_comp, cmyk_composite_map * cmyk_map) -{ - int pixel, comp_num; - uint temp, cyan, magenta, yellow, black; - cmyk_composite_map * cmyk_map_entry; - - for (pixel = 0; pixel < width; pixel++) { - cmyk_map_entry = cmyk_map; - temp = *(params.data[0] + pixel); - cyan = cmyk_map_entry->c * temp; - magenta = cmyk_map_entry->m * temp; - yellow = cmyk_map_entry->y * temp; - black = cmyk_map_entry->k * temp; - cmyk_map_entry++; - for (comp_num = 1; comp_num < num_comp; comp_num++) { - temp = *(params.data[comp_num] + pixel); - cyan += cmyk_map_entry->c * temp; - magenta += cmyk_map_entry->m * temp; - yellow += cmyk_map_entry->y * temp; - black += cmyk_map_entry->k * temp; - cmyk_map_entry++; - } - cyan /= frac_1; - magenta /= frac_1; - yellow /= frac_1; - black /= frac_1; - if (cyan > MAX_COLOR_VALUE) - cyan = MAX_COLOR_VALUE; - if (magenta > MAX_COLOR_VALUE) - magenta = MAX_COLOR_VALUE; - if (yellow > MAX_COLOR_VALUE) - yellow = MAX_COLOR_VALUE; - if (black > MAX_COLOR_VALUE) - black = MAX_COLOR_VALUE; - *dest++ = cyan; - *dest++ = magenta; - *dest++ = yellow; - *dest++ = black; - } -} -#else -/* - * Build a CMYK equivalent to a raster line. - */ -static void -build_cmyk_raster_line(byte * src, byte * dest, int width, - int num_comp, cmyk_composite_map * cmyk_map) +build_cmyk_raster_line_fromplanar(gs_get_bits_params_t params, byte * dest, + int width, int num_comp, + cmyk_composite_map * cmyk_map, int num_order, + tiffsep_device * const tfdev) { int pixel, comp_num; uint temp, cyan, magenta, yellow, black; @@ -1540,14 +1505,15 @@ build_cmyk_raster_line(byte * src, byte * dest, int width, for (pixel = 0; pixel < width; pixel++) { cmyk_map_entry = cmyk_map; - temp = *src++; + temp = *(params.data[tfdev->devn_params.separation_order_map[0]] + pixel); cyan = cmyk_map_entry->c * temp; magenta = cmyk_map_entry->m * temp; yellow = cmyk_map_entry->y * temp; black = cmyk_map_entry->k * temp; cmyk_map_entry++; for (comp_num = 1; comp_num < num_comp; comp_num++) { - temp = *src++; + temp = + *(params.data[tfdev->devn_params.separation_order_map[comp_num]] + pixel); cyan += cmyk_map_entry->c * temp; magenta += cmyk_map_entry->m * temp; yellow += cmyk_map_entry->y * temp; @@ -1572,7 +1538,6 @@ build_cmyk_raster_line(byte * src, byte * dest, int width, *dest++ = black; } } -#endif static int sep1_ht_order_to_thresholds(gx_device *pdev, const gs_imager_state *pis) @@ -1742,7 +1707,6 @@ tiffsep_print_page(gx_device_printer * pdev, FILE * file) int num_order = tfdev->devn_params.num_separation_order_names; int num_spot = tfdev->devn_params.separations.num_separations; int num_comp, comp_num, sep_num, code = 0, code1 = 0; - short map_comp_to_sep[GX_DEVICE_COLOR_MAX_COMPONENTS]; cmyk_composite_map cmyk_map[GX_DEVICE_COLOR_MAX_COMPONENTS]; char name[MAX_FILE_NAME_SIZE]; int base_filename_length = length_base_file_name(tfdev); @@ -1751,15 +1715,16 @@ tiffsep_print_page(gx_device_printer * pdev, FILE * file) const char *fmt; gs_parsed_file_name_t parsed; int non_encodable_count = 0; - - build_comp_to_sep_map(tfdev, map_comp_to_sep); + int plane_count = 0; /* quite compiler */ /* Print the names of the spot colors */ - for (sep_num = 0; sep_num < num_spot; sep_num++) { - copy_separation_name(tfdev, name, - MAX_FILE_NAME_SIZE - base_filename_length - SUFFIX_SIZE, sep_num); - dlprintf1("%%%%SeparationName: %s\n", name); - } + if (num_order == 0) { + for (sep_num = 0; sep_num < num_spot; sep_num++) { + copy_separation_name(tfdev, name, + MAX_FILE_NAME_SIZE - base_filename_length - SUFFIX_SIZE, sep_num); + dlprintf1("%%%%SeparationName: %s\n", name); + } + } /* * Check if the file name has a numeric format. If so then we want to @@ -1786,7 +1751,6 @@ tiffsep_print_page(gx_device_printer * pdev, FILE * file) return_error(gs_error_invalidfileaccess); } - code = tiff_set_fields_for_printer(pdev, tfdev->tiff_comp, 1, 0); if (tfdev->Compression==COMPRESSION_NONE || tfdev->Compression==COMPRESSION_LZW || tfdev->Compression==COMPRESSION_PACKBITS) tiff_set_cmyk_fields(pdev, tfdev->tiff_comp, 8, tfdev->Compression, tfdev->MaxStripSize); @@ -1805,10 +1769,10 @@ tiffsep_print_page(gx_device_printer * pdev, FILE * file) } for (comp_num = 0; comp_num < num_comp; comp_num++ ) { - int sep_num = map_comp_to_sep[comp_num]; + int sep_num = tfdev->devn_params.separation_order_map[comp_num]; code = create_separation_file_name(tfdev, name, MAX_FILE_NAME_SIZE, - sep_num, false); + sep_num, true); if (code < 0) return code; @@ -1839,9 +1803,8 @@ tiffsep_print_page(gx_device_printer * pdev, FILE * file) return code; } - build_cmyk_map(tfdev, num_comp, map_comp_to_sep, cmyk_map); + build_cmyk_map(tfdev, num_comp, cmyk_map); -#if TIFFSEP_PLANAR { int raster_plane = bitmap_raster(pdev->width * 8); byte *planes[GS_CLIENT_COLOR_MAX_COMPONENTS]; @@ -1849,6 +1812,7 @@ tiffsep_print_page(gx_device_printer * pdev, FILE * file) int cmyk_raster = width * NUM_CMYK_COMPONENTS; int pixel, y; byte * sep_line; + int plane_index, offset_plane; sep_line = gs_alloc_bytes(pdev->memory, cmyk_raster, "tiffsep_print_page"); @@ -1870,12 +1834,58 @@ tiffsep_print_page(gx_device_printer * pdev, FILE * file) GB_PACKING_PLANAR | GB_COLORS_NATIVE | GB_ALPHA_NONE); params.x_offset = 0; params.raster = bitmap_raster(pdev->width * pdev->color_info.depth); - for (comp_num = 0; comp_num < num_comp; comp_num++) { - planes[comp_num] = gs_alloc_bytes(pdev->memory, raster_plane, - "tiffsep_print_page"); - params.data[comp_num] = planes[comp_num]; - if (params.data[comp_num] == NULL) - return_error(gs_error_VMerror); + + if (num_order > 0) { + /* In this case, there was a specification for a separation + color order, which indicates what colorants we will + actually creat individual separation files for. We need + to allocate for the standard colorants. This is due to the + fact that even when we specify a single spot colorant, we + still create the composite CMYK output file. */ + for (comp_num = 0; comp_num < num_std_colorants; comp_num++) { + planes[comp_num] = gs_alloc_bytes(pdev->memory, raster_plane, + "tiffsep_print_page"); + params.data[comp_num] = planes[comp_num]; + if (params.data[comp_num] == NULL) + return_error(gs_error_VMerror); + } + offset_plane = num_std_colorants; + /* Now we need to make sure that we do not allocate extra + planes if any of the colorants in the order list are + one of the standard colorant names */ + plane_index = plane_count = num_std_colorants; + for (comp_num = 0; comp_num < num_comp; comp_num++) { + int temp_pos; + + temp_pos = tfdev->devn_params.separation_order_map[comp_num]; + if (temp_pos >= num_std_colorants) { + /* We have one that is not a standard colorant name + so allocate a new plane */ + planes[plane_count] = gs_alloc_bytes(pdev->memory, raster_plane, + "tiffsep_print_page"); + /* Assign the new plane to the appropriate position */ + params.data[plane_index] = planes[plane_count]; + if (params.data[plane_index] == NULL) + return_error(gs_error_VMerror); + plane_count += 1; + } else { + /* Assign params.data with the appropriate std. + colorant plane position */ + params.data[plane_index] = planes[temp_pos]; + } + plane_index += 1; + } + } else { + /* Sep color order number was not specified so just render all + the planes that we can */ + for (comp_num = 0; comp_num < num_comp; comp_num++) { + planes[comp_num] = gs_alloc_bytes(pdev->memory, raster_plane, + "tiffsep_print_page"); + params.data[comp_num] = planes[comp_num]; + if (params.data[comp_num] == NULL) + return_error(gs_error_VMerror); + } + offset_plane = 0; } for (y = 0; y < pdev->height; ++y) { rect.p.y = y; @@ -1884,79 +1894,46 @@ tiffsep_print_page(gx_device_printer * pdev, FILE * file) ((gx_device *) pdev, &rect, ¶ms, NULL); /* Write separation data (tiffgray format) */ for (comp_num = 0; comp_num < num_comp; comp_num++ ) { - byte * src = params.data[comp_num]; - byte * dest = sep_line; + byte *src; + byte *dest = sep_line; + if (num_order > 0) { + src = params.data[tfdev->devn_params.separation_order_map[comp_num]]; + } else + src = params.data[comp_num]; for (pixel = 0; pixel < width; pixel++, dest++, src++) *dest = MAX_COLOR_VALUE - *src; /* Gray is additive */ TIFFWriteScanline(tfdev->tiff[comp_num], (tdata_t)sep_line, y, 0); } /* Write CMYK equivalent data (tiff32nc format) */ - build_cmyk_raster_line_fromplanar(params, sep_line, - width, num_comp, cmyk_map); + build_cmyk_raster_line_fromplanar(params, sep_line, width, + num_comp, cmyk_map, num_order, + tfdev); TIFFWriteScanline(tfdev->tiff_comp, (tdata_t)sep_line, y, 0); } gs_free_object(pdev->memory, sep_line, "tiffsep_print_page"); - for (comp_num = 0; comp_num < num_comp; comp_num++) { - gs_free_object(pdev->memory, planes[comp_num], - "tiffsep_print_page"); - } - } -#else - { - int raster = gdev_prn_raster(pdev); - int width = tfdev->width; - int cmyk_raster = width * NUM_CMYK_COMPONENTS; - int pixel, y; - byte * line = gs_alloc_bytes(pdev->memory, raster, "tiffsep_print_page"); - byte * unpacked = gs_alloc_bytes(pdev->memory, width * num_comp, - "tiffsep_print_page"); - byte * sep_line; - byte * row; - - if (line == NULL || unpacked == NULL) - return_error(gs_error_VMerror); - sep_line = - gs_alloc_bytes(pdev->memory, cmyk_raster, "tiffsep_print_page"); - if (sep_line == NULL) { - gs_free_object(pdev->memory, line, "tiffsep_print_page"); - return_error(gs_error_VMerror); - } - - for (comp_num = 0; comp_num < num_comp; comp_num++ ) - TIFFCheckpointDirectory(tfdev->tiff[comp_num]); - TIFFCheckpointDirectory(tfdev->tiff_comp); - /* Write the page data. */ - for (y = 0; y < pdev->height; ++y) { - code = gdev_prn_get_bits(pdev, y, line, &row); - if (code < 0) - break; - /* Unpack the encoded color info */ - non_encodable_count += devn_unpack_row((gx_device *)pdev, num_comp, - &(tfdev->devn_params), width, row, unpacked); - /* Write separation data (tiffgray format) */ - for (comp_num = 0; comp_num < num_comp; comp_num++ ) { - byte * src = unpacked + comp_num; - byte * dest = sep_line; - - for (pixel = 0; pixel < width; pixel++, dest++, src += num_comp) - *dest = MAX_COLOR_VALUE - *src; /* Gray is additive */ - TIFFWriteScanline(tfdev->tiff[comp_num], (tdata_t)sep_line, y, 0); + if (num_order > 0) { + /* Free up the standard colorants if num_order was set. + In this process, we need to make sure that none of them + were the standard colorants. plane_count should have + the sum of the std. colorants plus any non-standard + ones listed in separation color order */ + for (comp_num = 0; comp_num < plane_count; comp_num++) { + gs_free_object(pdev->memory, planes[comp_num], + "tiffsep_print_page"); + } + } else { + for (comp_num = 0; comp_num < num_comp; comp_num++) { + gs_free_object(pdev->memory, planes[comp_num + offset_plane], + "tiffsep_print_page"); + } } - /* Write CMYK equivalent data (tiff32nc format) */ - build_cmyk_raster_line(unpacked, sep_line, - width, num_comp, cmyk_map); - TIFFWriteScanline(tfdev->tiff_comp, (tdata_t)sep_line, y, 0); } - gs_free_object(pdev->memory, line, "tiffsep_print_page"); - gs_free_object(pdev->memory, sep_line, "tiffsep_print_page"); -#endif - code1 = 0; for (comp_num = 0; comp_num < num_comp; comp_num++ ) { TIFFWriteDirectory(tfdev->tiff[comp_num]); if (fmt) { - int sep_num = map_comp_to_sep[comp_num]; + int sep_num = tfdev->devn_params.separation_order_map[comp_num]; code = create_separation_file_name(tfdev, name, MAX_FILE_NAME_SIZE, sep_num, false); if (code < 0) { |