app/paint-funcs/paint-funcs.c app/paint-funcs/paint-funcs-generic.h
2001-11-19 Daniel Egger <degger@fhm.edu> * app/paint-funcs/paint-funcs.c * app/paint-funcs/paint-funcs-generic.h * app/paint-funcs/paint-funcs.h: - Statified a few functions so they can be inlined. - Simplified function calls. - Unsignified variables and parameters where possible. - Reduced lookuptable size for add_pixels from 256*256*4 bytes to 2*256-1 bytes and O(n*n) function in paint_funcs_setup to O(n). Should reduce memory consumption by almost 1/4 Mb. This needs much more cleanup....
This commit is contained in:

committed by
Daniel Egger

parent
0a28fa8c9c
commit
70cec44587
14
ChangeLog
14
ChangeLog
@ -1,3 +1,17 @@
|
|||||||
|
2001-11-19 Daniel Egger <degger@fhm.edu>
|
||||||
|
|
||||||
|
* app/paint-funcs/paint-funcs.c
|
||||||
|
* app/paint-funcs/paint-funcs-generic.h
|
||||||
|
* app/paint-funcs/paint-funcs.h:
|
||||||
|
- Statified a few functions so they can be inlined.
|
||||||
|
- Simplified function calls.
|
||||||
|
- Unsignified variables and parameters where possible.
|
||||||
|
- Reduced lookuptable size for add_pixels from 256*256*4 bytes
|
||||||
|
to 2*256-1 bytes and O(n*n) function in paint_funcs_setup
|
||||||
|
to O(n). Should reduce memory consumption by almost 1/4 Mb.
|
||||||
|
|
||||||
|
This needs much more cleanup....
|
||||||
|
|
||||||
2001-11-19 Daniel Egger <degger@fhm.edu>
|
2001-11-19 Daniel Egger <degger@fhm.edu>
|
||||||
|
|
||||||
* app/paint-funcs/paint-funcs-mmx.h: New file. Added glue code
|
* app/paint-funcs/paint-funcs-mmx.h: New file. Added glue code
|
||||||
|
@ -61,11 +61,11 @@ struct apply_layer_mode_struct
|
|||||||
gint y;
|
gint y;
|
||||||
guint opacity;
|
guint opacity;
|
||||||
guint length;
|
guint length;
|
||||||
guint combine;
|
CombinationMode combine;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const guchar no_mask = OPAQUE_OPACITY;
|
static const guchar no_mask = OPAQUE_OPACITY;
|
||||||
static gint add_lut[256][256];
|
static guchar add_lut[511];
|
||||||
static gint random_table[RANDOM_TABLE_SIZE];
|
static gint random_table[RANDOM_TABLE_SIZE];
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -755,10 +755,7 @@ add_pixels (const guchar *src1,
|
|||||||
while (length --)
|
while (length --)
|
||||||
{
|
{
|
||||||
for (b = 0; b < alpha; b++)
|
for (b = 0; b < alpha; b++)
|
||||||
{
|
dest[b] = add_lut[src1[b] + src2[b]];
|
||||||
/* TODO: wouldn't it be better use a 1 dimensional lut ie. add_lut[src1+src2]; */
|
|
||||||
dest[b] = add_lut[(src1[b])] [(src2[b])];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (has_alpha1 && has_alpha2)
|
if (has_alpha1 && has_alpha2)
|
||||||
dest[alpha] = MIN (src1[alpha], src2[alpha]);
|
dest[alpha] = MIN (src1[alpha], src2[alpha]);
|
||||||
|
@ -121,10 +121,6 @@ static LayerModeFunc layer_mode_funcs[] =
|
|||||||
|
|
||||||
static gint * make_curve (gdouble sigma,
|
static gint * make_curve (gdouble sigma,
|
||||||
gint *length);
|
gint *length);
|
||||||
static void run_length_encode (guchar *src,
|
|
||||||
gint *dest,
|
|
||||||
gint w,
|
|
||||||
gint bytes);
|
|
||||||
static gdouble cubic (gdouble dx,
|
static gdouble cubic (gdouble dx,
|
||||||
gint jm1,
|
gint jm1,
|
||||||
gint j,
|
gint j,
|
||||||
@ -371,15 +367,15 @@ make_curve (gdouble sigma,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static inline void
|
||||||
run_length_encode (guchar *src,
|
run_length_encode (const guchar *src,
|
||||||
gint *dest,
|
guint *dest,
|
||||||
gint w,
|
guint w,
|
||||||
gint bytes)
|
guint bytes)
|
||||||
{
|
{
|
||||||
gint start;
|
guint start;
|
||||||
gint i;
|
guint i;
|
||||||
gint j;
|
guint j;
|
||||||
guchar last;
|
guchar last;
|
||||||
|
|
||||||
last = *src;
|
last = *src;
|
||||||
@ -429,9 +425,7 @@ cubic (gdouble dx,
|
|||||||
void
|
void
|
||||||
paint_funcs_setup (void)
|
paint_funcs_setup (void)
|
||||||
{
|
{
|
||||||
gint i;
|
guint i;
|
||||||
gint j, k;
|
|
||||||
gint tmp_sum;
|
|
||||||
|
|
||||||
/* generate a table of random seeds */
|
/* generate a table of random seeds */
|
||||||
srand (RANDOM_SEED);
|
srand (RANDOM_SEED);
|
||||||
@ -439,18 +433,11 @@ paint_funcs_setup (void)
|
|||||||
for (i = 0; i < RANDOM_TABLE_SIZE; i++)
|
for (i = 0; i < RANDOM_TABLE_SIZE; i++)
|
||||||
random_table[i] = rand ();
|
random_table[i] = rand ();
|
||||||
|
|
||||||
for (j = 0; j < 256; j++)
|
for (i = 0; i < 256; i++)
|
||||||
{ /* rows */
|
add_lut[i] = i;
|
||||||
for (k = 0; k < 256; k++)
|
|
||||||
{ /* column */
|
for (i = 256; i <= 510; i++)
|
||||||
tmp_sum = j + k;
|
add_lut[i] = 255;
|
||||||
|
|
||||||
if (tmp_sum > 255)
|
|
||||||
tmp_sum = 255;
|
|
||||||
|
|
||||||
add_lut[j][k] = tmp_sum;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_ASM_MMX
|
#ifdef HAVE_ASM_MMX
|
||||||
if (use_mmx)
|
if (use_mmx)
|
||||||
@ -1389,7 +1376,12 @@ combine_inten_a_and_channel_selection_pixels (const guchar *src,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
/* paint "behind" the existing pixel row.
|
||||||
|
* This is similar in appearance to painting on a layer below
|
||||||
|
* the existing pixels.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline void
|
||||||
behind_inten_pixels (const guchar *src1,
|
behind_inten_pixels (const guchar *src1,
|
||||||
const guchar *src2,
|
const guchar *src2,
|
||||||
guchar *dest,
|
guchar *dest,
|
||||||
@ -1397,12 +1389,12 @@ behind_inten_pixels (const guchar *src1,
|
|||||||
gint opacity,
|
gint opacity,
|
||||||
const gboolean *affect,
|
const gboolean *affect,
|
||||||
gint length,
|
gint length,
|
||||||
gint bytes1,
|
guint bytes1,
|
||||||
gint bytes2,
|
guint bytes2)
|
||||||
gint has_alpha1,
|
|
||||||
gint has_alpha2)
|
|
||||||
{
|
{
|
||||||
gint alpha, b;
|
// FIXME: Is this supposed to be different than in the other functions?
|
||||||
|
const guint alpha = bytes1 - 1;
|
||||||
|
guint b;
|
||||||
guchar src1_alpha;
|
guchar src1_alpha;
|
||||||
guchar src2_alpha;
|
guchar src2_alpha;
|
||||||
guchar new_alpha;
|
guchar new_alpha;
|
||||||
@ -1415,9 +1407,6 @@ behind_inten_pixels (const guchar *src1,
|
|||||||
else
|
else
|
||||||
m = &no_mask;
|
m = &no_mask;
|
||||||
|
|
||||||
/* the alpha channel */
|
|
||||||
alpha = bytes1 - 1;
|
|
||||||
|
|
||||||
while (length --)
|
while (length --)
|
||||||
{
|
{
|
||||||
src1_alpha = src1[alpha];
|
src1_alpha = src1[alpha];
|
||||||
@ -1447,20 +1436,24 @@ behind_inten_pixels (const guchar *src1,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
/* paint "behind" the existing pixel row (for indexed images).
|
||||||
|
* This is similar in appearance to painting on a layer below
|
||||||
|
* the existing pixels.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline void
|
||||||
behind_indexed_pixels (const guchar *src1,
|
behind_indexed_pixels (const guchar *src1,
|
||||||
const guchar *src2,
|
const guchar *src2,
|
||||||
guchar *dest,
|
guchar *dest,
|
||||||
const guchar *mask,
|
const guchar *mask,
|
||||||
gint opacity,
|
guint opacity,
|
||||||
const gboolean *affect,
|
const gboolean *affect,
|
||||||
gint length,
|
guint length,
|
||||||
gint bytes1,
|
guint bytes1,
|
||||||
gint bytes2,
|
guint bytes2)
|
||||||
gint has_alpha1,
|
|
||||||
gint has_alpha2)
|
|
||||||
{
|
{
|
||||||
gint alpha, b;
|
const guint alpha = bytes1 - 1;
|
||||||
|
guint b;
|
||||||
guchar src1_alpha;
|
guchar src1_alpha;
|
||||||
guchar src2_alpha;
|
guchar src2_alpha;
|
||||||
guchar new_alpha;
|
guchar new_alpha;
|
||||||
@ -1473,7 +1466,6 @@ behind_indexed_pixels (const guchar *src1,
|
|||||||
m = &no_mask;
|
m = &no_mask;
|
||||||
|
|
||||||
/* the alpha channel */
|
/* the alpha channel */
|
||||||
alpha = bytes1 - 1;
|
|
||||||
|
|
||||||
while (length --)
|
while (length --)
|
||||||
{
|
{
|
||||||
@ -1495,22 +1487,26 @@ behind_indexed_pixels (const guchar *src1,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
/* replace the contents of one pixel row with the other
|
||||||
|
* The operation is still bounded by mask/opacity constraints
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline void
|
||||||
replace_inten_pixels (const guchar *src1,
|
replace_inten_pixels (const guchar *src1,
|
||||||
const guchar *src2,
|
const guchar *src2,
|
||||||
guchar *dest,
|
guchar *dest,
|
||||||
const guchar *mask,
|
const guchar *mask,
|
||||||
gint opacity,
|
guint opacity,
|
||||||
const gboolean *affect,
|
const gboolean *affect,
|
||||||
gint length,
|
guint length,
|
||||||
gint bytes1,
|
guint bytes1,
|
||||||
gint bytes2,
|
guint bytes2)
|
||||||
gint has_alpha1,
|
|
||||||
gint has_alpha2)
|
|
||||||
{
|
{
|
||||||
gint b;
|
const guint has_alpha1 = HAS_ALPHA (bytes1);
|
||||||
|
const guint has_alpha2 = HAS_ALPHA (bytes2);
|
||||||
|
const guint bytes = MIN (bytes1, bytes2);
|
||||||
|
guint b;
|
||||||
gint tmp;
|
gint tmp;
|
||||||
const gint bytes = MIN (bytes1, bytes2);
|
|
||||||
|
|
||||||
if (mask)
|
if (mask)
|
||||||
{
|
{
|
||||||
@ -1538,7 +1534,7 @@ replace_inten_pixels (const guchar *src1,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
static const guchar mask_alpha = OPAQUE_OPACITY ;
|
const guchar mask_alpha = OPAQUE_OPACITY;
|
||||||
|
|
||||||
while (length --)
|
while (length --)
|
||||||
{
|
{
|
||||||
@ -1557,23 +1553,27 @@ replace_inten_pixels (const guchar *src1,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* replace the contents of one pixel row with the other
|
||||||
|
* The operation is still bounded by mask/opacity constraints
|
||||||
|
*/
|
||||||
|
|
||||||
void
|
static inline void
|
||||||
replace_indexed_pixels (const guchar *src1,
|
replace_indexed_pixels (const guchar *src1,
|
||||||
const guchar *src2,
|
const guchar *src2,
|
||||||
guchar *dest,
|
guchar *dest,
|
||||||
const guchar *mask,
|
const guchar *mask,
|
||||||
gint opacity,
|
guint opacity,
|
||||||
const gboolean *affect,
|
const gboolean *affect,
|
||||||
gint length,
|
guint length,
|
||||||
gint bytes1,
|
guint bytes1,
|
||||||
gint bytes2,
|
guint bytes2)
|
||||||
gint has_alpha1,
|
|
||||||
gint has_alpha2)
|
|
||||||
{
|
{
|
||||||
gint bytes, b;
|
const guint has_alpha1 = HAS_ALPHA (bytes1);
|
||||||
guchar mask_alpha;
|
const guint has_alpha2 = HAS_ALPHA (bytes2);
|
||||||
|
const guint bytes = MIN (bytes1, bytes2);
|
||||||
const guchar *m;
|
const guchar *m;
|
||||||
|
guint b;
|
||||||
|
guchar mask_alpha;
|
||||||
gint tmp;
|
gint tmp;
|
||||||
|
|
||||||
if (mask)
|
if (mask)
|
||||||
@ -1581,7 +1581,6 @@ replace_indexed_pixels (const guchar *src1,
|
|||||||
else
|
else
|
||||||
m = &no_mask;
|
m = &no_mask;
|
||||||
|
|
||||||
bytes = MIN (bytes1, bytes2);
|
|
||||||
while (length --)
|
while (length --)
|
||||||
{
|
{
|
||||||
mask_alpha = INT_MULT(*m, opacity, tmp);
|
mask_alpha = INT_MULT(*m, opacity, tmp);
|
||||||
@ -1601,21 +1600,24 @@ replace_indexed_pixels (const guchar *src1,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* apply source 2 to source 1, but in a non-additive way,
|
||||||
|
* multiplying alpha channels (works for intensity)
|
||||||
|
*/
|
||||||
|
|
||||||
void
|
static inline void
|
||||||
erase_inten_pixels (const guchar *src1,
|
erase_inten_pixels (const guchar *src1,
|
||||||
const guchar *src2,
|
const guchar *src2,
|
||||||
guchar *dest,
|
guchar *dest,
|
||||||
const guchar *mask,
|
const guchar *mask,
|
||||||
gint opacity,
|
guint opacity,
|
||||||
const gboolean *affect,
|
const gboolean *affect,
|
||||||
gint length,
|
guint length,
|
||||||
gint bytes)
|
guint bytes)
|
||||||
{
|
{
|
||||||
gint b;
|
const guint alpha = bytes - 1;
|
||||||
|
guint b;
|
||||||
guchar src2_alpha;
|
guchar src2_alpha;
|
||||||
glong tmp;
|
glong tmp;
|
||||||
const gint alpha = bytes - 1;
|
|
||||||
|
|
||||||
if (mask)
|
if (mask)
|
||||||
{
|
{
|
||||||
@ -1656,27 +1658,31 @@ erase_inten_pixels (const guchar *src1,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
/* apply source 2 to source 1, but in a non-additive way,
|
||||||
|
* multiplying alpha channels (works for indexed)
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline void
|
||||||
erase_indexed_pixels (const guchar *src1,
|
erase_indexed_pixels (const guchar *src1,
|
||||||
const guchar *src2,
|
const guchar *src2,
|
||||||
guchar *dest,
|
guchar *dest,
|
||||||
const guchar *mask,
|
const guchar *mask,
|
||||||
gint opacity,
|
guint opacity,
|
||||||
const gboolean *affect,
|
const gboolean *affect,
|
||||||
gint length,
|
guint length,
|
||||||
gint bytes)
|
guint bytes)
|
||||||
{
|
{
|
||||||
gint alpha, b;
|
const guint alpha = bytes - 1;
|
||||||
guchar src2_alpha;
|
|
||||||
const guchar *m;
|
const guchar *m;
|
||||||
glong tmp;
|
guchar src2_alpha;
|
||||||
|
guint b;
|
||||||
|
glong tmp;
|
||||||
|
|
||||||
if (mask)
|
if (mask)
|
||||||
m = mask;
|
m = mask;
|
||||||
else
|
else
|
||||||
m = &no_mask;
|
m = &no_mask;
|
||||||
|
|
||||||
alpha = bytes - 1;
|
|
||||||
while (length --)
|
while (length --)
|
||||||
{
|
{
|
||||||
for (b = 0; b < alpha; b++)
|
for (b = 0; b < alpha; b++)
|
||||||
@ -4019,10 +4025,10 @@ copy_gray_to_region (PixelRegion *src,
|
|||||||
|
|
||||||
struct initial_regions_struct
|
struct initial_regions_struct
|
||||||
{
|
{
|
||||||
gint opacity;
|
guint opacity;
|
||||||
LayerModeEffects mode;
|
LayerModeEffects mode;
|
||||||
gboolean *affect;
|
gboolean *affect;
|
||||||
gint type;
|
InitialMode type;
|
||||||
guchar *data;
|
guchar *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -4036,10 +4042,10 @@ initial_sub_region (struct initial_regions_struct *st,
|
|||||||
guchar *s, *d, *m;
|
guchar *s, *d, *m;
|
||||||
guchar buf[512];
|
guchar buf[512];
|
||||||
guchar *data;
|
guchar *data;
|
||||||
gint opacity;
|
guint opacity;
|
||||||
LayerModeEffects mode;
|
LayerModeEffects mode;
|
||||||
gboolean *affect;
|
gboolean *affect;
|
||||||
gint type;
|
InitialMode type;
|
||||||
|
|
||||||
data = st->data;
|
data = st->data;
|
||||||
opacity = st->opacity;
|
opacity = st->opacity;
|
||||||
@ -4112,7 +4118,7 @@ initial_region (PixelRegion *src,
|
|||||||
gint opacity,
|
gint opacity,
|
||||||
LayerModeEffects mode,
|
LayerModeEffects mode,
|
||||||
gboolean *affect,
|
gboolean *affect,
|
||||||
gint type)
|
InitialMode type)
|
||||||
{
|
{
|
||||||
struct initial_regions_struct st;
|
struct initial_regions_struct st;
|
||||||
|
|
||||||
@ -4131,13 +4137,50 @@ struct combine_regions_struct
|
|||||||
gint opacity;
|
gint opacity;
|
||||||
LayerModeEffects mode;
|
LayerModeEffects mode;
|
||||||
gboolean *affect;
|
gboolean *affect;
|
||||||
gint type;
|
CombinationMode type;
|
||||||
guchar *data;
|
guchar *data;
|
||||||
gboolean has_alpha1, has_alpha2;
|
//gboolean has_alpha1, has_alpha2;
|
||||||
gboolean opacity_quickskip_possible;
|
gboolean opacity_quickskip_possible;
|
||||||
gboolean transparency_quickskip_possible;
|
gboolean transparency_quickskip_possible;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline CombinationMode
|
||||||
|
apply_indexed_layer_mode (guchar *src1,
|
||||||
|
guchar *src2,
|
||||||
|
guchar **dest,
|
||||||
|
LayerModeEffects mode,
|
||||||
|
CombinationMode cmode)
|
||||||
|
{
|
||||||
|
/* assumes we're applying src2 TO src1 */
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case REPLACE_MODE:
|
||||||
|
*dest = src2;
|
||||||
|
cmode = REPLACE_INDEXED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BEHIND_MODE:
|
||||||
|
*dest = src2;
|
||||||
|
if (cmode == COMBINE_INDEXED_A_INDEXED_A)
|
||||||
|
cmode = BEHIND_INDEXED;
|
||||||
|
else
|
||||||
|
cmode = NO_COMBINATION;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ERASE_MODE:
|
||||||
|
*dest = src2;
|
||||||
|
/* If both sources have alpha channels, call erase function.
|
||||||
|
* Otherwise, just combine in the normal manner
|
||||||
|
*/
|
||||||
|
cmode = (cmode == COMBINE_INDEXED_A_INDEXED_A) ? ERASE_INDEXED : cmode;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -4148,13 +4191,12 @@ combine_sub_region (struct combine_regions_struct *st,
|
|||||||
PixelRegion *mask)
|
PixelRegion *mask)
|
||||||
{
|
{
|
||||||
guchar *data;
|
guchar *data;
|
||||||
gint opacity;
|
guint opacity;
|
||||||
LayerModeEffects mode;
|
LayerModeEffects mode;
|
||||||
gboolean *affect;
|
gboolean *affect;
|
||||||
gint type;
|
guint h;
|
||||||
gint h;
|
CombinationMode combine = NO_COMBINATION;
|
||||||
gboolean has_alpha1, has_alpha2;
|
CombinationMode type;
|
||||||
guint combine = 0;
|
|
||||||
guint mode_affect = 0;
|
guint mode_affect = 0;
|
||||||
guchar *s, *s1, *s2;
|
guchar *s, *s1, *s2;
|
||||||
guchar *d, *m;
|
guchar *d, *m;
|
||||||
@ -4168,8 +4210,6 @@ combine_sub_region (struct combine_regions_struct *st,
|
|||||||
affect = st->affect;
|
affect = st->affect;
|
||||||
type = st->type;
|
type = st->type;
|
||||||
data = st->data;
|
data = st->data;
|
||||||
has_alpha1 = st->has_alpha1;
|
|
||||||
has_alpha2 = st->has_alpha2;
|
|
||||||
|
|
||||||
opacity_quickskip_possible = (st->opacity_quickskip_possible &&
|
opacity_quickskip_possible = (st->opacity_quickskip_possible &&
|
||||||
src2->tiles);
|
src2->tiles);
|
||||||
@ -4233,8 +4273,7 @@ combine_sub_region (struct combine_regions_struct *st,
|
|||||||
case COMBINE_INDEXED_INDEXED_A:
|
case COMBINE_INDEXED_INDEXED_A:
|
||||||
case COMBINE_INDEXED_A_INDEXED_A:
|
case COMBINE_INDEXED_A_INDEXED_A:
|
||||||
/* Now, apply the paint mode--for indexed images */
|
/* Now, apply the paint mode--for indexed images */
|
||||||
combine = apply_indexed_layer_mode (s1, s2, &s, mode,
|
combine = apply_indexed_layer_mode (s1, s2, &s, mode, type);
|
||||||
has_alpha1, has_alpha2);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COMBINE_INTEN_INTEN_A:
|
case COMBINE_INTEN_INTEN_A:
|
||||||
@ -4250,6 +4289,7 @@ combine_sub_region (struct combine_regions_struct *st,
|
|||||||
alms.x = src1->x;
|
alms.x = src1->x;
|
||||||
alms.y = src1->y + h;
|
alms.y = src1->y + h;
|
||||||
alms.opacity = opacity;
|
alms.opacity = opacity;
|
||||||
|
alms.combine = combine;
|
||||||
alms.length = src1->w;
|
alms.length = src1->w;
|
||||||
alms.bytes1 = src1->bytes;
|
alms.bytes1 = src1->bytes;
|
||||||
alms.bytes2 = src2->bytes;
|
alms.bytes2 = src2->bytes;
|
||||||
@ -4261,7 +4301,7 @@ combine_sub_region (struct combine_regions_struct *st,
|
|||||||
|
|
||||||
mode_affect = layer_modes[mode].affect_alpha;
|
mode_affect = layer_modes[mode].affect_alpha;
|
||||||
layer_mode_funcs[mode](&alms);
|
layer_mode_funcs[mode](&alms);
|
||||||
combine = (alms.combine == 0) ? type : alms.combine;
|
combine = (alms.combine == NO_COMBINATION) ? type : alms.combine;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4351,25 +4391,25 @@ combine_sub_region (struct combine_regions_struct *st,
|
|||||||
case BEHIND_INTEN:
|
case BEHIND_INTEN:
|
||||||
behind_inten_pixels (s1, s, d, m, opacity,
|
behind_inten_pixels (s1, s, d, m, opacity,
|
||||||
affect, src1->w, src1->bytes,
|
affect, src1->w, src1->bytes,
|
||||||
src2->bytes, has_alpha1, has_alpha2);
|
src2->bytes);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BEHIND_INDEXED:
|
case BEHIND_INDEXED:
|
||||||
behind_indexed_pixels (s1, s, d, m, opacity,
|
behind_indexed_pixels (s1, s, d, m, opacity,
|
||||||
affect, src1->w, src1->bytes,
|
affect, src1->w, src1->bytes,
|
||||||
src2->bytes, has_alpha1, has_alpha2);
|
src2->bytes);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case REPLACE_INTEN:
|
case REPLACE_INTEN:
|
||||||
replace_inten_pixels (s1, s, d, m, opacity,
|
replace_inten_pixels (s1, s, d, m, opacity,
|
||||||
affect, src1->w, src1->bytes,
|
affect, src1->w, src1->bytes,
|
||||||
src2->bytes, has_alpha1, has_alpha2);
|
src2->bytes);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case REPLACE_INDEXED:
|
case REPLACE_INDEXED:
|
||||||
replace_indexed_pixels (s1, s, d, m, opacity,
|
replace_indexed_pixels (s1, s, d, m, opacity,
|
||||||
affect, src1->w, src1->bytes,
|
affect, src1->w, src1->bytes,
|
||||||
src2->bytes, has_alpha1, has_alpha2);
|
src2->bytes);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ERASE_INTEN:
|
case ERASE_INTEN:
|
||||||
@ -4397,7 +4437,7 @@ combine_sub_region (struct combine_regions_struct *st,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
g_warning("UNKNOWN COMBINATION");
|
g_warning("UNKNOWN COMBINATION: %d", combine);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4417,13 +4457,13 @@ combine_regions (PixelRegion *src1,
|
|||||||
PixelRegion *dest,
|
PixelRegion *dest,
|
||||||
PixelRegion *mask,
|
PixelRegion *mask,
|
||||||
guchar *data,
|
guchar *data,
|
||||||
gint opacity,
|
guint opacity,
|
||||||
LayerModeEffects mode,
|
LayerModeEffects mode,
|
||||||
gboolean *affect,
|
gboolean *affect,
|
||||||
gint type)
|
CombinationMode type)
|
||||||
{
|
{
|
||||||
gboolean has_alpha1, has_alpha2;
|
gboolean has_alpha1, has_alpha2;
|
||||||
gint i;
|
guint i;
|
||||||
struct combine_regions_struct st;
|
struct combine_regions_struct st;
|
||||||
|
|
||||||
/* Determine which sources have alpha channels */
|
/* Determine which sources have alpha channels */
|
||||||
@ -4455,8 +4495,6 @@ combine_regions (PixelRegion *src1,
|
|||||||
st.affect = affect;
|
st.affect = affect;
|
||||||
st.type = type;
|
st.type = type;
|
||||||
st.data = data;
|
st.data = data;
|
||||||
st.has_alpha1 = has_alpha1;
|
|
||||||
st.has_alpha2 = has_alpha2;
|
|
||||||
|
|
||||||
/* cheap and easy when the row of src2 is completely opaque/transparent
|
/* cheap and easy when the row of src2 is completely opaque/transparent
|
||||||
and the wind is otherwise blowing in the right direction.
|
and the wind is otherwise blowing in the right direction.
|
||||||
@ -4502,16 +4540,16 @@ combine_regions (PixelRegion *src1,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
combine_regions_replace (PixelRegion *src1,
|
combine_regions_replace (PixelRegion *src1,
|
||||||
PixelRegion *src2,
|
PixelRegion *src2,
|
||||||
PixelRegion *dest,
|
PixelRegion *dest,
|
||||||
PixelRegion *mask,
|
PixelRegion *mask,
|
||||||
guchar *data,
|
guchar *data,
|
||||||
gint opacity,
|
guint opacity,
|
||||||
gboolean *affect,
|
gboolean *affect,
|
||||||
gint type)
|
CombinationMode type)
|
||||||
{
|
{
|
||||||
gint h;
|
guint h;
|
||||||
guchar *s1;
|
guchar *s1;
|
||||||
guchar *s2;
|
guchar *s2;
|
||||||
guchar *d;
|
guchar *d;
|
||||||
@ -4543,58 +4581,6 @@ combine_regions_replace (PixelRegion *src1,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
gint
|
|
||||||
apply_indexed_layer_mode (guchar *src1,
|
|
||||||
guchar *src2,
|
|
||||||
guchar **dest,
|
|
||||||
LayerModeEffects mode,
|
|
||||||
gboolean has_alpha1, /* has alpha */
|
|
||||||
gboolean has_alpha2) /* has alpha */
|
|
||||||
{
|
|
||||||
gint combine;
|
|
||||||
|
|
||||||
if (!has_alpha1 && !has_alpha2)
|
|
||||||
combine = COMBINE_INDEXED_INDEXED;
|
|
||||||
else if (!has_alpha1 && has_alpha2)
|
|
||||||
combine = COMBINE_INDEXED_INDEXED_A;
|
|
||||||
else if (has_alpha1 && has_alpha2)
|
|
||||||
combine = COMBINE_INDEXED_A_INDEXED_A;
|
|
||||||
else
|
|
||||||
combine = NO_COMBINATION;
|
|
||||||
|
|
||||||
/* assumes we're applying src2 TO src1 */
|
|
||||||
switch (mode)
|
|
||||||
{
|
|
||||||
case REPLACE_MODE:
|
|
||||||
*dest = src2;
|
|
||||||
combine = REPLACE_INDEXED;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BEHIND_MODE:
|
|
||||||
*dest = src2;
|
|
||||||
if (has_alpha1)
|
|
||||||
combine = BEHIND_INDEXED;
|
|
||||||
else
|
|
||||||
combine = NO_COMBINATION;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ERASE_MODE:
|
|
||||||
*dest = src2;
|
|
||||||
/* If both sources have alpha channels, call erase function.
|
|
||||||
* Otherwise, just combine in the normal manner
|
|
||||||
*/
|
|
||||||
combine = (has_alpha1 && has_alpha2) ? ERASE_INDEXED : combine;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return combine;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
apply_layer_mode_replace (guchar *src1,
|
apply_layer_mode_replace (guchar *src1,
|
||||||
guchar *src2,
|
guchar *src2,
|
||||||
|
@ -236,92 +236,6 @@ void combine_inten_a_and_channel_selection_pixels(const unsigned char *src,
|
|||||||
int length,
|
int length,
|
||||||
int bytes);
|
int bytes);
|
||||||
|
|
||||||
/* paint "behind" the existing pixel row.
|
|
||||||
* This is similar in appearance to painting on a layer below
|
|
||||||
* the existing pixels.
|
|
||||||
*/
|
|
||||||
void behind_inten_pixels (const unsigned char *src1,
|
|
||||||
const unsigned char *src2,
|
|
||||||
unsigned char *dest,
|
|
||||||
const unsigned char *mask,
|
|
||||||
int opacity,
|
|
||||||
const int *affect,
|
|
||||||
int length,
|
|
||||||
int bytes1,
|
|
||||||
int bytes2,
|
|
||||||
int has_alpha1,
|
|
||||||
int has_alpha2);
|
|
||||||
|
|
||||||
/* paint "behind" the existing pixel row (for indexed images).
|
|
||||||
* This is similar in appearance to painting on a layer below
|
|
||||||
* the existing pixels.
|
|
||||||
*/
|
|
||||||
void behind_indexed_pixels (const unsigned char *src1,
|
|
||||||
const unsigned char *src2,
|
|
||||||
unsigned char *dest,
|
|
||||||
const unsigned char *mask,
|
|
||||||
int opacity,
|
|
||||||
const int *affect,
|
|
||||||
int length,
|
|
||||||
int bytes1,
|
|
||||||
int bytes2,
|
|
||||||
int has_alpha1,
|
|
||||||
int has_alpha2);
|
|
||||||
|
|
||||||
/* replace the contents of one pixel row with the other
|
|
||||||
* The operation is still bounded by mask/opacity constraints
|
|
||||||
*/
|
|
||||||
void replace_inten_pixels (const unsigned char *src1,
|
|
||||||
const unsigned char *src2,
|
|
||||||
unsigned char *dest,
|
|
||||||
const unsigned char *mask,
|
|
||||||
int opacity,
|
|
||||||
const int *affect,
|
|
||||||
int length,
|
|
||||||
int bytes1,
|
|
||||||
int bytes2,
|
|
||||||
int has_alpha1,
|
|
||||||
int has_alpha2);
|
|
||||||
|
|
||||||
/* replace the contents of one pixel row with the other
|
|
||||||
* The operation is still bounded by mask/opacity constraints
|
|
||||||
*/
|
|
||||||
void replace_indexed_pixels (const unsigned char *src1,
|
|
||||||
const unsigned char *src2,
|
|
||||||
unsigned char *dest,
|
|
||||||
const unsigned char *mask,
|
|
||||||
int opacity,
|
|
||||||
const int *affect,
|
|
||||||
int length,
|
|
||||||
int bytes1,
|
|
||||||
int bytes2,
|
|
||||||
int has_alpha1,
|
|
||||||
int has_alpha2);
|
|
||||||
|
|
||||||
/* apply source 2 to source 1, but in a non-additive way,
|
|
||||||
* multiplying alpha channels (works for intensity)
|
|
||||||
*/
|
|
||||||
void erase_inten_pixels (const unsigned char *src1,
|
|
||||||
const unsigned char *src2,
|
|
||||||
unsigned char *dest,
|
|
||||||
const unsigned char *mask,
|
|
||||||
int opacity,
|
|
||||||
const int *affect,
|
|
||||||
int length,
|
|
||||||
int bytes);
|
|
||||||
|
|
||||||
/* apply source 2 to source 1, but in a non-additive way,
|
|
||||||
* multiplying alpha channels (works for indexed)
|
|
||||||
*/
|
|
||||||
void erase_indexed_pixels (const unsigned char *src1,
|
|
||||||
const unsigned char *src2,
|
|
||||||
unsigned char *dest,
|
|
||||||
const unsigned char *mask,
|
|
||||||
int opacity,
|
|
||||||
const int *affect,
|
|
||||||
int length,
|
|
||||||
int bytes);
|
|
||||||
|
|
||||||
/* extract information from intensity pixels based on
|
/* extract information from intensity pixels based on
|
||||||
* a mask.
|
* a mask.
|
||||||
*/
|
*/
|
||||||
@ -429,38 +343,44 @@ void copy_gray_to_region (PixelRegion *, PixelRegion *);
|
|||||||
* images, floating selections, selective display of intensity
|
* images, floating selections, selective display of intensity
|
||||||
* channels, and display of arbitrary mask channels
|
* channels, and display of arbitrary mask channels
|
||||||
*/
|
*/
|
||||||
#define INITIAL_CHANNEL_MASK 0
|
typedef enum
|
||||||
#define INITIAL_CHANNEL_SELECTION 1
|
{
|
||||||
#define INITIAL_INDEXED 2
|
INITIAL_CHANNEL_MASK = 0,
|
||||||
#define INITIAL_INDEXED_ALPHA 3
|
INITIAL_CHANNEL_SELECTION,
|
||||||
#define INITIAL_INTENSITY 4
|
INITIAL_INDEXED,
|
||||||
#define INITIAL_INTENSITY_ALPHA 5
|
INITIAL_INDEXED_ALPHA,
|
||||||
|
INITIAL_INTENSITY,
|
||||||
|
INITIAL_INTENSITY_ALPHA,
|
||||||
|
} InitialMode;
|
||||||
|
|
||||||
/* Combine two source regions with the help of an optional mask
|
/* Combine two source regions with the help of an optional mask
|
||||||
* region into a destination region. This is used for constructing
|
* region into a destination region. This is used for constructing
|
||||||
* layer projections, and for applying image patches to an image
|
* layer projections, and for applying image patches to an image
|
||||||
*/
|
*/
|
||||||
#define COMBINE_INDEXED_INDEXED 0
|
typedef enum
|
||||||
#define COMBINE_INDEXED_INDEXED_A 1
|
{
|
||||||
#define COMBINE_INDEXED_A_INDEXED_A 2
|
NO_COMBINATION = 0,
|
||||||
#define COMBINE_INTEN_A_INDEXED_A 3
|
COMBINE_INDEXED_INDEXED,
|
||||||
#define COMBINE_INTEN_A_CHANNEL_MASK 4
|
COMBINE_INDEXED_INDEXED_A,
|
||||||
#define COMBINE_INTEN_A_CHANNEL_SELECTION 5
|
COMBINE_INDEXED_A_INDEXED_A,
|
||||||
#define COMBINE_INTEN_INTEN 6
|
COMBINE_INTEN_A_INDEXED_A,
|
||||||
#define COMBINE_INTEN_INTEN_A 7
|
COMBINE_INTEN_A_CHANNEL_MASK,
|
||||||
#define COMBINE_INTEN_A_INTEN 8
|
COMBINE_INTEN_A_CHANNEL_SELECTION,
|
||||||
#define COMBINE_INTEN_A_INTEN_A 9
|
COMBINE_INTEN_INTEN,
|
||||||
|
COMBINE_INTEN_INTEN_A,
|
||||||
|
COMBINE_INTEN_A_INTEN,
|
||||||
|
COMBINE_INTEN_A_INTEN_A,
|
||||||
|
|
||||||
/* Non-conventional combination modes */
|
/* Non-conventional combination modes */
|
||||||
#define BEHIND_INTEN 20
|
BEHIND_INTEN,
|
||||||
#define BEHIND_INDEXED 21
|
BEHIND_INDEXED,
|
||||||
#define REPLACE_INTEN 22
|
REPLACE_INTEN,
|
||||||
#define REPLACE_INDEXED 23
|
REPLACE_INDEXED,
|
||||||
#define ERASE_INTEN 24
|
ERASE_INTEN,
|
||||||
#define ERASE_INDEXED 25
|
ERASE_INDEXED,
|
||||||
#define ANTI_ERASE_INTEN 26
|
ANTI_ERASE_INTEN,
|
||||||
#define ANTI_ERASE_INDEXED 27
|
ANTI_ERASE_INDEXED,
|
||||||
#define NO_COMBINATION 28
|
} CombinationMode;
|
||||||
|
|
||||||
/* Opacities */
|
/* Opacities */
|
||||||
#define TRANSPARENT_OPACITY 0
|
#define TRANSPARENT_OPACITY 0
|
||||||
@ -468,30 +388,18 @@ void copy_gray_to_region (PixelRegion *, PixelRegion *);
|
|||||||
|
|
||||||
void initial_region (PixelRegion *, PixelRegion *,
|
void initial_region (PixelRegion *, PixelRegion *,
|
||||||
PixelRegion *, unsigned char *,
|
PixelRegion *, unsigned char *,
|
||||||
int, LayerModeEffects, int *, int);
|
int, LayerModeEffects, int *,
|
||||||
|
CombinationMode);
|
||||||
|
|
||||||
void combine_regions (PixelRegion *, PixelRegion *,
|
void combine_regions (PixelRegion *, PixelRegion *,
|
||||||
PixelRegion *, PixelRegion *,
|
PixelRegion *, PixelRegion *,
|
||||||
unsigned char *, int,
|
unsigned char *, guint,
|
||||||
LayerModeEffects,
|
LayerModeEffects,
|
||||||
int *, int);
|
int *, CombinationMode);
|
||||||
|
|
||||||
void combine_regions_replace (PixelRegion *, PixelRegion *,
|
void combine_regions_replace (PixelRegion *, PixelRegion *,
|
||||||
PixelRegion *, PixelRegion *,
|
PixelRegion *, PixelRegion *,
|
||||||
unsigned char *,
|
unsigned char *,
|
||||||
int, int *, int);
|
guint, int *, CombinationMode);
|
||||||
|
|
||||||
|
|
||||||
/* Applying layer modes... */
|
|
||||||
/*
|
|
||||||
int apply_layer_mode (unsigned char *, unsigned char *,
|
|
||||||
unsigned char **, int, int, int,
|
|
||||||
int,
|
|
||||||
LayerModeEffects,
|
|
||||||
int, int, int, int, int *);
|
|
||||||
*/
|
|
||||||
int apply_indexed_layer_mode (unsigned char *, unsigned char *,
|
|
||||||
unsigned char **,
|
|
||||||
LayerModeEffects, int, int);
|
|
||||||
|
|
||||||
#endif /* __PAINT_FUNCS_H__ */
|
#endif /* __PAINT_FUNCS_H__ */
|
||||||
|
Reference in New Issue
Block a user