* 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
This commit is contained in:
Benoît Minisini 2009-01-26 17:42:53 +00:00
parent 3769319e5a
commit f22644997e
3 changed files with 61 additions and 11 deletions

View file

@ -176,7 +176,7 @@ BEGIN_METHOD(CIMAGE_load, GB_STRING path)
if (pic) if (pic)
{ {
image = CIMAGE_create(pic); image = CIMAGE_create(pic);
PICTURE->getPixbuf(); pic->getPixbuf();
GB.ReturnObject(image); GB.ReturnObject(image);
return; return;
} }

View file

@ -230,6 +230,7 @@ extern "C"
GB.LoadComponent("gb.draw"); GB.LoadComponent("gb.draw");
GB.GetInterface("gb.image", IMAGE_INTERFACE_VERSION, &IMAGE); GB.GetInterface("gb.image", IMAGE_INTERFACE_VERSION, &IMAGE);
IMAGE.SetDefaultFormat(GB_IMAGE_RGBA);
return TRUE; return TRUE;
} }

View file

@ -24,6 +24,8 @@
#include "image.h" #include "image.h"
//#define DEBUG_CONVERT
static int _default_format = GB_IMAGE_RGBA; static int _default_format = GB_IMAGE_RGBA;
static inline unsigned char *GET_END_POINTER(GB_IMG *image) 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) static inline uint PREMUL(uint x)
{ {
uint a = x >> 24; uint a = x >> 24;
if (a == 0)
return 0;
else if (a == 0xFF)
return x;
uint t = (x & 0xff00ff) * a; uint t = (x & 0xff00ff) * a;
t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8; t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8;
t &= 0xff00ff; t &= 0xff00ff;
@ -47,12 +55,16 @@ static inline uint PREMUL(uint x)
static inline uint INV_PREMUL(uint p) static inline uint INV_PREMUL(uint p)
{ {
if (ALPHA(p) == 0)
return 0;
else if (ALPHA(p) == 0xFF)
return p;
else
return return
(ALPHA(p) == 0 ? 0 :
((ALPHA(p) << 24) ((ALPHA(p) << 24)
| (((255*RED(p))/ ALPHA(p)) << 16) | (((255*RED(p))/ ALPHA(p)) << 16)
| (((255*GREEN(p)) / ALPHA(p)) << 8) | (((255*GREEN(p)) / ALPHA(p)) << 8)
| ((255*BLUE(p)) / ALPHA(p)))); | ((255*BLUE(p)) / ALPHA(p)));
} }
static inline uint SWAP(uint 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 = { static GB_IMG_OWNER _image_owner = {
"gb.image", "gb.image",
free_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; uint *p, *pm;
bool psrc, pdst; 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); len = w * h * sizeof(uint);
dm = &d[len]; 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); pdst = GB_IMAGE_FMT_IS_PREMULTIPLIED(dst_format);
dst_format = GB_IMAGE_FMT_CLEAR_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) if (dst_format == GB_IMAGE_BGRA || dst_format == GB_IMAGE_BGRX)
{ {
switch (src_format) switch (src_format)
@ -197,11 +218,17 @@ static void convert_image(uchar *dst, int dst_format, uchar *src, int src_format
__0123: __0123:
#ifdef DEBUG_CONVERT
fprintf(stderr, "convert_image: 0123\n");
#endif
memcpy(dst, src, len); memcpy(dst, src, len);
goto __PREMULTIPLIED; goto __PREMULTIPLIED;
__3210: __3210:
#ifdef DEBUG_CONVERT
fprintf(stderr, "convert_image: 3210\n");
#endif
while (d != dm) while (d != dm)
{ {
d[0] = s[3]; d[0] = s[3];
@ -215,6 +242,10 @@ __3210:
__2103: __2103:
#ifdef DEBUG_CONVERT
fprintf(stderr, "convert_image: 2103\n");
#endif
while (d != dm) while (d != dm)
{ {
d[0] = s[2]; d[0] = s[2];
@ -228,6 +259,10 @@ __2103:
__1230: __1230:
#ifdef DEBUG_CONVERT
fprintf(stderr, "convert_image: 1230\n");
#endif
while (d != dm) while (d != dm)
{ {
d[0] = s[1]; d[0] = s[1];
@ -241,6 +276,10 @@ __1230:
__012X: __012X:
#ifdef DEBUG_CONVERT
fprintf(stderr, "convert_image: 012X\n");
#endif
while (d != dm) while (d != dm)
{ {
d[0] = s[0]; d[0] = s[0];
@ -254,6 +293,10 @@ __012X:
__210X: __210X:
#ifdef DEBUG_CONVERT
fprintf(stderr, "convert_image: 210X\n");
#endif
while (d != dm) while (d != dm)
{ {
d[0] = s[2]; d[0] = s[2];
@ -275,6 +318,9 @@ __PREMULTIPLIED:
if (psrc) if (psrc)
{ {
#ifdef DEBUG_CONVERT
fprintf(stderr, "convert_image: premultiplied -> normal\n");
#endif
// convert premultiplied to normal // convert premultiplied to normal
while (p != pm) while (p != pm)
{ {
@ -284,6 +330,9 @@ __PREMULTIPLIED:
} }
else else
{ {
#ifdef DEBUG_CONVERT
fprintf(stderr, "convert_image: normal -> premultiplied\n");
#endif
// convert normal to premultiplied // convert normal to premultiplied
while (p != pm) while (p != pm)
{ {
@ -314,6 +363,7 @@ void IMAGE_create(GB_IMG *img, int width, int height, int format)
img->format = format; img->format = format;
GB.Alloc(POINTER(&img->data), IMAGE_size(img)); GB.Alloc(POINTER(&img->data), IMAGE_size(img));
img->owner = &_image_owner; 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) 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)); 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; uchar *data;
int src_format = img->format;
if (format == img->format) if (src_format == dst_format)
return; return;
//fprintf(stderr, "convert image %p: %d -> %d\n", img, img->format, format);
//IMAGE_create(&tmp, img->width, img->height, format); //IMAGE_create(&tmp, img->width, img->height, format);
img->format = format; img->format = dst_format;
GB.Alloc(POINTER(&data), IMAGE_size(img)); 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)); //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 // Check if a temporary handle is needed, and create it if needed by calling the owner "temp" function