summaryrefslogtreecommitdiff
path: root/devices
diff options
context:
space:
mode:
Diffstat (limited to 'devices')
-rw-r--r--devices/gdevdsp.c107
1 files changed, 75 insertions, 32 deletions
diff --git a/devices/gdevdsp.c b/devices/gdevdsp.c
index fc41cdec8..90e25a79a 100644
--- a/devices/gdevdsp.c
+++ b/devices/gdevdsp.c
@@ -1044,15 +1044,31 @@ display_put_params(gx_device * dev, gs_param_list * plist)
}
if (ecode >= 0 &&
- (ddev->nFormat & DISPLAY_COLORS_MASK) == DISPLAY_COLORS_SEPARATION) {
- /* Use utility routine to handle devn parameters */
- ecode = devn_put_params(dev, plist, pdevn_params, pequiv_colors);
- /*
- * If we support_devn, setting MaxSeparations or PageSpotColors changed the
- * color_info.depth in devn_put_params, but we always use 64bpp, so reset it
- * to the correct value.
- */
- ddev->color_info.depth = ARCH_SIZEOF_COLOR_INDEX * 8;
+ (ddev->nFormat & DISPLAY_COLORS_MASK) == DISPLAY_COLORS_SEPARATION) {
+ if (ddev->nFormat & (DISPLAY_PLANAR | DISPLAY_PLANAR_INTERLEAVED))
+ {
+ /* If we are in planar mode, then we only want to allocate as many
+ * separations as we need (which may be 'MAX' in the PS case where
+ * we don't know how many we need). This means that we might want to
+ * close the device in order to reopen it with the revised number
+ * later on. Use a utility function for this. */
+ int n;
+ ecode = devn_generic_put_params(dev, plist, pdevn_params, pequiv_colors, 0);
+ n = pdevn_params->num_std_colorant_names + pdevn_params->separations.num_separations;
+ if (n > ddev->color_info.max_components)
+ n = ddev->color_info.max_components;
+ ddev->color_info.num_components = n;
+ ddev->color_info.depth = n * 8;
+ is_open = ddev->is_open;
+ }
+ else
+ {
+ /* In the chunky case, we always just use ARCH_SIZEOF_COLOR_INDEX (8) spots.
+ * Setting MaxSeparations or PageSpotColors will change the color_info.depth
+ * in devn_put_params, so we need to put it back to 64bpp. */
+ ecode = devn_put_params(dev, plist, pdevn_params, pequiv_colors);
+ ddev->color_info.depth = ARCH_SIZEOF_COLOR_INDEX * 8;
+ }
}
if (ecode >= 0) {
@@ -1303,6 +1319,11 @@ display_spec_op(gx_device *dev, int op, void *data, int datasize)
gx_device_display *ddev = (gx_device_display *)dev;
if (op == gxdso_supports_devn || op == gxdso_skip_icc_component_validation) {
+ /* If we're SEPARATION, then we certainly support devn. */
+ if (ddev->nFormat & DISPLAY_COLORS_SEPARATION)
+ return 1;
+ /* Not sure about this test. Historically this is what we've done, but
+ * it fails for planar SEPARATIONS because we're using mem_planar_fill_rectangle_hl_color. */
return (dev_proc(dev, fill_rectangle_hl_color) == display_fill_rectangle_hl_color);
}
if (op == gxdso_reopen_after_init) {
@@ -1449,6 +1470,7 @@ display_free_bitmap(gx_device_display * ddev)
gx_device_clist_reader * const pcrdev = &pclist_dev->reader;
/* Close cmd list device & point to the storage */
clist_close( (gx_device *)pcldev );
+ gs_free_object(ddev->memory->non_gc_memory, ddev->buf, "clist cmd buffer");
ddev->buf = NULL;
ddev->buffer_space = 0;
@@ -1615,6 +1637,12 @@ display_size_buf_device(gx_device_buf_space_t *space, gx_device *target,
/* Planar case */
mdev.color_info = target->color_info;
+ if (ddev->nFormat & DISPLAY_COLORS_SEPARATION)
+ {
+ /* For planar separations, we use the real number of comps
+ * with 8 bits per plane. */
+ mdev.color_info.depth = mdev.color_info.num_components * 8;
+ }
mdev.pad = target->pad;
mdev.log2_align_mod = target->log2_align_mod;
mdev.is_planar = target->is_planar;
@@ -1885,9 +1913,10 @@ typedef enum DISPLAY_MODEL_e {
*/
static void
set_color_info(gx_device_color_info * pdci, DISPLAY_MODEL model,
- int nc, int depth, int maxgray, int maxcolor)
+ int nc, int maxc, int depth, int maxgray, int maxcolor)
{
- pdci->num_components = pdci->max_components = nc;
+ pdci->num_components = nc;
+ pdci->max_components = maxc;
pdci->depth = depth;
pdci->gray_index = 0;
pdci->max_gray = maxgray;
@@ -2084,26 +2113,36 @@ display_set_color_format(gx_device_display *ddev, int nFormat)
return_error(gs_error_rangecheck);
}
+ switch (nFormat & (DISPLAY_PLANAR | DISPLAY_PLANAR_INTERLEAVED))
+ {
+ case DISPLAY_CHUNKY:
+ ddev->is_planar = 0;
+ break;
+ default:
+ ddev->is_planar = 1;
+ break;
+ }
+
switch (nFormat & DISPLAY_COLORS_MASK) {
case DISPLAY_COLORS_NATIVE:
switch (nFormat & DISPLAY_DEPTH_MASK) {
case DISPLAY_DEPTH_1:
/* 1bit/pixel, black is 1, white is 0 */
- set_color_info(&dci, DISPLAY_MODEL_GRAY, 1, 1, 1, 0);
+ set_color_info(&dci, DISPLAY_MODEL_GRAY, 1, 1, 1, 1, 0);
dci.separable_and_linear = GX_CINFO_SEP_LIN_NONE;
set_gray_color_procs(pdev, gx_b_w_gray_encode,
gx_default_b_w_map_color_rgb);
break;
case DISPLAY_DEPTH_4:
/* 4bit/pixel VGA color */
- set_color_info(&dci, DISPLAY_MODEL_RGB, 3, 4, 3, 2);
+ set_color_info(&dci, DISPLAY_MODEL_RGB, 3, 3, 4, 3, 2);
dci.separable_and_linear = GX_CINFO_SEP_LIN_NONE;
set_rgb_color_procs(pdev, display_map_rgb_color_device4,
display_map_color_rgb_device4);
break;
case DISPLAY_DEPTH_8:
/* 8bit/pixel 96 color palette */
- set_color_info(&dci, DISPLAY_MODEL_RGBK, 4, 8, 31, 3);
+ set_color_info(&dci, DISPLAY_MODEL_RGBK, 4, 4, 8, 31, 3);
dci.separable_and_linear = GX_CINFO_SEP_LIN_NONE;
set_rgbk_color_procs(pdev, display_encode_color_device8,
display_decode_color_device8);
@@ -2113,9 +2152,9 @@ display_set_color_format(gx_device_display *ddev, int nFormat)
/* Is maxgray = maxcolor = 63 correct? */
if ((ddev->nFormat & DISPLAY_555_MASK)
== DISPLAY_NATIVE_555)
- set_color_info(&dci, DISPLAY_MODEL_RGB, 3, 16, 31, 31);
+ set_color_info(&dci, DISPLAY_MODEL_RGB, 3, 3, 16, 31, 31);
else
- set_color_info(&dci, DISPLAY_MODEL_RGB, 3, 16, 63, 63);
+ set_color_info(&dci, DISPLAY_MODEL_RGB, 3, 3, 16, 63, 63);
set_rgb_color_procs(pdev, display_map_rgb_color_device16,
display_map_color_rgb_device16);
break;
@@ -2125,7 +2164,7 @@ display_set_color_format(gx_device_display *ddev, int nFormat)
dci.gray_index = GX_CINFO_COMP_NO_INDEX;
break;
case DISPLAY_COLORS_GRAY:
- set_color_info(&dci, DISPLAY_MODEL_GRAY, 1, bpc, maxvalue, 0);
+ set_color_info(&dci, DISPLAY_MODEL_GRAY, 1, 1, bpc, maxvalue, 0);
if (bpc == 1)
set_gray_color_procs(pdev, gx_default_gray_encode,
gx_default_w_b_map_color_rgb);
@@ -2138,7 +2177,7 @@ display_set_color_format(gx_device_display *ddev, int nFormat)
bpp = bpc * 3;
else
bpp = bpc * 4;
- set_color_info(&dci, DISPLAY_MODEL_RGB, 3, bpp, maxvalue, maxvalue);
+ set_color_info(&dci, DISPLAY_MODEL_RGB, 3, 3, bpp, maxvalue, maxvalue);
if (((nFormat & DISPLAY_DEPTH_MASK) == DISPLAY_DEPTH_8) &&
((nFormat & DISPLAY_ALPHA_MASK) == DISPLAY_ALPHA_NONE)) {
if ((nFormat & DISPLAY_ENDIAN_MASK) == DISPLAY_BIGENDIAN)
@@ -2156,7 +2195,7 @@ display_set_color_format(gx_device_display *ddev, int nFormat)
break;
case DISPLAY_COLORS_CMYK:
bpp = bpc * 4;
- set_color_info(&dci, DISPLAY_MODEL_CMYK, 4, bpp, maxvalue, maxvalue);
+ set_color_info(&dci, DISPLAY_MODEL_CMYK, 4, 4, bpp, maxvalue, maxvalue);
if ((nFormat & DISPLAY_ALPHA_MASK) != DISPLAY_ALPHA_NONE)
return_error(gs_error_rangecheck);
if ((nFormat & DISPLAY_ENDIAN_MASK) != DISPLAY_BIGENDIAN)
@@ -2174,9 +2213,23 @@ display_set_color_format(gx_device_display *ddev, int nFormat)
case DISPLAY_COLORS_SEPARATION:
if ((nFormat & DISPLAY_ENDIAN_MASK) != DISPLAY_BIGENDIAN)
return_error(gs_error_rangecheck);
- bpp = ARCH_SIZEOF_COLOR_INDEX * 8;
- set_color_info(&dci, DISPLAY_MODEL_SEP, bpp/bpc, bpp,
- maxvalue, maxvalue);
+ if (ddev->is_planar)
+ {
+ int n = ddev->devn_params.num_std_colorant_names + ddev->devn_params.separations.num_separations;
+ if (n == 0)
+ n = GS_CLIENT_COLOR_MAX_COMPONENTS;
+ if (n > GS_CLIENT_COLOR_MAX_COMPONENTS)
+ n = GS_CLIENT_COLOR_MAX_COMPONENTS;
+ bpp = n * 8;
+ set_color_info(&dci, DISPLAY_MODEL_SEP, n, GS_CLIENT_COLOR_MAX_COMPONENTS, bpp,
+ maxvalue, maxvalue);
+ }
+ else
+ {
+ bpp = ARCH_SIZEOF_COLOR_INDEX * 8;
+ set_color_info(&dci, DISPLAY_MODEL_SEP, bpp/bpc, bpp/bpc, bpp,
+ maxvalue, maxvalue);
+ }
if ((nFormat & DISPLAY_DEPTH_MASK) == DISPLAY_DEPTH_8) {
ddev->devn_params.bitspercomponent = bpc;
if (ddev->icc_struct == NULL) {
@@ -2199,16 +2252,6 @@ display_set_color_format(gx_device_display *ddev, int nFormat)
return_error(gs_error_rangecheck);
}
- switch (nFormat & (DISPLAY_PLANAR | DISPLAY_PLANAR_INTERLEAVED))
- {
- case DISPLAY_CHUNKY:
- ddev->is_planar = 0;
- break;
- default:
- ddev->is_planar = 1;
- break;
- }
-
/* restore old anti_alias info */
dci.anti_alias = ddev->color_info.anti_alias;
ddev->color_info = dci;