From 3d9a1198db571973e2760d6f27c771cbe31c844b Mon Sep 17 00:00:00 2001 From: Richard Wilson Date: Wed, 22 Feb 2006 01:58:19 +0000 Subject: [project @ 2006-02-22 01:58:19 by rjw] Reduce constant bitmap overhead per reference by moving to a flag word. Allow bitmaps to be reduced back to their raw data to free extra memory in a highly efficient manner. svn path=/import/netsurf/; revision=2089 --- image/bitmap.h | 16 ++++++++++------ image/gif.c | 8 ++++++++ image/gifread.c | 4 ++-- image/jpeg.c | 3 +-- image/mng.c | 2 +- 5 files changed, 22 insertions(+), 11 deletions(-) (limited to 'image') diff --git a/image/bitmap.h b/image/bitmap.h index c187b3ecb..bae1e1a15 100644 --- a/image/bitmap.h +++ b/image/bitmap.h @@ -20,18 +20,20 @@ #include #include -typedef enum { - BITMAP_READY, /** Bitmap buffer is ready */ - BITMAP_ALLOCATE_MEMORY, /** Allocate memory */ - BITMAP_CLEAR_MEMORY, /** Clear the memory */ -} bitmap_state; +#define BITMAP_NEW 0 +#define BITMAP_OPAQUE (1 << 0) /** image is opaque */ +#define BITMAP_MODIFIED (1 << 1) /** buffer has been modified */ +#define BITMAP_PERSISTENT (1 << 2) /** retain between sessions */ +#define BITMAP_CLEAR_MEMORY (1 << 3) /** memory should be wiped */ +#define BITMAP_SUSPENDED (1 << 4) /** currently suspended */ +#define BITMAP_READY (1 << 5) /** fully initialised */ struct content; /** An opaque image. */ struct bitmap; -struct bitmap *bitmap_create(int width, int height, bitmap_state state); +struct bitmap *bitmap_create(int width, int height, unsigned int state); void bitmap_set_opaque(struct bitmap *bitmap, bool opaque); bool bitmap_test_opaque(struct bitmap *bitmap); bool bitmap_get_opaque(struct bitmap *bitmap); @@ -40,5 +42,7 @@ size_t bitmap_get_rowstride(struct bitmap *bitmap); void bitmap_destroy(struct bitmap *bitmap); bool bitmap_save(struct bitmap *bitmap, const char *path); void bitmap_modified(struct bitmap *bitmap); +void bitmap_set_suspendable(struct bitmap *bitmap, void *private_word, + void (*invalidate)(struct bitmap *bitmap, void *private_word)); #endif diff --git a/image/gif.c b/image/gif.c index 312139173..5bd2c25aa 100644 --- a/image/gif.c +++ b/image/gif.c @@ -35,6 +35,7 @@ #ifdef WITH_GIF +static void nsgif_invalidate(struct bitmap *bitmap, void *private_word); static void nsgif_animate(void *p); static void nsgif_get_frame(struct content *c); @@ -105,6 +106,8 @@ bool nsgif_convert(struct content *c, int iwidth, int iheight) { c->data.gif.current_frame = 0; if (gif->frame_count_partial > 1) schedule(gif->frames[0].frame_delay, nsgif_animate, c); + else + bitmap_set_suspendable(gif->frame_image, gif, nsgif_invalidate); /* Exit as a success */ @@ -113,6 +116,11 @@ bool nsgif_convert(struct content *c, int iwidth, int iheight) { return true; } +void nsgif_invalidate(struct bitmap *bitmap, void *private_word) { + struct gif_animation *gif = (struct gif_animation *)private_word; + + gif->decoded_frame = -1; +} bool nsgif_redraw(struct content *c, int x, int y, int width, int height, diff --git a/image/gifread.c b/image/gifread.c index ba26452d8..9d81bb6a7 100644 --- a/image/gifread.c +++ b/image/gifread.c @@ -204,7 +204,7 @@ int gif_initialise(struct gif_animation *gif) { /* Initialise the sprite header */ - if ((gif->frame_image = bitmap_create(gif->width, gif->height, BITMAP_ALLOCATE_MEMORY)) == NULL) { + if ((gif->frame_image = bitmap_create(gif->width, gif->height, BITMAP_NEW)) == NULL) { gif_finalise(gif); return GIF_INSUFFICIENT_MEMORY; } @@ -283,7 +283,7 @@ static int gif_initialise_sprite(struct gif_animation *gif, unsigned int width, /* Allocate some more memory */ - if ((buffer = bitmap_create(max_width, max_height, BITMAP_ALLOCATE_MEMORY)) == NULL) + if ((buffer = bitmap_create(max_width, max_height, BITMAP_NEW)) == NULL) return GIF_INSUFFICIENT_MEMORY; bitmap_destroy(gif->frame_image); gif->frame_image = buffer; diff --git a/image/jpeg.c b/image/jpeg.c index 3efe698df..197a977b4 100644 --- a/image/jpeg.c +++ b/image/jpeg.c @@ -94,7 +94,7 @@ bool nsjpeg_convert(struct content *c, int w, int h) width = cinfo.output_width; height = cinfo.output_height; - bitmap = bitmap_create(width, height, BITMAP_ALLOCATE_MEMORY); + bitmap = bitmap_create(width, height, BITMAP_NEW | BITMAP_OPAQUE); if (bitmap) pixels = bitmap_get_buffer(bitmap); if ((!bitmap) || (!pixels)) { @@ -107,7 +107,6 @@ bool nsjpeg_convert(struct content *c, int w, int h) warn_user("NoMemory", 0); return false; } - bitmap_set_opaque(bitmap, true); rowstride = bitmap_get_rowstride(bitmap); do { diff --git a/image/mng.c b/image/mng.c index 838595960..cb4a7eef4 100644 --- a/image/mng.c +++ b/image/mng.c @@ -190,7 +190,7 @@ mng_bool nsmng_processheader(mng_handle mng, mng_uint32 width, mng_uint32 height LOG(("processing header (%p) %d, %d", c, width, height)); - c->bitmap = bitmap_create(width, height, BITMAP_ALLOCATE_MEMORY); + c->bitmap = bitmap_create(width, height, BITMAP_NEW); if (!c->bitmap) { msg_data.error = messages_get("NoMemory"); content_broadcast(c, CONTENT_MSG_ERROR, msg_data); -- cgit v1.2.3