summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam James <sam@gentoo.org>2022-09-21 14:18:08 +0100
committerSam James <sam@gentoo.org>2022-10-02 04:31:25 +0100
commita529111f77ff46f4836fe7312e70953bc16587cf (patch)
tree9dc3924cb1a6ef3ef853b7bb45f735365e0b4e6d /base/gdevp14.c
parentImport Ghostscript 9.56.1 (diff)
downloadghostscript-gpl-patches-ghostscript-10.tar.gz
ghostscript-gpl-patches-ghostscript-10.tar.bz2
ghostscript-gpl-patches-ghostscript-10.zip
Import Ghostscript 10.0ghostscript-10.0ghostscript-10
Signed-off-by: Sam James <sam@gentoo.org>
Diffstat (limited to 'base/gdevp14.c')
-rw-r--r--base/gdevp14.c160
1 files changed, 70 insertions, 90 deletions
diff --git a/base/gdevp14.c b/base/gdevp14.c
index b3018f85..0b47ae6d 100644
--- a/base/gdevp14.c
+++ b/base/gdevp14.c
@@ -1647,6 +1647,22 @@ pdf14_pop_transparency_group(gs_gstate *pgs, pdf14_ctx *ctx,
(nos->has_alpha_g ? 1 : 0)));
}
+ /* Before we get started, lets see if we have somehow gotten into
+ what should be an impossible situation where the group color
+ information does not match the buffer color information. This
+ can occur is there were memory issues that have perhaps blown
+ away information, or in the example of Bug 705197 the PDF interpreter
+ reuses a pattern during a circular reference causing an aliasing
+ of two nested patterns, one of which has a softmask. The change in
+ the buffer size of the inner one blows away the buffer of the
+ outer one leading to a mismatch of color spaces. Here
+ we can at least catch the case when the color space sizes have
+ changed and avoid buffer over-runs that would occur when we try
+ to do the group composition */
+ if (nos->n_chan - 1 != nos->group_color_info->num_components ||
+ tos->n_chan - 1 != tos_num_color_comp)
+ return_error(gs_error_Fatal);
+
nos_num_color_comp = nos->group_color_info->num_components - tos->num_spots;
tos_num_color_comp = tos_num_color_comp - tos->num_spots;
@@ -3119,48 +3135,6 @@ pdf14_blend_image_mixed_buffer16(byte* buf_ptr_, int width, int height, int rows
}
}
-static pdf14_buf*
-insert_empty_planes(pdf14_ctx* ctx, pdf14_buf** src_buf, int num_new_planes, int insert_index)
-{
- int planestride = (*src_buf)->planestride;
- int src_n_planes = (*src_buf)->n_planes;
- int src_n_chan = (*src_buf)->n_chan;
- int des_n_planes = src_n_planes + num_new_planes;
- int des_n_chan = src_n_chan + num_new_planes;
- byte *src_ptr = (*src_buf)->data;
- byte* des_ptr;
- byte *des_data;
- bool deep = ctx->deep;
-
- des_data = gs_alloc_bytes(ctx->memory,
- (size_t)planestride * des_n_planes + CAL_SLOP,
- "insert_empty_planes");
- if (des_data == NULL)
- return NULL;
-
- des_ptr = des_data;
-
- /* First copy portion prior to insert point */
- memcpy(des_ptr, src_ptr, (planestride * insert_index) << deep);
-
- /* New planes */
- des_ptr += (planestride * insert_index) << deep;
- src_ptr += (planestride * insert_index) << deep;
- memset(des_ptr, 0, (planestride * num_new_planes) << deep);
-
- /* Extra planes (i.e. doc spots, tags) */
- des_ptr += (planestride * num_new_planes) << deep;
- memcpy(des_ptr, src_ptr, (planestride * (src_n_planes - insert_index)) << deep);
-
- /* Set up buffer structure */
- gs_free_object(ctx->memory, (*src_buf)->data, "insert_empty_planes");
- (*src_buf)->n_planes = des_n_planes;
- (*src_buf)->n_chan = des_n_chan;
- (*src_buf)->data = des_data;
-
- return *src_buf;
-}
-
static int
pdf14_put_blended_image_cmykspot(gx_device* dev, gx_device* target,
gs_gstate* pgs, pdf14_buf* buf, int planestride_in,
@@ -3418,30 +3392,6 @@ pdf14_put_blended_image_cmykspot(gx_device* dev, gx_device* target,
tag_offset = buf->has_tags ? buf->n_chan : 0;
}
- /* We may need to pad the buffers to ensure that any additional spot
- channels that are not created by the ICC color conversion (or
- non-conversion if this is not an NCLR profile) get placed properly.
- It is up to the target device to
- handle these planes how it sees fit based upon the image data
- and/or any tags plane during any put image call. We *could*
- do something here to possibly communicate through the put_image
- call where the page related spots start, but that would/could
- be confusing, especially for long term maintenance. Easier just
- to have put_image hand all the data */
- if (dev_target_profile->spotnames != NULL &&
- dev_target_profile->spotnames->count > des_profile->num_comps) {
- int num_new_planes = dev_target_profile->spotnames->count - des_profile->num_comps;
- int insert_index = des_profile->num_comps;
- pdf14_buf* result;
-
- result = insert_empty_planes(pdev->ctx, &buf, num_new_planes, insert_index);
- if (result == NULL)
- return_error(gs_error_VMerror);
-
- num_comp = buf->n_chan;
- tag_offset = buf->has_tags ? buf->n_chan : 0;
- buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
- }
#if RAW_DUMP
/* Dump after the CS transform */
dump_raw_buffer_be(target->memory, height, width, buf->n_planes, planestride, rowstride,
@@ -3859,6 +3809,9 @@ gs_pdf14_device_copy_params(gx_device *dev, const gx_device *target)
dev->icc_struct->supports_devn = profile_targ->supports_devn;
dev->icc_struct->usefastcolor = profile_targ->usefastcolor;
dev->icc_struct->blacktext = profile_targ->blacktext;
+ dev->icc_struct->blackvector = profile_targ->blackvector;
+ dev->icc_struct->blackthresholdL = profile_targ->blackthresholdL;
+ dev->icc_struct->blackthresholdC = profile_targ->blackthresholdC;
switch (pdev->blend_cs_state) {
case PDF14_BLEND_CS_UNSPECIFIED:
@@ -5179,7 +5132,7 @@ pdf14_tile_pattern_fill(gx_device * pdev, const gs_gstate * pgs,
curr_clip_rect = cpath_intersection.rect_list->list.head->next;
for( k = 0; k < cpath_intersection.rect_list->list.count && code >= 0; k++){
if_debug5m('v', pgs->memory,
- "[v]pdf14_tile_pattern_fill, (%d, %d), %d x %d pat_id %d \n",
+ "[v]pdf14_tile_pattern_fill, (%d, %d), %d x %d pat_id %u \n",
curr_clip_rect->xmin, curr_clip_rect->ymin,
curr_clip_rect->xmax-curr_clip_rect->xmin,
curr_clip_rect->ymax-curr_clip_rect->ymin, (int)ptile->id);
@@ -5191,7 +5144,7 @@ pdf14_tile_pattern_fill(gx_device * pdev, const gs_gstate * pgs,
} else if (cpath_intersection.rect_list->list.count == 1) {
/* The case when there is just a single rect */
if_debug5m('v', pgs->memory,
- "[v]pdf14_tile_pattern_fill, (%d, %d), %d x %d pat_id %d \n",
+ "[v]pdf14_tile_pattern_fill, (%d, %d), %d x %d pat_id %u \n",
cpath_intersection.rect_list->list.single.xmin,
cpath_intersection.rect_list->list.single.ymin,
cpath_intersection.rect_list->list.single.xmax-
@@ -6292,7 +6245,17 @@ pdf14_copy_mono(gx_device * dev,
/* Set up for the start of each line of the area. */
sptr = line;
sbyte = *sptr++;
- bit = first_bit;
+ /* The +1 here is 'sacrificial', we are going to decrement it by 1 immediately in
+ * the loop below so adding 1 means that we don't fall into the bit == 0
+ * case and incorrectly read a new byte from the source. This weirdness is because
+ * the original code wouold read off the end of the buffer if the number of bits in
+ * the raster was an exact multiple of 8. If it was also a multiple of the word
+ * size we might read unallocated memory. Moving the 'sbyte = *sptr++' from the end
+ * of the loop to the beginning meant we would not read past the end of the buffer
+ * because we would drop out of the 'do ... while (count-- > 0)' loop before
+ * reading another byte.
+ */
+ bit = first_bit + 1;
count = w;
run_length = 0;
startx = x;
@@ -6301,6 +6264,13 @@ pdf14_copy_mono(gx_device * dev,
/* Loop across each pixel of a line. */
do {
+ /* Move to the next input bit. */
+ if (bit == 0) {
+ bit = 7;
+ sbyte = *sptr++;
+ }
+ else
+ bit--;
bit_value = (sbyte >> bit) & 1;
if (bit_value == current_bit) {
/* The value did not change, simply increment our run length */
@@ -6320,13 +6290,6 @@ pdf14_copy_mono(gx_device * dev,
current_color = bit_value ? one : zero;
current_bit = bit_value;
}
- /* Move to the next input bit. */
- if (bit == 0) {
- bit = 7;
- sbyte = *sptr++;
- }
- else
- bit--;
} while (--count > 0);
/* Fill the last rectangle in the line. */
if (run_length != 0 && current_color != gx_no_color_index) {
@@ -8432,6 +8395,11 @@ pdf14_cmap_separation_direct(frac all, gx_device_color * pdc, const gs_gstate *
} else {
frac comp_value[GX_DEVICE_COLOR_MAX_COMPONENTS];
+ if (pgs->color_component_map.sep_type == SEP_NONE) {
+ color_set_null(pdc);
+ return;
+ }
+
/* map to the color model */
for (i = pgs->color_component_map.num_components - 1; i >= 0; i--)
comp_value[i] = all;
@@ -8867,6 +8835,7 @@ gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs,
new_target->PageHandlerPushed = true;
new_target->ObjectHandlerPushed = true;
+ new_target->NupHandlerPushed = true;
/* if the device has separations already defined (by SeparationOrderNames) */
/* we need to copy them (allocating new names) so the colorants are in the */
/* same order as the target device. */
@@ -10699,7 +10668,7 @@ pdf14_clist_composite(gx_device * dev, gx_device ** pcdev,
gx_device *target = ((pdf14_device *)(tdev->save_p14dev))->target;
gs_image1_t image;
gs_color_space *pcs;
- gx_image_enum_common_t *info;
+ gx_image_enum_common_t *info = NULL;
gx_image_plane_t planes;
gsicc_rendering_param_t render_cond;
cmm_dev_profile_t *dev_profile;
@@ -10814,9 +10783,15 @@ pdf14_clist_composite(gx_device * dev, gx_device ** pcdev,
if ((code = info->procs->plane_data(info, &planes, 1, &rows_used)) < 0)
goto put_accum_error;
}
- code = info->procs->end_image(info, true);
put_accum_error:
+ if (info != NULL) {
+ if (code < 0)
+ (void)info->procs->end_image(info, true);
+ else
+ code = info->procs->end_image(info, true);
+ }
+
gs_free_object(pdev->memory, linebuf, "pdf14_put_image");
/* This will also decrement the device profile */
rc_decrement_only_cs(pcs, "pdf14_put_image");
@@ -11841,7 +11816,7 @@ c_pdf14trans_clist_read_update(gs_composite_t * pcte, gx_device * cdev,
* was buffered into the output device.
*/
pclist_devn_params = dev_proc(cdev, ret_devn_params)(cdev);
- if (pclist_devn_params != NULL && pclist_devn_params->page_spot_colors != 0) {
+ if (pclist_devn_params != NULL && pclist_devn_params->page_spot_colors > 0) {
int num_comp = p14dev->color_info.num_components;
/*
* The number of components for the PDF14 device is the sum
@@ -11850,18 +11825,23 @@ c_pdf14trans_clist_read_update(gs_composite_t * pcte, gx_device * cdev,
* device (which coming into this are the same as the p14dev)
* are smaller than the number of page spot colors then
* use that for the number of components. Otherwise use
- * the page_spot_colors.
+ * the page_spot_colors. The exception is, if we had used
+ * the sICCOutputColors setting, then just use that, which
+ * should be already baked into num_comp
*/
- p14dev->devn_params.page_spot_colors =
- pclist_devn_params->page_spot_colors;
- if (num_comp < p14dev->devn_params.page_spot_colors + 4 ) {
- p14dev->color_info.num_components = num_comp;
- } else {
- /* if page_spot_colors < 0, this will be wrong, so don't update num_components */
- if (p14dev->devn_params.page_spot_colors >= 0) {
- p14dev->color_info.num_components =
- p14dev->devn_params.num_std_colorant_names +
- p14dev->devn_params.page_spot_colors;
+
+ if (cdev->icc_struct->spotnames == NULL) {
+ p14dev->devn_params.page_spot_colors =
+ pclist_devn_params->page_spot_colors;
+ if (num_comp < p14dev->devn_params.page_spot_colors + 4 ) {
+ p14dev->color_info.num_components = num_comp;
+ } else {
+ /* if page_spot_colors < 0, this will be wrong, so don't update num_components */
+ if (p14dev->devn_params.page_spot_colors >= 0) {
+ p14dev->color_info.num_components =
+ p14dev->devn_params.num_std_colorant_names +
+ p14dev->devn_params.page_spot_colors;
+ }
}
}
/* limit the num_components to the max. */