diff options
author | Robin Watts <robin.watts@artifex.com> | 2016-02-08 12:23:01 +0000 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2016-02-10 12:40:57 +0000 |
commit | d9f041d6fe7eda89364df1424f85ace974ed0fec (patch) | |
tree | 594e4c025cc145d4ee194e6189951fd10884a249 /base | |
parent | 3c75e35b6bbadd553a074509c3d80046457dda98 (diff) | |
download | ghostpdl-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.c | 22 | ||||
-rw-r--r-- | base/gdevdbit.c | 61 | ||||
-rw-r--r-- | base/gdevm24.c | 33 | ||||
-rw-r--r-- | base/gdevp14.c | 23 |
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; |