mirror of https://github.com/GNOME/gimp.git
optimized by using a lookup table
* app/color_balance.c: optimized by using a lookup table * app/paint_funcs.c: parallelized apply_mask_to_region, combine_mask_and_region, and initial_region. Use rand_r if we are multithreaded.
This commit is contained in:
parent
27f68dfe6d
commit
fe34aed3a4
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,11 @@
|
|||
1999-01-31 Jay Cox <jaycox@earthlink.net>
|
||||
|
||||
* app/color_balance.c: optimized by using a lookup table
|
||||
|
||||
* app/paint_funcs.c: parallelized apply_mask_to_region,
|
||||
combine_mask_and_region, and initial_region. Use rand_r
|
||||
if we are multithreaded.
|
||||
|
||||
Sun Jan 31 18:02:46 1999 Owen Taylor <otaylor@gtk.org>
|
||||
|
||||
* app/blob.c: Merged in changes from gsumi. This
|
||||
|
@ -7,7 +15,7 @@ Sun Jan 31 18:02:46 1999 Owen Taylor <otaylor@gtk.org>
|
|||
|
||||
Sun Jan 31 19:42:26 GMT 1999 Adam D. Moss <adam@gimp.org>
|
||||
|
||||
* app/tile.c app/tile_manager.c:
|
||||
* app/tile.c, app/tile_manager.c:
|
||||
|
||||
Fixed the tile-corruption bug which has been around
|
||||
since early GIMP-1.1. When dirtying a copy-on-write
|
||||
|
|
|
@ -71,6 +71,10 @@ struct _ColorBalanceDialog
|
|||
double magenta_green[3];
|
||||
double yellow_blue[3];
|
||||
|
||||
char r_lookup[255];
|
||||
char g_lookup[255];
|
||||
char b_lookup[255];
|
||||
|
||||
gint preserve_luminosity;
|
||||
gint preview;
|
||||
gint application_mode;
|
||||
|
@ -122,23 +126,9 @@ color_balance (PixelRegion *srcPR,
|
|||
int r, g, b;
|
||||
int r_n, g_n, b_n;
|
||||
int w, h;
|
||||
double *cyan_red_transfer[3];
|
||||
double *magenta_green_transfer[3];
|
||||
double *yellow_blue_transfer[3];
|
||||
|
||||
cbd = (ColorBalanceDialog *) user_data;
|
||||
|
||||
/* Set the transfer arrays (for speed) */
|
||||
cyan_red_transfer[SHADOWS] = (cbd->cyan_red[SHADOWS] > 0) ? shadows_add : shadows_sub;
|
||||
cyan_red_transfer[MIDTONES] = (cbd->cyan_red[MIDTONES] > 0) ? midtones_add : midtones_sub;
|
||||
cyan_red_transfer[HIGHLIGHTS] = (cbd->cyan_red[HIGHLIGHTS] > 0) ? highlights_add : highlights_sub;
|
||||
magenta_green_transfer[SHADOWS] = (cbd->magenta_green[SHADOWS] > 0) ? shadows_add : shadows_sub;
|
||||
magenta_green_transfer[MIDTONES] = (cbd->magenta_green[MIDTONES] > 0) ? midtones_add : midtones_sub;
|
||||
magenta_green_transfer[HIGHLIGHTS] = (cbd->magenta_green[HIGHLIGHTS] > 0) ? highlights_add : highlights_sub;
|
||||
yellow_blue_transfer[SHADOWS] = (cbd->yellow_blue[SHADOWS] > 0) ? shadows_add : shadows_sub;
|
||||
yellow_blue_transfer[MIDTONES] = (cbd->yellow_blue[MIDTONES] > 0) ? midtones_add : midtones_sub;
|
||||
yellow_blue_transfer[HIGHLIGHTS] = (cbd->yellow_blue[HIGHLIGHTS] > 0) ? highlights_add : highlights_sub;
|
||||
|
||||
h = srcPR->h;
|
||||
src = srcPR->data;
|
||||
dest = destPR->data;
|
||||
|
@ -151,30 +141,14 @@ color_balance (PixelRegion *srcPR,
|
|||
d = dest;
|
||||
while (w--)
|
||||
{
|
||||
r = r_n = s[RED_PIX];
|
||||
g = g_n = s[GREEN_PIX];
|
||||
b = b_n = s[BLUE_PIX];
|
||||
r = s[RED_PIX];
|
||||
g = s[GREEN_PIX];
|
||||
b = s[BLUE_PIX];
|
||||
|
||||
r_n += cbd->cyan_red[SHADOWS] * cyan_red_transfer[SHADOWS][r_n];
|
||||
r_n = CLAMP0255 (r_n);
|
||||
r_n += cbd->cyan_red[MIDTONES] * cyan_red_transfer[MIDTONES][r_n];
|
||||
r_n = CLAMP0255 (r_n);
|
||||
r_n += cbd->cyan_red[HIGHLIGHTS] * cyan_red_transfer[HIGHLIGHTS][r_n];
|
||||
r_n = CLAMP0255 (r_n);
|
||||
r_n = cbd->r_lookup[r];
|
||||
g_n = cbd->g_lookup[g];
|
||||
b_n = cbd->b_lookup[b];
|
||||
|
||||
g_n += cbd->magenta_green[SHADOWS] * magenta_green_transfer[SHADOWS][g_n];
|
||||
g_n = CLAMP0255 (g_n);
|
||||
g_n += cbd->magenta_green[MIDTONES] * magenta_green_transfer[MIDTONES][g_n];
|
||||
g_n = CLAMP0255 (g_n);
|
||||
g_n += cbd->magenta_green[HIGHLIGHTS] * magenta_green_transfer[HIGHLIGHTS][g_n];
|
||||
g_n = CLAMP0255 (g_n);
|
||||
|
||||
b_n += cbd->yellow_blue[SHADOWS] * yellow_blue_transfer[SHADOWS][b_n];
|
||||
b_n = CLAMP0255 (b_n);
|
||||
b_n += cbd->yellow_blue[MIDTONES] * yellow_blue_transfer[MIDTONES][b_n];
|
||||
b_n = CLAMP0255 (b_n);
|
||||
b_n += cbd->yellow_blue[HIGHLIGHTS] * yellow_blue_transfer[HIGHLIGHTS][b_n];
|
||||
b_n = CLAMP0255 (b_n);
|
||||
|
||||
if (cbd->preserve_luminosity)
|
||||
{
|
||||
|
@ -616,12 +590,65 @@ color_balance_update (ColorBalanceDialog *cbd,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
color_balance_create_lookup_tables (ColorBalanceDialog *cbd)
|
||||
{
|
||||
double *cyan_red_transfer[3];
|
||||
double *magenta_green_transfer[3];
|
||||
double *yellow_blue_transfer[3];
|
||||
int i, r_n, g_n, b_n;
|
||||
/* Set the transfer arrays (for speed) */
|
||||
cyan_red_transfer[SHADOWS] = (cbd->cyan_red[SHADOWS] > 0) ? shadows_add : shadows_sub;
|
||||
cyan_red_transfer[MIDTONES] = (cbd->cyan_red[MIDTONES] > 0) ? midtones_add : midtones_sub;
|
||||
cyan_red_transfer[HIGHLIGHTS] = (cbd->cyan_red[HIGHLIGHTS] > 0) ? highlights_add : highlights_sub;
|
||||
magenta_green_transfer[SHADOWS] = (cbd->magenta_green[SHADOWS] > 0) ? shadows_add : shadows_sub;
|
||||
magenta_green_transfer[MIDTONES] = (cbd->magenta_green[MIDTONES] > 0) ? midtones_add : midtones_sub;
|
||||
magenta_green_transfer[HIGHLIGHTS] = (cbd->magenta_green[HIGHLIGHTS] > 0) ? highlights_add : highlights_sub;
|
||||
yellow_blue_transfer[SHADOWS] = (cbd->yellow_blue[SHADOWS] > 0) ? shadows_add : shadows_sub;
|
||||
yellow_blue_transfer[MIDTONES] = (cbd->yellow_blue[MIDTONES] > 0) ? midtones_add : midtones_sub;
|
||||
yellow_blue_transfer[HIGHLIGHTS] = (cbd->yellow_blue[HIGHLIGHTS] > 0) ? highlights_add : highlights_sub;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
r_n = i;
|
||||
g_n = i;
|
||||
b_n = i;
|
||||
|
||||
r_n += cbd->cyan_red[SHADOWS] * cyan_red_transfer[SHADOWS][r_n];
|
||||
r_n = CLAMP0255 (r_n);
|
||||
r_n += cbd->cyan_red[MIDTONES] * cyan_red_transfer[MIDTONES][r_n];
|
||||
r_n = CLAMP0255 (r_n);
|
||||
r_n += cbd->cyan_red[HIGHLIGHTS] * cyan_red_transfer[HIGHLIGHTS][r_n];
|
||||
r_n = CLAMP0255 (r_n);
|
||||
|
||||
g_n += cbd->magenta_green[SHADOWS] * magenta_green_transfer[SHADOWS][g_n];
|
||||
g_n = CLAMP0255 (g_n);
|
||||
g_n += cbd->magenta_green[MIDTONES] * magenta_green_transfer[MIDTONES][g_n];
|
||||
g_n = CLAMP0255 (g_n);
|
||||
g_n += cbd->magenta_green[HIGHLIGHTS] * magenta_green_transfer[HIGHLIGHTS][g_n];
|
||||
g_n = CLAMP0255 (g_n);
|
||||
|
||||
b_n += cbd->yellow_blue[SHADOWS] * yellow_blue_transfer[SHADOWS][b_n];
|
||||
b_n = CLAMP0255 (b_n);
|
||||
b_n += cbd->yellow_blue[MIDTONES] * yellow_blue_transfer[MIDTONES][b_n];
|
||||
b_n = CLAMP0255 (b_n);
|
||||
b_n += cbd->yellow_blue[HIGHLIGHTS] * yellow_blue_transfer[HIGHLIGHTS][b_n];
|
||||
b_n = CLAMP0255 (b_n);
|
||||
|
||||
cbd->r_lookup[i] = r_n;
|
||||
cbd->g_lookup[i] = g_n;
|
||||
cbd->b_lookup[i] = b_n;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
color_balance_preview (ColorBalanceDialog *cbd)
|
||||
{
|
||||
if (!cbd->image_map)
|
||||
g_message (_("color_balance_preview(): No image map"));
|
||||
active_tool->preserve = TRUE;
|
||||
color_balance_create_lookup_tables(cbd);
|
||||
image_map_apply (cbd->image_map, color_balance, (void *) cbd);
|
||||
active_tool->preserve = FALSE;
|
||||
}
|
||||
|
|
|
@ -71,6 +71,10 @@ struct _ColorBalanceDialog
|
|||
double magenta_green[3];
|
||||
double yellow_blue[3];
|
||||
|
||||
char r_lookup[255];
|
||||
char g_lookup[255];
|
||||
char b_lookup[255];
|
||||
|
||||
gint preserve_luminosity;
|
||||
gint preview;
|
||||
gint application_mode;
|
||||
|
@ -122,23 +126,9 @@ color_balance (PixelRegion *srcPR,
|
|||
int r, g, b;
|
||||
int r_n, g_n, b_n;
|
||||
int w, h;
|
||||
double *cyan_red_transfer[3];
|
||||
double *magenta_green_transfer[3];
|
||||
double *yellow_blue_transfer[3];
|
||||
|
||||
cbd = (ColorBalanceDialog *) user_data;
|
||||
|
||||
/* Set the transfer arrays (for speed) */
|
||||
cyan_red_transfer[SHADOWS] = (cbd->cyan_red[SHADOWS] > 0) ? shadows_add : shadows_sub;
|
||||
cyan_red_transfer[MIDTONES] = (cbd->cyan_red[MIDTONES] > 0) ? midtones_add : midtones_sub;
|
||||
cyan_red_transfer[HIGHLIGHTS] = (cbd->cyan_red[HIGHLIGHTS] > 0) ? highlights_add : highlights_sub;
|
||||
magenta_green_transfer[SHADOWS] = (cbd->magenta_green[SHADOWS] > 0) ? shadows_add : shadows_sub;
|
||||
magenta_green_transfer[MIDTONES] = (cbd->magenta_green[MIDTONES] > 0) ? midtones_add : midtones_sub;
|
||||
magenta_green_transfer[HIGHLIGHTS] = (cbd->magenta_green[HIGHLIGHTS] > 0) ? highlights_add : highlights_sub;
|
||||
yellow_blue_transfer[SHADOWS] = (cbd->yellow_blue[SHADOWS] > 0) ? shadows_add : shadows_sub;
|
||||
yellow_blue_transfer[MIDTONES] = (cbd->yellow_blue[MIDTONES] > 0) ? midtones_add : midtones_sub;
|
||||
yellow_blue_transfer[HIGHLIGHTS] = (cbd->yellow_blue[HIGHLIGHTS] > 0) ? highlights_add : highlights_sub;
|
||||
|
||||
h = srcPR->h;
|
||||
src = srcPR->data;
|
||||
dest = destPR->data;
|
||||
|
@ -151,30 +141,14 @@ color_balance (PixelRegion *srcPR,
|
|||
d = dest;
|
||||
while (w--)
|
||||
{
|
||||
r = r_n = s[RED_PIX];
|
||||
g = g_n = s[GREEN_PIX];
|
||||
b = b_n = s[BLUE_PIX];
|
||||
r = s[RED_PIX];
|
||||
g = s[GREEN_PIX];
|
||||
b = s[BLUE_PIX];
|
||||
|
||||
r_n += cbd->cyan_red[SHADOWS] * cyan_red_transfer[SHADOWS][r_n];
|
||||
r_n = CLAMP0255 (r_n);
|
||||
r_n += cbd->cyan_red[MIDTONES] * cyan_red_transfer[MIDTONES][r_n];
|
||||
r_n = CLAMP0255 (r_n);
|
||||
r_n += cbd->cyan_red[HIGHLIGHTS] * cyan_red_transfer[HIGHLIGHTS][r_n];
|
||||
r_n = CLAMP0255 (r_n);
|
||||
r_n = cbd->r_lookup[r];
|
||||
g_n = cbd->g_lookup[g];
|
||||
b_n = cbd->b_lookup[b];
|
||||
|
||||
g_n += cbd->magenta_green[SHADOWS] * magenta_green_transfer[SHADOWS][g_n];
|
||||
g_n = CLAMP0255 (g_n);
|
||||
g_n += cbd->magenta_green[MIDTONES] * magenta_green_transfer[MIDTONES][g_n];
|
||||
g_n = CLAMP0255 (g_n);
|
||||
g_n += cbd->magenta_green[HIGHLIGHTS] * magenta_green_transfer[HIGHLIGHTS][g_n];
|
||||
g_n = CLAMP0255 (g_n);
|
||||
|
||||
b_n += cbd->yellow_blue[SHADOWS] * yellow_blue_transfer[SHADOWS][b_n];
|
||||
b_n = CLAMP0255 (b_n);
|
||||
b_n += cbd->yellow_blue[MIDTONES] * yellow_blue_transfer[MIDTONES][b_n];
|
||||
b_n = CLAMP0255 (b_n);
|
||||
b_n += cbd->yellow_blue[HIGHLIGHTS] * yellow_blue_transfer[HIGHLIGHTS][b_n];
|
||||
b_n = CLAMP0255 (b_n);
|
||||
|
||||
if (cbd->preserve_luminosity)
|
||||
{
|
||||
|
@ -616,12 +590,65 @@ color_balance_update (ColorBalanceDialog *cbd,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
color_balance_create_lookup_tables (ColorBalanceDialog *cbd)
|
||||
{
|
||||
double *cyan_red_transfer[3];
|
||||
double *magenta_green_transfer[3];
|
||||
double *yellow_blue_transfer[3];
|
||||
int i, r_n, g_n, b_n;
|
||||
/* Set the transfer arrays (for speed) */
|
||||
cyan_red_transfer[SHADOWS] = (cbd->cyan_red[SHADOWS] > 0) ? shadows_add : shadows_sub;
|
||||
cyan_red_transfer[MIDTONES] = (cbd->cyan_red[MIDTONES] > 0) ? midtones_add : midtones_sub;
|
||||
cyan_red_transfer[HIGHLIGHTS] = (cbd->cyan_red[HIGHLIGHTS] > 0) ? highlights_add : highlights_sub;
|
||||
magenta_green_transfer[SHADOWS] = (cbd->magenta_green[SHADOWS] > 0) ? shadows_add : shadows_sub;
|
||||
magenta_green_transfer[MIDTONES] = (cbd->magenta_green[MIDTONES] > 0) ? midtones_add : midtones_sub;
|
||||
magenta_green_transfer[HIGHLIGHTS] = (cbd->magenta_green[HIGHLIGHTS] > 0) ? highlights_add : highlights_sub;
|
||||
yellow_blue_transfer[SHADOWS] = (cbd->yellow_blue[SHADOWS] > 0) ? shadows_add : shadows_sub;
|
||||
yellow_blue_transfer[MIDTONES] = (cbd->yellow_blue[MIDTONES] > 0) ? midtones_add : midtones_sub;
|
||||
yellow_blue_transfer[HIGHLIGHTS] = (cbd->yellow_blue[HIGHLIGHTS] > 0) ? highlights_add : highlights_sub;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
r_n = i;
|
||||
g_n = i;
|
||||
b_n = i;
|
||||
|
||||
r_n += cbd->cyan_red[SHADOWS] * cyan_red_transfer[SHADOWS][r_n];
|
||||
r_n = CLAMP0255 (r_n);
|
||||
r_n += cbd->cyan_red[MIDTONES] * cyan_red_transfer[MIDTONES][r_n];
|
||||
r_n = CLAMP0255 (r_n);
|
||||
r_n += cbd->cyan_red[HIGHLIGHTS] * cyan_red_transfer[HIGHLIGHTS][r_n];
|
||||
r_n = CLAMP0255 (r_n);
|
||||
|
||||
g_n += cbd->magenta_green[SHADOWS] * magenta_green_transfer[SHADOWS][g_n];
|
||||
g_n = CLAMP0255 (g_n);
|
||||
g_n += cbd->magenta_green[MIDTONES] * magenta_green_transfer[MIDTONES][g_n];
|
||||
g_n = CLAMP0255 (g_n);
|
||||
g_n += cbd->magenta_green[HIGHLIGHTS] * magenta_green_transfer[HIGHLIGHTS][g_n];
|
||||
g_n = CLAMP0255 (g_n);
|
||||
|
||||
b_n += cbd->yellow_blue[SHADOWS] * yellow_blue_transfer[SHADOWS][b_n];
|
||||
b_n = CLAMP0255 (b_n);
|
||||
b_n += cbd->yellow_blue[MIDTONES] * yellow_blue_transfer[MIDTONES][b_n];
|
||||
b_n = CLAMP0255 (b_n);
|
||||
b_n += cbd->yellow_blue[HIGHLIGHTS] * yellow_blue_transfer[HIGHLIGHTS][b_n];
|
||||
b_n = CLAMP0255 (b_n);
|
||||
|
||||
cbd->r_lookup[i] = r_n;
|
||||
cbd->g_lookup[i] = g_n;
|
||||
cbd->b_lookup[i] = b_n;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
color_balance_preview (ColorBalanceDialog *cbd)
|
||||
{
|
||||
if (!cbd->image_map)
|
||||
g_message (_("color_balance_preview(): No image map"));
|
||||
active_tool->preserve = TRUE;
|
||||
color_balance_create_lookup_tables(cbd);
|
||||
image_map_apply (cbd->image_map, color_balance, (void *) cbd);
|
||||
active_tool->preserve = FALSE;
|
||||
}
|
||||
|
|
|
@ -983,12 +983,19 @@ dissolve_pixels (const unsigned char *src,
|
|||
{
|
||||
int alpha, b;
|
||||
int rand_val;
|
||||
|
||||
#ifdef ENABLE_MP
|
||||
/* if we are running with multiple threads rand_r give _much_
|
||||
better performance than rand */
|
||||
unsigned int seed;
|
||||
seed = random_table [y % RANDOM_TABLE_SIZE];
|
||||
for (b = 0; b < x; b++)
|
||||
rand_r(&seed);
|
||||
#else
|
||||
/* Set up the random number generator */
|
||||
srand (random_table [y % RANDOM_TABLE_SIZE]);
|
||||
for (b = 0; b < x; b++)
|
||||
rand ();
|
||||
|
||||
#endif
|
||||
alpha = db - 1;
|
||||
|
||||
while (length --)
|
||||
|
@ -998,8 +1005,11 @@ dissolve_pixels (const unsigned char *src,
|
|||
dest[b] = src[b];
|
||||
|
||||
/* dissolve if random value is > opacity */
|
||||
#ifdef ENABLE_MP
|
||||
rand_val = (rand_r(&seed) & 0xFF);
|
||||
#else
|
||||
rand_val = (rand() & 0xFF);
|
||||
|
||||
#endif
|
||||
if (has_alpha)
|
||||
dest[alpha] = (rand_val > src[alpha]) ? 0 : src[alpha];
|
||||
else
|
||||
|
@ -4636,54 +4646,66 @@ swap_region (PixelRegion *src,
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
apply_mask_to_sub_region (int *opacityp,
|
||||
PixelRegion *src,
|
||||
PixelRegion *mask)
|
||||
{
|
||||
int h;
|
||||
unsigned char * s, * m;
|
||||
int opacity = *opacityp;
|
||||
|
||||
s = src->data;
|
||||
m = mask->data;
|
||||
h = src->h;
|
||||
|
||||
while (h --)
|
||||
{
|
||||
apply_mask_to_alpha_channel (s, m, opacity, src->w, src->bytes);
|
||||
s += src->rowstride;
|
||||
m += mask->rowstride;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
apply_mask_to_region (PixelRegion *src,
|
||||
PixelRegion *mask,
|
||||
int opacity)
|
||||
{
|
||||
int h;
|
||||
unsigned char * s, * m;
|
||||
void * pr;
|
||||
|
||||
for (pr = pixel_regions_register (2, src, mask); pr != NULL; pr = pixel_regions_process (pr))
|
||||
{
|
||||
s = src->data;
|
||||
m = mask->data;
|
||||
h = src->h;
|
||||
|
||||
while (h --)
|
||||
{
|
||||
apply_mask_to_alpha_channel (s, m, opacity, src->w, src->bytes);
|
||||
s += src->rowstride;
|
||||
m += mask->rowstride;
|
||||
}
|
||||
}
|
||||
pixel_regions_process_parallel ((p_func)apply_mask_to_sub_region,
|
||||
&opacity, 2, src, mask);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
combine_mask_and_sub_region (int *opacityp,
|
||||
PixelRegion *src,
|
||||
PixelRegion *mask)
|
||||
{
|
||||
int h;
|
||||
unsigned char * s, * m;
|
||||
int opacity = *opacityp;
|
||||
|
||||
s = src->data;
|
||||
m = mask->data;
|
||||
h = src->h;
|
||||
|
||||
while (h --)
|
||||
{
|
||||
combine_mask_and_alpha_channel (s, m, opacity, src->w, src->bytes);
|
||||
s += src->rowstride;
|
||||
m += mask->rowstride;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
combine_mask_and_region (PixelRegion *src,
|
||||
PixelRegion *mask,
|
||||
int opacity)
|
||||
{
|
||||
int h;
|
||||
unsigned char * s, * m;
|
||||
void * pr;
|
||||
|
||||
for (pr = pixel_regions_register (2, src, mask); pr != NULL; pr = pixel_regions_process (pr))
|
||||
{
|
||||
s = src->data;
|
||||
s = src->data;
|
||||
m = mask->data;
|
||||
h = src->h;
|
||||
|
||||
while (h --)
|
||||
{
|
||||
combine_mask_and_alpha_channel (s, m, opacity, src->w, src->bytes);
|
||||
s += src->rowstride;
|
||||
m += mask->rowstride;
|
||||
}
|
||||
}
|
||||
pixel_regions_process_parallel ((p_func)combine_mask_and_sub_region,
|
||||
&opacity, 2, src, mask);
|
||||
}
|
||||
|
||||
|
||||
|
@ -4711,6 +4733,93 @@ copy_gray_to_region (PixelRegion *src,
|
|||
}
|
||||
|
||||
|
||||
struct initial_regions_struct
|
||||
{
|
||||
int opacity;
|
||||
int mode;
|
||||
int *affect;
|
||||
int type;
|
||||
unsigned char *data;
|
||||
};
|
||||
|
||||
void
|
||||
initial_sub_region(struct initial_regions_struct *st,
|
||||
PixelRegion *src,
|
||||
PixelRegion *dest,
|
||||
PixelRegion *mask)
|
||||
{
|
||||
int h;
|
||||
unsigned char * s, * d, * m;
|
||||
unsigned char buf[512];
|
||||
unsigned char *data;
|
||||
int opacity;
|
||||
int mode;
|
||||
int *affect;
|
||||
int type;
|
||||
|
||||
data = st->data;
|
||||
opacity = st->opacity;
|
||||
mode = st->mode;
|
||||
affect = st->affect;
|
||||
type = st->type;
|
||||
|
||||
if (src->w * (src->bytes + 1) > 512)
|
||||
fprintf(stderr, "initial_sub_region:: error :: src->w * (src->bytes + 1) > 512");
|
||||
|
||||
s = src->data;
|
||||
d = dest->data;
|
||||
m = (mask) ? mask->data : NULL;
|
||||
|
||||
for (h = 0; h < src->h; h++)
|
||||
{
|
||||
/* based on the type of the initial image... */
|
||||
switch (type)
|
||||
{
|
||||
case INITIAL_CHANNEL_MASK:
|
||||
case INITIAL_CHANNEL_SELECTION:
|
||||
initial_channel_pixels (s, d, src->w, dest->bytes);
|
||||
break;
|
||||
|
||||
case INITIAL_INDEXED:
|
||||
initial_indexed_pixels (s, d, data, src->w);
|
||||
break;
|
||||
|
||||
case INITIAL_INDEXED_ALPHA:
|
||||
initial_indexed_a_pixels (s, d, m, data, opacity, src->w);
|
||||
break;
|
||||
|
||||
case INITIAL_INTENSITY:
|
||||
if (mode == DISSOLVE_MODE)
|
||||
{
|
||||
dissolve_pixels (s, buf, src->x, src->y + h, opacity, src->w, src->bytes,
|
||||
src->bytes + 1, 0);
|
||||
initial_inten_pixels (buf, d, m, opacity, affect,
|
||||
src->w, src->bytes);
|
||||
}
|
||||
else
|
||||
initial_inten_pixels (s, d, m, opacity, affect, src->w, src->bytes);
|
||||
break;
|
||||
|
||||
case INITIAL_INTENSITY_ALPHA:
|
||||
if (mode == DISSOLVE_MODE)
|
||||
{
|
||||
dissolve_pixels (s, buf, src->x, src->y + h, opacity, src->w, src->bytes,
|
||||
src->bytes, 1);
|
||||
initial_inten_a_pixels (buf, d, m, opacity, affect,
|
||||
src->w, src->bytes);
|
||||
}
|
||||
else
|
||||
initial_inten_a_pixels (s, d, m, opacity, affect, src->w, src->bytes);
|
||||
break;
|
||||
}
|
||||
|
||||
s += src->rowstride;
|
||||
d += dest->rowstride;
|
||||
if (mask)
|
||||
m += mask->rowstride;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
initial_region (PixelRegion *src,
|
||||
PixelRegion *dest,
|
||||
|
@ -4721,68 +4830,16 @@ initial_region (PixelRegion *src,
|
|||
int *affect,
|
||||
int type)
|
||||
{
|
||||
int h;
|
||||
unsigned char * s, * d, * m;
|
||||
unsigned char * buf;
|
||||
void * pr;
|
||||
struct initial_regions_struct st;
|
||||
|
||||
buf = paint_funcs_get_buffer (src->w * (src->bytes + 1));
|
||||
|
||||
for (pr = pixel_regions_register (3, src, dest, mask); pr != NULL; pr = pixel_regions_process (pr))
|
||||
{
|
||||
s = src->data;
|
||||
d = dest->data;
|
||||
m = (mask) ? mask->data : NULL;
|
||||
|
||||
for (h = 0; h < src->h; h++)
|
||||
{
|
||||
/* based on the type of the initial image... */
|
||||
switch (type)
|
||||
{
|
||||
case INITIAL_CHANNEL_MASK:
|
||||
case INITIAL_CHANNEL_SELECTION:
|
||||
initial_channel_pixels (s, d, src->w, dest->bytes);
|
||||
break;
|
||||
|
||||
case INITIAL_INDEXED:
|
||||
initial_indexed_pixels (s, d, data, src->w);
|
||||
break;
|
||||
|
||||
case INITIAL_INDEXED_ALPHA:
|
||||
initial_indexed_a_pixels (s, d, m, data, opacity, src->w);
|
||||
break;
|
||||
|
||||
case INITIAL_INTENSITY:
|
||||
if (mode == DISSOLVE_MODE)
|
||||
{
|
||||
dissolve_pixels (s, buf, src->x, src->y + h, opacity, src->w, src->bytes,
|
||||
src->bytes + 1, 0);
|
||||
initial_inten_pixels (buf, d, m, opacity, affect,
|
||||
src->w, src->bytes);
|
||||
}
|
||||
else
|
||||
initial_inten_pixels (s, d, m, opacity, affect, src->w, src->bytes);
|
||||
break;
|
||||
|
||||
case INITIAL_INTENSITY_ALPHA:
|
||||
if (mode == DISSOLVE_MODE)
|
||||
{
|
||||
dissolve_pixels (s, buf, src->x, src->y + h, opacity, src->w, src->bytes,
|
||||
src->bytes, 1);
|
||||
initial_inten_a_pixels (buf, d, m, opacity, affect,
|
||||
src->w, src->bytes);
|
||||
}
|
||||
else
|
||||
initial_inten_a_pixels (s, d, m, opacity, affect, src->w, src->bytes);
|
||||
break;
|
||||
}
|
||||
|
||||
s += src->rowstride;
|
||||
d += dest->rowstride;
|
||||
if (mask)
|
||||
m += mask->rowstride;
|
||||
}
|
||||
}
|
||||
st.opacity = opacity;
|
||||
st.mode = mode;
|
||||
st.affect = affect;
|
||||
st.type = type;
|
||||
st.data = data;
|
||||
|
||||
pixel_regions_process_parallel ((p_func)initial_sub_region, &st, 3,
|
||||
src, dest, mask);
|
||||
}
|
||||
|
||||
struct combine_regions_struct
|
||||
|
@ -4815,9 +4872,6 @@ combine_sub_region(struct combine_regions_struct *st,
|
|||
unsigned char * d, * m;
|
||||
unsigned char buf[512];
|
||||
|
||||
/* fprintf (stderr, "combine_whack_region: %p, %p, %p, %p, %p, %p\n", */
|
||||
/* (p4_func)combine_whack_region, */
|
||||
/* &st, src1, src2, dest, mask); */
|
||||
opacity = st->opacity;
|
||||
mode = st->mode;
|
||||
affect = st->affect;
|
||||
|
|
|
@ -983,12 +983,19 @@ dissolve_pixels (const unsigned char *src,
|
|||
{
|
||||
int alpha, b;
|
||||
int rand_val;
|
||||
|
||||
#ifdef ENABLE_MP
|
||||
/* if we are running with multiple threads rand_r give _much_
|
||||
better performance than rand */
|
||||
unsigned int seed;
|
||||
seed = random_table [y % RANDOM_TABLE_SIZE];
|
||||
for (b = 0; b < x; b++)
|
||||
rand_r(&seed);
|
||||
#else
|
||||
/* Set up the random number generator */
|
||||
srand (random_table [y % RANDOM_TABLE_SIZE]);
|
||||
for (b = 0; b < x; b++)
|
||||
rand ();
|
||||
|
||||
#endif
|
||||
alpha = db - 1;
|
||||
|
||||
while (length --)
|
||||
|
@ -998,8 +1005,11 @@ dissolve_pixels (const unsigned char *src,
|
|||
dest[b] = src[b];
|
||||
|
||||
/* dissolve if random value is > opacity */
|
||||
#ifdef ENABLE_MP
|
||||
rand_val = (rand_r(&seed) & 0xFF);
|
||||
#else
|
||||
rand_val = (rand() & 0xFF);
|
||||
|
||||
#endif
|
||||
if (has_alpha)
|
||||
dest[alpha] = (rand_val > src[alpha]) ? 0 : src[alpha];
|
||||
else
|
||||
|
@ -4636,54 +4646,66 @@ swap_region (PixelRegion *src,
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
apply_mask_to_sub_region (int *opacityp,
|
||||
PixelRegion *src,
|
||||
PixelRegion *mask)
|
||||
{
|
||||
int h;
|
||||
unsigned char * s, * m;
|
||||
int opacity = *opacityp;
|
||||
|
||||
s = src->data;
|
||||
m = mask->data;
|
||||
h = src->h;
|
||||
|
||||
while (h --)
|
||||
{
|
||||
apply_mask_to_alpha_channel (s, m, opacity, src->w, src->bytes);
|
||||
s += src->rowstride;
|
||||
m += mask->rowstride;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
apply_mask_to_region (PixelRegion *src,
|
||||
PixelRegion *mask,
|
||||
int opacity)
|
||||
{
|
||||
int h;
|
||||
unsigned char * s, * m;
|
||||
void * pr;
|
||||
|
||||
for (pr = pixel_regions_register (2, src, mask); pr != NULL; pr = pixel_regions_process (pr))
|
||||
{
|
||||
s = src->data;
|
||||
m = mask->data;
|
||||
h = src->h;
|
||||
|
||||
while (h --)
|
||||
{
|
||||
apply_mask_to_alpha_channel (s, m, opacity, src->w, src->bytes);
|
||||
s += src->rowstride;
|
||||
m += mask->rowstride;
|
||||
}
|
||||
}
|
||||
pixel_regions_process_parallel ((p_func)apply_mask_to_sub_region,
|
||||
&opacity, 2, src, mask);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
combine_mask_and_sub_region (int *opacityp,
|
||||
PixelRegion *src,
|
||||
PixelRegion *mask)
|
||||
{
|
||||
int h;
|
||||
unsigned char * s, * m;
|
||||
int opacity = *opacityp;
|
||||
|
||||
s = src->data;
|
||||
m = mask->data;
|
||||
h = src->h;
|
||||
|
||||
while (h --)
|
||||
{
|
||||
combine_mask_and_alpha_channel (s, m, opacity, src->w, src->bytes);
|
||||
s += src->rowstride;
|
||||
m += mask->rowstride;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
combine_mask_and_region (PixelRegion *src,
|
||||
PixelRegion *mask,
|
||||
int opacity)
|
||||
{
|
||||
int h;
|
||||
unsigned char * s, * m;
|
||||
void * pr;
|
||||
|
||||
for (pr = pixel_regions_register (2, src, mask); pr != NULL; pr = pixel_regions_process (pr))
|
||||
{
|
||||
s = src->data;
|
||||
s = src->data;
|
||||
m = mask->data;
|
||||
h = src->h;
|
||||
|
||||
while (h --)
|
||||
{
|
||||
combine_mask_and_alpha_channel (s, m, opacity, src->w, src->bytes);
|
||||
s += src->rowstride;
|
||||
m += mask->rowstride;
|
||||
}
|
||||
}
|
||||
pixel_regions_process_parallel ((p_func)combine_mask_and_sub_region,
|
||||
&opacity, 2, src, mask);
|
||||
}
|
||||
|
||||
|
||||
|
@ -4711,6 +4733,93 @@ copy_gray_to_region (PixelRegion *src,
|
|||
}
|
||||
|
||||
|
||||
struct initial_regions_struct
|
||||
{
|
||||
int opacity;
|
||||
int mode;
|
||||
int *affect;
|
||||
int type;
|
||||
unsigned char *data;
|
||||
};
|
||||
|
||||
void
|
||||
initial_sub_region(struct initial_regions_struct *st,
|
||||
PixelRegion *src,
|
||||
PixelRegion *dest,
|
||||
PixelRegion *mask)
|
||||
{
|
||||
int h;
|
||||
unsigned char * s, * d, * m;
|
||||
unsigned char buf[512];
|
||||
unsigned char *data;
|
||||
int opacity;
|
||||
int mode;
|
||||
int *affect;
|
||||
int type;
|
||||
|
||||
data = st->data;
|
||||
opacity = st->opacity;
|
||||
mode = st->mode;
|
||||
affect = st->affect;
|
||||
type = st->type;
|
||||
|
||||
if (src->w * (src->bytes + 1) > 512)
|
||||
fprintf(stderr, "initial_sub_region:: error :: src->w * (src->bytes + 1) > 512");
|
||||
|
||||
s = src->data;
|
||||
d = dest->data;
|
||||
m = (mask) ? mask->data : NULL;
|
||||
|
||||
for (h = 0; h < src->h; h++)
|
||||
{
|
||||
/* based on the type of the initial image... */
|
||||
switch (type)
|
||||
{
|
||||
case INITIAL_CHANNEL_MASK:
|
||||
case INITIAL_CHANNEL_SELECTION:
|
||||
initial_channel_pixels (s, d, src->w, dest->bytes);
|
||||
break;
|
||||
|
||||
case INITIAL_INDEXED:
|
||||
initial_indexed_pixels (s, d, data, src->w);
|
||||
break;
|
||||
|
||||
case INITIAL_INDEXED_ALPHA:
|
||||
initial_indexed_a_pixels (s, d, m, data, opacity, src->w);
|
||||
break;
|
||||
|
||||
case INITIAL_INTENSITY:
|
||||
if (mode == DISSOLVE_MODE)
|
||||
{
|
||||
dissolve_pixels (s, buf, src->x, src->y + h, opacity, src->w, src->bytes,
|
||||
src->bytes + 1, 0);
|
||||
initial_inten_pixels (buf, d, m, opacity, affect,
|
||||
src->w, src->bytes);
|
||||
}
|
||||
else
|
||||
initial_inten_pixels (s, d, m, opacity, affect, src->w, src->bytes);
|
||||
break;
|
||||
|
||||
case INITIAL_INTENSITY_ALPHA:
|
||||
if (mode == DISSOLVE_MODE)
|
||||
{
|
||||
dissolve_pixels (s, buf, src->x, src->y + h, opacity, src->w, src->bytes,
|
||||
src->bytes, 1);
|
||||
initial_inten_a_pixels (buf, d, m, opacity, affect,
|
||||
src->w, src->bytes);
|
||||
}
|
||||
else
|
||||
initial_inten_a_pixels (s, d, m, opacity, affect, src->w, src->bytes);
|
||||
break;
|
||||
}
|
||||
|
||||
s += src->rowstride;
|
||||
d += dest->rowstride;
|
||||
if (mask)
|
||||
m += mask->rowstride;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
initial_region (PixelRegion *src,
|
||||
PixelRegion *dest,
|
||||
|
@ -4721,68 +4830,16 @@ initial_region (PixelRegion *src,
|
|||
int *affect,
|
||||
int type)
|
||||
{
|
||||
int h;
|
||||
unsigned char * s, * d, * m;
|
||||
unsigned char * buf;
|
||||
void * pr;
|
||||
struct initial_regions_struct st;
|
||||
|
||||
buf = paint_funcs_get_buffer (src->w * (src->bytes + 1));
|
||||
|
||||
for (pr = pixel_regions_register (3, src, dest, mask); pr != NULL; pr = pixel_regions_process (pr))
|
||||
{
|
||||
s = src->data;
|
||||
d = dest->data;
|
||||
m = (mask) ? mask->data : NULL;
|
||||
|
||||
for (h = 0; h < src->h; h++)
|
||||
{
|
||||
/* based on the type of the initial image... */
|
||||
switch (type)
|
||||
{
|
||||
case INITIAL_CHANNEL_MASK:
|
||||
case INITIAL_CHANNEL_SELECTION:
|
||||
initial_channel_pixels (s, d, src->w, dest->bytes);
|
||||
break;
|
||||
|
||||
case INITIAL_INDEXED:
|
||||
initial_indexed_pixels (s, d, data, src->w);
|
||||
break;
|
||||
|
||||
case INITIAL_INDEXED_ALPHA:
|
||||
initial_indexed_a_pixels (s, d, m, data, opacity, src->w);
|
||||
break;
|
||||
|
||||
case INITIAL_INTENSITY:
|
||||
if (mode == DISSOLVE_MODE)
|
||||
{
|
||||
dissolve_pixels (s, buf, src->x, src->y + h, opacity, src->w, src->bytes,
|
||||
src->bytes + 1, 0);
|
||||
initial_inten_pixels (buf, d, m, opacity, affect,
|
||||
src->w, src->bytes);
|
||||
}
|
||||
else
|
||||
initial_inten_pixels (s, d, m, opacity, affect, src->w, src->bytes);
|
||||
break;
|
||||
|
||||
case INITIAL_INTENSITY_ALPHA:
|
||||
if (mode == DISSOLVE_MODE)
|
||||
{
|
||||
dissolve_pixels (s, buf, src->x, src->y + h, opacity, src->w, src->bytes,
|
||||
src->bytes, 1);
|
||||
initial_inten_a_pixels (buf, d, m, opacity, affect,
|
||||
src->w, src->bytes);
|
||||
}
|
||||
else
|
||||
initial_inten_a_pixels (s, d, m, opacity, affect, src->w, src->bytes);
|
||||
break;
|
||||
}
|
||||
|
||||
s += src->rowstride;
|
||||
d += dest->rowstride;
|
||||
if (mask)
|
||||
m += mask->rowstride;
|
||||
}
|
||||
}
|
||||
st.opacity = opacity;
|
||||
st.mode = mode;
|
||||
st.affect = affect;
|
||||
st.type = type;
|
||||
st.data = data;
|
||||
|
||||
pixel_regions_process_parallel ((p_func)initial_sub_region, &st, 3,
|
||||
src, dest, mask);
|
||||
}
|
||||
|
||||
struct combine_regions_struct
|
||||
|
@ -4815,9 +4872,6 @@ combine_sub_region(struct combine_regions_struct *st,
|
|||
unsigned char * d, * m;
|
||||
unsigned char buf[512];
|
||||
|
||||
/* fprintf (stderr, "combine_whack_region: %p, %p, %p, %p, %p, %p\n", */
|
||||
/* (p4_func)combine_whack_region, */
|
||||
/* &st, src1, src2, dest, mask); */
|
||||
opacity = st->opacity;
|
||||
mode = st->mode;
|
||||
affect = st->affect;
|
||||
|
|
|
@ -71,6 +71,10 @@ struct _ColorBalanceDialog
|
|||
double magenta_green[3];
|
||||
double yellow_blue[3];
|
||||
|
||||
char r_lookup[255];
|
||||
char g_lookup[255];
|
||||
char b_lookup[255];
|
||||
|
||||
gint preserve_luminosity;
|
||||
gint preview;
|
||||
gint application_mode;
|
||||
|
@ -122,23 +126,9 @@ color_balance (PixelRegion *srcPR,
|
|||
int r, g, b;
|
||||
int r_n, g_n, b_n;
|
||||
int w, h;
|
||||
double *cyan_red_transfer[3];
|
||||
double *magenta_green_transfer[3];
|
||||
double *yellow_blue_transfer[3];
|
||||
|
||||
cbd = (ColorBalanceDialog *) user_data;
|
||||
|
||||
/* Set the transfer arrays (for speed) */
|
||||
cyan_red_transfer[SHADOWS] = (cbd->cyan_red[SHADOWS] > 0) ? shadows_add : shadows_sub;
|
||||
cyan_red_transfer[MIDTONES] = (cbd->cyan_red[MIDTONES] > 0) ? midtones_add : midtones_sub;
|
||||
cyan_red_transfer[HIGHLIGHTS] = (cbd->cyan_red[HIGHLIGHTS] > 0) ? highlights_add : highlights_sub;
|
||||
magenta_green_transfer[SHADOWS] = (cbd->magenta_green[SHADOWS] > 0) ? shadows_add : shadows_sub;
|
||||
magenta_green_transfer[MIDTONES] = (cbd->magenta_green[MIDTONES] > 0) ? midtones_add : midtones_sub;
|
||||
magenta_green_transfer[HIGHLIGHTS] = (cbd->magenta_green[HIGHLIGHTS] > 0) ? highlights_add : highlights_sub;
|
||||
yellow_blue_transfer[SHADOWS] = (cbd->yellow_blue[SHADOWS] > 0) ? shadows_add : shadows_sub;
|
||||
yellow_blue_transfer[MIDTONES] = (cbd->yellow_blue[MIDTONES] > 0) ? midtones_add : midtones_sub;
|
||||
yellow_blue_transfer[HIGHLIGHTS] = (cbd->yellow_blue[HIGHLIGHTS] > 0) ? highlights_add : highlights_sub;
|
||||
|
||||
h = srcPR->h;
|
||||
src = srcPR->data;
|
||||
dest = destPR->data;
|
||||
|
@ -151,30 +141,14 @@ color_balance (PixelRegion *srcPR,
|
|||
d = dest;
|
||||
while (w--)
|
||||
{
|
||||
r = r_n = s[RED_PIX];
|
||||
g = g_n = s[GREEN_PIX];
|
||||
b = b_n = s[BLUE_PIX];
|
||||
r = s[RED_PIX];
|
||||
g = s[GREEN_PIX];
|
||||
b = s[BLUE_PIX];
|
||||
|
||||
r_n += cbd->cyan_red[SHADOWS] * cyan_red_transfer[SHADOWS][r_n];
|
||||
r_n = CLAMP0255 (r_n);
|
||||
r_n += cbd->cyan_red[MIDTONES] * cyan_red_transfer[MIDTONES][r_n];
|
||||
r_n = CLAMP0255 (r_n);
|
||||
r_n += cbd->cyan_red[HIGHLIGHTS] * cyan_red_transfer[HIGHLIGHTS][r_n];
|
||||
r_n = CLAMP0255 (r_n);
|
||||
r_n = cbd->r_lookup[r];
|
||||
g_n = cbd->g_lookup[g];
|
||||
b_n = cbd->b_lookup[b];
|
||||
|
||||
g_n += cbd->magenta_green[SHADOWS] * magenta_green_transfer[SHADOWS][g_n];
|
||||
g_n = CLAMP0255 (g_n);
|
||||
g_n += cbd->magenta_green[MIDTONES] * magenta_green_transfer[MIDTONES][g_n];
|
||||
g_n = CLAMP0255 (g_n);
|
||||
g_n += cbd->magenta_green[HIGHLIGHTS] * magenta_green_transfer[HIGHLIGHTS][g_n];
|
||||
g_n = CLAMP0255 (g_n);
|
||||
|
||||
b_n += cbd->yellow_blue[SHADOWS] * yellow_blue_transfer[SHADOWS][b_n];
|
||||
b_n = CLAMP0255 (b_n);
|
||||
b_n += cbd->yellow_blue[MIDTONES] * yellow_blue_transfer[MIDTONES][b_n];
|
||||
b_n = CLAMP0255 (b_n);
|
||||
b_n += cbd->yellow_blue[HIGHLIGHTS] * yellow_blue_transfer[HIGHLIGHTS][b_n];
|
||||
b_n = CLAMP0255 (b_n);
|
||||
|
||||
if (cbd->preserve_luminosity)
|
||||
{
|
||||
|
@ -616,12 +590,65 @@ color_balance_update (ColorBalanceDialog *cbd,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
color_balance_create_lookup_tables (ColorBalanceDialog *cbd)
|
||||
{
|
||||
double *cyan_red_transfer[3];
|
||||
double *magenta_green_transfer[3];
|
||||
double *yellow_blue_transfer[3];
|
||||
int i, r_n, g_n, b_n;
|
||||
/* Set the transfer arrays (for speed) */
|
||||
cyan_red_transfer[SHADOWS] = (cbd->cyan_red[SHADOWS] > 0) ? shadows_add : shadows_sub;
|
||||
cyan_red_transfer[MIDTONES] = (cbd->cyan_red[MIDTONES] > 0) ? midtones_add : midtones_sub;
|
||||
cyan_red_transfer[HIGHLIGHTS] = (cbd->cyan_red[HIGHLIGHTS] > 0) ? highlights_add : highlights_sub;
|
||||
magenta_green_transfer[SHADOWS] = (cbd->magenta_green[SHADOWS] > 0) ? shadows_add : shadows_sub;
|
||||
magenta_green_transfer[MIDTONES] = (cbd->magenta_green[MIDTONES] > 0) ? midtones_add : midtones_sub;
|
||||
magenta_green_transfer[HIGHLIGHTS] = (cbd->magenta_green[HIGHLIGHTS] > 0) ? highlights_add : highlights_sub;
|
||||
yellow_blue_transfer[SHADOWS] = (cbd->yellow_blue[SHADOWS] > 0) ? shadows_add : shadows_sub;
|
||||
yellow_blue_transfer[MIDTONES] = (cbd->yellow_blue[MIDTONES] > 0) ? midtones_add : midtones_sub;
|
||||
yellow_blue_transfer[HIGHLIGHTS] = (cbd->yellow_blue[HIGHLIGHTS] > 0) ? highlights_add : highlights_sub;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
r_n = i;
|
||||
g_n = i;
|
||||
b_n = i;
|
||||
|
||||
r_n += cbd->cyan_red[SHADOWS] * cyan_red_transfer[SHADOWS][r_n];
|
||||
r_n = CLAMP0255 (r_n);
|
||||
r_n += cbd->cyan_red[MIDTONES] * cyan_red_transfer[MIDTONES][r_n];
|
||||
r_n = CLAMP0255 (r_n);
|
||||
r_n += cbd->cyan_red[HIGHLIGHTS] * cyan_red_transfer[HIGHLIGHTS][r_n];
|
||||
r_n = CLAMP0255 (r_n);
|
||||
|
||||
g_n += cbd->magenta_green[SHADOWS] * magenta_green_transfer[SHADOWS][g_n];
|
||||
g_n = CLAMP0255 (g_n);
|
||||
g_n += cbd->magenta_green[MIDTONES] * magenta_green_transfer[MIDTONES][g_n];
|
||||
g_n = CLAMP0255 (g_n);
|
||||
g_n += cbd->magenta_green[HIGHLIGHTS] * magenta_green_transfer[HIGHLIGHTS][g_n];
|
||||
g_n = CLAMP0255 (g_n);
|
||||
|
||||
b_n += cbd->yellow_blue[SHADOWS] * yellow_blue_transfer[SHADOWS][b_n];
|
||||
b_n = CLAMP0255 (b_n);
|
||||
b_n += cbd->yellow_blue[MIDTONES] * yellow_blue_transfer[MIDTONES][b_n];
|
||||
b_n = CLAMP0255 (b_n);
|
||||
b_n += cbd->yellow_blue[HIGHLIGHTS] * yellow_blue_transfer[HIGHLIGHTS][b_n];
|
||||
b_n = CLAMP0255 (b_n);
|
||||
|
||||
cbd->r_lookup[i] = r_n;
|
||||
cbd->g_lookup[i] = g_n;
|
||||
cbd->b_lookup[i] = b_n;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
color_balance_preview (ColorBalanceDialog *cbd)
|
||||
{
|
||||
if (!cbd->image_map)
|
||||
g_message (_("color_balance_preview(): No image map"));
|
||||
active_tool->preserve = TRUE;
|
||||
color_balance_create_lookup_tables(cbd);
|
||||
image_map_apply (cbd->image_map, color_balance, (void *) cbd);
|
||||
active_tool->preserve = FALSE;
|
||||
}
|
||||
|
|
|
@ -71,6 +71,10 @@ struct _ColorBalanceDialog
|
|||
double magenta_green[3];
|
||||
double yellow_blue[3];
|
||||
|
||||
char r_lookup[255];
|
||||
char g_lookup[255];
|
||||
char b_lookup[255];
|
||||
|
||||
gint preserve_luminosity;
|
||||
gint preview;
|
||||
gint application_mode;
|
||||
|
@ -122,23 +126,9 @@ color_balance (PixelRegion *srcPR,
|
|||
int r, g, b;
|
||||
int r_n, g_n, b_n;
|
||||
int w, h;
|
||||
double *cyan_red_transfer[3];
|
||||
double *magenta_green_transfer[3];
|
||||
double *yellow_blue_transfer[3];
|
||||
|
||||
cbd = (ColorBalanceDialog *) user_data;
|
||||
|
||||
/* Set the transfer arrays (for speed) */
|
||||
cyan_red_transfer[SHADOWS] = (cbd->cyan_red[SHADOWS] > 0) ? shadows_add : shadows_sub;
|
||||
cyan_red_transfer[MIDTONES] = (cbd->cyan_red[MIDTONES] > 0) ? midtones_add : midtones_sub;
|
||||
cyan_red_transfer[HIGHLIGHTS] = (cbd->cyan_red[HIGHLIGHTS] > 0) ? highlights_add : highlights_sub;
|
||||
magenta_green_transfer[SHADOWS] = (cbd->magenta_green[SHADOWS] > 0) ? shadows_add : shadows_sub;
|
||||
magenta_green_transfer[MIDTONES] = (cbd->magenta_green[MIDTONES] > 0) ? midtones_add : midtones_sub;
|
||||
magenta_green_transfer[HIGHLIGHTS] = (cbd->magenta_green[HIGHLIGHTS] > 0) ? highlights_add : highlights_sub;
|
||||
yellow_blue_transfer[SHADOWS] = (cbd->yellow_blue[SHADOWS] > 0) ? shadows_add : shadows_sub;
|
||||
yellow_blue_transfer[MIDTONES] = (cbd->yellow_blue[MIDTONES] > 0) ? midtones_add : midtones_sub;
|
||||
yellow_blue_transfer[HIGHLIGHTS] = (cbd->yellow_blue[HIGHLIGHTS] > 0) ? highlights_add : highlights_sub;
|
||||
|
||||
h = srcPR->h;
|
||||
src = srcPR->data;
|
||||
dest = destPR->data;
|
||||
|
@ -151,30 +141,14 @@ color_balance (PixelRegion *srcPR,
|
|||
d = dest;
|
||||
while (w--)
|
||||
{
|
||||
r = r_n = s[RED_PIX];
|
||||
g = g_n = s[GREEN_PIX];
|
||||
b = b_n = s[BLUE_PIX];
|
||||
r = s[RED_PIX];
|
||||
g = s[GREEN_PIX];
|
||||
b = s[BLUE_PIX];
|
||||
|
||||
r_n += cbd->cyan_red[SHADOWS] * cyan_red_transfer[SHADOWS][r_n];
|
||||
r_n = CLAMP0255 (r_n);
|
||||
r_n += cbd->cyan_red[MIDTONES] * cyan_red_transfer[MIDTONES][r_n];
|
||||
r_n = CLAMP0255 (r_n);
|
||||
r_n += cbd->cyan_red[HIGHLIGHTS] * cyan_red_transfer[HIGHLIGHTS][r_n];
|
||||
r_n = CLAMP0255 (r_n);
|
||||
r_n = cbd->r_lookup[r];
|
||||
g_n = cbd->g_lookup[g];
|
||||
b_n = cbd->b_lookup[b];
|
||||
|
||||
g_n += cbd->magenta_green[SHADOWS] * magenta_green_transfer[SHADOWS][g_n];
|
||||
g_n = CLAMP0255 (g_n);
|
||||
g_n += cbd->magenta_green[MIDTONES] * magenta_green_transfer[MIDTONES][g_n];
|
||||
g_n = CLAMP0255 (g_n);
|
||||
g_n += cbd->magenta_green[HIGHLIGHTS] * magenta_green_transfer[HIGHLIGHTS][g_n];
|
||||
g_n = CLAMP0255 (g_n);
|
||||
|
||||
b_n += cbd->yellow_blue[SHADOWS] * yellow_blue_transfer[SHADOWS][b_n];
|
||||
b_n = CLAMP0255 (b_n);
|
||||
b_n += cbd->yellow_blue[MIDTONES] * yellow_blue_transfer[MIDTONES][b_n];
|
||||
b_n = CLAMP0255 (b_n);
|
||||
b_n += cbd->yellow_blue[HIGHLIGHTS] * yellow_blue_transfer[HIGHLIGHTS][b_n];
|
||||
b_n = CLAMP0255 (b_n);
|
||||
|
||||
if (cbd->preserve_luminosity)
|
||||
{
|
||||
|
@ -616,12 +590,65 @@ color_balance_update (ColorBalanceDialog *cbd,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
color_balance_create_lookup_tables (ColorBalanceDialog *cbd)
|
||||
{
|
||||
double *cyan_red_transfer[3];
|
||||
double *magenta_green_transfer[3];
|
||||
double *yellow_blue_transfer[3];
|
||||
int i, r_n, g_n, b_n;
|
||||
/* Set the transfer arrays (for speed) */
|
||||
cyan_red_transfer[SHADOWS] = (cbd->cyan_red[SHADOWS] > 0) ? shadows_add : shadows_sub;
|
||||
cyan_red_transfer[MIDTONES] = (cbd->cyan_red[MIDTONES] > 0) ? midtones_add : midtones_sub;
|
||||
cyan_red_transfer[HIGHLIGHTS] = (cbd->cyan_red[HIGHLIGHTS] > 0) ? highlights_add : highlights_sub;
|
||||
magenta_green_transfer[SHADOWS] = (cbd->magenta_green[SHADOWS] > 0) ? shadows_add : shadows_sub;
|
||||
magenta_green_transfer[MIDTONES] = (cbd->magenta_green[MIDTONES] > 0) ? midtones_add : midtones_sub;
|
||||
magenta_green_transfer[HIGHLIGHTS] = (cbd->magenta_green[HIGHLIGHTS] > 0) ? highlights_add : highlights_sub;
|
||||
yellow_blue_transfer[SHADOWS] = (cbd->yellow_blue[SHADOWS] > 0) ? shadows_add : shadows_sub;
|
||||
yellow_blue_transfer[MIDTONES] = (cbd->yellow_blue[MIDTONES] > 0) ? midtones_add : midtones_sub;
|
||||
yellow_blue_transfer[HIGHLIGHTS] = (cbd->yellow_blue[HIGHLIGHTS] > 0) ? highlights_add : highlights_sub;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
r_n = i;
|
||||
g_n = i;
|
||||
b_n = i;
|
||||
|
||||
r_n += cbd->cyan_red[SHADOWS] * cyan_red_transfer[SHADOWS][r_n];
|
||||
r_n = CLAMP0255 (r_n);
|
||||
r_n += cbd->cyan_red[MIDTONES] * cyan_red_transfer[MIDTONES][r_n];
|
||||
r_n = CLAMP0255 (r_n);
|
||||
r_n += cbd->cyan_red[HIGHLIGHTS] * cyan_red_transfer[HIGHLIGHTS][r_n];
|
||||
r_n = CLAMP0255 (r_n);
|
||||
|
||||
g_n += cbd->magenta_green[SHADOWS] * magenta_green_transfer[SHADOWS][g_n];
|
||||
g_n = CLAMP0255 (g_n);
|
||||
g_n += cbd->magenta_green[MIDTONES] * magenta_green_transfer[MIDTONES][g_n];
|
||||
g_n = CLAMP0255 (g_n);
|
||||
g_n += cbd->magenta_green[HIGHLIGHTS] * magenta_green_transfer[HIGHLIGHTS][g_n];
|
||||
g_n = CLAMP0255 (g_n);
|
||||
|
||||
b_n += cbd->yellow_blue[SHADOWS] * yellow_blue_transfer[SHADOWS][b_n];
|
||||
b_n = CLAMP0255 (b_n);
|
||||
b_n += cbd->yellow_blue[MIDTONES] * yellow_blue_transfer[MIDTONES][b_n];
|
||||
b_n = CLAMP0255 (b_n);
|
||||
b_n += cbd->yellow_blue[HIGHLIGHTS] * yellow_blue_transfer[HIGHLIGHTS][b_n];
|
||||
b_n = CLAMP0255 (b_n);
|
||||
|
||||
cbd->r_lookup[i] = r_n;
|
||||
cbd->g_lookup[i] = g_n;
|
||||
cbd->b_lookup[i] = b_n;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
color_balance_preview (ColorBalanceDialog *cbd)
|
||||
{
|
||||
if (!cbd->image_map)
|
||||
g_message (_("color_balance_preview(): No image map"));
|
||||
active_tool->preserve = TRUE;
|
||||
color_balance_create_lookup_tables(cbd);
|
||||
image_map_apply (cbd->image_map, color_balance, (void *) cbd);
|
||||
active_tool->preserve = FALSE;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue