[GB.IMAGE]
* NEW: New API for marking an image as modified, and for synchronizing it before reading it, when the temporary image owner needs it. git-svn-id: svn://localhost/gambas/trunk@3016 867c0c6c-44f3-4631-809d-bfa615b0a4ec
This commit is contained in:
parent
b2bba45700
commit
6059d4dcb7
14 changed files with 103 additions and 55 deletions
|
@ -70,7 +70,7 @@
|
|||
}
|
||||
}
|
||||
{ VBox1 VBox
|
||||
MoveScaled(28,0,29,17)
|
||||
MoveScaled(28,0,28,17)
|
||||
Expand = True
|
||||
{ chkIgnoreStrings CheckBox
|
||||
MoveScaled(0,0,25,4)
|
||||
|
@ -132,7 +132,7 @@
|
|||
Index = 1
|
||||
Text = ("Browse")
|
||||
{ VBox4 VBox
|
||||
MoveScaled(1,1,81.00000000000001,31)
|
||||
MoveScaled(1,1,81,31)
|
||||
Expand = True
|
||||
Spacing = True
|
||||
{ panBrowse Panel
|
||||
|
|
|
@ -51,22 +51,13 @@ static void *temp_image(GB_IMG *img)
|
|||
return image;
|
||||
}
|
||||
|
||||
static void lock_image(void *image)
|
||||
{
|
||||
}
|
||||
|
||||
static void unlock_image(void *image, int changed)
|
||||
{
|
||||
}
|
||||
|
||||
static GB_IMG_OWNER _image_owner = {
|
||||
"gb.gtk",
|
||||
GB_IMAGE_RGBA,
|
||||
free_image,
|
||||
free_image,
|
||||
temp_image,
|
||||
lock_image,
|
||||
unlock_image,
|
||||
NULL
|
||||
};
|
||||
|
||||
gPicture *CIMAGE_get(CIMAGE *_object)
|
||||
|
|
|
@ -48,22 +48,13 @@ static void *temp_image(GB_IMG *img)
|
|||
return image;
|
||||
}
|
||||
|
||||
static void lock_image(void *image)
|
||||
{
|
||||
}
|
||||
|
||||
static void unlock_image(void *image, int changed)
|
||||
{
|
||||
}
|
||||
|
||||
static GB_IMG_OWNER _image_owner = {
|
||||
"gb.image.imlib",
|
||||
GB_IMAGE_BGRA,
|
||||
free_image,
|
||||
free_image,
|
||||
temp_image,
|
||||
lock_image,
|
||||
unlock_image,
|
||||
NULL,
|
||||
};
|
||||
|
||||
Imlib_Image check_image(void *_object)
|
||||
|
|
|
@ -128,6 +128,7 @@ BEGIN_METHOD(CIMAGE_save, GB_STRING path; GB_INTEGER quality)
|
|||
goto __END;
|
||||
}
|
||||
|
||||
SYNCHRONIZE_IMAGE(THIS);
|
||||
IMAGE.Convert(THIS, GB_IMAGE_RGBA);
|
||||
image = gdk_pixbuf_new_from_data((const guchar *)THIS->data, GDK_COLORSPACE_RGB, TRUE, 8, THIS->width, THIS->height, THIS->width * sizeof(uint), NULL, NULL);
|
||||
|
||||
|
|
|
@ -95,22 +95,13 @@ static void *temp_image(GB_IMG *img)
|
|||
return image;
|
||||
}
|
||||
|
||||
static void lock_image(void *image)
|
||||
{
|
||||
}
|
||||
|
||||
static void unlock_image(void *image, int changed)
|
||||
{
|
||||
}
|
||||
|
||||
static GB_IMG_OWNER _image_owner = {
|
||||
"gb.qt4",
|
||||
GB_IMAGE_BGRA,
|
||||
free_image,
|
||||
free_image,
|
||||
temp_image,
|
||||
lock_image,
|
||||
unlock_image,
|
||||
NULL,
|
||||
};
|
||||
|
||||
QImage *CIMAGE_get(CIMAGE *_object)
|
||||
|
|
|
@ -33,6 +33,18 @@ static void free_image(GB_IMG *img, void *image)
|
|||
delete (SDLsurface *)image;
|
||||
}
|
||||
|
||||
static void check_modified(GB_IMG *img)
|
||||
{
|
||||
// Vérifie le flag modified
|
||||
if (img->modified)
|
||||
{
|
||||
// Synchronize l'image image->texture
|
||||
|
||||
// Réinitialise le flag modified
|
||||
img->modified = false;
|
||||
}
|
||||
}
|
||||
|
||||
static void *temp_image(GB_IMG *img)
|
||||
{
|
||||
SDLsurface *image;
|
||||
|
@ -40,19 +52,23 @@ static void *temp_image(GB_IMG *img)
|
|||
if (!img->data)
|
||||
image = new SDLsurface();
|
||||
else
|
||||
{
|
||||
// Pas besoin de faire de synchro image->texture, vu qu'on crée une nouvelle surface ?
|
||||
image = new SDLsurface((char *)img->data, img->width, img->height);
|
||||
}
|
||||
|
||||
image->SetAlphaBuffer(true);
|
||||
return image;
|
||||
}
|
||||
|
||||
static void lock_image(void *image)
|
||||
static void sync_image(GB_IMG *image)
|
||||
{
|
||||
// Synchronize l'image texture->image
|
||||
|
||||
// Puis mets le flag de synchro à false
|
||||
image->sync = false;
|
||||
}
|
||||
|
||||
static void unlock_image(void *image, int changed)
|
||||
{
|
||||
}
|
||||
|
||||
static GB_IMG_OWNER _image_owner = {
|
||||
"gb.sdl",
|
||||
|
@ -60,13 +76,17 @@ static GB_IMG_OWNER _image_owner = {
|
|||
free_image,
|
||||
free_image,
|
||||
temp_image,
|
||||
lock_image,
|
||||
unlock_image,
|
||||
sync_image,
|
||||
};
|
||||
|
||||
SDLsurface *CIMAGE_get(CIMAGE *_object)
|
||||
{
|
||||
return (SDLsurface *)IMAGE.Check(THIS_IMAGE, &_image_owner);
|
||||
GB_IMG *img = THIS_IMAGE;
|
||||
|
||||
// Si ce n'est pas nécessaire de le faire systématiquement chaque fois qu'on a besoin de l'image,
|
||||
// alors ne pas le faire ici, mais explicitement où c'est vraiment nécessaire.
|
||||
check_modified(img);
|
||||
return (SDLsurface *)IMAGE.Check(img, &_image_owner);
|
||||
}
|
||||
|
||||
#define check_image CIMAGE_get
|
||||
|
|
|
@ -47,9 +47,6 @@ typedef
|
|||
typedef
|
||||
struct {
|
||||
STREAM_CLASS *type;
|
||||
char *buffer;
|
||||
short buffer_pos;
|
||||
short buffer_len;
|
||||
short mode;
|
||||
unsigned swap : 1;
|
||||
unsigned eol : 2;
|
||||
|
@ -65,6 +62,9 @@ typedef
|
|||
#else
|
||||
unsigned _reserved : 7;
|
||||
#endif
|
||||
short buffer_pos;
|
||||
short buffer_len;
|
||||
char *buffer;
|
||||
}
|
||||
PACKED
|
||||
STREAM_COMMON;
|
||||
|
|
|
@ -31,6 +31,8 @@ static void get_info(GB_IMAGE img, uint **data, uint *width, uint *height, uint
|
|||
{
|
||||
GB_IMG *info = (GB_IMG *)img;
|
||||
|
||||
SYNCHRONIZE_IMAGE(info);
|
||||
|
||||
*data = (uint *)info->data;
|
||||
if (width) *width = info->width;
|
||||
if (height) *height = info->height;
|
||||
|
|
|
@ -68,6 +68,7 @@ QImage::QImage(GB_IMAGE image)
|
|||
{
|
||||
init();
|
||||
img = (GB_IMG *)image;
|
||||
SYNCHRONIZE_IMAGE(img);
|
||||
getInfo();
|
||||
}
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ public:
|
|||
void reset() { };
|
||||
void release();
|
||||
void create(int w, int h, bool t);
|
||||
GB_IMAGE object() { created = false; return (GB_IMAGE)img; }
|
||||
GB_IMAGE object() { created = false; MODIFY_IMAGE(img); return (GB_IMAGE)img; }
|
||||
int depth() const { return 32; }
|
||||
int width() const { return img->width; }
|
||||
int height() const { return img->height; }
|
||||
|
|
|
@ -70,8 +70,7 @@ typedef
|
|||
void (*free)(struct GB_IMG *img, void *handle); // free owner handle
|
||||
void (*release)(struct GB_IMG *img, void *handle); // free temporary handle
|
||||
void *(*temp)(struct GB_IMG *img); // create a temporary handle for an image and returns it
|
||||
void (*lock)(void *handle); // lock, before accessing pixels
|
||||
void (*unlock)(void *handle, int changed); // unlock, after accessing pixels, indicate if image was changed
|
||||
void (*sync)(struct GB_IMG *img); // synchronize the data. Called only if the GB_IMG.sync flag is set
|
||||
}
|
||||
GB_IMG_OWNER;
|
||||
|
||||
|
@ -88,6 +87,8 @@ typedef
|
|||
void *owner_handle; // handle for the owner
|
||||
GB_IMG_OWNER *temp_owner; // owner of the temporary handle that does not own the data
|
||||
void *temp_handle; // temporary handle
|
||||
unsigned modified : 1; // data has been modified by gb.image
|
||||
unsigned sync : 1; // data must be synchronized by calling GB_IMG_OWNER.sync()
|
||||
}
|
||||
GB_IMG;
|
||||
|
||||
|
@ -129,6 +130,8 @@ typedef
|
|||
void (*Take)(GB_IMG *img, GB_IMG_OWNER *owner, void *owner_handle, int width, int height, unsigned char *data);
|
||||
// Create a temporary handle on the image without becoming the owner.
|
||||
void *(*Check)(GB_IMG *img, GB_IMG_OWNER *temp_owner);
|
||||
// Synchronize the image data if needed
|
||||
void (*Synchronize)(GB_IMG *img);
|
||||
// Return the size of the image data in bytes
|
||||
int (*Size)(GB_IMG *img);
|
||||
// Set the default format used when creating images
|
||||
|
@ -150,6 +153,9 @@ typedef
|
|||
|
||||
#define GB_IMG_HANDLE(_image) ((_image)->temp_handle)
|
||||
|
||||
#define SYNCHRONIZE_IMAGE(_image) (IMAGE.Synchronize(_image))
|
||||
#define MODIFY_IMAGE(_image) ((_image)->modified = 1)
|
||||
|
||||
#define COLOR_DEFAULT (-1)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -141,22 +141,13 @@ static void free_image(GB_IMG *img, void *image)
|
|||
GB.Free(POINTER(&img->data));
|
||||
}
|
||||
|
||||
static void lock_image(void *image)
|
||||
{
|
||||
}
|
||||
|
||||
static void unlock_image(void *image, int changed)
|
||||
{
|
||||
}
|
||||
|
||||
static GB_IMG_OWNER _image_owner = {
|
||||
"gb.image",
|
||||
0,
|
||||
free_image,
|
||||
free_image,
|
||||
NULL,
|
||||
lock_image,
|
||||
unlock_image,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
|
@ -365,6 +356,9 @@ __PREMULTIPLIED:
|
|||
}
|
||||
}
|
||||
|
||||
#define SYNCHRONIZE(_img) ({ if ((_img)->sync) (*(_img)->temp_owner->sync)(_img); })
|
||||
#define MODIFY(_img) ((_img)->modified = TRUE)
|
||||
|
||||
int IMAGE_size(GB_IMG *img)
|
||||
{
|
||||
return img->width * img->height * (GB_IMAGE_FMT_IS_24_BITS(img->format) ? 3 : 4);
|
||||
|
@ -439,6 +433,8 @@ void *IMAGE_check(GB_IMG *img, GB_IMG_OWNER *temp_owner)
|
|||
// If we are not the owner, then we will have to create the temporary handle ourself
|
||||
else
|
||||
{
|
||||
// Synchronize the image if needed
|
||||
SYNCHRONIZE(img);
|
||||
// Conversion can make gb.image the new owner and temporary owner
|
||||
IMAGE_convert(img, temp_owner->format);
|
||||
img->temp_handle = (*temp_owner->temp)(img);
|
||||
|
@ -495,6 +491,11 @@ void IMAGE_delete(GB_IMG *img)
|
|||
img->format = 0;
|
||||
}
|
||||
|
||||
void IMAGE_synchronize(GB_IMG *img)
|
||||
{
|
||||
SYNCHRONIZE(img);
|
||||
}
|
||||
|
||||
#define GET_POINTER(_img, _p, _pm) \
|
||||
uint *_p = (uint *)(_img)->data; \
|
||||
uint *_pm = (uint *)GET_END_POINTER(_img);
|
||||
|
@ -506,6 +507,8 @@ void IMAGE_fill(GB_IMG *img, GB_COLOR col)
|
|||
col = from_GB_COLOR(col, img->format);
|
||||
while (p != pm)
|
||||
*p++ = col;
|
||||
|
||||
MODIFY(img);
|
||||
}
|
||||
|
||||
// GB_IMAGE_RGB[APX] only
|
||||
|
@ -515,6 +518,8 @@ void IMAGE_make_gray(GB_IMG *img)
|
|||
uint col;
|
||||
uchar g;
|
||||
|
||||
SYNCHRONIZE(img);
|
||||
|
||||
while (p != pm)
|
||||
{
|
||||
col = BGRA_from_format(*p, img->format);
|
||||
|
@ -522,6 +527,8 @@ void IMAGE_make_gray(GB_IMG *img)
|
|||
|
||||
*p++ = BGRA_to_format(RGBA(g, g, g, ALPHA(col)), img->format);
|
||||
}
|
||||
|
||||
MODIFY(img);
|
||||
}
|
||||
|
||||
GB_COLOR IMAGE_get_pixel(GB_IMG *img, int x, int y)
|
||||
|
@ -531,6 +538,7 @@ GB_COLOR IMAGE_get_pixel(GB_IMG *img, int x, int y)
|
|||
if (!is_valid(img, x, y))
|
||||
return (-1);
|
||||
|
||||
SYNCHRONIZE(img);
|
||||
col = ((uint *)img->data)[y * img->width + x];
|
||||
return to_GB_COLOR(col, img->format);
|
||||
}
|
||||
|
@ -540,7 +548,9 @@ void IMAGE_set_pixel(GB_IMG *img, int x, int y, GB_COLOR col)
|
|||
if (!is_valid(img, x, y))
|
||||
return;
|
||||
|
||||
SYNCHRONIZE(img);
|
||||
((uint *)img->data)[y * img->width + x] = from_GB_COLOR(col, img->format);
|
||||
MODIFY(img);
|
||||
}
|
||||
|
||||
void IMAGE_fill_rect(GB_IMG *img, int x, int y, int w, int h, GB_COLOR col)
|
||||
|
@ -558,6 +568,8 @@ void IMAGE_fill_rect(GB_IMG *img, int x, int y, int w, int h, GB_COLOR col)
|
|||
|
||||
if (w <= 0 || h <= 0) return;
|
||||
|
||||
SYNCHRONIZE(img);
|
||||
|
||||
c = from_GB_COLOR(col, img->format);
|
||||
p = &((uint *)img->data)[y * img->width + x];
|
||||
|
||||
|
@ -568,6 +580,8 @@ void IMAGE_fill_rect(GB_IMG *img, int x, int y, int w, int h, GB_COLOR col)
|
|||
h--;
|
||||
p += img->width - w;
|
||||
}
|
||||
|
||||
MODIFY(img);
|
||||
}
|
||||
|
||||
void IMAGE_replace(GB_IMG *img, GB_COLOR src, GB_COLOR dst, bool noteq)
|
||||
|
@ -577,6 +591,8 @@ void IMAGE_replace(GB_IMG *img, GB_COLOR src, GB_COLOR dst, bool noteq)
|
|||
src = from_GB_COLOR(src, img->format);
|
||||
dst = from_GB_COLOR(dst, img->format);
|
||||
|
||||
SYNCHRONIZE(img);
|
||||
|
||||
if (noteq)
|
||||
{
|
||||
while (p != pm)
|
||||
|
@ -595,6 +611,8 @@ void IMAGE_replace(GB_IMG *img, GB_COLOR src, GB_COLOR dst, bool noteq)
|
|||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
MODIFY(img);
|
||||
}
|
||||
|
||||
// Comes from the GIMP
|
||||
|
@ -678,6 +696,8 @@ void IMAGE_make_transparent(GB_IMG *img, GB_COLOR col)
|
|||
|
||||
//fprintf(stderr, "IMAGE_make_transparent: %d x %d / %d\n", img->width, img->height, img->format);
|
||||
|
||||
SYNCHRONIZE(img);
|
||||
|
||||
color = from_GB_COLOR(col, img->format);
|
||||
rgb_color.b = BLUE(color) / 255.0;
|
||||
rgb_color.g = GREEN(color) / 255.0;
|
||||
|
@ -706,6 +726,7 @@ void IMAGE_make_transparent(GB_IMG *img, GB_COLOR col)
|
|||
p++;
|
||||
}
|
||||
|
||||
MODIFY(img);
|
||||
//fprintf(stderr, "IMAGE_make_transparent: ** DONE **\n");
|
||||
}
|
||||
|
||||
|
@ -739,6 +760,9 @@ void IMAGE_bitblt(GB_IMG *dst, int dx, int dy, GB_IMG *src, int sx, int sy, int
|
|||
if ( dy + sh > dst->height ) sh = dst->height - dy;
|
||||
if ( sw <= 0 || sh <= 0 ) return; // Nothing left to copy
|
||||
|
||||
SYNCHRONIZE(src);
|
||||
SYNCHRONIZE(dst);
|
||||
|
||||
if (GB_IMAGE_FMT_IS_32_BITS(src->format))
|
||||
{
|
||||
uint *d = (uint *)dst->data + dy * dst->width + dx;
|
||||
|
@ -787,6 +811,8 @@ void IMAGE_bitblt(GB_IMG *dst, int dx, int dy, GB_IMG *src, int sx, int sy, int
|
|||
s += ds;
|
||||
}
|
||||
}
|
||||
|
||||
MODIFY(dst);
|
||||
}
|
||||
|
||||
void IMAGE_compose(GB_IMG *dst, int dx, int dy, GB_IMG *src, int sx, int sy, int sw, int sh)
|
||||
|
@ -808,6 +834,9 @@ void IMAGE_compose(GB_IMG *dst, int dx, int dy, GB_IMG *src, int sx, int sy, int
|
|||
if ( dy + sh > dst->height ) sh = dst->height - dy;
|
||||
if ( sw <= 0 || sh <= 0 ) return;
|
||||
|
||||
SYNCHRONIZE(src);
|
||||
SYNCHRONIZE(dst);
|
||||
|
||||
/*if ( src->hasAlphaBuffer() ) {
|
||||
QRgb* d = (QRgb*)dst->scanLine(dy) + dx;
|
||||
QRgb* s = (QRgb*)src->scanLine(sy) + sx;
|
||||
|
@ -871,6 +900,8 @@ void IMAGE_compose(GB_IMG *dst, int dx, int dy, GB_IMG *src, int sx, int sy, int
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
MODIFY(dst);
|
||||
}
|
||||
|
||||
void IMAGE_colorize(GB_IMG *img, GB_COLOR color)
|
||||
|
@ -881,6 +912,8 @@ void IMAGE_colorize(GB_IMG *img, GB_COLOR color)
|
|||
int r, g, b;
|
||||
int hcol, scol, vcol;
|
||||
|
||||
SYNCHRONIZE(img);
|
||||
|
||||
col = from_GB_COLOR(color, img->format);
|
||||
COLOR_rgb_to_hsv(RED(col), GREEN(col), BLUE(col), &hcol, &scol, &vcol);
|
||||
|
||||
|
@ -891,6 +924,8 @@ void IMAGE_colorize(GB_IMG *img, GB_COLOR color)
|
|||
COLOR_hsv_to_rgb(hcol, scol, v, &r, &g, &b);
|
||||
*p++ = BGRA_to_format(RGBA(r, g, b, ALPHA(col)), img->format);
|
||||
}
|
||||
|
||||
MODIFY(img);
|
||||
}
|
||||
|
||||
void IMAGE_mask(GB_IMG *img, GB_COLOR color)
|
||||
|
@ -900,6 +935,8 @@ void IMAGE_mask(GB_IMG *img, GB_COLOR color)
|
|||
unsigned char red[256], blue[256], green[256], alpha[256];
|
||||
int i, r, g, b, a;
|
||||
|
||||
SYNCHRONIZE(img);
|
||||
|
||||
col = from_GB_COLOR(color, img->format);
|
||||
r = RED(col);
|
||||
g = GREEN(col);
|
||||
|
@ -919,6 +956,8 @@ void IMAGE_mask(GB_IMG *img, GB_COLOR color)
|
|||
col = BGRA_from_format(*p, img->format);
|
||||
*p++ = BGRA_to_format(RGBA(red[RED(col)], green[GREEN(col)], blue[BLUE(col)], alpha[ALPHA(col)]), img->format);
|
||||
}
|
||||
|
||||
MODIFY(img);
|
||||
}
|
||||
|
||||
void IMAGE_mirror(GB_IMG *src, GB_IMG *dst, bool horizontal, bool vertical)
|
||||
|
@ -935,6 +974,8 @@ void IMAGE_mirror(GB_IMG *src, GB_IMG *dst, bool horizontal, bool vertical)
|
|||
int dy = vertical ? (h - 1) : 0;
|
||||
int sx, sy;
|
||||
|
||||
SYNCHRONIZE(src);
|
||||
|
||||
if (GB_IMAGE_FMT_IS_24_BITS(src->format))
|
||||
{
|
||||
for (sy = 0; sy < h; sy++, dy += dyi)
|
||||
|
@ -957,6 +998,8 @@ void IMAGE_mirror(GB_IMG *src, GB_IMG *dst, bool horizontal, bool vertical)
|
|||
dsl[dx] = ssl[sx];
|
||||
}
|
||||
}
|
||||
|
||||
MODIFY(dst);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
|
|
@ -38,6 +38,7 @@ void IMAGE_create(GB_IMG *img, int width, int height, int format);
|
|||
void IMAGE_create_with_data(GB_IMG *img, int width, int height, int format, unsigned char *data);
|
||||
void IMAGE_take(GB_IMG *img, GB_IMG_OWNER *owner, void *owner_handle, int width, int height, unsigned char *data);
|
||||
void *IMAGE_check(GB_IMG *img, GB_IMG_OWNER *temp_owner);
|
||||
void IMAGE_synchronize(GB_IMG *img);
|
||||
void IMAGE_delete(GB_IMG *img);
|
||||
void IMAGE_convert(GB_IMG *img, int format);
|
||||
void IMAGE_fill(GB_IMG *img, GB_COLOR col);
|
||||
|
|
|
@ -58,6 +58,7 @@ void *GB_IMAGE_1[] EXPORT =
|
|||
(void *)create_image,
|
||||
(void *)IMAGE_take,
|
||||
(void *)IMAGE_check,
|
||||
(void *)IMAGE_synchronize,
|
||||
(void *)IMAGE_size,
|
||||
(void *)IMAGE_set_default_format,
|
||||
(void *)IMAGE_get_default_format,
|
||||
|
|
Loading…
Reference in a new issue