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:
Daniel Egger
2001-11-19 17:21:03 +00:00
committed by Daniel Egger
parent 0a28fa8c9c
commit 70cec44587
4 changed files with 207 additions and 302 deletions

View File

@ -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>
* app/paint-funcs/paint-funcs-mmx.h: New file. Added glue code

View File

@ -61,11 +61,11 @@ struct apply_layer_mode_struct
gint y;
guint opacity;
guint length;
guint combine;
CombinationMode combine;
};
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];
void
@ -755,10 +755,7 @@ add_pixels (const guchar *src1,
while (length --)
{
for (b = 0; b < alpha; 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])];
}
dest[b] = add_lut[src1[b] + src2[b]];
if (has_alpha1 && has_alpha2)
dest[alpha] = MIN (src1[alpha], src2[alpha]);

View File

@ -121,10 +121,6 @@ static LayerModeFunc layer_mode_funcs[] =
static gint * make_curve (gdouble sigma,
gint *length);
static void run_length_encode (guchar *src,
gint *dest,
gint w,
gint bytes);
static gdouble cubic (gdouble dx,
gint jm1,
gint j,
@ -371,15 +367,15 @@ make_curve (gdouble sigma,
}
static void
run_length_encode (guchar *src,
gint *dest,
gint w,
gint bytes)
static inline void
run_length_encode (const guchar *src,
guint *dest,
guint w,
guint bytes)
{
gint start;
gint i;
gint j;
guint start;
guint i;
guint j;
guchar last;
last = *src;
@ -429,9 +425,7 @@ cubic (gdouble dx,
void
paint_funcs_setup (void)
{
gint i;
gint j, k;
gint tmp_sum;
guint i;
/* generate a table of random seeds */
srand (RANDOM_SEED);
@ -439,18 +433,11 @@ paint_funcs_setup (void)
for (i = 0; i < RANDOM_TABLE_SIZE; i++)
random_table[i] = rand ();
for (j = 0; j < 256; j++)
{ /* rows */
for (k = 0; k < 256; k++)
{ /* column */
tmp_sum = j + k;
if (tmp_sum > 255)
tmp_sum = 255;
add_lut[j][k] = tmp_sum;
}
}
for (i = 0; i < 256; i++)
add_lut[i] = i;
for (i = 256; i <= 510; i++)
add_lut[i] = 255;
#ifdef HAVE_ASM_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,
const guchar *src2,
guchar *dest,
@ -1397,12 +1389,12 @@ behind_inten_pixels (const guchar *src1,
gint opacity,
const gboolean *affect,
gint length,
gint bytes1,
gint bytes2,
gint has_alpha1,
gint has_alpha2)
guint bytes1,
guint bytes2)
{
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 src2_alpha;
guchar new_alpha;
@ -1415,9 +1407,6 @@ behind_inten_pixels (const guchar *src1,
else
m = &no_mask;
/* the alpha channel */
alpha = bytes1 - 1;
while (length --)
{
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,
const guchar *src2,
guchar *dest,
const guchar *mask,
gint opacity,
guint opacity,
const gboolean *affect,
gint length,
gint bytes1,
gint bytes2,
gint has_alpha1,
gint has_alpha2)
guint length,
guint bytes1,
guint bytes2)
{
gint alpha, b;
const guint alpha = bytes1 - 1;
guint b;
guchar src1_alpha;
guchar src2_alpha;
guchar new_alpha;
@ -1473,7 +1466,6 @@ behind_indexed_pixels (const guchar *src1,
m = &no_mask;
/* the alpha channel */
alpha = bytes1 - 1;
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,
const guchar *src2,
guchar *dest,
const guchar *mask,
gint opacity,
guint opacity,
const gboolean *affect,
gint length,
gint bytes1,
gint bytes2,
gint has_alpha1,
gint has_alpha2)
guint length,
guint bytes1,
guint bytes2)
{
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;
const gint bytes = MIN (bytes1, bytes2);
if (mask)
{
@ -1538,7 +1534,7 @@ replace_inten_pixels (const guchar *src1,
}
else
{
static const guchar mask_alpha = OPAQUE_OPACITY ;
const guchar mask_alpha = OPAQUE_OPACITY;
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,
const guchar *src2,
guchar *dest,
const guchar *mask,
gint opacity,
guint opacity,
const gboolean *affect,
gint length,
gint bytes1,
gint bytes2,
gint has_alpha1,
gint has_alpha2)
guint length,
guint bytes1,
guint bytes2)
{
gint bytes, b;
guchar mask_alpha;
const guint has_alpha1 = HAS_ALPHA (bytes1);
const guint has_alpha2 = HAS_ALPHA (bytes2);
const guint bytes = MIN (bytes1, bytes2);
const guchar *m;
guint b;
guchar mask_alpha;
gint tmp;
if (mask)
@ -1581,7 +1581,6 @@ replace_indexed_pixels (const guchar *src1,
else
m = &no_mask;
bytes = MIN (bytes1, bytes2);
while (length --)
{
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,
const guchar *src2,
guchar *dest,
const guchar *mask,
gint opacity,
guint opacity,
const gboolean *affect,
gint length,
gint bytes)
guint length,
guint bytes)
{
gint b;
const guint alpha = bytes - 1;
guint b;
guchar src2_alpha;
glong tmp;
const gint alpha = bytes - 1;
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,
const guchar *src2,
guchar *dest,
const guchar *mask,
gint opacity,
guint opacity,
const gboolean *affect,
gint length,
gint bytes)
guint length,
guint bytes)
{
gint alpha, b;
guchar src2_alpha;
const guint alpha = bytes - 1;
const guchar *m;
glong tmp;
guchar src2_alpha;
guint b;
glong tmp;
if (mask)
m = mask;
else
m = &no_mask;
alpha = bytes - 1;
while (length --)
{
for (b = 0; b < alpha; b++)
@ -4019,10 +4025,10 @@ copy_gray_to_region (PixelRegion *src,
struct initial_regions_struct
{
gint opacity;
guint opacity;
LayerModeEffects mode;
gboolean *affect;
gint type;
InitialMode type;
guchar *data;
};
@ -4036,10 +4042,10 @@ initial_sub_region (struct initial_regions_struct *st,
guchar *s, *d, *m;
guchar buf[512];
guchar *data;
gint opacity;
guint opacity;
LayerModeEffects mode;
gboolean *affect;
gint type;
InitialMode type;
data = st->data;
opacity = st->opacity;
@ -4112,7 +4118,7 @@ initial_region (PixelRegion *src,
gint opacity,
LayerModeEffects mode,
gboolean *affect,
gint type)
InitialMode type)
{
struct initial_regions_struct st;
@ -4131,13 +4137,50 @@ struct combine_regions_struct
gint opacity;
LayerModeEffects mode;
gboolean *affect;
gint type;
CombinationMode type;
guchar *data;
gboolean has_alpha1, has_alpha2;
//gboolean has_alpha1, has_alpha2;
gboolean opacity_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
@ -4148,13 +4191,12 @@ combine_sub_region (struct combine_regions_struct *st,
PixelRegion *mask)
{
guchar *data;
gint opacity;
guint opacity;
LayerModeEffects mode;
gboolean *affect;
gint type;
gint h;
gboolean has_alpha1, has_alpha2;
guint combine = 0;
guint h;
CombinationMode combine = NO_COMBINATION;
CombinationMode type;
guint mode_affect = 0;
guchar *s, *s1, *s2;
guchar *d, *m;
@ -4168,8 +4210,6 @@ combine_sub_region (struct combine_regions_struct *st,
affect = st->affect;
type = st->type;
data = st->data;
has_alpha1 = st->has_alpha1;
has_alpha2 = st->has_alpha2;
opacity_quickskip_possible = (st->opacity_quickskip_possible &&
src2->tiles);
@ -4233,8 +4273,7 @@ combine_sub_region (struct combine_regions_struct *st,
case COMBINE_INDEXED_INDEXED_A:
case COMBINE_INDEXED_A_INDEXED_A:
/* Now, apply the paint mode--for indexed images */
combine = apply_indexed_layer_mode (s1, s2, &s, mode,
has_alpha1, has_alpha2);
combine = apply_indexed_layer_mode (s1, s2, &s, mode, type);
break;
case COMBINE_INTEN_INTEN_A:
@ -4250,6 +4289,7 @@ combine_sub_region (struct combine_regions_struct *st,
alms.x = src1->x;
alms.y = src1->y + h;
alms.opacity = opacity;
alms.combine = combine;
alms.length = src1->w;
alms.bytes1 = src1->bytes;
alms.bytes2 = src2->bytes;
@ -4261,7 +4301,7 @@ combine_sub_region (struct combine_regions_struct *st,
mode_affect = layer_modes[mode].affect_alpha;
layer_mode_funcs[mode](&alms);
combine = (alms.combine == 0) ? type : alms.combine;
combine = (alms.combine == NO_COMBINATION) ? type : alms.combine;
break;
}
@ -4351,25 +4391,25 @@ combine_sub_region (struct combine_regions_struct *st,
case BEHIND_INTEN:
behind_inten_pixels (s1, s, d, m, opacity,
affect, src1->w, src1->bytes,
src2->bytes, has_alpha1, has_alpha2);
src2->bytes);
break;
case BEHIND_INDEXED:
behind_indexed_pixels (s1, s, d, m, opacity,
affect, src1->w, src1->bytes,
src2->bytes, has_alpha1, has_alpha2);
src2->bytes);
break;
case REPLACE_INTEN:
replace_inten_pixels (s1, s, d, m, opacity,
affect, src1->w, src1->bytes,
src2->bytes, has_alpha1, has_alpha2);
src2->bytes);
break;
case REPLACE_INDEXED:
replace_indexed_pixels (s1, s, d, m, opacity,
affect, src1->w, src1->bytes,
src2->bytes, has_alpha1, has_alpha2);
src2->bytes);
break;
case ERASE_INTEN:
@ -4397,7 +4437,7 @@ combine_sub_region (struct combine_regions_struct *st,
break;
default:
g_warning("UNKNOWN COMBINATION");
g_warning("UNKNOWN COMBINATION: %d", combine);
break;
}
@ -4417,13 +4457,13 @@ combine_regions (PixelRegion *src1,
PixelRegion *dest,
PixelRegion *mask,
guchar *data,
gint opacity,
guint opacity,
LayerModeEffects mode,
gboolean *affect,
gint type)
CombinationMode type)
{
gboolean has_alpha1, has_alpha2;
gint i;
guint i;
struct combine_regions_struct st;
/* Determine which sources have alpha channels */
@ -4455,8 +4495,6 @@ combine_regions (PixelRegion *src1,
st.affect = affect;
st.type = type;
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
and the wind is otherwise blowing in the right direction.
@ -4502,16 +4540,16 @@ combine_regions (PixelRegion *src1,
}
void
combine_regions_replace (PixelRegion *src1,
PixelRegion *src2,
PixelRegion *dest,
PixelRegion *mask,
guchar *data,
gint opacity,
gboolean *affect,
gint type)
combine_regions_replace (PixelRegion *src1,
PixelRegion *src2,
PixelRegion *dest,
PixelRegion *mask,
guchar *data,
guint opacity,
gboolean *affect,
CombinationMode type)
{
gint h;
guint h;
guchar *s1;
guchar *s2;
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
apply_layer_mode_replace (guchar *src1,
guchar *src2,

View File

@ -236,92 +236,6 @@ void combine_inten_a_and_channel_selection_pixels(const unsigned char *src,
int length,
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
* a mask.
*/
@ -429,38 +343,44 @@ void copy_gray_to_region (PixelRegion *, PixelRegion *);
* images, floating selections, selective display of intensity
* channels, and display of arbitrary mask channels
*/
#define INITIAL_CHANNEL_MASK 0
#define INITIAL_CHANNEL_SELECTION 1
#define INITIAL_INDEXED 2
#define INITIAL_INDEXED_ALPHA 3
#define INITIAL_INTENSITY 4
#define INITIAL_INTENSITY_ALPHA 5
typedef enum
{
INITIAL_CHANNEL_MASK = 0,
INITIAL_CHANNEL_SELECTION,
INITIAL_INDEXED,
INITIAL_INDEXED_ALPHA,
INITIAL_INTENSITY,
INITIAL_INTENSITY_ALPHA,
} InitialMode;
/* Combine two source regions with the help of an optional mask
* region into a destination region. This is used for constructing
* layer projections, and for applying image patches to an image
*/
#define COMBINE_INDEXED_INDEXED 0
#define COMBINE_INDEXED_INDEXED_A 1
#define COMBINE_INDEXED_A_INDEXED_A 2
#define COMBINE_INTEN_A_INDEXED_A 3
#define COMBINE_INTEN_A_CHANNEL_MASK 4
#define COMBINE_INTEN_A_CHANNEL_SELECTION 5
#define COMBINE_INTEN_INTEN 6
#define COMBINE_INTEN_INTEN_A 7
#define COMBINE_INTEN_A_INTEN 8
#define COMBINE_INTEN_A_INTEN_A 9
typedef enum
{
NO_COMBINATION = 0,
COMBINE_INDEXED_INDEXED,
COMBINE_INDEXED_INDEXED_A,
COMBINE_INDEXED_A_INDEXED_A,
COMBINE_INTEN_A_INDEXED_A,
COMBINE_INTEN_A_CHANNEL_MASK,
COMBINE_INTEN_A_CHANNEL_SELECTION,
COMBINE_INTEN_INTEN,
COMBINE_INTEN_INTEN_A,
COMBINE_INTEN_A_INTEN,
COMBINE_INTEN_A_INTEN_A,
/* Non-conventional combination modes */
#define BEHIND_INTEN 20
#define BEHIND_INDEXED 21
#define REPLACE_INTEN 22
#define REPLACE_INDEXED 23
#define ERASE_INTEN 24
#define ERASE_INDEXED 25
#define ANTI_ERASE_INTEN 26
#define ANTI_ERASE_INDEXED 27
#define NO_COMBINATION 28
/* Non-conventional combination modes */
BEHIND_INTEN,
BEHIND_INDEXED,
REPLACE_INTEN,
REPLACE_INDEXED,
ERASE_INTEN,
ERASE_INDEXED,
ANTI_ERASE_INTEN,
ANTI_ERASE_INDEXED,
} CombinationMode;
/* Opacities */
#define TRANSPARENT_OPACITY 0
@ -468,30 +388,18 @@ void copy_gray_to_region (PixelRegion *, PixelRegion *);
void initial_region (PixelRegion *, PixelRegion *,
PixelRegion *, unsigned char *,
int, LayerModeEffects, int *, int);
int, LayerModeEffects, int *,
CombinationMode);
void combine_regions (PixelRegion *, PixelRegion *,
PixelRegion *, PixelRegion *,
unsigned char *, int,
unsigned char *, guint,
LayerModeEffects,
int *, int);
int *, CombinationMode);
void combine_regions_replace (PixelRegion *, PixelRegion *,
PixelRegion *, PixelRegion *,
unsigned char *,
int, int *, int);
/* 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);
guint, int *, CombinationMode);
#endif /* __PAINT_FUNCS_H__ */