summaryrefslogtreecommitdiff
path: root/gs/base/gxblend.c
diff options
context:
space:
mode:
Diffstat (limited to 'gs/base/gxblend.c')
-rw-r--r--gs/base/gxblend.c1422
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];