[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:
Benoît Minisini 2009-01-17 01:11:36 +00:00
parent e945a9faa6
commit 6700b4a603
4 changed files with 138 additions and 121 deletions

View file

@ -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),

View file

@ -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

View file

@ -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

View file

@ -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++;
}
}