diff options
-rw-r--r-- | base/gsicc_cache.c | 8 | ||||
-rw-r--r-- | base/gsicc_cache.h | 4 | ||||
-rw-r--r-- | base/gxdownscale.c | 146 | ||||
-rw-r--r-- | base/gxdownscale.h | 7 | ||||
-rw-r--r-- | base/lib.mak | 6 | ||||
-rw-r--r-- | devices/devs.mak | 4 | ||||
-rw-r--r-- | devices/gdevpdfimg.c | 88 | ||||
-rw-r--r-- | devices/gdevplan.c | 174 | ||||
-rw-r--r-- | devices/gdevtifs.c | 46 | ||||
-rw-r--r-- | devices/gdevtsep.c | 46 |
10 files changed, 289 insertions, 240 deletions
diff --git a/base/gsicc_cache.c b/base/gsicc_cache.c index 372cde854..bdf57bde6 100644 --- a/base/gsicc_cache.c +++ b/base/gsicc_cache.c @@ -260,10 +260,12 @@ gsicc_alloc_link_dev(gs_memory_t *memory, cmm_profile_t *src_profile, /* And the related release of the link */ void -gsicc_free_link_dev(gs_memory_t *memory, gsicc_link_t *link) +gsicc_free_link_dev(gsicc_link_t *link) { - gs_memory_t *nongc_mem = memory->non_gc_memory; - gs_free_object(nongc_mem, link, "gsicc_free_link_dev"); + if (link == NULL) + return; + link->procs.free_link(link); + gs_free_object(link->memory, link, "gsicc_free_link_dev"); } static gsicc_link_t * diff --git a/base/gsicc_cache.h b/base/gsicc_cache.h index 7aa87a43a..c9f51b3b4 100644 --- a/base/gsicc_cache.h +++ b/base/gsicc_cache.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2021 Artifex Software, Inc. +/* Copyright (C) 2001-2022 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -66,5 +66,5 @@ bool gsicc_support_named_color(const gs_color_space *pcs, const gs_gstate *pgs); int gsicc_get_device_profile_comps(const cmm_dev_profile_t *dev_profile); gsicc_link_t * gsicc_alloc_link_dev(gs_memory_t *memory, cmm_profile_t *src_profile, cmm_profile_t *des_profile, gsicc_rendering_param_t *rendering_params); -void gsicc_free_link_dev(gs_memory_t *memory, gsicc_link_t *link); +void gsicc_free_link_dev(gsicc_link_t *link); #endif diff --git a/base/gxdownscale.c b/base/gxdownscale.c index 4e36c81ae..870b22558 100644 --- a/base/gxdownscale.c +++ b/base/gxdownscale.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2021 Artifex Software, Inc. +/* Copyright (C) 2001-2022 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -19,6 +19,7 @@ #include "string_.h" #include "gdevprn.h" #include "assert_.h" +#include "gsicc_cache.h" #ifdef WITH_CAL #include "cal_ets.h" @@ -2046,11 +2047,17 @@ getbits_planar_line(gx_downscale_liner *liner_, void *output, int row) code = (*dev_proc(liner->dev, get_bits_rectangle))(liner->dev, &rect, ¶ms2); - /* get_bits_rectangle doesn't like doing planar copies, only return - * pointers. This is a problem for us, so fudge it here. */ - for (i = 0; i < liner->num_comps; i++) - if (params->data[i] != params2.data[1]) - memcpy(params->data[i], params2.data[i], n); + /* If our caller can't accept a pointer, we need to do some work. */ + if (params->options & GB_RETURN_POINTER) { + for (i = 0; i < liner->num_comps; i++) + params->data[i] = params2.data[i]; + } else { + /* get_bits_rectangle doesn't like doing planar copies, only return + * pointers. This is a problem for us, so fudge it here. */ + for (i = 0; i < liner->num_comps; i++) + if (params->data[i] != params2.data[i]) + memcpy(params->data[i], params2.data[i], n); + } return code; } @@ -2268,23 +2275,25 @@ int gx_downscaler_init_planar_cm(gx_downscaler_t *ds, ds->factor = factor; ds->num_planes = num_comps; ds->src_bpc = src_bpc; + ds->dst_bpc = dst_bpc; ds->scaled_data = NULL; ds->scaled_span = bitmap_raster((dst_bpc*dev->width*upfactor + downfactor-1)/downfactor); ds->apply_cm = apply_cm; ds->apply_cm_arg = apply_cm_arg; - ds->early_cm = dst_bpc < src_bpc; + ds->early_cm = dst_bpc < src_bpc || (dst_bpc == src_bpc && post_cm_num_comps < num_comps); ds->post_cm_num_comps = post_cm_num_comps; ds->do_skew_detection = params->do_skew_detection; if (apply_cm) { - for (i = 0; i < post_cm_num_comps; i++) { - ds->post_cm[i] = gs_alloc_bytes(dev->memory, - (size_t)post_span * downfactor, - "gx_downscaler(planar_data)"); - if (ds->post_cm[i] == NULL) { - code = gs_note_error(gs_error_VMerror); - goto cleanup; - } + ds->post_cm[0] = gs_alloc_bytes(dev->memory, + (size_t)post_span * downfactor * post_cm_num_comps, + "gx_downscaler(planar_data)"); + if (ds->post_cm[0] == NULL) { + code = gs_note_error(gs_error_VMerror); + goto cleanup; + } + for (i = 1; i < post_cm_num_comps; i++) { + ds->post_cm[i] = ds->post_cm[i-1] + (size_t)post_span * downfactor; } } @@ -2307,14 +2316,11 @@ int gx_downscaler_init_planar_cm(gx_downscaler_t *ds, memcpy(&ds->params, gb_params, sizeof(*gb_params)); ds->params.raster = span; - for (i = 0; i < num_comps; i++) { - ds->pre_cm[i] = gs_alloc_bytes(dev->memory, - (size_t)span * downfactor, - "gx_downscaler(planar_data)"); - if (ds->pre_cm[i] == NULL) { - code = gs_note_error(gs_error_VMerror); - goto cleanup; - } + ds->pre_cm[0] = gs_alloc_bytes(dev->memory, + (size_t)span * downfactor * num_comps, + "gx_downscaler(planar_data)"); + for (i = 1; i < num_comps; i++) { + ds->pre_cm[i] = ds->pre_cm[i-1] + (size_t)span * downfactor; } #ifdef WITH_CAL @@ -2462,7 +2468,9 @@ int gx_downscaler_init_planar_cm(gx_downscaler_t *ds, code = gs_note_error(gs_error_rangecheck); goto cleanup; } else if (dst_bpc == 1) { - if (mfs > 1) + if (src_bpc == dst_bpc) + core = NULL; + else if (mfs > 1) core = &down_core_mfs; else if (factor == 4) core = &down_core_4; @@ -2913,19 +2921,15 @@ gx_downscaler_init_cm_halftone(gx_downscaler_t *ds, void gx_downscaler_fin(gx_downscaler_t *ds) { - int plane; - if (ds->dev == NULL) return; - for (plane=0; plane < GS_CLIENT_COLOR_MAX_COMPONENTS; plane++) { - gs_free_object(ds->dev->memory, ds->pre_cm[plane], - "gx_downscaler(planar_data)"); - gs_free_object(ds->dev->memory, ds->post_cm[plane], - "gx_downscaler(planar_data)"); - ds->pre_cm[plane] = NULL; - ds->post_cm[plane] = NULL; - } + gs_free_object(ds->dev->memory, ds->pre_cm[0], + "gx_downscaler(planar_data)"); + gs_free_object(ds->dev->memory, ds->post_cm[0], + "gx_downscaler(planar_data)"); + ds->pre_cm[0] = NULL; + ds->post_cm[0] = NULL; ds->num_planes = 0; gs_free_object(ds->dev->memory, ds->mfs_data, "gx_downscaler(mfs)"); @@ -3018,11 +3022,14 @@ int gx_downscaler_get_bits_rectangle(gx_downscaler_t *ds, int subrow; int copy = (ds->dev->width * ds->src_bpc + 7)>>3; int i, j, n; + int num_planes_to_downscale; n = ds->dev->width; if (ds->dev->color_info.depth > ds->dev->color_info.num_components*8+8) n *= 2; + n = (n*ds->src_bpc+7)/8; + gx_downscaler_decode_factor(factor, &upfactor, &downfactor); subrow = row % upfactor; @@ -3059,11 +3066,10 @@ int gx_downscaler_get_bits_rectangle(gx_downscaler_t *ds, params->options &= ~GB_RETURN_POINTER; buffer = saved.data; } else - buffer = ds->pre_cm; - code = ds->apply_cm(ds->apply_cm_arg, params->data, buffer, ds->dev->width, rect.q.y - rect.p.y, params->raster); - if ((saved.options & GB_RETURN_COPY) == 0) - for (i = 0; i < ds->num_planes; i++) - params->data[i] = buffer[i]; + buffer = ds->post_cm; + code = ds->apply_cm(ds->apply_cm_arg, buffer, params->data, ds->dev->width, rect.q.y - rect.p.y, params->raster); + for (i = 0; i < ds->post_cm_num_comps; i++) + params->data[i] = buffer[i]; } return code; } @@ -3103,42 +3109,56 @@ int gx_downscaler_get_bits_rectangle(gx_downscaler_t *ds, for (j = 0; j < ds->num_planes; j++) memcpy(ds->pre_cm[j] + i*ds->span, ds->pre_cm[j] + (i-1)*ds->span, copy); + /* All the data is now in ds->pre_cm. Update params2.data so that this points to + * it. From here on in, we will keep params2.data pointing to whereever the + * latest processed version of the data is. */ for (j = 0; j < ds->num_planes; j++) params2.data[j] = ds->pre_cm[j]; + num_planes_to_downscale = ds->num_planes; if (ds->early_cm && ds->apply_cm) { - code = ds->apply_cm(ds->apply_cm_arg, ds->params.data, ds->post_cm, ds->dev->width, downfactor, params->raster); + code = ds->apply_cm(ds->apply_cm_arg, ds->post_cm, params2.data, ds->dev->width, downfactor, ds->span); if (code < 0) return code; - for (j = 0; j < ds->num_planes; j++) + for (j = 0; j < ds->post_cm_num_comps; j++) params2.data[j] = ds->post_cm[j]; + num_planes_to_downscale = ds->post_cm_num_comps; } if (upfactor > 1) { /* Downscale the block of lines into our output buffer */ - for (plane=0; plane < ds->num_planes; plane++) { + for (plane=0; plane < num_planes_to_downscale; plane++) { byte *scaled = ds->scaled_data + upfactor * plane * ds->scaled_span; (ds->down_core)(ds, scaled, params2.data[plane], row, plane, params2.raster); - params->data[plane] = scaled; + params2.data[plane] = scaled; } } else if (ds->down_core != NULL) { /* Downscale direct into output buffer */ - for (plane=0; plane < ds->num_planes; plane++) + for (plane=0; plane < num_planes_to_downscale; plane++) { (ds->down_core)(ds, params->data[plane], params2.data[plane], row, plane, params2.raster); + params2.data[plane] = params->data[plane]; + } } else { /* Copy into output buffer */ /* No color management can be required here */ assert(!ds->early_cm || ds->apply_cm == NULL); - for (plane=0; plane < ds->num_planes; plane++) + for (plane=0; plane < num_planes_to_downscale; plane++) { memcpy(params->data[plane], params2.data[plane], params2.raster); + params2.data[plane] = params->data[plane]; + } } if (!ds->early_cm && ds->apply_cm) { - code = ds->apply_cm(ds->apply_cm_arg, ds->params.data, params2.data, ds->width, 1, params->raster); + code = ds->apply_cm(ds->apply_cm_arg, params->data, params2.data, ds->width, 1, params->raster); if (code < 0) return code; + for (plane=0; plane < num_planes_to_downscale; plane++) + params2.data[plane] = params->data[plane]; } + for (plane=0; plane < num_planes_to_downscale; plane++) + params->data[plane] = params->data[plane]; + return code; } @@ -3566,3 +3586,37 @@ void ets_free(void *malloc_arg, void *p) gs_free_object((gs_memory_t *)malloc_arg, p, "ets_malloc"); } + +int gx_downscaler_create_post_render_link(gx_device *dev, gsicc_link_t **link) +{ + cmm_dev_profile_t *profile_struct; + gsicc_rendering_param_t rendering_params; + int code = dev_proc(dev, get_profile)(dev, &profile_struct); + if (code < 0) + return_error(gs_error_undefined); + + *link = NULL; + if (profile_struct->postren_profile == NULL) { + return 0; + } + + rendering_params.black_point_comp = gsBLACKPTCOMP_ON; + rendering_params.graphics_type_tag = GS_UNKNOWN_TAG; + rendering_params.override_icc = false; + rendering_params.preserve_black = gsBLACKPRESERVE_OFF; + rendering_params.rendering_intent = gsRELATIVECOLORIMETRIC; + rendering_params.cmm = gsCMM_DEFAULT; + *link = gsicc_alloc_link_dev(dev->memory, + profile_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], + profile_struct->postren_profile, + &rendering_params); + if (*link == NULL) + return_error(gs_error_VMerror); + + /* If it is identity, release it now and set link to NULL */ + if ((*link)->is_identity) { + gsicc_free_link_dev(*link); + *link = NULL; + } + return 0; +} diff --git a/base/gxdownscale.h b/base/gxdownscale.h index ed945b461..b8b9fc9a4 100644 --- a/base/gxdownscale.h +++ b/base/gxdownscale.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2021 Artifex Software, Inc. +/* Copyright (C) 2001-2022 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -248,4 +248,9 @@ int gx_downscaler_write_params(gs_param_list *plist, gx_downscaler_params *params, int features); +/* A helper function for creating the post render ICC link. + * This should be destroyed using gsicc_free_link_dev.*/ +int gx_downscaler_create_post_render_link(gx_device *dev, + gsicc_link_t **link); + #endif diff --git a/base/lib.mak b/base/lib.mak index 40f3979f0..4dc6c26e9 100644 --- a/base/lib.mak +++ b/base/lib.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2021 Artifex Software, Inc. +# Copyright (C) 2001-2022 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -1404,12 +1404,12 @@ downscale_=$(GLOBJ)gxdownscale.$(OBJ) $(claptrap) $(ets) $(GLOBJ)gxdownscale_0.$(OBJ) : $(GLSRC)gxdownscale.c $(AK) $(string__h)\ $(gxdownscale_h) $(gserrors_h) $(gdevprn_h) $(assert__h) $(ets_h)\ - $(LIB_MAK) $(MAKEDIRS) + $(gsicc_cache_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxdownscale_0.$(OBJ) $(C_) $(GLSRC)gxdownscale.c $(GLOBJ)gxdownscale_1.$(OBJ) : $(GLSRC)gxdownscale.c $(AK) $(string__h)\ $(gxdownscale_h) $(gserrors_h) $(gdevprn_h) $(assert__h) $(ets_h)\ - $(LIB_MAK) $(MAKEDIRS) + $(gsicc_cache_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(D_)WITH_CAL$(_D) $(I_)$(CALSRCDIR)$(_I) $(GLO_)gxdownscale_1.$(OBJ) $(C_) $(GLSRC)gxdownscale.c $(GLOBJ)gxdownscale.$(OBJ) : $(GLOBJ)gxdownscale_$(WITH_CAL).$(OBJ) $(AK) $(gp_h) diff --git a/devices/devs.mak b/devices/devs.mak index 6124af47c..a7838a7ed 100644 --- a/devices/devs.mak +++ b/devices/devs.mak @@ -1811,8 +1811,8 @@ $(DD)tiffsep1.dev : $(tiffsep_) $(DD)tiffs.dev $(minftrsz_h)\ plan_=$(DEVOBJ)gdevplan.$(OBJ) $(DEVOBJ)gdevppla.$(OBJ) $(DEVOBJ)gdevmpla.$(OBJ) -$(DEVOBJ)gdevplan.$(OBJ) : $(DEVSRC)gdevplan.c $(PDEVH)\ - $(gdevmpla_h) $(gdevplnx_h) $(gdevppla_h)\ +$(DEVOBJ)gdevplan.$(OBJ) : $(DEVSRC)gdevplan.c $(PDEVH) $(gxdevsop_h)\ + $(gdevmpla_h) $(gdevplnx_h) $(gdevppla_h) $(gxdownscale_h) $(gsicc_cache_h)\ $(gscdefs_h) $(gscspace_h) $(gxgetbit_h) $(gxiparam_h) $(gxlum_h) \ $(DEVS_MAK) $(MAKEDIRS) $(DEVCC) $(DEVO_)gdevplan.$(OBJ) $(C_) $(DEVSRC)gdevplan.c diff --git a/devices/gdevpdfimg.c b/devices/gdevpdfimg.c index 2b7d9c777..06caa447e 100644 --- a/devices/gdevpdfimg.c +++ b/devices/gdevpdfimg.c @@ -200,8 +200,6 @@ static int gdev_pdf_image_begin_page(gx_device_pdf_image *pdf_dev, gp_file *file) { gx_device_printer *const pdev = (gx_device_printer *)pdf_dev; - cmm_dev_profile_t *profile_struct; - gsicc_rendering_param_t rendering_params; int code; pdfimage_page *page; @@ -213,39 +211,11 @@ static int gdev_pdf_image_begin_page(gx_device_pdf_image *pdf_dev, if (gdev_prn_file_is_new(pdev)) { /* Set up the icc link settings at this time */ - code = dev_proc(pdev, get_profile)((gx_device *)pdev, &profile_struct); - if (code < 0) - return_error(gs_error_undefined); - if (profile_struct->postren_profile != NULL) { - rendering_params.black_point_comp = gsBLACKPTCOMP_ON; - rendering_params.graphics_type_tag = GS_UNKNOWN_TAG; - rendering_params.override_icc = false; - rendering_params.preserve_black = gsBLACKPRESERVE_OFF; - rendering_params.rendering_intent = gsRELATIVECOLORIMETRIC; - rendering_params.cmm = gsCMM_DEFAULT; - if (profile_struct->oi_profile != NULL) { - pdf_dev->icclink = gsicc_alloc_link_dev(pdev->memory, - profile_struct->oi_profile, profile_struct->postren_profile, - &rendering_params); - } else if (profile_struct->link_profile != NULL) { - pdf_dev->icclink = gsicc_alloc_link_dev(pdev->memory, - profile_struct->link_profile, profile_struct->postren_profile, - &rendering_params); - } else { - pdf_dev->icclink = gsicc_alloc_link_dev(pdev->memory, - profile_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], profile_struct->postren_profile, - &rendering_params); - } - if (pdf_dev->icclink == NULL) { - gs_free_object(pdf_dev->memory->non_gc_memory, page, "pdfimage create new page"); - return_error(gs_error_VMerror); - } - /* If it is identity, release it now and set link to NULL */ - if (pdf_dev->icclink->is_identity) { - pdf_dev->icclink->procs.free_link(pdf_dev->icclink); - gsicc_free_link_dev(pdev->memory, pdf_dev->icclink); - pdf_dev->icclink = NULL; - } + code = gx_downscaler_create_post_render_link((gx_device *)pdev, + &pdf_dev->icclink); + if (code < 0) { + gs_free_object(pdf_dev->memory->non_gc_memory, page, "pdfimage create new page"); + return code; } /* Set up the stream and insert the file header */ @@ -851,12 +821,8 @@ static int pdf_image_finish_file(gx_device_pdf_image *pdf_dev, int PCLm) pdf_dev->Pages = NULL; pdf_dev->NumPages = 0; } - if (pdf_dev->icclink != NULL) - { - pdf_dev->icclink->procs.free_link(pdf_dev->icclink); - gsicc_free_link_dev(pdf_dev->memory, pdf_dev->icclink); - pdf_dev->icclink = NULL; - } + gsicc_free_link_dev(pdf_dev->icclink); + pdf_dev->icclink = NULL; pdf_dev->RootOffset = 0; pdf_dev->PagesOffset = 0; pdf_dev->xrefOffset = 0; @@ -1325,8 +1291,6 @@ static int gdev_PCLm_begin_page(gx_device_pdf_image *pdf_dev, gp_file *file) { gx_device_printer *const pdev = (gx_device_printer *)pdf_dev; - cmm_dev_profile_t *profile_struct; - gsicc_rendering_param_t rendering_params; int code; pdfimage_page *page; @@ -1338,39 +1302,11 @@ static int gdev_PCLm_begin_page(gx_device_pdf_image *pdf_dev, if (gdev_prn_file_is_new(pdev)) { /* Set up the icc link settings at this time */ - code = dev_proc(pdev, get_profile)((gx_device *)pdev, &profile_struct); - if (code < 0) - return_error(gs_error_undefined); - if (profile_struct->postren_profile != NULL) { - rendering_params.black_point_comp = gsBLACKPTCOMP_ON; - rendering_params.graphics_type_tag = GS_UNKNOWN_TAG; - rendering_params.override_icc = false; - rendering_params.preserve_black = gsBLACKPRESERVE_OFF; - rendering_params.rendering_intent = gsRELATIVECOLORIMETRIC; - rendering_params.cmm = gsCMM_DEFAULT; - if (profile_struct->oi_profile != NULL) { - pdf_dev->icclink = gsicc_alloc_link_dev(pdev->memory, - profile_struct->oi_profile, profile_struct->postren_profile, - &rendering_params); - } else if (profile_struct->link_profile != NULL) { - pdf_dev->icclink = gsicc_alloc_link_dev(pdev->memory, - profile_struct->link_profile, profile_struct->postren_profile, - &rendering_params); - } else { - pdf_dev->icclink = gsicc_alloc_link_dev(pdev->memory, - profile_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], profile_struct->postren_profile, - &rendering_params); - } - if (pdf_dev->icclink == NULL) { - gs_free_object(pdf_dev->memory->non_gc_memory, page, "pdfimage create new page"); - return_error(gs_error_VMerror); - } - /* If it is identity, release it now and set link to NULL */ - if (pdf_dev->icclink->is_identity) { - pdf_dev->icclink->procs.free_link(pdf_dev->icclink); - gsicc_free_link_dev(pdev->memory, pdf_dev->icclink); - pdf_dev->icclink = NULL; - } + code = gx_downscaler_create_post_render_link((gx_device *)pdev, + &pdf_dev->icclink); + if (code < 0) { + gs_free_object(pdf_dev->memory->non_gc_memory, page, "pdfimage create new page"); + return code; } /* Set up the stream and insert the file header */ diff --git a/devices/gdevplan.c b/devices/gdevplan.c index 0ce82cda4..0cf28518f 100644 --- a/devices/gdevplan.c +++ b/devices/gdevplan.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2021 Artifex Software, Inc. +/* Copyright (C) 2001-2022 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -24,6 +24,9 @@ #include "gdevplnx.h" #include "gdevppla.h" #include "gdevmem.h" +#include "gxdownscale.h" +#include "gsicc_cache.h" +#include "gxdevsop.h" /* This file defines 5 different devices: * @@ -48,6 +51,13 @@ /* ------ The device descriptors ------ */ +typedef struct { + gx_device_common; + gx_prn_device_common; + gx_downscaler_params downscale; + gsicc_link_t *icclink; +} gx_device_plan; + /* * Default X and Y resolution. */ @@ -61,6 +71,7 @@ static dev_proc_decode_color(plang_decode_color); static dev_proc_encode_color(planc_encode_color); static dev_proc_decode_color(planc_decode_color); static dev_proc_map_color_rgb(planc_map_color_rgb); +static dev_proc_dev_spec_op(plan_spec_op); static dev_proc_open_device(plan_open); static dev_proc_close_device(plan_close); @@ -77,6 +88,31 @@ static int planr_print_page(gx_device_printer * pdev, gp_file * pstream); /* The device procedures */ +static int +plan_get_params(gx_device * dev, gs_param_list * plist) +{ + gx_device_plan *pdev = (gx_device_plan *)dev; + int code = gdev_prn_get_params(dev, plist); + + if (code < 0) + return code; + + return gx_downscaler_write_params(plist, &pdev->downscale, 0); +} + +static int +plan_put_params(gx_device *dev, gs_param_list * plist) +{ + gx_device_plan *pdev = (gx_device_plan *)dev; + int code; + + code = gx_downscaler_read_params(plist, &pdev->downscale, 0); + if (code < 0) + return code; + + return gdev_prn_put_params(dev, plist); +} + static void plan_base_initialize_device_procs(gx_device *dev, dev_proc_map_color_rgb(map_color_rgb), @@ -91,6 +127,8 @@ plan_base_initialize_device_procs(gx_device *dev, set_dev_proc(dev, get_page_device, gx_page_device_get_page_device); set_dev_proc(dev, encode_color, encode_color); set_dev_proc(dev, decode_color, decode_color); + set_dev_proc(dev, get_params, plan_get_params); + set_dev_proc(dev, put_params, plan_put_params); } static void @@ -109,6 +147,7 @@ plang_initialize_device_procs(gx_device *dev) plang_decode_color, plang_encode_color, plang_decode_color); + set_dev_proc(dev, dev_spec_op, plan_spec_op); } static void @@ -118,6 +157,7 @@ plan_initialize_device_procs(gx_device *dev) plan_decode_color, gx_default_rgb_map_rgb_color, plan_decode_color); + set_dev_proc(dev, dev_spec_op, plan_spec_op); } static void @@ -127,6 +167,7 @@ planc_initialize_device_procs(gx_device *dev) planc_map_color_rgb, planc_encode_color, planc_decode_color); + set_dev_proc(dev, dev_spec_op, plan_spec_op); } static void @@ -149,30 +190,31 @@ planr_initialize_device_procs(gx_device *dev) /* Macro for generating device descriptors. */ #define plan_prn_device(init, dev_name, num_comp, depth, max_gray, max_rgb, print_page) \ -{ prn_device_body(gx_device_printer, init, dev_name,\ +{ prn_device_body(gx_device_plan, init, dev_name,\ DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS, X_DPI, Y_DPI,\ 0, 0, 0, 0,\ num_comp, depth, max_gray, max_rgb, max_gray + 1, max_rgb + 1,\ - print_page)\ + print_page),\ + GX_DOWNSCALER_PARAMS_DEFAULTS\ } /* The device descriptors themselves */ -const gx_device_printer gs_plan_device = +const gx_device_plan gs_plan_device = plan_prn_device(plan_initialize_device_procs, "plan", 3, 24, 255, 255, plan_print_page); -const gx_device_printer gs_plang_device = +const gx_device_plan gs_plang_device = plan_prn_device(plang_initialize_device_procs, "plang", 1, 8, 255, 0, plang_print_page); -const gx_device_printer gs_planm_device = +const gx_device_plan gs_planm_device = plan_prn_device(planm_initialize_device_procs, "planm", 1, 1, 1, 0, planm_print_page); -const gx_device_printer gs_plank_device = +const gx_device_plan gs_plank_device = plan_prn_device(plank_initialize_device_procs, "plank", 4, 4, 1, 1, plank_print_page); -const gx_device_printer gs_planc_device = +const gx_device_plan gs_planc_device = plan_prn_device(planc_initialize_device_procs, "planc", 4, 32, 255, 255, planc_print_page); -const gx_device_printer gs_planr_device = +const gx_device_plan gs_planr_device = plan_prn_device(planr_initialize_device_procs, "planr", 3, 3, 1, 1, planr_print_page); @@ -363,10 +405,14 @@ plan_open(gx_device * pdev) static int plan_close(gx_device *pdev) { + gx_device_plan *dev = (gx_device_plan *)pdev; + #ifdef DEBUG_PRINT emprintf(pdev->memory, "plan_close\n"); #endif + gsicc_free_link_dev(dev->icclink); + dev->icclink = NULL; return gdev_prn_close(pdev); } @@ -486,26 +532,71 @@ planc_encode_color(gx_device * dev, const gx_color_value cv[]) return (color == gx_no_color_index ? color ^ 1 : color); } +static int +plan_spec_op(gx_device *dev, int op, void *data, int datasize) +{ + if (op == gxdso_supports_iccpostrender) { + int bpc = dev->color_info.depth / dev->color_info.num_components; + return bpc == 8; + } + return gdev_prn_dev_spec_op(dev, op, data, datasize); +} + /* ------ Internal routines ------ */ +static int post_cm(void *arg, + byte **dst, + byte **src, + int w, + int h, + int raster) +{ + gsicc_bufferdesc_t input_buffer_desc, output_buffer_desc; + gsicc_link_t *icclink = (gsicc_link_t*)arg; + + gsicc_init_buffer(&input_buffer_desc, icclink->num_input, 1, false, + false, true, src[1] - src[0], raster, h, w); + gsicc_init_buffer(&output_buffer_desc, icclink->num_output, 1, false, + false, true, dst[1] - dst[0], raster, h, w); + icclink->procs.map_buffer(NULL, icclink, &input_buffer_desc, &output_buffer_desc, + src[0], dst[0]); + return 0; +} + /* Print a page using a given row printing routine. */ static int -plan_print_page_loop(gx_device_printer * pdev, int log2bits, int numComps, +plan_print_page_loop(gx_device_printer *pdev, int log2bits, int numComps, gp_file *pstream) { - int lnum; + gx_device_plan *dev = (gx_device_plan *)pdev; + int i, lnum; int code = 0; gs_get_bits_options_t options; + gx_downscaler_t ds; + gs_get_bits_params_t params; + int post_cm_comps; + byte *planes[GS_CLIENT_COLOR_MAX_COMPONENTS]; + int factor = dev->downscale.downscale_factor; + int width = gx_downscaler_scale(pdev->width, factor); + int height = gx_downscaler_scale(pdev->height, factor); + int raster_plane = bitmap_raster(width << log2bits); + #ifdef DEBUG_DUMP dump_row row_proc = NULL; int output_is_nul = !strncmp(pdev->fname, "nul:", min(strlen(pdev->fname), 4)) || !strncmp(pdev->fname, "/dev/null", min(strlen(pdev->fname), 9)); - - if (!output_is_nul) - row_proc = dump_start(pdev->width, pdev->height, numComps, log2bits, pstream); #endif + + if (gdev_prn_file_is_new(pdev)) { + code = gx_downscaler_create_post_render_link((gx_device *)pdev, + &dev->icclink); + if (code < 0) + return code; + } + options = GB_ALIGN_ANY | GB_RETURN_POINTER | + GB_RETURN_COPY | GB_OFFSET_0 | GB_RASTER_STANDARD | GB_COLORS_NATIVE | @@ -514,25 +605,54 @@ plan_print_page_loop(gx_device_printer * pdev, int log2bits, int numComps, options |= GB_PACKING_CHUNKY; else options |= GB_PACKING_PLANAR; - for (lnum = 0; lnum < pdev->height; lnum++) { - gs_int_rect rect; - gs_get_bits_params_t params; - - rect.p.x = 0; - rect.p.y = lnum; - rect.q.x = pdev->width; - rect.q.y = lnum+1; - memset(¶ms, 0, sizeof(params)); - params.options = options; - params.x_offset = 0; - code = (*dev_proc(pdev, get_bits_rectangle))((gx_device *)pdev, &rect, ¶ms); + + memset(¶ms, 0, sizeof(params)); + params.options = options; + params.x_offset = 0; + post_cm_comps = dev->icclink ? dev->icclink->num_output : numComps; + + planes[0] = gs_alloc_bytes(pdev->memory, raster_plane * post_cm_comps, + "plan_print_page_loop"); + if (planes[0] == NULL) + return_error(gs_error_VMerror); + for (i = 1; i < post_cm_comps; i++) { + planes[i] = planes[i-1] + raster_plane; + params.data[i] = planes[i]; + } + + code = gx_downscaler_init_planar_cm(&ds, + (gx_device *)dev, + 1<<log2bits, /* src_bpc */ + 1<<log2bits, /* dst_bpc */ + numComps, + &dev->downscale, + ¶ms, + dev->icclink ? post_cm : NULL, + dev->icclink, + post_cm_comps); + if (code < 0) + goto fail; + +#ifdef DEBUG_DUMP + if (!output_is_nul) + row_proc = dump_start(width, height, post_cm_comps, log2bits, pstream); +#endif + + for (lnum = 0; lnum < height; lnum++) { + for (i = 0; i < post_cm_comps; i++) + params.data[i] = planes[i]; + code = gx_downscaler_get_bits_rectangle(&ds, ¶ms, lnum); if (code < 0) break; #ifdef DEBUG_DUMP if (row_proc) - (*row_proc)(pdev->width, params.data, pstream); + (*row_proc)(width, params.data, pstream); #endif } + + gx_downscaler_fin(&ds); +fail: + gs_free_object(pdev->memory, planes[0], "plan_print_page_loop"); return (code < 0 ? code : 0); } diff --git a/devices/gdevtifs.c b/devices/gdevtifs.c index f5f38f8c1..9c629afa7 100644 --- a/devices/gdevtifs.c +++ b/devices/gdevtifs.c @@ -76,12 +76,9 @@ tiff_close(gx_device * pdev) if (tfdev->tif) TIFFClose(tfdev->tif); - if (tfdev->icclink != NULL) - { - tfdev->icclink->procs.free_link(tfdev->icclink); - gsicc_free_link_dev(pdev->memory, tfdev->icclink); - tfdev->icclink = NULL; - } + gsicc_free_link_dev(tfdev->icclink); + tfdev->icclink = NULL; + return gdev_prn_close(pdev); } @@ -298,8 +295,6 @@ int gdev_tiff_begin_page(gx_device_tiff *tfdev, gp_file *file) { gx_device_printer *const pdev = (gx_device_printer *)tfdev; - cmm_dev_profile_t *profile_struct; - gsicc_rendering_param_t rendering_params; int code; if (gdev_prn_file_is_new(pdev)) { @@ -308,39 +303,10 @@ int gdev_tiff_begin_page(gx_device_tiff *tfdev, if (!tfdev->tif) return_error(gs_error_invalidfileaccess); /* Set up the icc link settings at this time */ - code = dev_proc(pdev, get_profile)((gx_device *)pdev, &profile_struct); + code = gx_downscaler_create_post_render_link((gx_device *)pdev, + &tfdev->icclink); if (code < 0) - return_error(gs_error_undefined); - if (profile_struct->postren_profile != NULL) { - rendering_params.black_point_comp = gsBLACKPTCOMP_ON; - rendering_params.graphics_type_tag = GS_UNKNOWN_TAG; - rendering_params.override_icc = false; - rendering_params.preserve_black = gsBLACKPRESERVE_OFF; - rendering_params.rendering_intent = gsRELATIVECOLORIMETRIC; - rendering_params.cmm = gsCMM_DEFAULT; - if (profile_struct->oi_profile != NULL) { - tfdev->icclink = gsicc_alloc_link_dev(pdev->memory, - profile_struct->oi_profile, profile_struct->postren_profile, - &rendering_params); - } else if (profile_struct->link_profile != NULL) { - tfdev->icclink = gsicc_alloc_link_dev(pdev->memory, - profile_struct->link_profile, profile_struct->postren_profile, - &rendering_params); - } else { - tfdev->icclink = gsicc_alloc_link_dev(pdev->memory, - profile_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], - profile_struct->postren_profile, &rendering_params); - } - if (tfdev->icclink == NULL) { - return_error(gs_error_VMerror); - } - /* If it is identity, release it now and set link to NULL */ - if (tfdev->icclink->is_identity) { - tfdev->icclink->procs.free_link(tfdev->icclink); - gsicc_free_link_dev(pdev->memory, tfdev->icclink); - tfdev->icclink = NULL; - } - } + return code; } return tiff_set_fields_for_printer(pdev, tfdev->tif, tfdev->downscale.downscale_factor, diff --git a/devices/gdevtsep.c b/devices/gdevtsep.c index c1f556379..52a15708e 100644 --- a/devices/gdevtsep.c +++ b/devices/gdevtsep.c @@ -1594,7 +1594,6 @@ tiffsep_prn_open(gx_device * pdev) tiffsep_device *pdev_sep = (tiffsep_device *) pdev; int code, k; cmm_dev_profile_t *profile_struct; - gsicc_rendering_param_t rendering_params; /* Use our own warning and error message handlers in libtiff */ tiff_set_handlers(); @@ -1681,41 +1680,10 @@ tiffsep_prn_open(gx_device * pdev) /* Set up the icc link settings at this time. Only CMYK post render profiles are allowed */ - code = dev_proc(pdev, get_profile)((gx_device *)pdev, &profile_struct); + code = gx_downscaler_create_post_render_link((gx_device *)pdev, + &pdev_sep->icclink); if (code < 0) - return_error(gs_error_undefined); - - if (profile_struct->postren_profile != NULL && - profile_struct->postren_profile->data_cs == gsCMYK) { - rendering_params.black_point_comp = gsBLACKPTCOMP_ON; - rendering_params.graphics_type_tag = GS_UNKNOWN_TAG; - rendering_params.override_icc = false; - rendering_params.preserve_black = gsBLACKPRESERVE_OFF; - rendering_params.rendering_intent = gsRELATIVECOLORIMETRIC; - rendering_params.cmm = gsCMM_DEFAULT; - if (profile_struct->oi_profile != NULL) { - pdev_sep->icclink = gsicc_alloc_link_dev(pdev->memory, - profile_struct->oi_profile, profile_struct->postren_profile, - &rendering_params); - } else if (profile_struct->link_profile != NULL) { - pdev_sep->icclink = gsicc_alloc_link_dev(pdev->memory, - profile_struct->link_profile, profile_struct->postren_profile, - &rendering_params); - } else { - pdev_sep->icclink = gsicc_alloc_link_dev(pdev->memory, - profile_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], - profile_struct->postren_profile, &rendering_params); - } - if (pdev_sep->icclink == NULL) { - return_error(gs_error_VMerror); - } - /* If it is identity, release it now and set link to NULL */ - if (pdev_sep->icclink->is_identity) { - pdev_sep->icclink->procs.free_link(pdev_sep->icclink); - gsicc_free_link_dev(pdev->memory, pdev_sep->icclink); - pdev_sep->icclink = NULL; - } - } + return code; return code; } @@ -1771,11 +1739,9 @@ tiffsep_prn_close(gx_device * pdev) int comp_num; int num_comp = number_output_separations(num_dev_comp, num_std_colorants, num_order, num_spot); - if (pdevn->icclink != NULL) { - pdevn->icclink->procs.free_link(pdevn->icclink); - gsicc_free_link_dev(pdevn->memory, pdevn->icclink); - pdevn->icclink = NULL; - } + + gsicc_free_link_dev(pdevn->icclink); + pdevn->icclink = NULL; name = (char *)gs_alloc_bytes(pdevn->memory, gp_file_name_sizeof, "tiffsep_prn_close(name)"); if (!name) |