diff options
Diffstat (limited to 'gs/base/gxblend.c')
-rw-r--r-- | gs/base/gxblend.c | 1422 |
1 files changed, 710 insertions, 712 deletions
diff --git a/gs/base/gxblend.c b/gs/base/gxblend.c index c09ccac7a..26428d37e 100644 --- a/gs/base/gxblend.c +++ b/gs/base/gxblend.c @@ -1,6 +1,6 @@ /* Copyright (C) 2001-2006 Artifex Software, Inc. All Rights Reserved. - + This software is provided AS-IS with no warranty, either express or implied. @@ -21,7 +21,6 @@ #include "gsicc_cache.h" #include "gsicc_manage.h" - typedef int art_s32; #if RAW_DUMP @@ -30,14 +29,14 @@ extern unsigned int clist_band_count; #endif /* This function is used for mapping the SMask source to a - monochrome luminosity value which basically is the alpha value + monochrome luminosity value which basically is the alpha value Note, that separation colors are not allowed here. Everything must be in CMYK, RGB or monochrome. */ /* Note, data is planar */ -void -smask_luminosity_mapping(int num_rows, int num_cols, int n_chan, int row_stride, +void +smask_luminosity_mapping(int num_rows, int num_cols, int n_chan, int row_stride, int plane_stride, byte *src, const byte *dst, bool isadditive, gs_transparency_mask_subtype_t SMask_SubType) { @@ -48,7 +47,7 @@ smask_luminosity_mapping(int num_rows, int num_cols, int n_chan, int row_stride, #if RAW_DUMP dump_raw_buffer(num_rows, row_stride, n_chan, - plane_stride, row_stride, + plane_stride, row_stride, "Raw_Mask", src); global_index++; @@ -59,14 +58,14 @@ smask_luminosity_mapping(int num_rows, int num_cols, int n_chan, int row_stride, memcpy(dst, &(src[plane_stride]), plane_stride); return; } - /* If we are alpha type, then just grab that */ + /* If we are alpha type, then just grab that */ /* We need to optimize this so that we are only drawing alpha in the rect fills */ if ( SMask_SubType == TRANSPARENCY_MASK_Alpha ){ mask_alpha_offset = (n_chan - 1) * plane_stride; memcpy(dst, &(src[mask_alpha_offset]), plane_stride); return; } - /* To avoid the if statement inside this loop, + /* To avoid the if statement inside this loop, decide on additive or subractive now */ if (isadditive || n_chan == 2) { /* Now we need to split Gray from RGB */ @@ -76,12 +75,12 @@ smask_luminosity_mapping(int num_rows, int num_cols, int n_chan, int row_stride, mask_R_offset = 0; for ( y = 0; y < num_rows; y++ ) { for ( x = 0; x < num_cols; x++ ){ - /* With the current design this will indicate if + /* With the current design this will indicate if we ever did a fill at this pixel. if not then move on. This could have some serious optimization */ - if (src[x + mask_alpha_offset] != 0x00) { + if (src[x + mask_alpha_offset] != 0x00) { dstptr[x] = src[x + mask_R_offset]; - } + } } dstptr += row_stride; mask_alpha_offset += row_stride; @@ -95,17 +94,17 @@ smask_luminosity_mapping(int num_rows, int num_cols, int n_chan, int row_stride, mask_alpha_offset = (n_chan - 1) * plane_stride; for ( y = 0; y < num_rows; y++ ) { for ( x = 0; x < num_cols; x++ ){ - /* With the current design this will indicate if + /* With the current design this will indicate if we ever did a fill at this pixel. if not then move on */ - if (src[x + mask_alpha_offset] != 0x00) { - /* Get luminosity of Device RGB value */ + if (src[x + mask_alpha_offset] != 0x00) { + /* Get luminosity of Device RGB value */ float temp; - temp = ( 0.30 * src[x + mask_R_offset] + - 0.59 * src[x + mask_G_offset] + + temp = ( 0.30 * src[x + mask_R_offset] + + 0.59 * src[x + mask_G_offset] + 0.11 * src[x + mask_B_offset] ); temp = temp * (1.0 / 255.0 ); /* May need to be optimized */ - dstptr[x] = float_color_to_byte_color(temp); - } + dstptr[x] = float_color_to_byte_color(temp); + } } dstptr += row_stride; mask_alpha_offset += row_stride; @@ -123,20 +122,20 @@ smask_luminosity_mapping(int num_rows, int num_cols, int n_chan, int row_stride, mask_K_offset = 3 * plane_stride; for ( y = 0; y < num_rows; y++ ){ for ( x = 0; x < num_cols; x++ ){ - /* With the current design this will indicate if + /* With the current design this will indicate if we ever did a fill at this pixel. if not then move on */ - if (src[x + mask_alpha_offset] != 0x00){ - /* PDF spec says to use Y = 0.30 (1 - C)(1 - K) + + if (src[x + mask_alpha_offset] != 0x00){ + /* PDF spec says to use Y = 0.30 (1 - C)(1 - K) + 0.59 (1 - M)(1 - K) + 0.11 (1 - Y)(1 - K) */ /* For device CMYK */ float temp; - temp = ( 0.30 * ( 0xff - src[x + mask_C_offset]) + - 0.59 * ( 0xff - src[x + mask_M_offset]) + - 0.11 * ( 0xff - src[x + mask_Y_offset]) ) * + temp = ( 0.30 * ( 0xff - src[x + mask_C_offset]) + + 0.59 * ( 0xff - src[x + mask_M_offset]) + + 0.11 * ( 0xff - src[x + mask_Y_offset]) ) * ( 0xff - src[x + mask_K_offset]); temp = temp * (1.0 / 65025.0 ); /* May need to be optimized */ - dstptr[x] = float_color_to_byte_color(temp); - } + dstptr[x] = float_color_to_byte_color(temp); + } } dstptr += row_stride; mask_alpha_offset += row_stride; @@ -150,10 +149,10 @@ smask_luminosity_mapping(int num_rows, int num_cols, int n_chan, int row_stride, /* soft mask gray buffer should be blended with its transparency planar data during the pop for a luminosity case if we have a soft mask within a soft - mask. This situation is detected in the code so that we only do this + mask. This situation is detected in the code so that we only do this blending in those rare situations */ void -smask_blend(byte *src, int width, int height, int rowstride, +smask_blend(byte *src, int width, int height, int rowstride, int planestride) { int x, y; @@ -180,7 +179,7 @@ smask_blend(byte *src, int width, int height, int rowstride, } } -void smask_copy(int num_rows, int num_cols, int row_stride, +void smask_copy(int num_rows, int num_cols, int row_stride, byte *src, const byte *dst) { int y; @@ -195,8 +194,8 @@ void smask_copy(int num_rows, int num_cols, int row_stride, } } -void smask_icc(int num_rows, int num_cols, int n_chan, int row_stride, - int plane_stride, byte *src, const byte *dst, +void smask_icc(int num_rows, int num_cols, int n_chan, int row_stride, + int plane_stride, byte *src, const byte *dst, gsicc_link_t *icclink) { gsicc_bufferdesc_t input_buff_desc; @@ -204,29 +203,29 @@ void smask_icc(int num_rows, int num_cols, int n_chan, int row_stride, #if RAW_DUMP dump_raw_buffer(num_rows, row_stride, n_chan, - plane_stride, row_stride, + plane_stride, row_stride, "Raw_Mask_ICC", src); global_index++; #endif /* Set up the buffer descriptors. Note that pdf14 always has - the alpha channels at the back end (last planes). - We will just handle that here and let the CMM know + the alpha channels at the back end (last planes). + We will just handle that here and let the CMM know nothing about it */ gsicc_init_buffer(&input_buff_desc, n_chan-1, 1, false, false, true, plane_stride, row_stride, num_rows, num_cols); gsicc_init_buffer(&output_buff_desc, 1, 1, - false, false, true, plane_stride, + false, false, true, plane_stride, row_stride, num_rows, num_cols); /* Transform the data */ - gscms_transform_color_buffer(icclink, &input_buff_desc, + gscms_transform_color_buffer(icclink, &input_buff_desc, &output_buff_desc, (void*) src, (void*) dst); } void art_blend_luminosity_rgb_8(int n_chan, byte *dst, const byte *backdrop, - const byte *src) + const byte *src) { int rb = backdrop[0], gb = backdrop[1], bb = backdrop[2]; int rs = src[0], gs = src[1], bs = src[2]; @@ -242,26 +241,26 @@ art_blend_luminosity_rgb_8(int n_chan, byte *dst, const byte *backdrop, g = gb + delta_y; b = bb + delta_y; if ((r | g | b) & 0x100) { - int y; - int scale; - - y = (rs * 77 + gs * 151 + bs * 28 + 0x80) >> 8; - if (delta_y > 0) { - int max; - - max = r > g ? r : g; - max = b > max ? b : max; - scale = ((255 - y) << 16) / (max - y); - } else { - int min; - - min = r < g ? r : g; - min = b < min ? b : min; - scale = (y << 16) / (y - min); - } - r = y + (((r - y) * scale + 0x8000) >> 16); - g = y + (((g - y) * scale + 0x8000) >> 16); - b = y + (((b - y) * scale + 0x8000) >> 16); + int y; + int scale; + + y = (rs * 77 + gs * 151 + bs * 28 + 0x80) >> 8; + if (delta_y > 0) { + int max; + + max = r > g ? r : g; + max = b > max ? b : max; + scale = ((255 - y) << 16) / (max - y); + } else { + int min; + + min = r < g ? r : g; + min = b < min ? b : min; + scale = (y << 16) / (y - min); + } + r = y + (((r - y) * scale + 0x8000) >> 16); + g = y + (((g - y) * scale + 0x8000) >> 16); + b = y + (((b - y) * scale + 0x8000) >> 16); } dst[0] = r; dst[1] = g; @@ -270,7 +269,7 @@ art_blend_luminosity_rgb_8(int n_chan, byte *dst, const byte *backdrop, void art_blend_luminosity_custom_8(int n_chan, byte *dst, const byte *backdrop, - const byte *src) + const byte *src) { int delta_y = 0, test = 0; int r[ART_MAX_CHAN]; @@ -282,40 +281,40 @@ art_blend_luminosity_custom_8(int n_chan, byte *dst, const byte *backdrop, * delta luminosity values. */ for (i = 0; i < n_chan; i++) - delta_y += src[i] - backdrop[i]; + delta_y += src[i] - backdrop[i]; delta_y = (delta_y + n_chan / 2) / n_chan; for (i = 0; i < n_chan; i++) { - r[i] = backdrop[i] + delta_y; - test |= r[i]; + r[i] = backdrop[i] + delta_y; + test |= r[i]; } - + if (test & 0x100) { - int y; - int scale; - - /* Assume that the luminosity is simply the average of the backdrop. */ - y = src[0]; - for (i = 1; i < n_chan; i++) - y += src[i]; - y = (y + n_chan / 2) / n_chan; - - if (delta_y > 0) { - int max; - - max = r[0]; - for (i = 1; i < n_chan; i++) - max = max(max, r[i]); - scale = ((255 - y) << 16) / (max - y); - } else { - int min; - - min = r[0]; - for (i = 1; i < n_chan; i++) - min = min(min, r[i]); - scale = (y << 16) / (y - min); - } - for (i = 0; i < n_chan; i++) - r[i] = y + (((r[i] - y) * scale + 0x8000) >> 16); + int y; + int scale; + + /* Assume that the luminosity is simply the average of the backdrop. */ + y = src[0]; + for (i = 1; i < n_chan; i++) + y += src[i]; + y = (y + n_chan / 2) / n_chan; + + if (delta_y > 0) { + int max; + + max = r[0]; + for (i = 1; i < n_chan; i++) + max = max(max, r[i]); + scale = ((255 - y) << 16) / (max - y); + } else { + int min; + + min = r[0]; + for (i = 1; i < n_chan; i++) + min = min(min, r[i]); + scale = (y << 16) / (y - min); + } + for (i = 0; i < n_chan; i++) + r[i] = y + (((r[i] - y) * scale + 0x8000) >> 16); } for (i = 0; i < n_chan; i++) dst[i] = r[i]; @@ -342,7 +341,7 @@ art_blend_luminosity_custom_8(int n_chan, byte *dst, const byte *backdrop, */ void art_blend_luminosity_cmyk_8(int n_chan, byte *dst, const byte *backdrop, - const byte *src) + const byte *src) { int i; @@ -354,7 +353,7 @@ art_blend_luminosity_cmyk_8(int n_chan, byte *dst, const byte *backdrop, void art_blend_saturation_rgb_8(int n_chan, byte *dst, const byte *backdrop, - const byte *src) + const byte *src) { int rb = backdrop[0], gb = backdrop[1], bb = backdrop[2]; int rs = src[0], gs = src[1], bs = src[2]; @@ -369,11 +368,11 @@ art_blend_saturation_rgb_8(int n_chan, byte *dst, const byte *backdrop, maxb = rb > gb ? rb : gb; maxb = maxb > bb ? maxb : bb; if (minb == maxb) { - /* backdrop has zero saturation, avoid divide by 0 */ - dst[0] = gb; - dst[1] = gb; - dst[2] = gb; - return; + /* backdrop has zero saturation, avoid divide by 0 */ + dst[0] = gb; + dst[1] = gb; + dst[2] = gb; + return; } mins = rs < gs ? rs : gs; @@ -388,28 +387,28 @@ art_blend_saturation_rgb_8(int n_chan, byte *dst, const byte *backdrop, b = y + ((((bb - y) * scale) + 0x8000) >> 16); if ((r | g | b) & 0x100) { - int scalemin, scalemax; - int min, max; - - min = r < g ? r : g; - min = min < b ? min : b; - max = r > g ? r : g; - max = max > b ? max : b; - - if (min < 0) - scalemin = (y << 16) / (y - min); - else - scalemin = 0x10000; - - if (max > 255) - scalemax = ((255 - y) << 16) / (max - y); - else - scalemax = 0x10000; - - scale = scalemin < scalemax ? scalemin : scalemax; - r = y + (((r - y) * scale + 0x8000) >> 16); - g = y + (((g - y) * scale + 0x8000) >> 16); - b = y + (((b - y) * scale + 0x8000) >> 16); + int scalemin, scalemax; + int min, max; + + min = r < g ? r : g; + min = min < b ? min : b; + max = r > g ? r : g; + max = max > b ? max : b; + + if (min < 0) + scalemin = (y << 16) / (y - min); + else + scalemin = 0x10000; + + if (max > 255) + scalemax = ((255 - y) << 16) / (max - y); + else + scalemax = 0x10000; + + scale = scalemin < scalemax ? scalemin : scalemax; + r = y + (((r - y) * scale + 0x8000) >> 16); + g = y + (((g - y) * scale + 0x8000) >> 16); + b = y + (((b - y) * scale + 0x8000) >> 16); } dst[0] = r; @@ -419,7 +418,7 @@ art_blend_saturation_rgb_8(int n_chan, byte *dst, const byte *backdrop, void art_blend_saturation_custom_8(int n_chan, byte *dst, const byte *backdrop, - const byte *src) + const byte *src) { int minb, maxb; int mins, maxs; @@ -432,24 +431,24 @@ art_blend_saturation_custom_8(int n_chan, byte *dst, const byte *backdrop, /* Determine min and max of the backdrop */ minb = maxb = temp = backdrop[0]; for (i = 1; i < n_chan; i++) { - temp = backdrop[i]; - minb = min(minb, temp); - maxb = max(maxb, temp); + temp = backdrop[i]; + minb = min(minb, temp); + maxb = max(maxb, temp); } if (minb == maxb) { - /* backdrop has zero saturation, avoid divide by 0 */ + /* backdrop has zero saturation, avoid divide by 0 */ for (i = 0; i < n_chan; i++) - dst[i] = temp; - return; + dst[i] = temp; + return; } /* Determine min and max of the source */ mins = maxs = src[0]; for (i = 1; i < n_chan; i++) { - temp = src[i]; - mins = min(minb, temp); - maxs = max(minb, temp); + temp = src[i]; + mins = min(minb, temp); + maxs = max(minb, temp); } scale = ((maxs - mins) << 16) / (maxb - minb); @@ -457,50 +456,50 @@ art_blend_saturation_custom_8(int n_chan, byte *dst, const byte *backdrop, /* Assume that the saturation is simply the average of the backdrop. */ y = backdrop[0]; for (i = 1; i < n_chan; i++) - y += backdrop[i]; + y += backdrop[i]; y = (y + n_chan / 2) / n_chan; - + /* Calculate the saturated values */ for (i = 0; i < n_chan; i++) { r[i] = y + ((((backdrop[i] - y) * scale) + 0x8000) >> 16); - test |= r[i]; + test |= r[i]; } if (test & 0x100) { - int scalemin, scalemax; - int min, max; + int scalemin, scalemax; + int min, max; /* Determine min and max of our blended values */ min = max = temp = r[0]; for (i = 1; i < n_chan; i++) { - temp = src[i]; - min = min(min, temp); - max = max(max, temp); + temp = src[i]; + min = min(min, temp); + max = max(max, temp); } - if (min < 0) - scalemin = (y << 16) / (y - min); - else - scalemin = 0x10000; + if (min < 0) + scalemin = (y << 16) / (y - min); + else + scalemin = 0x10000; - if (max > 255) - scalemax = ((255 - y) << 16) / (max - y); - else - scalemax = 0x10000; + if (max > 255) + scalemax = ((255 - y) << 16) / (max - y); + else + scalemax = 0x10000; - scale = scalemin < scalemax ? scalemin : scalemax; + scale = scalemin < scalemax ? scalemin : scalemax; for (i = 0; i < n_chan; i++) - r[i] = y + (((r[i] - y) * scale + 0x8000) >> 16); + r[i] = y + (((r[i] - y) * scale + 0x8000) >> 16); } for (i = 0; i < n_chan; i++) - dst[i] = r[i]; + dst[i] = r[i]; } /* Our component values have already been complemented, i.e. (1 - X). */ void art_blend_saturation_cmyk_8(int n_chan, byte *dst, const byte *backdrop, - const byte *src) + const byte *src) { int i; @@ -574,286 +573,286 @@ const byte art_blend_soft_light_8[256] = { void art_blend_pixel_8(byte *dst, const byte *backdrop, - const byte *src, int n_chan, gs_blend_mode_t blend_mode, - const pdf14_nonseparable_blending_procs_t * pblend_procs) + const byte *src, int n_chan, gs_blend_mode_t blend_mode, + const pdf14_nonseparable_blending_procs_t * pblend_procs) { int i; byte b, s; bits32 t; switch (blend_mode) { - case BLEND_MODE_Normal: - case BLEND_MODE_Compatible: /* todo */ - memcpy(dst, src, n_chan); - break; - case BLEND_MODE_Multiply: - for (i = 0; i < n_chan; i++) { - t = ((bits32) backdrop[i]) * ((bits32) src[i]); - t += 0x80; - t += (t >> 8); - dst[i] = t >> 8; - } - break; - case BLEND_MODE_Screen: - for (i = 0; i < n_chan; i++) { - t = - ((bits32) (0xff - backdrop[i])) * - ((bits32) (0xff - src[i])); - t += 0x80; - t += (t >> 8); - dst[i] = 0xff - (t >> 8); - } - break; - case BLEND_MODE_Overlay: - for (i = 0; i < n_chan; i++) { - b = backdrop[i]; - s = src[i]; - if (b < 0x80) - t = 2 * ((bits32) b) * ((bits32) s); - else - t = 0xfe01 - - 2 * ((bits32) (0xff - b)) * ((bits32) (0xff - s)); - t += 0x80; - t += (t >> 8); - dst[i] = t >> 8; - } - break; - case BLEND_MODE_SoftLight: - for (i = 0; i < n_chan; i++) { - b = backdrop[i]; - s = src[i]; - if (s < 0x80) { - t = (0xff - (s << 1)) * art_blend_sq_diff_8[b]; - t += 0x8000; - dst[i] = b - (t >> 16); - } else { - t = - ((s << 1) - - 0xff) * ((bits32) (art_blend_soft_light_8[b])); - t += 0x80; - t += (t >> 8); - dst[i] = b + (t >> 8); - } - } - break; - case BLEND_MODE_HardLight: - for (i = 0; i < n_chan; i++) { - b = backdrop[i]; - s = src[i]; - if (s < 0x80) - t = 2 * ((bits32) b) * ((bits32) s); - else - t = 0xfe01 - - 2 * ((bits32) (0xff - b)) * ((bits32) (0xff - s)); - t += 0x80; - t += (t >> 8); - dst[i] = t >> 8; - } - break; - case BLEND_MODE_ColorDodge: - for (i = 0; i < n_chan; i++) { - b = backdrop[i]; - s = 0xff - src[i]; - if (b == 0) - dst[i] = 0; - else if (b >= s) - dst[i] = 0xff; - else - dst[i] = (0x1fe * b + s) / (s << 1); - } - break; - case BLEND_MODE_ColorBurn: - for (i = 0; i < n_chan; i++) { - b = 0xff - backdrop[i]; - s = src[i]; - if (b == 0) - dst[i] = 0xff; - else if (b >= s) - dst[i] = 0; - else - dst[i] = 0xff - (0x1fe * b + s) / (s << 1); - } - break; - case BLEND_MODE_Darken: - for (i = 0; i < n_chan; i++) { - b = backdrop[i]; - s = src[i]; - dst[i] = b < s ? b : s; - } - break; - case BLEND_MODE_Lighten: - for (i = 0; i < n_chan; i++) { - b = backdrop[i]; - s = src[i]; - dst[i] = b > s ? b : s; - } - break; - case BLEND_MODE_Difference: - for (i = 0; i < n_chan; i++) { - art_s32 tmp; - - tmp = ((art_s32) backdrop[i]) - ((art_s32) src[i]); - dst[i] = tmp < 0 ? -tmp : tmp; - } - break; - case BLEND_MODE_Exclusion: - for (i = 0; i < n_chan; i++) { - b = backdrop[i]; - s = src[i]; - t = ((bits32) (0xff - b)) * ((bits32) s) + - ((bits32) b) * ((bits32) (0xff - s)); - t += 0x80; - t += (t >> 8); - dst[i] = t >> 8; - } - break; - case BLEND_MODE_Luminosity: - pblend_procs->blend_luminosity(n_chan, dst, backdrop, src); - break; - case BLEND_MODE_Color: - pblend_procs->blend_luminosity(n_chan, dst, src, backdrop); - break; - case BLEND_MODE_Saturation: - pblend_procs->blend_saturation(n_chan, dst, backdrop, src); - break; - case BLEND_MODE_Hue: - { - byte tmp[4]; - - pblend_procs->blend_luminosity(n_chan, tmp, src, backdrop); - pblend_procs->blend_saturation(n_chan, dst, tmp, backdrop); - } - break; - default: - dlprintf1("art_blend_pixel_8: blend mode %d not implemented\n", - blend_mode); - memcpy(dst, src, n_chan); - break; + case BLEND_MODE_Normal: + case BLEND_MODE_Compatible: /* todo */ + memcpy(dst, src, n_chan); + break; + case BLEND_MODE_Multiply: + for (i = 0; i < n_chan; i++) { + t = ((bits32) backdrop[i]) * ((bits32) src[i]); + t += 0x80; + t += (t >> 8); + dst[i] = t >> 8; + } + break; + case BLEND_MODE_Screen: + for (i = 0; i < n_chan; i++) { + t = + ((bits32) (0xff - backdrop[i])) * + ((bits32) (0xff - src[i])); + t += 0x80; + t += (t >> 8); + dst[i] = 0xff - (t >> 8); + } + break; + case BLEND_MODE_Overlay: + for (i = 0; i < n_chan; i++) { + b = backdrop[i]; + s = src[i]; + if (b < 0x80) + t = 2 * ((bits32) b) * ((bits32) s); + else + t = 0xfe01 - + 2 * ((bits32) (0xff - b)) * ((bits32) (0xff - s)); + t += 0x80; + t += (t >> 8); + dst[i] = t >> 8; + } + break; + case BLEND_MODE_SoftLight: + for (i = 0; i < n_chan; i++) { + b = backdrop[i]; + s = src[i]; + if (s < 0x80) { + t = (0xff - (s << 1)) * art_blend_sq_diff_8[b]; + t += 0x8000; + dst[i] = b - (t >> 16); + } else { + t = + ((s << 1) - + 0xff) * ((bits32) (art_blend_soft_light_8[b])); + t += 0x80; + t += (t >> 8); + dst[i] = b + (t >> 8); + } + } + break; + case BLEND_MODE_HardLight: + for (i = 0; i < n_chan; i++) { + b = backdrop[i]; + s = src[i]; + if (s < 0x80) + t = 2 * ((bits32) b) * ((bits32) s); + else + t = 0xfe01 - + 2 * ((bits32) (0xff - b)) * ((bits32) (0xff - s)); + t += 0x80; + t += (t >> 8); + dst[i] = t >> 8; + } + break; + case BLEND_MODE_ColorDodge: + for (i = 0; i < n_chan; i++) { + b = backdrop[i]; + s = 0xff - src[i]; + if (b == 0) + dst[i] = 0; + else if (b >= s) + dst[i] = 0xff; + else + dst[i] = (0x1fe * b + s) / (s << 1); + } + break; + case BLEND_MODE_ColorBurn: + for (i = 0; i < n_chan; i++) { + b = 0xff - backdrop[i]; + s = src[i]; + if (b == 0) + dst[i] = 0xff; + else if (b >= s) + dst[i] = 0; + else + dst[i] = 0xff - (0x1fe * b + s) / (s << 1); + } + break; + case BLEND_MODE_Darken: + for (i = 0; i < n_chan; i++) { + b = backdrop[i]; + s = src[i]; + dst[i] = b < s ? b : s; + } + break; + case BLEND_MODE_Lighten: + for (i = 0; i < n_chan; i++) { + b = backdrop[i]; + s = src[i]; + dst[i] = b > s ? b : s; + } + break; + case BLEND_MODE_Difference: + for (i = 0; i < n_chan; i++) { + art_s32 tmp; + + tmp = ((art_s32) backdrop[i]) - ((art_s32) src[i]); + dst[i] = tmp < 0 ? -tmp : tmp; + } + break; + case BLEND_MODE_Exclusion: + for (i = 0; i < n_chan; i++) { + b = backdrop[i]; + s = src[i]; + t = ((bits32) (0xff - b)) * ((bits32) s) + + ((bits32) b) * ((bits32) (0xff - s)); + t += 0x80; + t += (t >> 8); + dst[i] = t >> 8; + } + break; + case BLEND_MODE_Luminosity: + pblend_procs->blend_luminosity(n_chan, dst, backdrop, src); + break; + case BLEND_MODE_Color: + pblend_procs->blend_luminosity(n_chan, dst, src, backdrop); + break; + case BLEND_MODE_Saturation: + pblend_procs->blend_saturation(n_chan, dst, backdrop, src); + break; + case BLEND_MODE_Hue: + { + byte tmp[4]; + + pblend_procs->blend_luminosity(n_chan, tmp, src, backdrop); + pblend_procs->blend_saturation(n_chan, dst, tmp, backdrop); + } + break; + default: + dlprintf1("art_blend_pixel_8: blend mode %d not implemented\n", + blend_mode); + memcpy(dst, src, n_chan); + break; } } void art_blend_pixel(ArtPixMaxDepth* dst, const ArtPixMaxDepth *backdrop, - const ArtPixMaxDepth* src, int n_chan, - gs_blend_mode_t blend_mode) + const ArtPixMaxDepth* src, int n_chan, + gs_blend_mode_t blend_mode) { int i; ArtPixMaxDepth b, s; bits32 t; switch (blend_mode) { - case BLEND_MODE_Normal: - case BLEND_MODE_Compatible: /* todo */ - memcpy(dst, src, n_chan * sizeof(ArtPixMaxDepth)); - break; - case BLEND_MODE_Multiply: - for (i = 0; i < n_chan; i++) { - t = ((bits32) backdrop[i]) * ((bits32) src[i]); - t += 0x8000; - t += (t >> 16); - dst[i] = t >> 16; - } - break; - case BLEND_MODE_Screen: - for (i = 0; i < n_chan; i++) { - t = - ((bits32) (0xffff - backdrop[i])) * - ((bits32) (0xffff - src[i])); - t += 0x8000; - t += (t >> 16); - dst[i] = 0xffff - (t >> 16); - } - break; - case BLEND_MODE_Overlay: - for (i = 0; i < n_chan; i++) { - b = backdrop[i]; - s = src[i]; - if (b < 0x8000) - t = 2 * ((bits32) b) * ((bits32) s); - else - t = 0xfffe0001u - - 2 * ((bits32) (0xffff - b)) * ((bits32) (0xffff - s)); - t += 0x8000; - t += (t >> 16); - dst[i] = t >> 16; - } - break; - case BLEND_MODE_HardLight: - for (i = 0; i < n_chan; i++) { - b = backdrop[i]; - s = src[i]; - if (s < 0x8000) - t = 2 * ((bits32) b) * ((bits32) s); - else - t = 0xfffe0001u - - 2 * ((bits32) (0xffff - b)) * ((bits32) (0xffff - s)); - t += 0x8000; - t += (t >> 16); - dst[i] = t >> 16; - } - break; - case BLEND_MODE_ColorDodge: - for (i = 0; i < n_chan; i++) { - b = backdrop[i]; - s = src[i]; - if (b == 0) - dst[i] = 0; - else if (s >= b) - dst[i] = 0xffff; - else - dst[i] = (0x1fffe * s + b) / (b << 1); - } - break; - case BLEND_MODE_ColorBurn: - for (i = 0; i < n_chan; i++) { - b = 0xffff - backdrop[i]; - s = src[i]; - if (b == 0) - dst[i] = 0xffff; - else if (b >= s) - dst[i] = 0; - else - dst[i] = 0xffff - (0x1fffe * b + s) / (s << 1); - } + case BLEND_MODE_Normal: + case BLEND_MODE_Compatible: /* todo */ + memcpy(dst, src, n_chan * sizeof(ArtPixMaxDepth)); + break; + case BLEND_MODE_Multiply: + for (i = 0; i < n_chan; i++) { + t = ((bits32) backdrop[i]) * ((bits32) src[i]); + t += 0x8000; + t += (t >> 16); + dst[i] = t >> 16; + } + break; + case BLEND_MODE_Screen: + for (i = 0; i < n_chan; i++) { + t = + ((bits32) (0xffff - backdrop[i])) * + ((bits32) (0xffff - src[i])); + t += 0x8000; + t += (t >> 16); + dst[i] = 0xffff - (t >> 16); + } + break; + case BLEND_MODE_Overlay: + for (i = 0; i < n_chan; i++) { + b = backdrop[i]; + s = src[i]; + if (b < 0x8000) + t = 2 * ((bits32) b) * ((bits32) s); + else + t = 0xfffe0001u - + 2 * ((bits32) (0xffff - b)) * ((bits32) (0xffff - s)); + t += 0x8000; + t += (t >> 16); + dst[i] = t >> 16; + } + break; + case BLEND_MODE_HardLight: + for (i = 0; i < n_chan; i++) { + b = backdrop[i]; + s = src[i]; + if (s < 0x8000) + t = 2 * ((bits32) b) * ((bits32) s); + else + t = 0xfffe0001u - + 2 * ((bits32) (0xffff - b)) * ((bits32) (0xffff - s)); + t += 0x8000; + t += (t >> 16); + dst[i] = t >> 16; + } + break; + case BLEND_MODE_ColorDodge: + for (i = 0; i < n_chan; i++) { + b = backdrop[i]; + s = src[i]; + if (b == 0) + dst[i] = 0; + else if (s >= b) + dst[i] = 0xffff; + else + dst[i] = (0x1fffe * s + b) / (b << 1); + } + break; + case BLEND_MODE_ColorBurn: + for (i = 0; i < n_chan; i++) { + b = 0xffff - backdrop[i]; + s = src[i]; + if (b == 0) + dst[i] = 0xffff; + else if (b >= s) + dst[i] = 0; + else + dst[i] = 0xffff - (0x1fffe * b + s) / (s << 1); + } + break; + case BLEND_MODE_Darken: + for (i = 0; i < n_chan; i++) { + b = backdrop[i]; + s = src[i]; + dst[i] = b < s ? b : s; + } + break; + case BLEND_MODE_Lighten: + for (i = 0; i < n_chan; i++) { + b = backdrop[i]; + s = src[i]; + dst[i] = b > s ? b : s; + } + break; + case BLEND_MODE_Difference: + for (i = 0; i < n_chan; i++) { + art_s32 tmp; + + tmp = ((art_s32) backdrop[i]) - ((art_s32) src[i]); + dst[i] = tmp < 0 ? -tmp : tmp; + } + break; + case BLEND_MODE_Exclusion: + for (i = 0; i < n_chan; i++) { + b = backdrop[i]; + s = src[i]; + t = ((bits32) (0xffff - b)) * ((bits32) s) + + ((bits32) b) * ((bits32) (0xffff - s)); + t += 0x8000; + t += (t >> 16); + dst[i] = t >> 16; + } + break; + default: + dlprintf1("art_blend_pixel: blend mode %d not implemented\n", + blend_mode); + memcpy(dst, src, n_chan); break; - case BLEND_MODE_Darken: - for (i = 0; i < n_chan; i++) { - b = backdrop[i]; - s = src[i]; - dst[i] = b < s ? b : s; - } - break; - case BLEND_MODE_Lighten: - for (i = 0; i < n_chan; i++) { - b = backdrop[i]; - s = src[i]; - dst[i] = b > s ? b : s; - } - break; - case BLEND_MODE_Difference: - for (i = 0; i < n_chan; i++) { - art_s32 tmp; - - tmp = ((art_s32) backdrop[i]) - ((art_s32) src[i]); - dst[i] = tmp < 0 ? -tmp : tmp; - } - break; - case BLEND_MODE_Exclusion: - for (i = 0; i < n_chan; i++) { - b = backdrop[i]; - s = src[i]; - t = ((bits32) (0xffff - b)) * ((bits32) s) + - ((bits32) b) * ((bits32) (0xffff - s)); - t += 0x8000; - t += (t >> 16); - dst[i] = t >> 16; - } - break; - default: - dlprintf1("art_blend_pixel: blend mode %d not implemented\n", - blend_mode); - memcpy(dst, src, n_chan); - break; } } @@ -872,20 +871,20 @@ art_pdf_union_mul_8(byte alpha1, byte alpha2, byte alpha_mask) int tmp; if (alpha_mask == 0xff) { - tmp = (0xff - alpha1) * (0xff - alpha2) + 0x80; - return 0xff - ((tmp + (tmp >> 8)) >> 8); + tmp = (0xff - alpha1) * (0xff - alpha2) + 0x80; + return 0xff - ((tmp + (tmp >> 8)) >> 8); } else { - tmp = alpha2 * alpha_mask + 0x80; - tmp = (tmp + (tmp >> 8)) >> 8; - tmp = (0xff - alpha1) * (0xff - tmp) + 0x80; - return 0xff - ((tmp + (tmp >> 8)) >> 8); + tmp = alpha2 * alpha_mask + 0x80; + tmp = (tmp + (tmp >> 8)) >> 8; + tmp = (0xff - alpha1) * (0xff - tmp) + 0x80; + return 0xff - ((tmp + (tmp >> 8)) >> 8); } } void art_pdf_composite_pixel_alpha_8(byte *dst, const byte *src, int n_chan, - gs_blend_mode_t blend_mode, - const pdf14_nonseparable_blending_procs_t * pblend_procs) + gs_blend_mode_t blend_mode, + const pdf14_nonseparable_blending_procs_t * pblend_procs) { byte a_b, a_s; unsigned int a_r; @@ -896,23 +895,23 @@ art_pdf_composite_pixel_alpha_8(byte *dst, const byte *src, int n_chan, a_s = src[n_chan]; if (a_s == 0) { - /* source alpha is zero, avoid all computations and possible - divide by zero errors. */ - return; + /* source alpha is zero, avoid all computations and possible + divide by zero errors. */ + return; } a_b = dst[n_chan]; if (a_b == 0) { - /* backdrop alpha is zero, just copy source pixels and avoid - computation. */ + /* backdrop alpha is zero, just copy source pixels and avoid + computation. */ - /* this idiom is faster than memcpy (dst, src, n_chan + 1); for - expected small values of n_chan. */ - for (i = 0; i <= n_chan >> 2; i++) { - ((bits32 *) dst)[i] = ((const bits32 *)src)[i]; - } + /* this idiom is faster than memcpy (dst, src, n_chan + 1); for + expected small values of n_chan. */ + for (i = 0; i <= n_chan >> 2; i++) { + ((bits32 *) dst)[i] = ((const bits32 *)src)[i]; + } - return; + return; } /* Result alpha is Union of backdrop and source alpha */ @@ -924,30 +923,30 @@ art_pdf_composite_pixel_alpha_8(byte *dst, const byte *src, int n_chan, src_scale = ((a_s << 16) + (a_r >> 1)) / a_r; if (blend_mode == BLEND_MODE_Normal) { - /* Do simple compositing of source over backdrop */ - for (i = 0; i < n_chan; i++) { - c_s = src[i]; - c_b = dst[i]; - tmp = (c_b << 16) + src_scale * (c_s - c_b) + 0x8000; - dst[i] = tmp >> 16; - } + /* Do simple compositing of source over backdrop */ + for (i = 0; i < n_chan; i++) { + c_s = src[i]; + c_b = dst[i]; + tmp = (c_b << 16) + src_scale * (c_s - c_b) + 0x8000; + dst[i] = tmp >> 16; + } } else { - /* Do compositing with blending */ - byte blend[ART_MAX_CHAN]; - - art_blend_pixel_8(blend, dst, src, n_chan, blend_mode, pblend_procs); - for (i = 0; i < n_chan; i++) { - int c_bl; /* Result of blend function */ - int c_mix; /* Blend result mixed with source color */ - - c_s = src[i]; - c_b = dst[i]; - c_bl = blend[i]; - tmp = a_b * (c_bl - ((int)c_s)) + 0x80; - c_mix = c_s + (((tmp >> 8) + tmp) >> 8); - tmp = (c_b << 16) + src_scale * (c_mix - c_b) + 0x8000; - dst[i] = tmp >> 16; - } + /* Do compositing with blending */ + byte blend[ART_MAX_CHAN]; + + art_blend_pixel_8(blend, dst, src, n_chan, blend_mode, pblend_procs); + for (i = 0; i < n_chan; i++) { + int c_bl; /* Result of blend function */ + int c_mix; /* Blend result mixed with source color */ + + c_s = src[i]; + c_b = dst[i]; + c_bl = blend[i]; + tmp = a_b * (c_bl - ((int)c_s)) + 0x80; + c_mix = c_s + (((tmp >> 8) + tmp) >> 8); + tmp = (c_b << 16) + src_scale * (c_mix - c_b) + 0x8000; + dst[i] = tmp >> 16; + } } dst[n_chan] = a_r; } @@ -981,8 +980,8 @@ art_pdf_composite_pixel_alpha_8(byte *dst, const byte *src, int n_chan, **/ void art_pdf_composite_pixel_knockout_8(byte *dst, - const byte *backdrop, const byte *src, - int n_chan, gs_blend_mode_t blend_mode) + const byte *backdrop, const byte *src, + int n_chan, gs_blend_mode_t blend_mode) { int i; byte ct[ART_MAX_CHAN + 1]; @@ -994,57 +993,56 @@ art_pdf_composite_pixel_knockout_8(byte *dst, int tmp; if (src[n_chan] == 0) - return; + return; if (src[n_chan + 1] == 255 && blend_mode == BLEND_MODE_Normal || - dst[n_chan] == 0) { - /* this idiom is faster than memcpy (dst, src, n_chan + 2); for - expected small values of n_chan. */ - for (i = 0; i <= (n_chan + 1) >> 2; i++) { - ((bits32 *) dst)[i] = ((const bits32 *)src[i]); - } - - return; - } + dst[n_chan] == 0) { + /* this idiom is faster than memcpy (dst, src, n_chan + 2); for + expected small values of n_chan. */ + for (i = 0; i <= (n_chan + 1) >> 2; i++) { + ((bits32 *) dst)[i] = ((const bits32 *)src[i]); + } + return; + } src_shape = src[n_chan + 1]; /* $fs_i$ */ src_opacity = (255 * src[n_chan] + 0x80) / src_shape; /* $qs_i$ */ #if 0 for (i = 0; i < (n_chan + 3) >> 2; i++) { - ((bits32 *) src_tmp)[i] = ((const bits32 *)src[i]); + ((bits32 *) src_tmp)[i] = ((const bits32 *)src[i]); } src_tmp[n_chan] = src_opacity; for (i = 0; i <= n_chan >> 2; i++) { - ((bits32 *) tmp)[i] = ((bits32 *) backdrop[i]); + ((bits32 *) tmp)[i] = ((bits32 *) backdrop[i]); } #endif backdrop_scale = if (blend_mode == BLEND_MODE_Normal) { - /* Do simple compositing of source over backdrop */ - for (i = 0; i < n_chan; i++) { - c_s = src[i]; - c_b = dst[i]; - tmp = (c_b << 16) + ct_scale * (c_s - c_b) + 0x8000; - ct[i] = tmp >> 16; - } + /* Do simple compositing of source over backdrop */ + for (i = 0; i < n_chan; i++) { + c_s = src[i]; + c_b = dst[i]; + tmp = (c_b << 16) + ct_scale * (c_s - c_b) + 0x8000; + ct[i] = tmp >> 16; + } } else { - /* Do compositing with blending */ - byte blend[ART_MAX_CHAN]; - - art_blend_pixel_8(blend, backdrop, src, n_chan, blend_mode, pblend_procs); - for (i = 0; i < n_chan; i++) { - int c_bl; /* Result of blend function */ - int c_mix; /* Blend result mixed with source color */ - - c_s = src[i]; - c_b = dst[i]; - c_bl = blend[i]; - tmp = a_b * (((int)c_bl) - ((int)c_s)) + 0x80; - c_mix = c_s + (((tmp >> 8) + tmp) >> 8); - tmp = (c_b << 16) + ct_scale * (c_mix - c_b) + 0x8000; - ct[i] = tmp >> 16; - } + /* Do compositing with blending */ + byte blend[ART_MAX_CHAN]; + + art_blend_pixel_8(blend, backdrop, src, n_chan, blend_mode, pblend_procs); + for (i = 0; i < n_chan; i++) { + int c_bl; /* Result of blend function */ + int c_mix; /* Blend result mixed with source color */ + + c_s = src[i]; + c_b = dst[i]; + c_bl = blend[i]; + tmp = a_b * (((int)c_bl) - ((int)c_s)) + 0x80; + c_mix = c_s + (((tmp >> 8) + tmp) >> 8); + tmp = (c_b << 16) + ct_scale * (c_mix - c_b) + 0x8000; + ct[i] = tmp >> 16; + } } /* do weighted average of $Ct$ using relative alpha contribution as weight */ @@ -1061,8 +1059,8 @@ art_pdf_composite_pixel_knockout_8(byte *dst, void art_pdf_uncomposite_group_8(byte *dst, - const byte *backdrop, - const byte *src, byte src_alpha_g, int n_chan) + const byte *backdrop, + const byte *src, byte src_alpha_g, int n_chan) { byte backdrop_alpha = backdrop[n_chan]; int i; @@ -1072,33 +1070,33 @@ art_pdf_uncomposite_group_8(byte *dst, dst[n_chan] = src_alpha_g; if (src_alpha_g == 0) - return; + return; scale = (backdrop_alpha * 255 * 2 + src_alpha_g) / (src_alpha_g << 1) - - backdrop_alpha; + backdrop_alpha; for (i = 0; i < n_chan; i++) { - int si, di; - - si = src[i]; - di = backdrop[i]; - tmp = (si - di) * scale + 0x80; - tmp = si + ((tmp + (tmp >> 8)) >> 8); - - /* todo: it should be possible to optimize these cond branches */ - if (tmp < 0) - tmp = 0; - if (tmp > 255) - tmp = 255; - dst[i] = tmp; + int si, di; + + si = src[i]; + di = backdrop[i]; + tmp = (si - di) * scale + 0x80; + tmp = si + ((tmp + (tmp >> 8)) >> 8); + + /* todo: it should be possible to optimize these cond branches */ + if (tmp < 0) + tmp = 0; + if (tmp > 255) + tmp = 255; + dst[i] = tmp; } } void art_pdf_recomposite_group_8(byte *dst, byte *dst_alpha_g, - const byte *src, byte src_alpha_g, int n_chan, - byte alpha, gs_blend_mode_t blend_mode, - const pdf14_nonseparable_blending_procs_t * pblend_procs) + const byte *src, byte src_alpha_g, int n_chan, + byte alpha, gs_blend_mode_t blend_mode, + const pdf14_nonseparable_blending_procs_t * pblend_procs) { byte dst_alpha; int i; @@ -1106,72 +1104,72 @@ art_pdf_recomposite_group_8(byte *dst, byte *dst_alpha_g, int scale; if (src_alpha_g == 0) - return; + return; if (blend_mode == BLEND_MODE_Normal && alpha == 255) { - /* In this case, uncompositing and recompositing cancel each - other out. Note: if the reason that alpha == 255 is that - there is no constant mask and no soft mask, then this - operation should be optimized away at a higher level. */ - for (i = 0; i <= n_chan >> 2; i++) - ((bits32 *) dst)[i] = ((const bits32 *)src)[i]; - if (dst_alpha_g != NULL) { - tmp = (255 - *dst_alpha_g) * (255 - src_alpha_g) + 0x80; - *dst_alpha_g = 255 - ((tmp + (tmp >> 8)) >> 8); - } - return; + /* In this case, uncompositing and recompositing cancel each + other out. Note: if the reason that alpha == 255 is that + there is no constant mask and no soft mask, then this + operation should be optimized away at a higher level. */ + for (i = 0; i <= n_chan >> 2; i++) + ((bits32 *) dst)[i] = ((const bits32 *)src)[i]; + if (dst_alpha_g != NULL) { + tmp = (255 - *dst_alpha_g) * (255 - src_alpha_g) + 0x80; + *dst_alpha_g = 255 - ((tmp + (tmp >> 8)) >> 8); + } + return; } else { - /* "interesting" blend mode */ - byte ca[ART_MAX_CHAN + 1]; /* $C, \alpha$ */ - - dst_alpha = dst[n_chan]; - if (src_alpha_g == 255 || dst_alpha == 0) { - for (i = 0; i < (n_chan + 3) >> 2; i++) - ((bits32 *) ca)[i] = ((const bits32 *)src)[i]; - } else { - /* Uncomposite the color. In other words, solve - "src = (ca, src_alpha_g) over dst" for ca */ - - /* todo (maybe?): replace this code with call to - art_pdf_uncomposite_group_8() to reduce code - duplication. */ - - scale = (dst_alpha * 255 * 2 + src_alpha_g) / (src_alpha_g << 1) - - dst_alpha; - for (i = 0; i < n_chan; i++) { - int si, di; - - si = src[i]; - di = dst[i]; - tmp = (si - di) * scale + 0x80; - tmp = si + ((tmp + (tmp >> 8)) >> 8); - - /* todo: it should be possible to optimize these cond branches */ - if (tmp < 0) - tmp = 0; - if (tmp > 255) - tmp = 255; - ca[i] = tmp; - } - } - - tmp = src_alpha_g * alpha + 0x80; - tmp = (tmp + (tmp >> 8)) >> 8; - ca[n_chan] = tmp; - if (dst_alpha_g != NULL) { - tmp = (255 - *dst_alpha_g) * (255 - tmp) + 0x80; - *dst_alpha_g = 255 - ((tmp + (tmp >> 8)) >> 8); - } - art_pdf_composite_pixel_alpha_8(dst, ca, n_chan, - blend_mode, pblend_procs); + /* "interesting" blend mode */ + byte ca[ART_MAX_CHAN + 1]; /* $C, \alpha$ */ + + dst_alpha = dst[n_chan]; + if (src_alpha_g == 255 || dst_alpha == 0) { + for (i = 0; i < (n_chan + 3) >> 2; i++) + ((bits32 *) ca)[i] = ((const bits32 *)src)[i]; + } else { + /* Uncomposite the color. In other words, solve + "src = (ca, src_alpha_g) over dst" for ca */ + + /* todo (maybe?): replace this code with call to + art_pdf_uncomposite_group_8() to reduce code + duplication. */ + + scale = (dst_alpha * 255 * 2 + src_alpha_g) / (src_alpha_g << 1) - + dst_alpha; + for (i = 0; i < n_chan; i++) { + int si, di; + + si = src[i]; + di = dst[i]; + tmp = (si - di) * scale + 0x80; + tmp = si + ((tmp + (tmp >> 8)) >> 8); + + /* todo: it should be possible to optimize these cond branches */ + if (tmp < 0) + tmp = 0; + if (tmp > 255) + tmp = 255; + ca[i] = tmp; + } + } + + tmp = src_alpha_g * alpha + 0x80; + tmp = (tmp + (tmp >> 8)) >> 8; + ca[n_chan] = tmp; + if (dst_alpha_g != NULL) { + tmp = (255 - *dst_alpha_g) * (255 - tmp) + 0x80; + *dst_alpha_g = 255 - ((tmp + (tmp >> 8)) >> 8); + } + art_pdf_composite_pixel_alpha_8(dst, ca, n_chan, + blend_mode, pblend_procs); } /* todo: optimize BLEND_MODE_Normal buf alpha != 255 case */ } void art_pdf_composite_group_8(byte *dst, byte *dst_alpha_g, - const byte *src, int n_chan, byte alpha, gs_blend_mode_t blend_mode, - const pdf14_nonseparable_blending_procs_t * pblend_procs) + const byte *src, int n_chan, byte alpha, gs_blend_mode_t blend_mode, + const pdf14_nonseparable_blending_procs_t * pblend_procs) { byte src_alpha; /* $\alpha g_n$ */ byte src_tmp[ART_MAX_CHAN + 1]; @@ -1179,26 +1177,26 @@ art_pdf_composite_group_8(byte *dst, byte *dst_alpha_g, int tmp; if (alpha == 255) { - art_pdf_composite_pixel_alpha_8(dst, src, n_chan, - blend_mode, pblend_procs); - if (dst_alpha_g != NULL) { - tmp = (255 - *dst_alpha_g) * (255 - src[n_chan]) + 0x80; - *dst_alpha_g = 255 - ((tmp + (tmp >> 8)) >> 8); - } + art_pdf_composite_pixel_alpha_8(dst, src, n_chan, + blend_mode, pblend_procs); + if (dst_alpha_g != NULL) { + tmp = (255 - *dst_alpha_g) * (255 - src[n_chan]) + 0x80; + *dst_alpha_g = 255 - ((tmp + (tmp >> 8)) >> 8); + } } else { - src_alpha = src[n_chan]; - if (src_alpha == 0) - return; - for (i = 0; i < (n_chan + 3) >> 2; i++) - ((bits32 *) src_tmp)[i] = ((const bits32 *)src)[i]; - tmp = src_alpha * alpha + 0x80; - src_tmp[n_chan] = (tmp + (tmp >> 8)) >> 8; - art_pdf_composite_pixel_alpha_8(dst, src_tmp, n_chan, - blend_mode, pblend_procs); - if (dst_alpha_g != NULL) { - tmp = (255 - *dst_alpha_g) * (255 - src_tmp[n_chan]) + 0x80; - *dst_alpha_g = 255 - ((tmp + (tmp >> 8)) >> 8); - } + src_alpha = src[n_chan]; + if (src_alpha == 0) + return; + for (i = 0; i < (n_chan + 3) >> 2; i++) + ((bits32 *) src_tmp)[i] = ((const bits32 *)src)[i]; + tmp = src_alpha * alpha + 0x80; + src_tmp[n_chan] = (tmp + (tmp >> 8)) >> 8; + art_pdf_composite_pixel_alpha_8(dst, src_tmp, n_chan, + blend_mode, pblend_procs); + if (dst_alpha_g != NULL) { + tmp = (255 - *dst_alpha_g) * (255 - src_tmp[n_chan]) + 0x80; + *dst_alpha_g = 255 - ((tmp + (tmp >> 8)) >> 8); + } } } @@ -1208,7 +1206,7 @@ void art_pdf_knockoutisolated_group_8(byte *dst, const byte *src, int n_chan) { int i; - byte src_alpha; + byte src_alpha; src_alpha = src[n_chan]; if (src_alpha == 0) @@ -1220,120 +1218,120 @@ art_pdf_knockoutisolated_group_8(byte *dst, const byte *src, int n_chan) void art_pdf_composite_knockout_simple_8(byte *dst, - byte *dst_shape, + byte *dst_shape, byte *dst_tag, - const byte *src, + const byte *src, byte tag, - int n_chan, byte opacity) + int n_chan, byte opacity) { byte src_shape = src[n_chan]; int i; if (src_shape == 0) - return; + return; else if (src_shape == 255) { - for (i = 0; i < (n_chan + 3) >> 2; i++) - ((bits32 *) dst)[i] = ((const bits32 *)src)[i]; - dst[n_chan] = opacity; - if (dst_shape != NULL) - *dst_shape = 255; + for (i = 0; i < (n_chan + 3) >> 2; i++) + ((bits32 *) dst)[i] = ((const bits32 *)src)[i]; + dst[n_chan] = opacity; + if (dst_shape != NULL) + *dst_shape = 255; } else { - /* Use src_shape to interpolate (in premultiplied alpha space) - between dst and (src, opacity). */ - int dst_alpha = dst[n_chan]; - byte result_alpha; - int tmp; - - tmp = (opacity - dst_alpha) * src_shape + 0x80; - result_alpha = dst_alpha + ((tmp + (tmp >> 8)) >> 8); - - if (result_alpha != 0) - for (i = 0; i < n_chan; i++) { - /* todo: optimize this - can strength-reduce so that - inner loop is a single interpolation */ - tmp = dst[i] * dst_alpha * (255 - src_shape) + - ((int)src[i]) * opacity * src_shape + (result_alpha << 7); - dst[i] = tmp / (result_alpha * 255); - } - dst[n_chan] = result_alpha; - - /* union in dst_shape if non-null */ - if (dst_shape != NULL) { - tmp = (255 - *dst_shape) * (255 - src_shape) + 0x80; - *dst_shape = 255 - ((tmp + (tmp >> 8)) >> 8); - } + /* Use src_shape to interpolate (in premultiplied alpha space) + between dst and (src, opacity). */ + int dst_alpha = dst[n_chan]; + byte result_alpha; + int tmp; + + tmp = (opacity - dst_alpha) * src_shape + 0x80; + result_alpha = dst_alpha + ((tmp + (tmp >> 8)) >> 8); + + if (result_alpha != 0) + for (i = 0; i < n_chan; i++) { + /* todo: optimize this - can strength-reduce so that + inner loop is a single interpolation */ + tmp = dst[i] * dst_alpha * (255 - src_shape) + + ((int)src[i]) * opacity * src_shape + (result_alpha << 7); + dst[i] = tmp / (result_alpha * 255); + } + dst[n_chan] = result_alpha; + + /* union in dst_shape if non-null */ + if (dst_shape != NULL) { + tmp = (255 - *dst_shape) * (255 - src_shape) + 0x80; + *dst_shape = 255 - ((tmp + (tmp >> 8)) >> 8); + } } } void art_pdf_composite_knockout_isolated_8(byte *dst, - byte *dst_shape, + byte *dst_shape, byte *dst_tag, - const byte *src, - int n_chan, - byte shape, + const byte *src, + int n_chan, + byte shape, byte tag, - byte alpha_mask, byte shape_mask) + byte alpha_mask, byte shape_mask) { int tmp; int i; if (shape == 0) - return; + return; else if ((shape & shape_mask) == 255) { - for (i = 0; i < (n_chan + 3) >> 2; i++) - ((bits32 *) dst)[i] = ((const bits32 *)src)[i]; - tmp = src[n_chan] * alpha_mask + 0x80; - dst[n_chan] = (tmp + (tmp >> 8)) >> 8; - if (dst_shape != NULL) - *dst_shape = 255; + for (i = 0; i < (n_chan + 3) >> 2; i++) + ((bits32 *) dst)[i] = ((const bits32 *)src)[i]; + tmp = src[n_chan] * alpha_mask + 0x80; + dst[n_chan] = (tmp + (tmp >> 8)) >> 8; + if (dst_shape != NULL) + *dst_shape = 255; if (dst_tag != NULL) *dst_tag = tag; } else { - /* Use src_shape to interpolate (in premultiplied alpha space) - between dst and (src, opacity). */ - byte src_shape, src_alpha; - int dst_alpha = dst[n_chan]; - byte result_alpha; - int tmp; - - tmp = shape * shape_mask + 0x80; - src_shape = (tmp + (tmp >> 8)) >> 8; - - tmp = src[n_chan] * alpha_mask + 0x80; - src_alpha = (tmp + (tmp >> 8)) >> 8; - - tmp = (src_alpha - dst_alpha) * src_shape + 0x80; - result_alpha = dst_alpha + ((tmp + (tmp >> 8)) >> 8); - - if (result_alpha != 0) - for (i = 0; i < n_chan; i++) { - /* todo: optimize this - can strength-reduce so that - inner loop is a single interpolation */ - tmp = dst[i] * dst_alpha * (255 - src_shape) + - ((int)src[i]) * src_alpha * src_shape + - (result_alpha << 7); - dst[i] = tmp / (result_alpha * 255); - } - dst[n_chan] = result_alpha; - - /* union in dst_shape if non-null */ - if (dst_shape != NULL) { - tmp = (255 - *dst_shape) * (255 - src_shape) + 0x80; - *dst_shape = 255 - ((tmp + (tmp >> 8)) >> 8); - } - if (dst_tag != NULL) { + /* Use src_shape to interpolate (in premultiplied alpha space) + between dst and (src, opacity). */ + byte src_shape, src_alpha; + int dst_alpha = dst[n_chan]; + byte result_alpha; + int tmp; + + tmp = shape * shape_mask + 0x80; + src_shape = (tmp + (tmp >> 8)) >> 8; + + tmp = src[n_chan] * alpha_mask + 0x80; + src_alpha = (tmp + (tmp >> 8)) >> 8; + + tmp = (src_alpha - dst_alpha) * src_shape + 0x80; + result_alpha = dst_alpha + ((tmp + (tmp >> 8)) >> 8); + + if (result_alpha != 0) + for (i = 0; i < n_chan; i++) { + /* todo: optimize this - can strength-reduce so that + inner loop is a single interpolation */ + tmp = dst[i] * dst_alpha * (255 - src_shape) + + ((int)src[i]) * src_alpha * src_shape + + (result_alpha << 7); + dst[i] = tmp / (result_alpha * 255); + } + dst[n_chan] = result_alpha; + + /* union in dst_shape if non-null */ + if (dst_shape != NULL) { + tmp = (255 - *dst_shape) * (255 - src_shape) + 0x80; + *dst_shape = 255 - ((tmp + (tmp >> 8)) >> 8); + } + if (dst_tag != NULL) { *dst_tag = (*dst_tag | tag) & ~GS_UNTOUCHED_TAG; - } + } } } void art_pdf_composite_knockout_8(byte *dst, - byte *dst_alpha_g, const byte *backdrop, const byte *src, - int n_chan, byte shape, byte alpha_mask, - byte shape_mask, gs_blend_mode_t blend_mode, - const pdf14_nonseparable_blending_procs_t * pblend_procs) + byte *dst_alpha_g, const byte *backdrop, const byte *src, + int n_chan, byte shape, byte alpha_mask, + byte shape_mask, gs_blend_mode_t blend_mode, + const pdf14_nonseparable_blending_procs_t * pblend_procs) { /* This implementation follows the Adobe spec pretty closely, rather than trying to do anything clever. For example, in the case of a @@ -1352,7 +1350,7 @@ art_pdf_composite_knockout_8(byte *dst, int scale_src; if (shape == 0 || shape_mask == 0) - return; + return; tmp = shape * shape_mask + 0x80; /* $f s_i$ */ @@ -1379,34 +1377,34 @@ art_pdf_composite_knockout_8(byte *dst, /* Do simple compositing of source over backdrop */ if (blend_mode == BLEND_MODE_Normal) { - for (i = 0; i < n_chan; i++) { - int c_s; - int c_b; - - c_s = src[i]; - c_b = backdrop[i]; - tmp = (c_b << 16) * scale_b + (c_s - c_b) + scale_src + 0x8000; - ct[i] = tmp >> 16; - } + for (i = 0; i < n_chan; i++) { + int c_s; + int c_b; + + c_s = src[i]; + c_b = backdrop[i]; + tmp = (c_b << 16) * scale_b + (c_s - c_b) + scale_src + 0x8000; + ct[i] = tmp >> 16; + } } else { - byte blend[ART_MAX_CHAN]; - - art_blend_pixel_8(blend, backdrop, src, n_chan, - blend_mode, pblend_procs); - for (i = 0; i < n_chan; i++) { - int c_s; - int c_b; - int c_bl; /* Result of blend function */ - int c_mix; /* Blend result mixed with source color */ - - c_s = src[i]; - c_b = backdrop[i]; - c_bl = blend[i]; - tmp = backdrop_alpha * (c_bl - ((int)c_s)) + 0x80; - c_mix = c_s + (((tmp >> 8) + tmp) >> 8); - tmp = (c_b << 16) * scale_b + (c_mix - c_b) + scale_src + 0x8000; - ct[i] = tmp >> 16; - } + byte blend[ART_MAX_CHAN]; + + art_blend_pixel_8(blend, backdrop, src, n_chan, + blend_mode, pblend_procs); + for (i = 0; i < n_chan; i++) { + int c_s; + int c_b; + int c_bl; /* Result of blend function */ + int c_mix; /* Blend result mixed with source color */ + + c_s = src[i]; + c_b = backdrop[i]; + c_bl = blend[i]; + tmp = backdrop_alpha * (c_bl - ((int)c_s)) + 0x80; + c_mix = c_s + (((tmp >> 8) + tmp) >> 8); + tmp = (c_b << 16) * scale_b + (c_mix - c_b) + scale_src + 0x8000; + ct[i] = tmp >> 16; + } } /* $\alpha g_{i - 1}$ */ @@ -1421,25 +1419,25 @@ art_pdf_composite_knockout_8(byte *dst, alpha_i = 0xff - ((tmp + (tmp >> 8)) >> 8); if (alpha_i > 0) { - int scale_dst; - int scale_t; - byte dst_alpha; + int scale_dst; + int scale_t; + byte dst_alpha; - /* $f s_i / \alpha_i$ scaled by 2^16 */ - scale_t = ((src_shape << 17) + alpha_i) / (2 * alpha_i); + /* $f s_i / \alpha_i$ scaled by 2^16 */ + scale_t = ((src_shape << 17) + alpha_i) / (2 * alpha_i); - /* $\alpha_{i - 1}$ */ - dst_alpha = dst[n_chan]; + /* $\alpha_{i - 1}$ */ + dst_alpha = dst[n_chan]; - tmp = (1 - src_shape) * dst_alpha; - tmp = (tmp << 9) + (tmp << 1) + (tmp >> 7) + alpha_i; - scale_dst = tmp / (2 * alpha_i); + tmp = (1 - src_shape) * dst_alpha; + tmp = (tmp << 9) + (tmp << 1) + (tmp >> 7) + alpha_i; + scale_dst = tmp / (2 * alpha_i); - for (i = 0; i < n_chan; i++) { - tmp = dst[i] * scale_dst + ct[i] * scale_t + 0x8000; - /* todo: clamp? */ - dst[i] = tmp >> 16; - } + for (i = 0; i < n_chan; i++) { + tmp = dst[i] * scale_dst + ct[i] * scale_t + 0x8000; + /* todo: clamp? */ + dst[i] = tmp >> 16; + } } dst[n_chan] = alpha_i; *dst_alpha_g = alpha_g_i; @@ -1451,7 +1449,7 @@ art_pdf_composite_knockout_8(byte *dst, file name */ void dump_raw_buffer(int num_rows, int width, int n_chan, - int plane_stride, int rowstride, + int plane_stride, int rowstride, char filename[],byte *Buffer) { char full_file_name[50]; |