summaryrefslogtreecommitdiff
path: root/base
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2016-02-08 12:23:01 +0000
committerRobin Watts <robin.watts@artifex.com>2016-02-10 12:40:57 +0000
commitd9f041d6fe7eda89364df1424f85ace974ed0fec (patch)
tree594e4c025cc145d4ee194e6189951fd10884a249 /base
parent3c75e35b6bbadd553a074509c3d80046457dda98 (diff)
downloadghostpdl-d9f041d6fe7eda89364df1424f85ace974ed0fec.tar.gz
Extend copy_alpha to support 8 bit depth.
Currently copy_alpha (and copy_alpha_hl_color) can only accept 2 or 4 bits of alpha data. In order for the work on bug 696562 to proceed we need it to support 8 bits of alpha data. Extend the 2 default implementations here. Also update the docs to mention the new bit depths, and to mention the existence of copy_alpha_hl_color at all. Remove the line in the docs that claims copy_alpha will not be called unless get_alpha_bits returns non-1, as this will shortly not be true.
Diffstat (limited to 'base')
-rw-r--r--base/gdevabuf.c22
-rw-r--r--base/gdevdbit.c61
-rw-r--r--base/gdevm24.c33
-rw-r--r--base/gdevp14.c23
4 files changed, 102 insertions, 37 deletions
diff --git a/base/gdevabuf.c b/base/gdevabuf.c
index 4473f92fd..9bcdff20d 100644
--- a/base/gdevabuf.c
+++ b/base/gdevabuf.c
@@ -97,6 +97,28 @@ mem_alpha_copy_alpha(gx_device * dev, const byte * data, int data_x,
int raster, gx_bitmap_id id, int x, int y, int width, int height,
gx_color_index color, int depth)
{ /* Just use copy_color. */
+ if (depth == 8) {
+ /* We don't support depth=8 in this function, but this doesn't
+ * matter, because:
+ * 1) This code is only called for dTextAlphaBits > 0, when
+ * DisableFAPI=true. And we don't support DisableFAPI.
+ * 2) Even if we did support DisableFAPI, this can never actually
+ * be called because gx_compute_text_oversampling arranges that
+ * log2_scale.{x,y} sum to <= alpha_bits, and this code is only
+ * called if it sums to MORE than alpha_bits.
+ * 3) Even if copy_alpha DID somehow manage to be called, the
+ * only place that uses depth==8 is the imagemask interpolation
+ * code, and that can never hit this code. (Type 3 fonts might
+ * include Imagemasks, but those don't go through FAPI).
+ *
+ * If in the future we ever rearrange the conditions under which
+ * this code is called (so that it CAN be called with depth == 8)
+ * then this will probably be best implemented by decimating the
+ * input alpha values to either 2 or 4 bits as appropriate and
+ * then recursively calling us back.
+ */
+ return gs_error_unknownerror;
+ }
return (color == 0 ?
(*dev_proc(dev, fill_rectangle)) (dev, x, y, width, height,
color) :
diff --git a/base/gdevdbit.c b/base/gdevdbit.c
index eae3e6770..9f00be0c6 100644
--- a/base/gdevdbit.c
+++ b/base/gdevdbit.c
@@ -260,14 +260,24 @@ gx_default_copy_alpha_hl_color(gx_device * dev, const byte * data, int data_x,
int alpha2, alpha;
w_curr += 1;
- if (depth == 2) /* map 0 - 3 to 0 - 15 */
- alpha = ((row_alpha[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 5;
- else
- alpha2 = row_alpha[sx >> 1],
- alpha = (sx & 1 ? alpha2 & 0xf : alpha2 >> 4);
+ switch (depth)
+ {
+ case 2:
+ alpha = ((row_alpha[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 85;
+ break;
+ case 4:
+ alpha2 = row_alpha[sx >> 1];
+ alpha = (sx & 1 ? alpha2 & 0xf : alpha2 >> 4);
+ break;
+ case 8:
+ alpha = row_alpha[sx];
+ break;
+ default:
+ return gs_error_rangecheck;
+ }
if (alpha == 0) {
- /* With alpha 0 we want to avoid writting out this value.
+ /* With alpha 0 we want to avoid writing out this value.
* While it is true that writting it out leaves the color
* unchanged, any device that's watching what pixels are
* written (such as the pattern tile devices) may have problems.
@@ -286,11 +296,12 @@ gx_default_copy_alpha_hl_color(gx_device * dev, const byte * data, int data_x,
w_curr = 0;
x_curr = rx + 1;
} else {
- if (alpha == 15) {
+ if (alpha == 255) {
/* Just use the new color. */
composite = &(src_cv[0]);
} else {
/* We need to do the weighting by the alpha value */
+ alpha += (alpha>>7); /* Expand from 0..255->0..256 */
/* First get the old color */
for (k = 0; k < ncomps; k++) {
/* We only have 8 and 16 bit depth to worry about.
@@ -309,8 +320,8 @@ gx_default_copy_alpha_hl_color(gx_device * dev, const byte * data, int data_x,
}
/* Now compute the new color which is a blend of
the old and the new */
- blend_cv[k] = curr_cv[k] +
- (((long) src_cv[k] - (long) curr_cv[k]) * alpha / 15);
+ blend_cv[k] = ((curr_cv[k]<<8) +
+ (((long) src_cv[k] - (long) curr_cv[k]) * alpha))>>8;
composite = &(blend_cv[0]);
}
}
@@ -387,11 +398,22 @@ gx_default_copy_alpha(gx_device * dev, const byte * data, int data_x,
gx_color_index composite;
int alpha2, alpha;
- if (depth == 2) /* map 0 - 3 to 0 - 15 */
- alpha = ((row[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 5;
- else
+ switch(depth)
+ {
+ case 2:
+ /* map 0 - 3 to 0 - 15 */
+ alpha = ((row[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 85;
+ break;
+ case 4:
alpha2 = row[sx >> 1],
- alpha = (sx & 1 ? alpha2 & 0xf : alpha2 >> 4);
+ alpha = (sx & 1 ? alpha2 & 0xf : alpha2 >> 4) * 17;
+ break;
+ case 8:
+ alpha = row[sx];
+ break;
+ default:
+ return gs_error_rangecheck;
+ }
blend:
if (alpha == 0) {
/* Previously the code used to just write out the previous
@@ -405,11 +427,12 @@ gx_default_copy_alpha(gx_device * dev, const byte * data, int data_x,
LINE_ACCUM_FLUSH_AND_RESTART(dev, lout, bpp, lx, rx, out_size, ry);
lx = rx+1;
} else {
- if (alpha == 15) { /* Just write the new color. */
+ if (alpha == 255) { /* Just write the new color. */
composite = color;
} else {
gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
int i;
+ int alpha2 = alpha + (alpha>>7);
if (previous == gx_no_color_index) { /* Extract the old color. */
if (bpp < 8) {
@@ -453,19 +476,19 @@ gx_default_copy_alpha(gx_device * dev, const byte * data, int data_x,
#else
# define b_int int
#endif
-#define make_shade(old, clr, alpha, amax) \
- (old) + (((b_int)(clr) - (b_int)(old)) * (alpha) / (amax))
+#define make_shade(old, clr, alpha) \
+ (((((b_int)(old))<<8) + (((b_int)(clr) - (b_int)(old)) * (alpha)))>>8)
for (i=0; i<ncomps; i++)
- cv[i] = make_shade(cv[i], color_cv[i], alpha, 15);
+ cv[i] = make_shade(cv[i], color_cv[i], alpha2);
#undef b_int
#undef make_shade
composite =
(*dev_proc(dev, encode_color)) (dev, cv);
if (composite == gx_no_color_index) { /* The device can't represent this color. */
/* Move the alpha value towards 0 or 1. */
- if (alpha == 7) /* move 1/2 towards 1 */
+ if (alpha == 127) /* move 1/2 towards 1 */
++alpha;
- alpha = (alpha & 8) | (alpha >> 1);
+ alpha = (alpha & 128) | (alpha >> 1);
goto blend;
}
}
diff --git a/base/gdevm24.c b/base/gdevm24.c
index 70eb243f2..78f93d382 100644
--- a/base/gdevm24.c
+++ b/base/gdevm24.c
@@ -508,20 +508,31 @@ mem_true24_copy_alpha(gx_device * dev, const byte * base, int sourcex,
for (sx = sourcex; sx < sourcex + w; ++sx, pptr += 3) {
int alpha2, alpha;
- if (depth == 2) /* map 0 - 3 to 0 - 15 */
+ switch(depth)
+ {
+ case 2: /* map 0 - 3 to 0 - 255 */
alpha =
- ((line[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 5;
- else
- alpha2 = line[sx >> 1],
- alpha = (sx & 1 ? alpha2 & 0xf : alpha2 >> 4);
- if (alpha == 15) { /* Just write the new color. */
+ ((line[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 85;
+ break;
+ case 4:
+ alpha2 = line[sx >> 1];
+ alpha = (sx & 1 ? alpha2 & 0xf : alpha2 >> 4) * 17;
+ break;
+ case 8:
+ alpha = line[sx];
+ break;
+ default:
+ return gs_error_rangecheck;
+ }
+ if (alpha == 255) { /* Just write the new color. */
put3(pptr, r, g, b);
} else if (alpha != 0) { /* Blend RGB values. */
-#define make_shade(old, clr, alpha, amax) \
- (old) + (((int)(clr) - (int)(old)) * (alpha) / (amax))
- pptr[0] = make_shade(pptr[0], r, alpha, 15);
- pptr[1] = make_shade(pptr[1], g, alpha, 15);
- pptr[2] = make_shade(pptr[2], b, alpha, 15);
+ alpha += alpha>>7;
+#define make_shade(old, clr, alpha) \
+ ((((old)<<8) + ((int)(clr) - (int)(old)) * (alpha))>>8)
+ pptr[0] = make_shade(pptr[0], r, alpha);
+ pptr[1] = make_shade(pptr[1], g, alpha);
+ pptr[2] = make_shade(pptr[2], b, alpha);
#undef make_shade
}
}
diff --git a/base/gdevp14.c b/base/gdevp14.c
index dea1f81f1..ab59ab035 100644
--- a/base/gdevp14.c
+++ b/base/gdevp14.c
@@ -2492,16 +2492,25 @@ pdf14_copy_alpha_color(gx_device * dev, const byte * data, int data_x,
dst[num_comp] = dst_ptr[num_comp * planestride]; /* alpha */
}
/* Get the aa alpha from the buffer */
- if (depth == 2) { /* map 0 - 3 to 0 - 15 */
- alpha_aa = ((aa_row[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 5;
- } else {
- alpha2_aa = aa_row[sx >> 1],
- alpha_aa = (sx & 1 ? alpha2_aa & 0xf : alpha2_aa >> 4);
+ switch(depth)
+ {
+ case 2: /* map 0 - 3 to 0 - 255 */
+ alpha_aa = ((aa_row[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 85;
+ break;
+ case 4:
+ alpha2_aa = aa_row[sx >> 1];
+ alpha_aa = (sx & 1 ? alpha2_aa & 0xf : alpha2_aa >> 4) * 17;
+ break;
+ case 8:
+ alpha_aa = aa_row[sx];
+ break;
+ default:
+ return gs_error_rangecheck;
}
if (alpha_aa != 0) { /* This does happen */
- if (!(alpha_aa == 15)) {
+ if (alpha_aa != 255) {
/* We have an alpha value from aa */
- alpha_aa_act = (255 * alpha_aa) / 15;
+ alpha_aa_act = alpha_aa;
if (src_alpha != 255) {
/* Need to combine it with the existing alpha */
int tmp = src_alpha * alpha_aa_act + 0x80;