summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Watts <Robin.Watts@artifex.com>2019-04-01 20:30:23 +0100
committerRobin Watts <Robin.Watts@artifex.com>2019-04-27 00:39:01 +0100
commit991eca03f9b12ab50ce650bc67a20e6cc72924b5 (patch)
tree9d81c217326d7489712caa304633337a50df4396
parente1a534e843743230019de57a36a04129347a505e (diff)
downloadghostpdl-dev-robin.tar.gz
Move transfer functions to 16 bits.dev-robin
This means that in 'deep' modes, we sample them in 257 places (0000,0100,....ff00,ffff) rather than 256 (00,01,...ff), and in 16 bits rather than 8. We also interpolate them on reading. This in turn increases the size of the data put into the clist.
-rw-r--r--base/gdevp14.c181
-rw-r--r--base/gstparam.h2
-rw-r--r--base/gstrans.c29
-rw-r--r--base/gstrans.h2
-rw-r--r--base/gxblend.c85
5 files changed, 177 insertions, 122 deletions
diff --git a/base/gdevp14.c b/base/gdevp14.c
index 273056b3a..60e85b6e7 100644
--- a/base/gdevp14.c
+++ b/base/gdevp14.c
@@ -675,6 +675,84 @@ RELOC_PTRS_END
/* ------ Private definitions ------ */
+static void
+resolve_matte(pdf14_buf *maskbuf, byte *src_data, int src_planestride, int src_rowstride,
+ int width, int height, cmm_profile_t *src_profile, int deep)
+{
+ if (deep) {
+ int x, y, i;
+ uint16_t *mask_row_ptr = (uint16_t *)maskbuf->data;
+ uint16_t *src_row_ptr = (uint16_t *)src_data;
+ uint16_t *mask_tr_fn = (uint16_t *)maskbuf->transfer_fn;
+
+ src_planestride >>= 1;
+ src_rowstride >>= 1;
+
+ for (y = 0; y < height; y++) {
+ uint16_t *mask_curr_ptr = mask_row_ptr;
+ uint16_t *src_curr_ptr = src_row_ptr;
+ for (x = 0; x < width; x++) {
+ uint16_t idx = *mask_curr_ptr;
+ byte top = idx>>8;
+ uint16_t a = mask_tr_fn[top];
+ int b = mask_tr_fn[top+1]-a;
+ uint16_t matte_alpha = a + ((0x80 + b*(idx & 0xff))>>8);
+
+ if (matte_alpha != 0 && matte_alpha != 0xffff) {
+ for (i = 0; i < src_profile->num_comps; i++) {
+ int val = src_curr_ptr[i * src_planestride] - maskbuf->matte[i];
+ int temp = ((unsigned int)(val * 0xffff) / matte_alpha) + maskbuf->matte[i];
+
+ /* clip */
+ if (temp > 0xffff)
+ src_curr_ptr[i * src_planestride] = 0xffff;
+ else if (temp < 0)
+ src_curr_ptr[i * src_planestride] = 0;
+ else
+ src_curr_ptr[i * src_planestride] = temp;
+ }
+ }
+ mask_curr_ptr++;
+ src_curr_ptr++;
+ }
+ src_row_ptr += src_rowstride;
+ mask_row_ptr += (maskbuf->rowstride>>1);
+ }
+ } else {
+ int x, y, i;
+ byte *mask_row_ptr = maskbuf->data;
+ byte *src_row_ptr = src_data;
+ byte *mask_tr_fn = maskbuf->transfer_fn;
+
+ for (y = 0; y < height; y++) {
+ byte *mask_curr_ptr = mask_row_ptr;
+ byte *src_curr_ptr = src_row_ptr;
+ for (x = 0; x < width; x++) {
+ byte matte_alpha = mask_tr_fn[*mask_curr_ptr];
+ if (matte_alpha != 0 && matte_alpha != 0xff) {
+ for (i = 0; i < src_profile->num_comps; i++) {
+ byte matte = maskbuf->matte[i]>>8;
+ int val = src_curr_ptr[i * src_planestride] - matte;
+ int temp = ((((val * 0xff) << 8) / matte_alpha) >> 8) + matte;
+
+ /* clip */
+ if (temp > 0xff)
+ src_curr_ptr[i * src_planestride] = 0xff;
+ else if (temp < 0)
+ src_curr_ptr[i * src_planestride] = 0;
+ else
+ src_curr_ptr[i * src_planestride] = temp;
+ }
+ }
+ mask_curr_ptr++;
+ src_curr_ptr++;
+ }
+ src_row_ptr += src_rowstride;
+ mask_row_ptr += maskbuf->rowstride;
+ }
+ }
+}
+
/* Transform of color data and copy noncolor data. Used in
group pop and during the pdf14 put image calls when the blend color space
is different than the target device color space. The function will try do
@@ -773,72 +851,7 @@ template_transform_color_buffer(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev,
((mask_stack = ctx->mask_stack) != NULL) &&
((maskbuf = mask_stack->rc_mask->mask_buf) != NULL))
{
- byte *mask_tr_fn = maskbuf->transfer_fn;
- if (deep) {
- int x, y, i;
- uint16_t *mask_row_ptr = (uint16_t *)maskbuf->data;
- uint16_t *src_row_ptr = (uint16_t *)src_data;
-
- src_planestride >>= 1;
- src_rowstride >>= 1;
-
- for (y = 0; y < height; y++) {
- uint16_t *mask_curr_ptr = mask_row_ptr;
- uint16_t *src_curr_ptr = src_row_ptr;
- for (x = 0; x < width; x++) {
- uint16_t matte_alpha = 0x101*mask_tr_fn[(*mask_curr_ptr)>>8]; /* FIXME: Still using 8 bits for transfer functions */
- if (matte_alpha != 0 && matte_alpha != 0xffff) {
- for (i = 0; i < src_profile->num_comps; i++) {
- int val = src_curr_ptr[i * src_planestride] - maskbuf->matte[i];
- int temp = ((unsigned int)(val * 0xffff) / matte_alpha) + maskbuf->matte[i];
-
- /* clip */
- if (temp > 0xffff)
- src_curr_ptr[i * src_planestride] = 0xffff;
- else if (temp < 0)
- src_curr_ptr[i * src_planestride] = 0;
- else
- src_curr_ptr[i * src_planestride] = temp;
- }
- }
- mask_curr_ptr++;
- src_curr_ptr++;
- }
- src_row_ptr += src_rowstride;
- mask_row_ptr += (maskbuf->rowstride>>1);
- }
- } else {
- int x, y, i;
- byte *mask_row_ptr = maskbuf->data;
- byte *src_row_ptr = src_data;
-
- for (y = 0; y < height; y++) {
- byte *mask_curr_ptr = mask_row_ptr;
- byte *src_curr_ptr = src_row_ptr;
- for (x = 0; x < width; x++) {
- byte matte_alpha = mask_tr_fn[*mask_curr_ptr];
- if (matte_alpha != 0 && matte_alpha != 0xff) {
- for (i = 0; i < src_profile->num_comps; i++) {
- byte matte = maskbuf->matte[i]>>8;
- int val = src_curr_ptr[i * src_planestride] - matte;
- int temp = ((((val * 0xff) << 8) / matte_alpha) >> 8) + matte;
-
- /* clip */
- if (temp > 0xff)
- src_curr_ptr[i * src_planestride] = 0xff;
- else if (temp < 0)
- src_curr_ptr[i * src_planestride] = 0;
- else
- src_curr_ptr[i * src_planestride] = temp;
- }
- }
- mask_curr_ptr++;
- src_curr_ptr++;
- }
- src_row_ptr += src_rowstride;
- mask_row_ptr += maskbuf->rowstride;
- }
- }
+ resolve_matte(maskbuf, src_data, src_planestride, src_rowstride, width, height, src_profile, deep);
}
/* Transform the data. Since the pdf14 device should be using RGB, CMYK or
@@ -5435,6 +5448,10 @@ pdf14_begin_transparency_mask(gx_device *dev,
int code;
int group_color_numcomps;
gs_transparency_color_t group_color;
+ bool has_tags = device_encodes_tags(dev);
+ int bits_per_comp = ((dev->color_info.depth - has_tags*8) /
+ dev->color_info.num_components);
+ int deep = bits_per_comp > 8;
if (ptmp->subtype == TRANSPARENCY_MASK_None) {
pdf14_ctx *ctx = pdev->ctx;
@@ -5448,7 +5465,7 @@ pdf14_begin_transparency_mask(gx_device *dev,
}
return 0;
}
- transfer_fn = (byte *)gs_alloc_bytes(pdev->ctx->memory, 256,
+ transfer_fn = (byte *)gs_alloc_bytes(pdev->ctx->memory, (256+deep)<<deep,
"pdf14_begin_transparency_mask");
if (transfer_fn == NULL)
return_error(gs_error_VMerror);
@@ -5460,7 +5477,7 @@ pdf14_begin_transparency_mask(gx_device *dev,
bg_alpha = (int)(65535 * ptmp->GrayBackground + 0.5);
if_debug1m('v', dev->memory,
"pdf14_begin_transparency_mask, bg_alpha = %d\n", bg_alpha);
- memcpy(transfer_fn, ptmp->transfer_fn, size_of(ptmp->transfer_fn));
+ memcpy(transfer_fn, ptmp->transfer_fn, (256+deep)<<deep);
/* If the group color is unknown, then we must use the previous group color
space or the device process color space */
if (ptmp->group_color == UNKNOWN){
@@ -6653,6 +6670,10 @@ c_pdf14trans_write(const gs_composite_t * pct, byte * data, uint * psize,
int pdf14_needed = cdev->pdf14_needed;
int trans_group_level = cdev->pdf14_trans_group_level;
int smask_level = cdev->pdf14_smask_level;
+ bool has_tags = device_encodes_tags((gx_device *)cdev);
+ int bits_per_comp = ((cdev->color_info.depth - has_tags*8) /
+ cdev->color_info.num_components);
+ bool deep = bits_per_comp > 8;
code = dev_proc((gx_device *) cdev, get_profile)((gx_device *) cdev,
&dev_profile);
@@ -6748,7 +6769,7 @@ c_pdf14trans_write(const gs_composite_t * pct, byte * data, uint * psize,
*pbuf++ = pparams->group_color;
put_value(pbuf, pparams->group_color_numcomps);
*pbuf++ = pparams->replacing;
- *pbuf++ = pparams->function_is_identity;
+ *pbuf++ = (pparams->function_is_identity) | (deep<<1);
*pbuf++ = pparams->Background_components;
*pbuf++ = pparams->Matte_components;
put_value(pbuf, pparams->bbox);
@@ -6769,7 +6790,7 @@ c_pdf14trans_write(const gs_composite_t * pct, byte * data, uint * psize,
pbuf += m;
}
if (!pparams->function_is_identity)
- mask_size = sizeof(pparams->transfer_fn);
+ mask_size = (256+deep)<<deep;
/* Color space information may be ICC based
in this case we need to store the ICC
profile or the ID if it is cached already */
@@ -6882,6 +6903,7 @@ c_pdf14trans_read(gs_composite_t * * ppct, const byte * data,
gs_pdf14trans_params_t params = {0};
const byte * start = data;
int used, code = 0;
+ bool deep;
if (size < 1)
return_error(gs_error_rangecheck);
@@ -6950,7 +6972,8 @@ c_pdf14trans_read(gs_composite_t * * ppct, const byte * data,
params.group_color = *data++;
read_value(data, params.group_color_numcomps);
params.replacing = *data++;
- params.function_is_identity = *data++;
+ params.function_is_identity = *data & 1;
+ deep = (*data++)>>1;
params.Background_components = *data++;
params.Matte_components = *data++;
read_value(data, params.bbox);
@@ -6973,13 +6996,19 @@ c_pdf14trans_read(gs_composite_t * * ppct, const byte * data,
if (params.function_is_identity) {
int i;
- /* FIXME: Transfer functions may want to be based on 16 bits? */
- for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++) {
- params.transfer_fn[i] = (byte)floor(i *
- (255.0 / (MASK_TRANSFER_FUNCTION_SIZE - 1)) + 0.5);
+ if (deep) {
+ for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++)
+ ((uint16_t *)params.transfer_fn)[i] = i*0x10000/MASK_TRANSFER_FUNCTION_SIZE;
+ ((uint16_t *)params.transfer_fn)[i] = 0xffff;
+ } else {
+ for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++) {
+ params.transfer_fn[i] = (byte)floor(i *
+ (255.0 / (MASK_TRANSFER_FUNCTION_SIZE - 1)) + 0.5);
+ }
}
} else {
- read_value(data, params.transfer_fn);
+ memcpy(params.transfer_fn, data, (256+deep)<<deep);
+ data += (256+deep)<<deep;
}
break;
case PDF14_END_TRANS_MASK:
diff --git a/base/gstparam.h b/base/gstparam.h
index 219a04898..4de92bfb4 100644
--- a/base/gstparam.h
+++ b/base/gstparam.h
@@ -114,7 +114,7 @@ typedef struct gx_transparency_mask_params_s {
bool idle;
bool replacing;
uint mask_id;
- byte transfer_fn[MASK_TRANSFER_FUNCTION_SIZE];
+ byte transfer_fn[MASK_TRANSFER_FUNCTION_SIZE*2+2];
int64_t icc_hashcode; /* Needed when we are doing clist reading */
cmm_profile_t *iccprofile; /* The profile */
} gx_transparency_mask_params_t;
diff --git a/base/gstrans.c b/base/gstrans.c
index 68b603ccc..75f83288a 100644
--- a/base/gstrans.c
+++ b/base/gstrans.c
@@ -548,6 +548,10 @@ gs_begin_transparency_mask(gs_gstate * pgs,
int i, code;
gs_color_space *blend_color_space;
gsicc_manager_t *icc_manager = pgs->icc_manager;
+ bool has_tags = device_encodes_tags(pgs->device);
+ int bits_per_comp = ((pgs->device->color_info.depth - has_tags*8) /
+ pgs->device->color_info.num_components);
+ int deep = bits_per_comp > 8;
if (check_for_nontrans_pattern(pgs,
(unsigned char *)"gs_pop_transparency_state")) {
@@ -601,12 +605,29 @@ gs_begin_transparency_mask(gs_gstate * pgs,
(ptmp->TransferFunction == mask_transfer_identity ? "no TR" :
"has TR"));
/* Sample the transfer function */
- for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++) {
- float in = (float)(i * (1.0 / (MASK_TRANSFER_FUNCTION_SIZE - 1)));
+ /* For non-deep cases, we sample at 00,01,02..fe,ff.
+ * For deep cases, we sample from 0000,0100,0200..fe00,ff00 and a final one at ffff.
+ * This enables us to interpolate easily.
+ */
+ if (deep) {
+ uint16_t *trans16 = (uint16_t *)params.transfer_fn;
float out;
+ for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++) {
+ float in = (float)(i * (1.0 / MASK_TRANSFER_FUNCTION_SIZE));
- ptmp->TransferFunction(in, &out, ptmp->TransferFunction_data);
- params.transfer_fn[i] = (byte)floor((double)(out * 255 + 0.5));
+ ptmp->TransferFunction(in, &out, ptmp->TransferFunction_data);
+ trans16[i] = (uint16_t)floor((double)(out * 65535 + 0.5));
+ }
+ ptmp->TransferFunction(1.0, &out, ptmp->TransferFunction_data);
+ trans16[MASK_TRANSFER_FUNCTION_SIZE] = (uint16_t)floor((double)(out * 65535 + 0.5));
+ } else {
+ for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++) {
+ float in = (float)(i * (1.0 / (MASK_TRANSFER_FUNCTION_SIZE - 1)));
+ float out;
+
+ ptmp->TransferFunction(in, &out, ptmp->TransferFunction_data);
+ params.transfer_fn[i] = (byte)floor((double)(out * 255 + 0.5));
+ }
}
/* Note: This function is called during the c-list writer side. */
if ( blend_color_space->cmm_icc_profile_data != NULL ) {
diff --git a/base/gstrans.h b/base/gstrans.h
index 96e53fcaf..25180072a 100644
--- a/base/gstrans.h
+++ b/base/gstrans.h
@@ -114,7 +114,7 @@ struct gs_pdf14trans_params_s {
outside its own groups bounding
box in such a case */
gs_function_t *transfer_function;
- byte transfer_fn[MASK_TRANSFER_FUNCTION_SIZE];
+ byte transfer_fn[MASK_TRANSFER_FUNCTION_SIZE*2+2];
/* Individual transparency parameters */
gs_blend_mode_t blend_mode;
bool text_knockout;
diff --git a/base/gxblend.c b/base/gxblend.c
index 0dd1a8a26..f95129254 100644
--- a/base/gxblend.c
+++ b/base/gxblend.c
@@ -2661,7 +2661,7 @@ typedef void (*art_pdf_compose_group_fn)(byte *tos_ptr, bool tos_isolated, int t
int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag,
byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride,
byte *nos_alpha_g_ptr, bool nos_knockout, int nos_shape_offset, int nos_tag_offset,
- byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, byte *mask_tr_fn,
+ byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, const byte *mask_tr_fn,
byte *backdrop_ptr, bool has_matte, int n_chan, bool additive, int num_spots, bool overprint,
gx_color_index drawn_comps, int x0, int y0, int x1, int y1,
const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev);
@@ -2678,7 +2678,7 @@ template_compose_group(byte *gs_restrict tos_ptr, bool tos_isolated,
bool nos_knockout, int nos_shape_offset,
int nos_tag_offset, byte *gs_restrict mask_row_ptr,
int has_mask, pdf14_buf *gs_restrict maskbuf,
- byte mask_bg_alpha, byte *gs_restrict mask_tr_fn,
+ byte mask_bg_alpha, const byte *gs_restrict mask_tr_fn,
byte *gs_restrict backdrop_ptr, bool has_matte,
int n_chan, bool additive, int num_spots,
bool overprint, gx_color_index drawn_comps,
@@ -2916,7 +2916,7 @@ compose_group_knockout(byte *tos_ptr, bool tos_isolated, int tos_planestride, in
int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag,
byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, byte *nos_alpha_g_ptr, bool nos_knockout,
int nos_shape_offset, int nos_tag_offset,
- byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, byte *mask_tr_fn,
+ byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, const byte *mask_tr_fn,
byte *backdrop_ptr,
bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1,
const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev)
@@ -2933,7 +2933,7 @@ compose_group_nonknockout_blend(byte *tos_ptr, bool tos_isolated, int tos_planes
int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag,
byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, byte *nos_alpha_g_ptr, bool nos_knockout,
int nos_shape_offset, int nos_tag_offset,
- byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, byte *mask_tr_fn,
+ byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, const byte *mask_tr_fn,
byte *backdrop_ptr,
bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1,
const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev)
@@ -2950,7 +2950,7 @@ compose_group_nonknockout_nonblend_isolated_allmask_common(byte *tos_ptr, bool t
int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag,
byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, byte *nos_alpha_g_ptr, bool nos_knockout,
int nos_shape_offset, int nos_tag_offset,
- byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, byte *mask_tr_fn,
+ byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, const byte *mask_tr_fn,
byte *backdrop_ptr,
bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1,
const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev)
@@ -3015,7 +3015,7 @@ compose_group_nonknockout_nonblend_isolated_mask_common(byte *tos_ptr, bool tos_
int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag,
byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, byte *nos_alpha_g_ptr, bool nos_knockout,
int nos_shape_offset, int nos_tag_offset,
- byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, byte *mask_tr_fn,
+ byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, const byte *mask_tr_fn,
byte *backdrop_ptr,
bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1,
const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev)
@@ -3105,7 +3105,7 @@ compose_group_nonknockout_nonblend_isolated_nomask_common(byte *tos_ptr, bool to
int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag,
byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, byte *nos_alpha_g_ptr, bool nos_knockout,
int nos_shape_offset, int nos_tag_offset,
- byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, byte *mask_tr_fn,
+ byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, const byte *mask_tr_fn,
byte *backdrop_ptr,
bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1,
const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev)
@@ -3122,7 +3122,7 @@ compose_group_nonknockout_nonblend_nonisolated_mask_common(byte *tos_ptr, bool t
int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag,
byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, byte *nos_alpha_g_ptr, bool nos_knockout,
int nos_shape_offset, int nos_tag_offset,
- byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, byte *mask_tr_fn,
+ byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, const byte *mask_tr_fn,
byte *backdrop_ptr,
bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1,
const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev)
@@ -3139,7 +3139,7 @@ compose_group_nonknockout_nonblend_nonisolated_nomask_common(byte *tos_ptr, bool
int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag,
byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, byte *nos_alpha_g_ptr, bool nos_knockout,
int nos_shape_offset, int nos_tag_offset,
- byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, byte *mask_tr_fn,
+ byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, const byte *mask_tr_fn,
byte *backdrop_ptr,
bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1,
const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev)
@@ -3156,7 +3156,7 @@ compose_group_nonknockout_noblend_general(byte *tos_ptr, bool tos_isolated, int
int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag,
byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, byte *nos_alpha_g_ptr, bool nos_knockout,
int nos_shape_offset, int nos_tag_offset,
- byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, byte *mask_tr_fn,
+ byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, const byte *mask_tr_fn,
byte *backdrop_ptr,
bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1,
const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev)
@@ -3173,7 +3173,7 @@ compose_group_alphaless_knockout(byte *tos_ptr, bool tos_isolated, int tos_plane
int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag,
byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, byte *nos_alpha_g_ptr, bool nos_knockout,
int nos_shape_offset, int nos_tag_offset,
- byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, byte *mask_tr_fn,
+ byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, const byte *mask_tr_fn,
byte *backdrop_ptr,
bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1,
const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev)
@@ -3190,7 +3190,7 @@ compose_group_alphaless_nonknockout(byte *tos_ptr, bool tos_isolated, int tos_pl
int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag,
byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, byte *nos_alpha_g_ptr, bool nos_knockout,
int nos_shape_offset, int nos_tag_offset,
- byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, byte *mask_tr_fn,
+ byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, const byte *mask_tr_fn,
byte *backdrop_ptr,
bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1,
const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev)
@@ -3379,13 +3379,22 @@ do_compose_group(pdf14_buf *tos, pdf14_buf *nos, pdf14_buf *maskbuf,
#endif
}
+static inline uint16_t
+interp16(const uint16_t *table, uint16_t idx)
+{
+ byte top = idx>>8;
+ uint16_t a = table[top];
+ int b = table[top+1]-a;
+
+ return a + ((0x80 + b*(idx & 0xff))>>8);
+}
typedef void (*art_pdf_compose_group16_fn)(uint16_t *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride,
uint16_t alpha, uint16_t shape, gs_blend_mode_t blend_mode, bool tos_has_shape,
int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag,
uint16_t *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride,
uint16_t *nos_alpha_g_ptr, bool nos_knockout, int nos_shape_offset, int nos_tag_offset,
- uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, byte *mask_tr_fn,
+ uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, const uint16_t *mask_tr_fn,
uint16_t *backdrop_ptr, bool has_matte, int n_chan, bool additive, int num_spots, bool overprint,
gx_color_index drawn_comps, int x0, int y0, int x1, int y1,
const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev);
@@ -3402,7 +3411,7 @@ template_compose_group16(uint16_t *gs_restrict tos_ptr, bool tos_isolated,
bool nos_knockout, int nos_shape_offset,
int nos_tag_offset, uint16_t *gs_restrict mask_row_ptr,
int has_mask, pdf14_buf *gs_restrict maskbuf,
- uint16_t mask_bg_alpha, byte *gs_restrict mask_tr_fn,
+ uint16_t mask_bg_alpha, const uint16_t *gs_restrict mask_tr_fn,
uint16_t *gs_restrict backdrop_ptr, bool has_matte,
int n_chan, bool additive, int num_spots,
bool overprint, gx_color_index drawn_comps,
@@ -3463,8 +3472,7 @@ template_compose_group16(uint16_t *gs_restrict tos_ptr, bool tos_isolated,
matte_alpha = 0xffff;
} else {
if (has_matte)
- /* FIXME: Not ideal */
- matte_alpha = mask_tr_fn[*mask_curr_ptr >> 8] * 0x101;
+ matte_alpha = interp16(mask_tr_fn, *mask_curr_ptr);
}
}
@@ -3521,8 +3529,7 @@ template_compose_group16(uint16_t *gs_restrict tos_ptr, bool tos_isolated,
if (mask_curr_ptr != NULL) {
if (in_mask_rect) {
- /* FIXME: Not ideal */
- uint16_t mask = mask_tr_fn[(*mask_curr_ptr++)>>8] * 0x101;
+ uint16_t mask = interp16(mask_tr_fn, *mask_curr_ptr++);
int tmp = pix_alpha * (mask+(mask>>15)) + 0x8000;
pix_alpha = (tmp >> 16);
} else {
@@ -3654,7 +3661,7 @@ compose_group16_knockout(uint16_t *tos_ptr, bool tos_isolated, int tos_planestri
bool tos_has_shape, int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag,
uint16_t *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, uint16_t *nos_alpha_g_ptr, bool nos_knockout,
int nos_shape_offset, int nos_tag_offset,
- uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, byte *mask_tr_fn,
+ uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, const uint16_t *mask_tr_fn,
uint16_t *backdrop_ptr,
bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1,
const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev)
@@ -3671,7 +3678,7 @@ compose_group16_nonknockout_blend(uint16_t *tos_ptr, bool tos_isolated, int tos_
gs_blend_mode_t blend_mode, bool tos_has_shape, int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag,
uint16_t *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, uint16_t *nos_alpha_g_ptr, bool nos_knockout,
int nos_shape_offset, int nos_tag_offset,
- uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, byte *mask_tr_fn,
+ uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, const uint16_t *mask_tr_fn,
uint16_t *backdrop_ptr,
bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1,
const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev)
@@ -3688,7 +3695,7 @@ compose_group16_nonknockout_nonblend_isolated_allmask_common(uint16_t *tos_ptr,
uint16_t shape, gs_blend_mode_t blend_mode, bool tos_has_shape, int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag,
uint16_t *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, uint16_t *nos_alpha_g_ptr, bool nos_knockout,
int nos_shape_offset, int nos_tag_offset,
- uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, byte *mask_tr_fn,
+ uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, const uint16_t *mask_tr_fn,
uint16_t *backdrop_ptr,
bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1,
const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev)
@@ -3700,8 +3707,7 @@ compose_group16_nonknockout_nonblend_isolated_allmask_common(uint16_t *tos_ptr,
for (y = y1 - y0; y > 0; --y) {
uint16_t *gs_restrict mask_curr_ptr = mask_row_ptr;
for (x = 0; x < width; x++) {
- /* FIXME: Not ideal */
- int mask = mask_tr_fn[(*mask_curr_ptr++)>>8] * 0x101;
+ int mask = interp16(mask_tr_fn, *mask_curr_ptr++);
uint16_t src_alpha = tos_ptr[n_chan * tos_planestride];
if (src_alpha != 0) {
uint16_t a_b;
@@ -3759,7 +3765,7 @@ compose_group16_nonknockout_nonblend_isolated_mask_common(uint16_t *tos_ptr, boo
gs_blend_mode_t blend_mode, bool tos_has_shape, int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag,
uint16_t *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, uint16_t *nos_alpha_g_ptr, bool nos_knockout,
int nos_shape_offset, int nos_tag_offset,
- uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, byte *mask_tr_fn,
+ uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, const uint16_t *mask_tr_fn,
uint16_t *backdrop_ptr,
bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1,
const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev)
@@ -3791,8 +3797,7 @@ compose_group16_nonknockout_nonblend_isolated_mask_common(uint16_t *tos_ptr, boo
if (mask_curr_ptr != NULL) {
if (in_mask_rect) {
- /* FIXME: Not ideal */
- int mask = mask_tr_fn[(*mask_curr_ptr++)>>8] * 0x101;
+ int mask = interp16(mask_tr_fn, *mask_curr_ptr++);
mask += mask>>15;
pix_alpha = (pix_alpha * mask + 0x8000)>>16;
} else {
@@ -3854,7 +3859,7 @@ compose_group16_nonknockout_nonblend_isolated_nomask_common(uint16_t *tos_ptr, b
uint16_t shape, gs_blend_mode_t blend_mode, bool tos_has_shape, int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag,
uint16_t *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, uint16_t *nos_alpha_g_ptr, bool nos_knockout,
int nos_shape_offset, int nos_tag_offset,
- uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, byte *mask_tr_fn,
+ uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, const uint16_t *mask_tr_fn,
uint16_t *backdrop_ptr,
bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1,
const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev)
@@ -3871,7 +3876,7 @@ compose_group16_nonknockout_nonblend_nonisolated_mask_common(uint16_t *tos_ptr,
uint16_t shape, gs_blend_mode_t blend_mode, bool tos_has_shape, int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag,
uint16_t *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, uint16_t *nos_alpha_g_ptr, bool nos_knockout,
int nos_shape_offset, int nos_tag_offset,
- uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, byte *mask_tr_fn,
+ uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, const uint16_t *mask_tr_fn,
uint16_t *backdrop_ptr,
bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1,
const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev)
@@ -3888,7 +3893,7 @@ compose_group16_nonknockout_nonblend_nonisolated_nomask_common(uint16_t *tos_ptr
uint16_t shape, gs_blend_mode_t blend_mode, bool tos_has_shape, int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag,
uint16_t *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, uint16_t *nos_alpha_g_ptr, bool nos_knockout,
int nos_shape_offset, int nos_tag_offset,
- uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, byte *mask_tr_fn,
+ uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, const uint16_t *mask_tr_fn,
uint16_t *backdrop_ptr,
bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1,
const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev)
@@ -3905,7 +3910,7 @@ compose_group16_nonknockout_noblend_general(uint16_t *tos_ptr, bool tos_isolated
gs_blend_mode_t blend_mode, bool tos_has_shape, int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag,
uint16_t *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, uint16_t *nos_alpha_g_ptr, bool nos_knockout,
int nos_shape_offset, int nos_tag_offset,
- uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, byte *mask_tr_fn,
+ uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, const uint16_t *mask_tr_fn,
uint16_t *backdrop_ptr,
bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1,
const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev)
@@ -3922,7 +3927,7 @@ compose_group16_alphaless_knockout(uint16_t *tos_ptr, bool tos_isolated, int tos
gs_blend_mode_t blend_mode, bool tos_has_shape, int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag,
uint16_t *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, uint16_t *nos_alpha_g_ptr, bool nos_knockout,
int nos_shape_offset, int nos_tag_offset,
- uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, byte *mask_tr_fn,
+ uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, const uint16_t *mask_tr_fn,
uint16_t *backdrop_ptr,
bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1,
const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev)
@@ -3939,7 +3944,7 @@ compose_group16_alphaless_nonknockout(uint16_t *tos_ptr, bool tos_isolated, int
gs_blend_mode_t blend_mode, bool tos_has_shape, int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag,
uint16_t *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, uint16_t *nos_alpha_g_ptr, bool nos_knockout,
int nos_shape_offset, int nos_tag_offset,
- uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, byte *mask_tr_fn,
+ uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, const uint16_t *mask_tr_fn,
uint16_t *backdrop_ptr,
bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1,
const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev)
@@ -3983,7 +3988,7 @@ do_compose_group16(pdf14_buf *tos, pdf14_buf *nos, pdf14_buf *maskbuf,
int nos_shape_offset = n_chan * nos_planestride;
int nos_alpha_g_offset = nos_shape_offset + (nos->has_shape ? nos_planestride : 0);
int nos_tag_offset = nos_planestride * (nos->n_planes - 1);
- byte *mask_tr_fn = NULL; /* Quiet compiler. */
+ const uint16_t *mask_tr_fn = NULL; /* Quiet compiler. */
bool has_mask = false;
uint16_t *backdrop_ptr = NULL;
pdf14_device *pdev = (pdf14_device *)dev;
@@ -4021,7 +4026,8 @@ do_compose_group16(pdf14_buf *tos, pdf14_buf *nos, pdf14_buf *maskbuf,
overprint = false;
if (maskbuf != NULL) {
- mask_tr_fn = maskbuf->transfer_fn;
+ unsigned int tmp;
+ mask_tr_fn = (uint16_t *)maskbuf->transfer_fn;
/* Make sure we are in the mask buffer */
if (maskbuf->data != NULL) {
mask_row_ptr =
@@ -4036,9 +4042,9 @@ do_compose_group16(pdf14_buf *tos, pdf14_buf *nos, pdf14_buf *maskbuf,
mask_bg_alpha = maskbuf->alpha;
/* Adjust alpha by the mask background alpha. This is only used
if we are outside the soft mask rect during the filling operation */
- mask_bg_alpha = mask_tr_fn[mask_bg_alpha>>8] * 0x101;
- mask_bg_alpha += mask_bg_alpha>>8;
- mask_bg_alpha = (alpha * mask_bg_alpha + 0x8000)>>16;
+ mask_bg_alpha = interp16(mask_tr_fn, mask_bg_alpha);
+ tmp = alpha * mask_bg_alpha + 0x8000;
+ mask_bg_alpha = (tmp + (tmp >> 8)) >> 8;
}
n_chan--; /* Now the true number of colorants (i.e. not including alpha)*/
#if RAW_DUMP
@@ -4187,7 +4193,7 @@ do_compose_alphaless_group(pdf14_buf *tos, pdf14_buf *nos,
int nos_shape_offset = n_chan * nos_planestride;
int nos_alpha_g_offset = nos_shape_offset + (nos->has_shape ? nos_planestride : 0);
int nos_tag_offset = nos_planestride * (nos->n_planes - 1);
- byte *mask_tr_fn = NULL; /* Quiet compiler. */
+ const byte *mask_tr_fn = NULL; /* Quiet compiler. */
bool has_mask = false;
byte *backdrop_ptr = NULL;
#if RAW_DUMP
@@ -4319,7 +4325,6 @@ do_compose_alphaless_group16(pdf14_buf *tos, pdf14_buf *nos,
int nos_shape_offset = n_chan * nos_planestride;
int nos_alpha_g_offset = nos_shape_offset + (nos->has_shape ? nos_planestride : 0);
int nos_tag_offset = nos_planestride * (nos->n_planes - 1);
- byte *mask_tr_fn = NULL; /* Quiet compiler. */
bool has_mask = false;
uint16_t *backdrop_ptr = NULL;
#if RAW_DUMP
@@ -4405,7 +4410,7 @@ do_compose_alphaless_group16(pdf14_buf *tos, pdf14_buf *nos,
tos_shape_offset>>1, tos_alpha_g_offset>>1, tos_tag_offset>>1, tos_has_tag,
nos_ptr, nos_isolated, nos_planestride>>1, nos->rowstride>>1, nos_alpha_g_ptr, nos_knockout,
nos_shape_offset>>1, nos_tag_offset>>1,
- mask_row_ptr, has_mask, /* maskbuf */ NULL, mask_bg_alpha, mask_tr_fn,
+ mask_row_ptr, has_mask, /* maskbuf */ NULL, mask_bg_alpha, NULL,
backdrop_ptr,
/* has_matte */ 0, n_chan, additive, num_spots, overprint, drawn_comps, x0, y0, x1, y1,
pdev->blend_procs, pdev);