[GB.IMAGE]
* NEW: Put the Image.MakeTransparent() method in gb.image. * NEW: Compiles the image.c source file with full optimization. git-svn-id: svn://localhost/gambas/trunk@1804 867c0c6c-44f3-4631-809d-bfa615b0a4ec
This commit is contained in:
parent
e945a9faa6
commit
6700b4a603
4 changed files with 138 additions and 121 deletions
|
@ -349,119 +349,6 @@ BEGIN_METHOD(CIMAGE_draw, GB_OBJECT img; GB_INTEGER x; GB_INTEGER y; GB_INTEGER
|
|||
|
||||
END_METHOD
|
||||
|
||||
// Comes from the GIMP
|
||||
|
||||
typedef
|
||||
struct {
|
||||
float r;
|
||||
float b;
|
||||
float g;
|
||||
float a;
|
||||
}
|
||||
RGB;
|
||||
|
||||
static void color_to_alpha(RGB *src, const RGB *color)
|
||||
{
|
||||
RGB alpha;
|
||||
|
||||
alpha.a = src->a;
|
||||
|
||||
if (color->r < 0.0001)
|
||||
alpha.r = src->r;
|
||||
else if (src->r > color->r)
|
||||
alpha.r = (src->r - color->r) / (1.0 - color->r);
|
||||
else if (src->r < color->r)
|
||||
alpha.r = (color->r - src->r) / color->r;
|
||||
else alpha.r = 0.0;
|
||||
|
||||
if (color->g < 0.0001)
|
||||
alpha.g = src->g;
|
||||
else if (src->g > color->g)
|
||||
alpha.g = (src->g - color->g) / (1.0 - color->g);
|
||||
else if (src->g < color->g)
|
||||
alpha.g = (color->g - src->g) / (color->g);
|
||||
else alpha.g = 0.0;
|
||||
|
||||
if (color->b < 0.0001)
|
||||
alpha.b = src->b;
|
||||
else if (src->b > color->b)
|
||||
alpha.b = (src->b - color->b) / (1.0 - color->b);
|
||||
else if (src->b < color->b)
|
||||
alpha.b = (color->b - src->b) / (color->b);
|
||||
else alpha.b = 0.0;
|
||||
|
||||
if (alpha.r > alpha.g)
|
||||
{
|
||||
if (alpha.r > alpha.b)
|
||||
{
|
||||
src->a = alpha.r;
|
||||
}
|
||||
else
|
||||
{
|
||||
src->a = alpha.b;
|
||||
}
|
||||
}
|
||||
else if (alpha.g > alpha.b)
|
||||
{
|
||||
src->a = alpha.g;
|
||||
}
|
||||
else
|
||||
{
|
||||
src->a = alpha.b;
|
||||
}
|
||||
|
||||
if (src->a < 0.0001)
|
||||
return;
|
||||
|
||||
src->r = (src->r - color->r) / src->a + color->r;
|
||||
src->g = (src->g - color->g) / src->a + color->g;
|
||||
src->b = (src->b - color->b) / src->a + color->b;
|
||||
|
||||
src->a *= alpha.a;
|
||||
}
|
||||
|
||||
BEGIN_METHOD(CIMAGE_make_transparent, GB_INTEGER color)
|
||||
|
||||
check_image(THIS);
|
||||
|
||||
QImage *img = QIMAGE;
|
||||
uchar *b = img->bits();
|
||||
uchar *g = b + 1;
|
||||
uchar *r = b + 2;
|
||||
uchar *a = b + 3;
|
||||
uchar *end = img->bits() + img->numBytes();
|
||||
uint color = VARGOPT(color, 0xFFFFFFL);
|
||||
RGB rgb_color;
|
||||
RGB rgb_src;
|
||||
|
||||
rgb_color.b = (color & 0xFF) / 255.0;
|
||||
rgb_color.g = ((color >> 8) & 0xFF) / 255.0;
|
||||
rgb_color.r = ((color >> 16) & 0xFF) / 255.0;
|
||||
rgb_color.a = 1.0;
|
||||
|
||||
while (b != end)
|
||||
{
|
||||
rgb_src.b = *b / 255.0;
|
||||
rgb_src.g = *g / 255.0;
|
||||
rgb_src.r = *r / 255.0;
|
||||
rgb_src.a = *a / 255.0;
|
||||
|
||||
color_to_alpha(&rgb_src, &rgb_color);
|
||||
|
||||
*b = 255.0 * rgb_src.b + 0.5;
|
||||
*g = 255.0 * rgb_src.g + 0.5;
|
||||
*r = 255.0 * rgb_src.r + 0.5;
|
||||
*a = 255.0 * rgb_src.a + 0.5;
|
||||
|
||||
b += 4;
|
||||
g += 4;
|
||||
r += 4;
|
||||
a += 4;
|
||||
}
|
||||
|
||||
END_METHOD
|
||||
|
||||
|
||||
|
||||
GB_DESC CImageDesc[] =
|
||||
{
|
||||
|
@ -471,8 +358,6 @@ GB_DESC CImageDesc[] =
|
|||
GB_METHOD("Save", NULL, CIMAGE_save, "(Path)s[(Quality)i]"),
|
||||
GB_METHOD("Resize", NULL, CIMAGE_resize, "(Width)i(Height)i"),
|
||||
|
||||
GB_METHOD("MakeTransparent", NULL, CIMAGE_make_transparent, "[(Color)i]"),
|
||||
|
||||
GB_METHOD("Copy", "Image", CIMAGE_copy, "[(X)i(Y)i(Width)i(Height)i]"),
|
||||
GB_METHOD("Stretch", "Image", CIMAGE_stretch, "(Width)i(Height)i[(Smooth)b]"),
|
||||
GB_METHOD("Flip", "Image", CIMAGE_flip, NULL),
|
||||
|
|
|
@ -103,6 +103,12 @@ BEGIN_METHOD(CIMAGE_replace, GB_INTEGER src; GB_INTEGER dst; GB_BOOLEAN noteq)
|
|||
|
||||
END_METHOD
|
||||
|
||||
BEGIN_METHOD(CIMAGE_make_transparent, GB_INTEGER color)
|
||||
|
||||
IMAGE_make_transparent(THIS_IMAGE, VARGOPT(color, 0xFFFFFF));
|
||||
|
||||
END_METHOD
|
||||
|
||||
GB_DESC CImageDesc[] =
|
||||
{
|
||||
GB_DECLARE("Image", sizeof(CIMAGE)),
|
||||
|
@ -127,6 +133,7 @@ GB_DESC CImageDesc[] =
|
|||
GB_METHOD("Clear", NULL, CIMAGE_clear, NULL),
|
||||
GB_METHOD("Fill", NULL, CIMAGE_fill, "(Color)i"),
|
||||
GB_METHOD("MakeGray", NULL, CIMAGE_make_gray, NULL),
|
||||
GB_METHOD("MakeTransparent", NULL, CIMAGE_make_transparent, "[(Color)i]"),
|
||||
GB_METHOD("Replace", NULL, CIMAGE_replace, "(OldColor)i(NewColor)i[(NotEqual)b]"),
|
||||
|
||||
GB_END_DECLARE
|
||||
|
|
|
@ -16,4 +16,8 @@ gb_image_la_SOURCES = \
|
|||
gb.image.h \
|
||||
main.h main.c
|
||||
|
||||
image.lo: image.c
|
||||
$(LTCOMPILE) -O3 $(CFLAGS) -MT image.o -MD -MP -MF $(DEPDIR)/image.Tpo -c -o image.o image.c
|
||||
mv -f $(DEPDIR)/image.Tpo $(DEPDIR)/image.Po
|
||||
|
||||
|
||||
|
|
|
@ -77,6 +77,24 @@ static GB_COLOR to_GB_COLOR(uint col, int format)
|
|||
return col ^ 0xFF000000;
|
||||
}
|
||||
|
||||
static inline uint BGRA_to_format(uint col, int format)
|
||||
{
|
||||
if (GB_IMAGE_FMT_IS_PREMULTIPLIED(format))
|
||||
col = PREMUL(col);
|
||||
if (GB_IMAGE_FMT_IS_SWAPPED(format))
|
||||
col = SWAP(col);
|
||||
return col;
|
||||
}
|
||||
|
||||
static inline uint BGRA_from_format(uint col, int format)
|
||||
{
|
||||
if (GB_IMAGE_FMT_IS_SWAPPED(format))
|
||||
col = SWAP(col);
|
||||
if (GB_IMAGE_FMT_IS_PREMULTIPLIED(format))
|
||||
col = INV_PREMUL(col);
|
||||
return col;
|
||||
}
|
||||
|
||||
static inline bool is_valid(GB_IMG *img, int x, int y)
|
||||
{
|
||||
return !(x >= img->width || y >= img->height || x < 0 || y < 0);
|
||||
|
@ -259,8 +277,6 @@ int IMAGE_size(GB_IMG *img)
|
|||
|
||||
void IMAGE_create(GB_IMG *img, int width, int height, int format)
|
||||
{
|
||||
int size;
|
||||
|
||||
if (width <= 0 || height <= 0)
|
||||
{
|
||||
GB_BASE save = img->ob;
|
||||
|
@ -403,10 +419,6 @@ void IMAGE_make_gray(GB_IMG *img)
|
|||
}
|
||||
}
|
||||
|
||||
void IMAGE_make_transparent(GB_IMG *img, GB_COLOR color)
|
||||
{
|
||||
}
|
||||
|
||||
GB_COLOR IMAGE_get_pixel(GB_IMG *img, int x, int y)
|
||||
{
|
||||
uint col;
|
||||
|
@ -455,3 +467,112 @@ void IMAGE_replace(GB_IMG *img, GB_COLOR src, GB_COLOR dst, bool noteq)
|
|||
}
|
||||
}
|
||||
|
||||
// Comes from the GIMP
|
||||
|
||||
typedef
|
||||
struct {
|
||||
float r;
|
||||
float b;
|
||||
float g;
|
||||
float a;
|
||||
}
|
||||
FLOAT_RGB;
|
||||
|
||||
static void color_to_alpha(FLOAT_RGB *src, const FLOAT_RGB *color)
|
||||
{
|
||||
FLOAT_RGB alpha;
|
||||
|
||||
alpha.a = src->a;
|
||||
|
||||
if (color->r < 0.0001)
|
||||
alpha.r = src->r;
|
||||
else if (src->r > color->r)
|
||||
alpha.r = (src->r - color->r) / (1.0 - color->r);
|
||||
else if (src->r < color->r)
|
||||
alpha.r = (color->r - src->r) / color->r;
|
||||
else alpha.r = 0.0;
|
||||
|
||||
if (color->g < 0.0001)
|
||||
alpha.g = src->g;
|
||||
else if (src->g > color->g)
|
||||
alpha.g = (src->g - color->g) / (1.0 - color->g);
|
||||
else if (src->g < color->g)
|
||||
alpha.g = (color->g - src->g) / (color->g);
|
||||
else alpha.g = 0.0;
|
||||
|
||||
if (color->b < 0.0001)
|
||||
alpha.b = src->b;
|
||||
else if (src->b > color->b)
|
||||
alpha.b = (src->b - color->b) / (1.0 - color->b);
|
||||
else if (src->b < color->b)
|
||||
alpha.b = (color->b - src->b) / (color->b);
|
||||
else alpha.b = 0.0;
|
||||
|
||||
if (alpha.r > alpha.g)
|
||||
{
|
||||
if (alpha.r > alpha.b)
|
||||
{
|
||||
src->a = alpha.r;
|
||||
}
|
||||
else
|
||||
{
|
||||
src->a = alpha.b;
|
||||
}
|
||||
}
|
||||
else if (alpha.g > alpha.b)
|
||||
{
|
||||
src->a = alpha.g;
|
||||
}
|
||||
else
|
||||
{
|
||||
src->a = alpha.b;
|
||||
}
|
||||
|
||||
if (src->a < 0.0001)
|
||||
return;
|
||||
|
||||
src->r = (src->r - color->r) / src->a + color->r;
|
||||
src->g = (src->g - color->g) / src->a + color->g;
|
||||
src->b = (src->b - color->b) / src->a + color->b;
|
||||
|
||||
src->a *= alpha.a;
|
||||
}
|
||||
|
||||
void IMAGE_make_transparent(GB_IMG *img, GB_COLOR col)
|
||||
{
|
||||
uint *p = (uint *)img->data;
|
||||
uint *pm = (uint *)(img->data + IMAGE_size(img));
|
||||
uint color;
|
||||
FLOAT_RGB rgb_color;
|
||||
FLOAT_RGB rgb_src;
|
||||
|
||||
color = from_GB_COLOR(col, img->format);
|
||||
rgb_color.b = BLUE(color) / 255.0;
|
||||
rgb_color.g = GREEN(color) / 255.0;
|
||||
rgb_color.r = RED(color) / 255.0;
|
||||
rgb_color.a = 1.0;
|
||||
|
||||
while (p != pm)
|
||||
{
|
||||
color = BGRA_from_format(*p, img->format);
|
||||
rgb_src.b = BLUE(color) / 255.0;
|
||||
rgb_src.g = GREEN(color) / 255.0;
|
||||
rgb_src.r = RED(color) / 255.0;
|
||||
rgb_src.a = ALPHA(color) / 255.0;
|
||||
|
||||
color_to_alpha(&rgb_src, &rgb_color);
|
||||
|
||||
color = RGBA(
|
||||
(unsigned char)(255.0 * rgb_src.r + 0.5),
|
||||
(unsigned char)(255.0 * rgb_src.g + 0.5),
|
||||
(unsigned char)(255.0 * rgb_src.b + 0.5),
|
||||
(unsigned char)(255.0 * rgb_src.a + 0.5)
|
||||
);
|
||||
|
||||
*p = BGRA_to_format(color, img->format);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue