Hue, Saturation, Value and Color blending modes. Only Dissolve still
needed :) Also lots of cleanups and an alphalevel fix (use minimum of source and destination instead of always source) ... SVN revision: 3380
This commit is contained in:
parent
7149339729
commit
d4fa780358
|
@ -264,7 +264,7 @@ void formats(ImlibLoader *l);
|
|||
|
||||
static void xcf_seek_pos (int pos);
|
||||
static int xcf_read_int32 (FILE *fp, DATA32 *data, int count);
|
||||
static int xcf_read_float (FILE *fp, float *data, int count);
|
||||
/*static int xcf_read_float (FILE *fp, float *data, int count);*/
|
||||
static int xcf_read_int8 (FILE *fp, DATA8 *data, int count);
|
||||
static int xcf_read_string (FILE *fp, char **data, int count);
|
||||
static char xcf_load_prop (PropType *prop_type, DATA32 *prop_size);
|
||||
|
@ -309,6 +309,10 @@ extern void combine_pixels_mult (DATA8* src, int src_w, int src_h, DATA8* dest,
|
|||
extern void combine_pixels_div (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y);
|
||||
extern void combine_pixels_screen (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y);
|
||||
extern void combine_pixels_overlay (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y);
|
||||
extern void combine_pixels_hue (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y);
|
||||
extern void combine_pixels_sat (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y);
|
||||
extern void combine_pixels_val (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y);
|
||||
extern void combine_pixels_col (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y);
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------------------- globals ------------ */
|
||||
|
@ -350,6 +354,7 @@ xcf_read_int32 (FILE *fp,
|
|||
return total * 4;
|
||||
}
|
||||
|
||||
/*
|
||||
static int
|
||||
xcf_read_float (FILE *fp,
|
||||
float *data,
|
||||
|
@ -357,6 +362,7 @@ xcf_read_float (FILE *fp,
|
|||
{
|
||||
return (xcf_read_int32(fp, (DATA32 *)((void *)data), count));
|
||||
}
|
||||
*/
|
||||
|
||||
static int
|
||||
xcf_read_int8 (FILE *fp,
|
||||
|
@ -1431,10 +1437,8 @@ flatten_image(void)
|
|||
while (l)
|
||||
{
|
||||
/* Ok, paste each layer on top of the image, using the mode's merging type.
|
||||
We're moving upward through the layer stack. The code that's commented
|
||||
out is directly from Gimp. Right now fall through all of these
|
||||
and simply combine the layers.
|
||||
--cK.
|
||||
We're moving upward through the layer stack.
|
||||
--cK.
|
||||
*/
|
||||
if (image->single_layer_index < 0 || layer_index == image->single_layer_index)
|
||||
{
|
||||
|
@ -1486,11 +1490,26 @@ flatten_image(void)
|
|||
l->offset_x, l->offset_y);
|
||||
break;
|
||||
|
||||
/* These are still to be finished ... */
|
||||
case HUE_MODE:
|
||||
combine_pixels_hue(l->data, l->width, l->height,
|
||||
image->data, image->width, image->height,
|
||||
l->offset_x, l->offset_y);
|
||||
break;
|
||||
case SATURATION_MODE:
|
||||
combine_pixels_sat(l->data, l->width, l->height,
|
||||
image->data, image->width, image->height,
|
||||
l->offset_x, l->offset_y);
|
||||
break;
|
||||
case VALUE_MODE:
|
||||
combine_pixels_val(l->data, l->width, l->height,
|
||||
image->data, image->width, image->height,
|
||||
l->offset_x, l->offset_y);
|
||||
break;
|
||||
case COLOR_MODE:
|
||||
combine_pixels_col(l->data, l->width, l->height,
|
||||
image->data, image->width, image->height,
|
||||
l->offset_x, l->offset_y);
|
||||
break;
|
||||
case DISSOLVE_MODE:
|
||||
|
||||
/* None of those is actually valid for layer blending, fall through: */
|
||||
|
@ -1633,6 +1652,10 @@ load(ImlibImage *im, ImlibProgressFunction progress, char progress_granularity,
|
|||
xcf_cleanup();
|
||||
|
||||
return 1;
|
||||
|
||||
/* shut up warnings: */
|
||||
progress_granularity = 0;
|
||||
immediate_load = 0;
|
||||
}
|
||||
|
||||
char
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/XShm.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
@ -16,27 +17,259 @@
|
|||
#include "image.h"
|
||||
#include "color_values.h"
|
||||
|
||||
#define EPSILON 0.0001
|
||||
#define RS R_VAL(src + s_idx)
|
||||
#define GS G_VAL(src + s_idx)
|
||||
#define BS B_VAL(src + s_idx)
|
||||
#define AS A_VAL(src + s_idx)
|
||||
#define RD R_VAL(dest + d_idx)
|
||||
#define GD G_VAL(dest + d_idx)
|
||||
#define BD B_VAL(dest + d_idx)
|
||||
#define AD A_VAL(dest + d_idx)
|
||||
|
||||
#define EPS 0.00001
|
||||
#define PI 3.141592654
|
||||
#define MAX(a, b) ((a > b) ? a : b)
|
||||
#define MIN(a, b) ((a < b) ? a : b)
|
||||
#define INT_MULT(a,b,t) ((t) = (a) * (b) + 0x80, ((((t) >> 8) + (t)) >> 8))
|
||||
#define LINEAR(x,y,w) ((w*y + x)*4)
|
||||
|
||||
#define alphify(src_alpha,new_alpha) \
|
||||
b = 3; \
|
||||
if (new_alpha != 0) \
|
||||
{ \
|
||||
ratio = (float) src_alpha / new_alpha; \
|
||||
compl_ratio = 1.0 - ratio; \
|
||||
\
|
||||
do { b--; \
|
||||
dest[d_idx + b] = \
|
||||
(unsigned char) (src[s_idx + b] * ratio + dest[d_idx + b] * compl_ratio + EPSILON); \
|
||||
} while (b); \
|
||||
}
|
||||
void
|
||||
rgb_to_hls (DATA8 *red, DATA8 *green, DATA8 *blue)
|
||||
{
|
||||
int r, g, b;
|
||||
double h, l, s;
|
||||
int min, max;
|
||||
int delta;
|
||||
|
||||
r = *red;
|
||||
g = *green;
|
||||
b = *blue;
|
||||
|
||||
if (r > g)
|
||||
{
|
||||
max = MAX (r, b);
|
||||
min = MIN (g, b);
|
||||
}
|
||||
else
|
||||
{
|
||||
max = MAX (g, b);
|
||||
min = MIN (r, b);
|
||||
}
|
||||
|
||||
l = (max + min) / 2.0;
|
||||
|
||||
if (max == min)
|
||||
{
|
||||
s = 0.0;
|
||||
h = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
delta = (max - min);
|
||||
|
||||
if (l < 128)
|
||||
s = 255 * (double) delta / (double) (max + min);
|
||||
else
|
||||
s = 255 * (double) delta / (double) (511 - max - min);
|
||||
|
||||
if (r == max)
|
||||
h = (g - b) / (double) delta;
|
||||
else if (g == max)
|
||||
h = 2 + (b - r) / (double) delta;
|
||||
else
|
||||
h = 4 + (r - g) / (double) delta;
|
||||
|
||||
h = h * 42.5;
|
||||
|
||||
if (h < 0)
|
||||
h += 255;
|
||||
else if (h > 255)
|
||||
h -= 255;
|
||||
}
|
||||
|
||||
*red = h;
|
||||
*green = l;
|
||||
*blue = s;
|
||||
}
|
||||
|
||||
|
||||
/* translate negative destinations */
|
||||
DATA8
|
||||
gimp_hls_value (double n1, double n2, double hue)
|
||||
{
|
||||
double value;
|
||||
|
||||
if (hue > 255)
|
||||
hue -= 255;
|
||||
else if (hue < 0)
|
||||
hue += 255;
|
||||
if (hue < 42.5)
|
||||
value = n1 + (n2 - n1) * (hue / 42.5);
|
||||
else if (hue < 127.5)
|
||||
value = n2;
|
||||
else if (hue < 170)
|
||||
value = n1 + (n2 - n1) * ((170 - hue) / 42.5);
|
||||
else
|
||||
value = n1;
|
||||
|
||||
return (DATA8) (value * 255);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hls_to_rgb (DATA8 *hue, DATA8 *lightness, DATA8 *saturation)
|
||||
{
|
||||
double h, l, s;
|
||||
double m1, m2;
|
||||
|
||||
h = *hue;
|
||||
l = *lightness;
|
||||
s = *saturation;
|
||||
|
||||
if (s == 0)
|
||||
{
|
||||
/* achromatic case */
|
||||
*hue = l;
|
||||
*lightness = l;
|
||||
*saturation = l;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (l < 128)
|
||||
m2 = (l * (255 + s)) / 65025.0;
|
||||
else
|
||||
m2 = (l + s - (l * s) / 255.0) / 255.0;
|
||||
|
||||
m1 = (l / 127.5) - m2;
|
||||
|
||||
/* chromatic case */
|
||||
*hue = gimp_hls_value (m1, m2, h + 85);
|
||||
*lightness = gimp_hls_value (m1, m2, h);
|
||||
*saturation = gimp_hls_value (m1, m2, h - 85);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
rgb_to_hsv (DATA8 *red, DATA8 *green, DATA8 *blue)
|
||||
{
|
||||
int r, g, b;
|
||||
double h, s, v;
|
||||
int min, max;
|
||||
int delta;
|
||||
|
||||
h = 0.0;
|
||||
|
||||
r = *red;
|
||||
g = *green;
|
||||
b = *blue;
|
||||
|
||||
if (r > g)
|
||||
{
|
||||
max = MAX (r, b);
|
||||
min = MIN (g, b);
|
||||
}
|
||||
else
|
||||
{
|
||||
max = MAX (g, b);
|
||||
min = MIN (r, b);
|
||||
}
|
||||
|
||||
v = max;
|
||||
|
||||
if (max != 0)
|
||||
s = ((max - min) * 255) / (double) max;
|
||||
else
|
||||
s = 0;
|
||||
|
||||
if (s == 0)
|
||||
h = 0;
|
||||
else
|
||||
{
|
||||
delta = max - min;
|
||||
if (r == max)
|
||||
h = (g - b) / (double) delta;
|
||||
else if (g == max)
|
||||
h = 2 + (b - r) / (double) delta;
|
||||
else if (b == max)
|
||||
h = 4 + (r - g) / (double) delta;
|
||||
h *= 42.5;
|
||||
|
||||
if (h < 0)
|
||||
h += 255;
|
||||
if (h > 255)
|
||||
h -= 255;
|
||||
}
|
||||
|
||||
*red = h;
|
||||
*green = s;
|
||||
*blue = v;
|
||||
}
|
||||
|
||||
void
|
||||
hsv_to_rgb (DATA8 *hue, DATA8 *saturation, DATA8 *value)
|
||||
{
|
||||
double h, s, v;
|
||||
double f, p, q, t;
|
||||
|
||||
if (*saturation == 0)
|
||||
{
|
||||
*hue = *value;
|
||||
*saturation = *value;
|
||||
*value = *value;
|
||||
}
|
||||
else
|
||||
{
|
||||
h = *hue * 6.0 / 255.0;
|
||||
s = *saturation / 255.0;
|
||||
v = *value / 255.0;
|
||||
|
||||
f = h - (int) h;
|
||||
p = v * (1.0 - s);
|
||||
q = v * (1.0 - (s * f));
|
||||
t = v * (1.0 - (s * (1.0 - f)));
|
||||
|
||||
switch ((int) h)
|
||||
{
|
||||
case 0:
|
||||
*hue = v * 255;
|
||||
*saturation = t * 255;
|
||||
*value = p * 255;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
*hue = q * 255;
|
||||
*saturation = v * 255;
|
||||
*value = p * 255;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
*hue = p * 255;
|
||||
*saturation = v * 255;
|
||||
*value = t * 255;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
*hue = p * 255;
|
||||
*saturation = q * 255;
|
||||
*value = v * 255;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
*hue = t * 255;
|
||||
*saturation = p * 255;
|
||||
*value = v * 255;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
*hue = v * 255;
|
||||
*saturation = p * 255;
|
||||
*value = q * 255;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* translate negative destinations */
|
||||
void clip(int * src_tl_x, int * src_tl_y,
|
||||
int * src_br_x, int * src_br_y,
|
||||
int * dest_x, int * dest_y,
|
||||
|
@ -82,22 +315,31 @@ combine_pixels_normal (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w
|
|||
d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w);
|
||||
s_idx = LINEAR(x, y, src_w);
|
||||
|
||||
src_alpha = A_VAL(src + s_idx);
|
||||
src_alpha = AS;
|
||||
|
||||
if (src_alpha != 0)
|
||||
{
|
||||
if (src_alpha == 255)
|
||||
{
|
||||
new_alpha = src_alpha;
|
||||
alphify (src_alpha, new_alpha);
|
||||
A_VAL(dest + d_idx) = new_alpha;
|
||||
}
|
||||
new_alpha = src_alpha;
|
||||
else
|
||||
{
|
||||
new_alpha = A_VAL(dest + d_idx) + INT_MULT((255 - A_VAL(dest + d_idx)), src_alpha, tmp);
|
||||
alphify (src_alpha, new_alpha);
|
||||
A_VAL(dest + d_idx) = new_alpha;
|
||||
new_alpha = AD + INT_MULT((255 - AD), src_alpha, tmp);
|
||||
|
||||
b = 3;
|
||||
if (new_alpha != 0)
|
||||
{
|
||||
ratio = (float) src_alpha / new_alpha;
|
||||
compl_ratio = 1.0 - ratio;
|
||||
|
||||
do
|
||||
{
|
||||
b--;
|
||||
dest[d_idx + b] =
|
||||
(unsigned char) (src[s_idx + b] * ratio + dest[d_idx + b] * compl_ratio + EPS);
|
||||
}
|
||||
while (b);
|
||||
}
|
||||
|
||||
AD = new_alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -119,16 +361,16 @@ combine_pixels_add (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, i
|
|||
d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w);
|
||||
s_idx = LINEAR(x, y, src_w);
|
||||
|
||||
tmp = R_VAL(dest + d_idx) + R_VAL(src + s_idx);
|
||||
R_VAL(dest + d_idx) = (tmp > 255 ? 255 : tmp);
|
||||
tmp = RD + RS;
|
||||
RD = (tmp > 255 ? 255 : tmp);
|
||||
|
||||
tmp = G_VAL(dest + d_idx) + G_VAL(src + s_idx);
|
||||
G_VAL(dest + d_idx) = (tmp > 255 ? 255 : tmp);
|
||||
tmp = GD + GS;
|
||||
GD = (tmp > 255 ? 255 : tmp);
|
||||
|
||||
tmp = B_VAL(dest + d_idx) + B_VAL(src + s_idx);
|
||||
B_VAL(dest + d_idx) = (tmp > 255 ? 255 : tmp);
|
||||
tmp = BD + BS;
|
||||
BD = (tmp > 255 ? 255 : tmp);
|
||||
|
||||
A_VAL(dest + d_idx) = A_VAL(src + s_idx);
|
||||
AD = MIN(AD, AS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -149,16 +391,16 @@ combine_pixels_sub (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, i
|
|||
d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w);
|
||||
s_idx = LINEAR(x, y, src_w);
|
||||
|
||||
tmp = R_VAL(dest + d_idx) - R_VAL(src + s_idx);
|
||||
R_VAL(dest + d_idx) = (tmp < 0 ? 0 : tmp);
|
||||
tmp = RD - RS;
|
||||
RD = (tmp < 0 ? 0 : tmp);
|
||||
|
||||
tmp = G_VAL(dest + d_idx) - G_VAL(src + s_idx);
|
||||
G_VAL(dest + d_idx) = (tmp < 0 ? 0 : tmp);
|
||||
tmp = GD - GS;
|
||||
GD = (tmp < 0 ? 0 : tmp);
|
||||
|
||||
tmp = B_VAL(dest + d_idx) - B_VAL(src + s_idx);
|
||||
B_VAL(dest + d_idx) = (tmp < 0 ? 0 : tmp);
|
||||
tmp = BD - BS;
|
||||
BD = (tmp < 0 ? 0 : tmp);
|
||||
|
||||
A_VAL(dest + d_idx) = A_VAL(src + s_idx);
|
||||
AD = MIN(AD, AS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -179,16 +421,16 @@ combine_pixels_diff (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w,
|
|||
d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w);
|
||||
s_idx = LINEAR(x, y, src_w);
|
||||
|
||||
tmp = R_VAL(dest + d_idx) - R_VAL(src + s_idx);
|
||||
R_VAL(dest + d_idx) = (tmp < 0 ? -tmp : tmp);
|
||||
tmp = RD - RS;
|
||||
RD = (tmp < 0 ? -tmp : tmp);
|
||||
|
||||
tmp = G_VAL(dest + d_idx) - G_VAL(src + s_idx);
|
||||
G_VAL(dest + d_idx) = (tmp < 0 ? -tmp : tmp);
|
||||
tmp = GD - GS;
|
||||
GD = (tmp < 0 ? -tmp : tmp);
|
||||
|
||||
tmp = B_VAL(dest + d_idx) - B_VAL(src + s_idx);
|
||||
B_VAL(dest + d_idx) = (tmp < 0 ? -tmp : tmp);
|
||||
tmp = BD - BS;
|
||||
BD = (tmp < 0 ? -tmp : tmp);
|
||||
|
||||
A_VAL(dest + d_idx) = A_VAL(src + s_idx);
|
||||
AD = MIN(AD, AS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -208,11 +450,11 @@ combine_pixels_darken (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w
|
|||
d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w);
|
||||
s_idx = LINEAR(x, y, src_w);
|
||||
|
||||
R_VAL(dest + d_idx) = MIN(R_VAL(dest + d_idx), R_VAL(src + s_idx));
|
||||
G_VAL(dest + d_idx) = MIN(G_VAL(dest + d_idx), G_VAL(src + s_idx));
|
||||
B_VAL(dest + d_idx) = MIN(B_VAL(dest + d_idx), B_VAL(src + s_idx));
|
||||
RD = MIN(RD, RS);
|
||||
GD = MIN(GD, GS);
|
||||
BD = MIN(BD, BS);
|
||||
|
||||
A_VAL(dest + d_idx) = A_VAL(src + s_idx);
|
||||
AD = MIN(AD, AS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -232,11 +474,11 @@ combine_pixels_lighten (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_
|
|||
d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w);
|
||||
s_idx = LINEAR(x, y, src_w);
|
||||
|
||||
R_VAL(dest + d_idx) = MAX(R_VAL(dest + d_idx), R_VAL(src + s_idx));
|
||||
G_VAL(dest + d_idx) = MAX(G_VAL(dest + d_idx), G_VAL(src + s_idx));
|
||||
B_VAL(dest + d_idx) = MAX(B_VAL(dest + d_idx), B_VAL(src + s_idx));
|
||||
RD = MAX(RD, RS);
|
||||
GD = MAX(GD, GS);
|
||||
BD = MAX(BD, BS);
|
||||
|
||||
A_VAL(dest + d_idx) = A_VAL(src + s_idx);
|
||||
AD = MIN(AD, AS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -256,11 +498,11 @@ combine_pixels_mult (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w,
|
|||
d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w);
|
||||
s_idx = LINEAR(x, y, src_w);
|
||||
|
||||
R_VAL(dest + d_idx) = (R_VAL(dest + d_idx) * R_VAL(src + s_idx)) >> 8;
|
||||
G_VAL(dest + d_idx) = (G_VAL(dest + d_idx) * G_VAL(src + s_idx)) >> 8;
|
||||
B_VAL(dest + d_idx) = (B_VAL(dest + d_idx) * B_VAL(src + s_idx)) >> 8;
|
||||
RD = (RD * RS) >> 8;
|
||||
GD = (GD * GS) >> 8;
|
||||
BD = (BD * BS) >> 8;
|
||||
|
||||
A_VAL(dest + d_idx) = A_VAL(src + s_idx);
|
||||
AD = MIN(AD, AS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -280,11 +522,11 @@ combine_pixels_div (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, i
|
|||
d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w);
|
||||
s_idx = LINEAR(x, y, src_w);
|
||||
|
||||
R_VAL(dest + d_idx) = MIN(255, ((float)R_VAL(dest + d_idx) / (R_VAL(src + s_idx) + 1)) * 256);
|
||||
G_VAL(dest + d_idx) = MIN(255, ((float)G_VAL(dest + d_idx) / (G_VAL(src + s_idx) + 1)) * 256);
|
||||
B_VAL(dest + d_idx) = MIN(255, ((float)B_VAL(dest + d_idx) / (B_VAL(src + s_idx) + 1)) * 256);
|
||||
RD = MIN(255, ((float)RD / (RS + 1)) * 256);
|
||||
GD = MIN(255, ((float)GD / (GS + 1)) * 256);
|
||||
BD = MIN(255, ((float)BD / (BS + 1)) * 256);
|
||||
|
||||
A_VAL(dest + d_idx) = A_VAL(src + s_idx);
|
||||
AD = MIN(AD, AS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -304,11 +546,11 @@ combine_pixels_screen (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w
|
|||
d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w);
|
||||
s_idx = LINEAR(x, y, src_w);
|
||||
|
||||
R_VAL(dest + d_idx) = 255 - (((255 - R_VAL(dest + d_idx)) * (255 - R_VAL(src + s_idx))) >> 8);
|
||||
G_VAL(dest + d_idx) = 255 - (((255 - G_VAL(dest + d_idx)) * (255 - G_VAL(src + s_idx))) >> 8);
|
||||
B_VAL(dest + d_idx) = 255 - (((255 - B_VAL(dest + d_idx)) * (255 - B_VAL(src + s_idx))) >> 8);
|
||||
RD = 255 - (((255 - RD) * (255 - RS)) >> 8);
|
||||
GD = 255 - (((255 - GD) * (255 - GS)) >> 8);
|
||||
BD = 255 - (((255 - BD) * (255 - BS)) >> 8);
|
||||
|
||||
A_VAL(dest + d_idx) = A_VAL(src + s_idx);
|
||||
AD = MIN(AD, AS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -329,19 +571,104 @@ combine_pixels_overlay (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_
|
|||
d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w);
|
||||
s_idx = LINEAR(x, y, src_w);
|
||||
|
||||
tmp_screen = 255 - (((255 - R_VAL(dest + d_idx)) * (255 - R_VAL(src + s_idx))) >> 8);
|
||||
tmp_mult = (R_VAL(dest + d_idx) * R_VAL(src + s_idx)) >> 8;
|
||||
R_VAL(dest + d_idx) = (R_VAL(dest + d_idx) * tmp_screen + (255 - R_VAL(dest + d_idx)) * tmp_mult) >> 8;
|
||||
tmp_screen = 255 - (((255 - RD) * (255 - RS)) >> 8);
|
||||
tmp_mult = (RD * RS) >> 8;
|
||||
RD = (RD * tmp_screen + (255 - RD) * tmp_mult) >> 8;
|
||||
|
||||
tmp_screen = 255 - (((255 - G_VAL(dest + d_idx)) * (255 - G_VAL(src + s_idx))) >> 8);
|
||||
tmp_mult = (G_VAL(dest + d_idx) * G_VAL(src + s_idx)) >> 8;
|
||||
G_VAL(dest + d_idx) = (G_VAL(dest + d_idx) * tmp_screen + (255 - G_VAL(dest + d_idx)) * tmp_mult) >> 8;
|
||||
tmp_screen = 255 - (((255 - GD) * (255 - GS)) >> 8);
|
||||
tmp_mult = (GD * GS) >> 8;
|
||||
GD = (GD * tmp_screen + (255 - GD) * tmp_mult) >> 8;
|
||||
|
||||
tmp_screen = 255 - (((255 - B_VAL(dest + d_idx)) * (255 - B_VAL(src + s_idx))) >> 8);
|
||||
tmp_mult = (B_VAL(dest + d_idx) * B_VAL(src + s_idx)) >> 8;
|
||||
B_VAL(dest + d_idx) = (B_VAL(dest + d_idx) * tmp_screen + (255 - B_VAL(dest + d_idx)) * tmp_mult) >> 8;
|
||||
tmp_screen = 255 - (((255 - BD) * (255 - BS)) >> 8);
|
||||
tmp_mult = (BD * BS) >> 8;
|
||||
BD = (BD * tmp_screen + (255 - BD) * tmp_mult) >> 8;
|
||||
|
||||
A_VAL(dest + d_idx) = A_VAL(src + s_idx);
|
||||
AD = MIN(AD, AS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
combine_pixels_hsv (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y, int mode)
|
||||
{
|
||||
int x, y, s_idx, d_idx;
|
||||
int src_tl_x = 0, src_tl_y = 0;
|
||||
int src_br_x = src_w, src_br_y = src_h;
|
||||
|
||||
clip(&src_tl_x, &src_tl_y, &src_br_x, &src_br_y, &dest_x, &dest_y, dest_w, dest_h);
|
||||
|
||||
for (y = src_tl_y; y < src_br_y; y++)
|
||||
for (x = src_tl_x; x < src_br_x; x++)
|
||||
{
|
||||
d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w);
|
||||
s_idx = LINEAR(x, y, src_w);
|
||||
|
||||
rgb_to_hsv(&RS, &GS, &BS);
|
||||
rgb_to_hsv(&RD, &GD, &BD);
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case 0: /* hue mode */
|
||||
RD = RS;
|
||||
break;
|
||||
case 1: /* saturation mode */
|
||||
GD = GS;
|
||||
break;
|
||||
case 2: /* value mode */
|
||||
BD = BS;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
hsv_to_rgb(&RD, &GD, &BD);
|
||||
AD = MIN(AD, AS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
combine_pixels_hue (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y)
|
||||
{
|
||||
combine_pixels_hsv(src, src_w, src_h, dest, dest_w, dest_h, dest_x, dest_y, 0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
combine_pixels_sat (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y)
|
||||
{
|
||||
combine_pixels_hsv(src, src_w, src_h, dest, dest_w, dest_h, dest_x, dest_y, 1);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
combine_pixels_val (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y)
|
||||
{
|
||||
combine_pixels_hsv(src, src_w, src_h, dest, dest_w, dest_h, dest_x, dest_y, 2);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
combine_pixels_col (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y)
|
||||
{
|
||||
int x, y, s_idx, d_idx;
|
||||
int src_tl_x = 0, src_tl_y = 0;
|
||||
int src_br_x = src_w, src_br_y = src_h;
|
||||
|
||||
clip(&src_tl_x, &src_tl_y, &src_br_x, &src_br_y, &dest_x, &dest_y, dest_w, dest_h);
|
||||
|
||||
for (y = src_tl_y; y < src_br_y; y++)
|
||||
for (x = src_tl_x; x < src_br_x; x++)
|
||||
{
|
||||
d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w);
|
||||
s_idx = LINEAR(x, y, src_w);
|
||||
|
||||
rgb_to_hls(&RS, &GS, &BS);
|
||||
rgb_to_hls(&RD, &GD, &BD);
|
||||
RD = RS;
|
||||
BD = BS;
|
||||
hls_to_rgb(&RD, &GD, &BD);
|
||||
|
||||
AD = MIN(AD, AS);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue