From f22644997eaf4439cde7c84e5cf7a96578a2f691 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Minisini?= <gambas@users.sourceforge.net> Date: Mon, 26 Jan 2009 17:42:53 +0000 Subject: [PATCH] [GB.GTK] * BUG: Define the default image format when the gb.gtk component is used. * BUG: Image.Load() does not crash anymore. [GB.IMAGE] * BUG: Sometimes the conversion between formats was not done. That was fixed. git-svn-id: svn://localhost/gambas/trunk@1819 867c0c6c-44f3-4631-809d-bfa615b0a4ec --- gb.gtk/src/CImage.cpp | 2 +- gb.gtk/src/main.cpp | 1 + main/lib/image/image.c | 69 ++++++++++++++++++++++++++++++++++++------ 3 files changed, 61 insertions(+), 11 deletions(-) diff --git a/gb.gtk/src/CImage.cpp b/gb.gtk/src/CImage.cpp index 1abf01105..e8182bd7b 100644 --- a/gb.gtk/src/CImage.cpp +++ b/gb.gtk/src/CImage.cpp @@ -176,7 +176,7 @@ BEGIN_METHOD(CIMAGE_load, GB_STRING path) if (pic) { image = CIMAGE_create(pic); - PICTURE->getPixbuf(); + pic->getPixbuf(); GB.ReturnObject(image); return; } diff --git a/gb.gtk/src/main.cpp b/gb.gtk/src/main.cpp index 456f5e14b..95e33876a 100644 --- a/gb.gtk/src/main.cpp +++ b/gb.gtk/src/main.cpp @@ -230,6 +230,7 @@ extern "C" GB.LoadComponent("gb.draw"); GB.GetInterface("gb.image", IMAGE_INTERFACE_VERSION, &IMAGE); + IMAGE.SetDefaultFormat(GB_IMAGE_RGBA); return TRUE; } diff --git a/main/lib/image/image.c b/main/lib/image/image.c index 0e69438dc..bf37a312c 100644 --- a/main/lib/image/image.c +++ b/main/lib/image/image.c @@ -24,6 +24,8 @@ #include "image.h" +//#define DEBUG_CONVERT + static int _default_format = GB_IMAGE_RGBA; static inline unsigned char *GET_END_POINTER(GB_IMG *image) @@ -34,6 +36,12 @@ static inline unsigned char *GET_END_POINTER(GB_IMG *image) static inline uint PREMUL(uint x) { uint a = x >> 24; + + if (a == 0) + return 0; + else if (a == 0xFF) + return x; + uint t = (x & 0xff00ff) * a; t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8; t &= 0xff00ff; @@ -47,12 +55,16 @@ static inline uint PREMUL(uint x) static inline uint INV_PREMUL(uint p) { + if (ALPHA(p) == 0) + return 0; + else if (ALPHA(p) == 0xFF) + return p; + else return - (ALPHA(p) == 0 ? 0 : ((ALPHA(p) << 24) | (((255*RED(p))/ ALPHA(p)) << 16) | (((255*GREEN(p)) / ALPHA(p)) << 8) - | ((255*BLUE(p)) / ALPHA(p)))); + | ((255*BLUE(p)) / ALPHA(p))); } static inline uint SWAP(uint p) @@ -120,7 +132,8 @@ static void free_image(GB_IMG *img, void *image) static GB_IMG_OWNER _image_owner = { "gb.image", free_image, - free_image + free_image, + NULL }; @@ -139,6 +152,10 @@ static void convert_image(uchar *dst, int dst_format, uchar *src, int src_format uint *p, *pm; bool psrc, pdst; + #ifdef DEBUG_CONVERT + fprintf(stderr, "convert_image: src_format = %d dst_format = %d\n", src_format, dst_format); + #endif + len = w * h * sizeof(uint); dm = &d[len]; @@ -148,6 +165,10 @@ static void convert_image(uchar *dst, int dst_format, uchar *src, int src_format pdst = GB_IMAGE_FMT_IS_PREMULTIPLIED(dst_format); dst_format = GB_IMAGE_FMT_CLEAR_PREMULTIPLIED(dst_format); + #ifdef DEBUG_CONVERT + fprintf(stderr, "convert_image: after: src_format = %d dst_format = %d\n", src_format, dst_format); + #endif + if (dst_format == GB_IMAGE_BGRA || dst_format == GB_IMAGE_BGRX) { switch (src_format) @@ -197,11 +218,17 @@ static void convert_image(uchar *dst, int dst_format, uchar *src, int src_format __0123: + #ifdef DEBUG_CONVERT + fprintf(stderr, "convert_image: 0123\n"); + #endif memcpy(dst, src, len); goto __PREMULTIPLIED; __3210: + #ifdef DEBUG_CONVERT + fprintf(stderr, "convert_image: 3210\n"); + #endif while (d != dm) { d[0] = s[3]; @@ -215,6 +242,10 @@ __3210: __2103: + #ifdef DEBUG_CONVERT + fprintf(stderr, "convert_image: 2103\n"); + #endif + while (d != dm) { d[0] = s[2]; @@ -228,6 +259,10 @@ __2103: __1230: + #ifdef DEBUG_CONVERT + fprintf(stderr, "convert_image: 1230\n"); + #endif + while (d != dm) { d[0] = s[1]; @@ -241,6 +276,10 @@ __1230: __012X: + #ifdef DEBUG_CONVERT + fprintf(stderr, "convert_image: 012X\n"); + #endif + while (d != dm) { d[0] = s[0]; @@ -254,6 +293,10 @@ __012X: __210X: + #ifdef DEBUG_CONVERT + fprintf(stderr, "convert_image: 210X\n"); + #endif + while (d != dm) { d[0] = s[2]; @@ -275,6 +318,9 @@ __PREMULTIPLIED: if (psrc) { + #ifdef DEBUG_CONVERT + fprintf(stderr, "convert_image: premultiplied -> normal\n"); + #endif // convert premultiplied to normal while (p != pm) { @@ -284,6 +330,9 @@ __PREMULTIPLIED: } else { + #ifdef DEBUG_CONVERT + fprintf(stderr, "convert_image: normal -> premultiplied\n"); + #endif // convert normal to premultiplied while (p != pm) { @@ -314,6 +363,7 @@ void IMAGE_create(GB_IMG *img, int width, int height, int format) img->format = format; GB.Alloc(POINTER(&img->data), IMAGE_size(img)); img->owner = &_image_owner; + img->owner_handle = img->data; } void IMAGE_create_with_data(GB_IMG *img, int width, int height, int format, unsigned char *data) @@ -322,21 +372,20 @@ void IMAGE_create_with_data(GB_IMG *img, int width, int height, int format, unsi memcpy(img->data, data, IMAGE_size(img)); } -static void IMAGE_convert(GB_IMG *img, int format) +static void IMAGE_convert(GB_IMG *img, int dst_format) { uchar *data; + int src_format = img->format; - if (format == img->format) + if (src_format == dst_format) return; - //fprintf(stderr, "convert image %p: %d -> %d\n", img, img->format, format); - //IMAGE_create(&tmp, img->width, img->height, format); - img->format = format; + img->format = dst_format; GB.Alloc(POINTER(&data), IMAGE_size(img)); - convert_image(data, format, img->data, img->format, img->width, img->height); + convert_image(data, dst_format, img->data, src_format, img->width, img->height); //GB.Free(POINTER(&img->data)); - IMAGE_take(img, &_image_owner, NULL, img->width, img->height, data); + IMAGE_take(img, &_image_owner, data, img->width, img->height, data); } // Check if a temporary handle is needed, and create it if needed by calling the owner "temp" function