forked from enlightenment/efl
764 lines
17 KiB
C
764 lines
17 KiB
C
/*
|
|
|
|
-----------------------------[ XCF Loader ]-----------------------------
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2, or (at your option)
|
|
any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software Foundation,
|
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
#include "common.h"
|
|
|
|
#include <float.h>
|
|
|
|
#define EINA_FLT_EQ(a, b) (fabsf((float)a - (float)b) <= FLT_EPSILON)
|
|
|
|
#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)
|
|
|
|
static 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;
|
|
}
|
|
|
|
|
|
static 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);
|
|
}
|
|
|
|
|
|
static void
|
|
hls_to_rgb (DATA8 *hue, DATA8 *lightness, DATA8 *saturation)
|
|
{
|
|
double h, l, s;
|
|
double m1, m2;
|
|
|
|
h = *hue;
|
|
l = *lightness;
|
|
s = *saturation;
|
|
|
|
if (EINA_FLT_EQ(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);
|
|
}
|
|
}
|
|
|
|
|
|
static 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 (EINA_FLT_EQ(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;
|
|
}
|
|
|
|
static 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 */
|
|
static
|
|
void _clip(int * src_tl_x, int * src_tl_y,
|
|
int * src_br_x, int * src_br_y,
|
|
int * dest_x, int * dest_y,
|
|
int dest_w, int dest_h)
|
|
{
|
|
if (*dest_x + *src_br_x >= dest_w)
|
|
{ *src_br_x -= (*dest_x + *src_br_x) - dest_w; }
|
|
|
|
if (*dest_y + *src_br_y >= dest_h)
|
|
{ *src_br_y -= (*dest_y + *src_br_y) - dest_h; }
|
|
|
|
if (*dest_x < 0)
|
|
{
|
|
*src_tl_x = -(*dest_x);
|
|
*dest_x = 0;
|
|
}
|
|
if (*dest_y < 0)
|
|
{
|
|
*src_tl_y = -(*dest_y);
|
|
*dest_y = 0;
|
|
}
|
|
}
|
|
|
|
// FIXME: make sure layer alpha is used/applied in all cases
|
|
void
|
|
combine_pixels_normal (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;
|
|
|
|
int b;
|
|
unsigned char src_alpha;
|
|
unsigned char new_alpha;
|
|
float ratio, compl_ratio;
|
|
unsigned long tmp;
|
|
|
|
_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);
|
|
|
|
src_alpha = AS;
|
|
|
|
if (src_alpha != 0)
|
|
{
|
|
if (src_alpha == 255)
|
|
new_alpha = src_alpha;
|
|
else
|
|
new_alpha = AD + INT_MULT((255u - 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;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
combine_pixels_add (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;
|
|
int tmp, tmp2;
|
|
|
|
_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);
|
|
|
|
tmp2 = INT_MULT(AS, RS, tmp);
|
|
tmp = RD + tmp2;
|
|
RD = (tmp > 255 ? 255 : tmp);
|
|
|
|
tmp2 = INT_MULT(AS, GS, tmp);
|
|
tmp = GD + tmp2;
|
|
GD = (tmp > 255 ? 255 : tmp);
|
|
|
|
tmp2 = INT_MULT(AS, BS, tmp);
|
|
tmp = BD + tmp2;
|
|
BD = (tmp > 255 ? 255 : tmp);
|
|
|
|
// AD = MIN(AD, AS);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
combine_pixels_sub (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;
|
|
int tmp, tmp2;
|
|
|
|
_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);
|
|
|
|
tmp2 = INT_MULT(AS, RS, tmp);
|
|
tmp = RD - tmp2;
|
|
RD = (tmp < 0 ? 0 : tmp);
|
|
|
|
tmp2 = INT_MULT(AS, GS, tmp);
|
|
tmp = GD - tmp2;
|
|
GD = (tmp < 0 ? 0 : tmp);
|
|
|
|
tmp2 = INT_MULT(AS, BS, tmp);
|
|
tmp = BD - tmp2;
|
|
BD = (tmp < 0 ? 0 : tmp);
|
|
|
|
// AD = MIN(AD, AS);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
combine_pixels_diff (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;
|
|
int tmp, tmp2;
|
|
|
|
_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);
|
|
|
|
tmp2 = INT_MULT(AS, RS, tmp);
|
|
tmp = RD - tmp2;
|
|
RD = (tmp < 0 ? -tmp : tmp);
|
|
|
|
tmp2 = INT_MULT(AS, GS, tmp);
|
|
tmp = GD - tmp2;
|
|
GD = (tmp < 0 ? -tmp : tmp);
|
|
|
|
tmp2 = INT_MULT(AS, BS, tmp);
|
|
tmp = BD - tmp2;
|
|
BD = (tmp < 0 ? -tmp : tmp);
|
|
|
|
// AD = MIN(AD, AS);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
combine_pixels_darken (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);
|
|
|
|
RD = MIN(RD, RS);
|
|
GD = MIN(GD, GS);
|
|
BD = MIN(BD, BS);
|
|
|
|
// AD = MIN(AD, AS);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
combine_pixels_lighten (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);
|
|
|
|
RD = MAX(RD, RS);
|
|
GD = MAX(GD, GS);
|
|
BD = MAX(BD, BS);
|
|
|
|
// AD = MIN(AD, AS);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
combine_pixels_mult (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;
|
|
int tmp, tmp2, tmp3;
|
|
|
|
_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);
|
|
|
|
tmp2 = INT_MULT(RS, AS, tmp);
|
|
tmp2 = INT_MULT(RD, tmp2, tmp);
|
|
tmp3 = INT_MULT(RD, (255 - AS), tmp);
|
|
RD = (tmp2 + tmp3);
|
|
|
|
tmp2 = INT_MULT(GS, AS, tmp);
|
|
tmp2 = INT_MULT(GD, tmp2, tmp);
|
|
tmp3 = INT_MULT(GD, (255 - AS), tmp);
|
|
GD = (tmp2 + tmp3);
|
|
|
|
tmp2 = INT_MULT(BS, AS, tmp);
|
|
tmp2 = INT_MULT(BD, tmp2, tmp);
|
|
tmp3 = INT_MULT(BD, (255 - AS), tmp);
|
|
BD = (tmp2 + tmp3);
|
|
|
|
// AS = MIN(AS, AD);
|
|
}
|
|
|
|
// combine_pixels_normal(src, src_w, src_h, dest, dest_w, dest_h, dest_x, dest_y);
|
|
}
|
|
|
|
|
|
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)
|
|
{
|
|
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);
|
|
|
|
RS = MIN(255, ((float)RD / (RS + 1)) * 256);
|
|
GS = MIN(255, ((float)GD / (GS + 1)) * 256);
|
|
BS = MIN(255, ((float)BD / (BS + 1)) * 256);
|
|
|
|
// AS = MIN(AD, AS);
|
|
}
|
|
|
|
combine_pixels_normal(src, src_w, src_h, dest, dest_w, dest_h, dest_x, dest_y);
|
|
}
|
|
|
|
|
|
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)
|
|
{
|
|
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);
|
|
|
|
RD = 255 - (((255 - RD) * (255 - RS)) >> 8);
|
|
GD = 255 - (((255 - GD) * (255 - GS)) >> 8);
|
|
BD = 255 - (((255 - BD) * (255 - BS)) >> 8);
|
|
|
|
// AD = MIN(AD, AS);
|
|
}
|
|
}
|
|
|
|
|
|
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)
|
|
{
|
|
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;
|
|
int tmp_screen, tmp_mult;
|
|
|
|
_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);
|
|
|
|
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 - GD) * (255 - GS)) >> 8);
|
|
tmp_mult = (GD * GS) >> 8;
|
|
GD = (GD * tmp_screen + (255 - GD) * 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;
|
|
|
|
// AD = MIN(AD, AS);
|
|
}
|
|
}
|
|
|
|
|
|
static 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);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
combine_pixels_diss (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;
|
|
|
|
srand(12345);
|
|
|
|
_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);
|
|
|
|
if ((rand() % 255) < AS)
|
|
{
|
|
int b;
|
|
unsigned char src_alpha;
|
|
unsigned char new_alpha;
|
|
float ratio, compl_ratio;
|
|
unsigned long tmp;
|
|
|
|
src_alpha = AS;
|
|
|
|
if (src_alpha != 0)
|
|
{
|
|
if (src_alpha == 255)
|
|
new_alpha = src_alpha;
|
|
else
|
|
new_alpha = AD + INT_MULT((255u - 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;
|
|
}
|
|
}
|
|
}
|
|
}
|