diff options
author | Sam James <sam@gentoo.org> | 2022-09-21 14:18:08 +0100 |
---|---|---|
committer | Sam James <sam@gentoo.org> | 2022-10-02 04:31:25 +0100 |
commit | a529111f77ff46f4836fe7312e70953bc16587cf (patch) | |
tree | 9dc3924cb1a6ef3ef853b7bb45f735365e0b4e6d /base/gdevp14.c | |
parent | Import Ghostscript 9.56.1 (diff) | |
download | ghostscript-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.c | 160 |
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. */ |