diff options
author | John Mark Bell <jmb@netsurf-browser.org> | 2011-05-06 20:40:09 +0000 |
---|---|---|
committer | John Mark Bell <jmb@netsurf-browser.org> | 2011-05-06 20:40:09 +0000 |
commit | e71691bae890040b83cfd54a2d9a1097d5026866 (patch) | |
tree | 96b2680dc6559ca0ab88fa0b6a533c13b7c9487e /image/bmp.c | |
parent | e77b1a29550e4753f771848705975295a6ebe99e (diff) | |
download | netsurf-e71691bae890040b83cfd54a2d9a1097d5026866.tar.gz netsurf-e71691bae890040b83cfd54a2d9a1097d5026866.tar.bz2 |
Merge branches/jmb/content-factory to trunk
svn path=/trunk/netsurf/; revision=12283
Diffstat (limited to 'image/bmp.c')
-rw-r--r-- | image/bmp.c | 225 |
1 files changed, 193 insertions, 32 deletions
diff --git a/image/bmp.c b/image/bmp.c index 1e8ec5be9..dbb4d9796 100644 --- a/image/bmp.c +++ b/image/bmp.c @@ -31,13 +31,40 @@ #include <libnsbmp.h> #include "utils/config.h" #include "content/content_protected.h" +#include "content/hlcache.h" #include "desktop/plotters.h" #include "image/bitmap.h" #include "image/bmp.h" #include "utils/log.h" #include "utils/messages.h" +#include "utils/talloc.h" #include "utils/utils.h" +typedef struct nsbmp_content { + struct content base; + + bmp_image *bmp; /** BMP image data */ +} nsbmp_content; + +static nserror nsbmp_create(const content_handler *handler, + lwc_string *imime_type, const struct http_parameter *params, + llcache_handle *llcache, const char *fallback_charset, + bool quirks, struct content **c); +static nserror nsbmp_create_bmp_data(nsbmp_content *bmp); +static bool nsbmp_convert(struct content *c); +static void nsbmp_destroy(struct content *c); +static bool nsbmp_redraw(struct content *c, int x, int y, + int width, int height, const struct rect *clip, + float scale, colour background_colour); +static bool nsbmp_redraw_tiled(struct content *c, int x, int y, + int width, int height, const struct rect *clip, + float scale, colour background_colour, + bool repeat_x, bool repeat_y); +static nserror nsbmp_clone(const struct content *old, struct content **newc); +static content_type nsbmp_content_type(lwc_string *mime_type); + +static void *nsbmp_bitmap_create(int width, int height, unsigned int bmp_state); + /* The Bitmap callbacks function table; * necessary for interaction with nsbmplib. */ @@ -49,25 +76,131 @@ bmp_bitmap_callback_vt bmp_bitmap_callbacks = { .bitmap_get_bpp = bitmap_get_bpp }; -bool nsbmp_create(struct content *c, const struct http_parameter *params) +static const content_handler nsbmp_content_handler = { + nsbmp_create, + NULL, + nsbmp_convert, + NULL, + nsbmp_destroy, + NULL, + NULL, + NULL, + nsbmp_redraw, + nsbmp_redraw_tiled, + NULL, + NULL, + nsbmp_clone, + NULL, + nsbmp_content_type, + false +}; + +static const char *nsbmp_types[] = { + "application/bmp", + "application/preview", + "application/x-bmp", + "application/x-win-bitmap", + "image/bmp", + "image/ms-bmp", + "image/x-bitmap", + "image/x-bmp", + "image/x-ms-bmp", + "image/x-win-bitmap", + "image/x-windows-bmp", + "image/x-xbitmap" +}; + +static lwc_string *nsbmp_mime_types[NOF_ELEMENTS(nsbmp_types)]; + +nserror nsbmp_init(void) { + uint32_t i; + lwc_error lerror; + nserror error; + + for (i = 0; i < NOF_ELEMENTS(nsbmp_mime_types); i++) { + lerror = lwc_intern_string(nsbmp_types[i], + strlen(nsbmp_types[i]), + &nsbmp_mime_types[i]); + if (lerror != lwc_error_ok) { + error = NSERROR_NOMEM; + goto error; + } + + error = content_factory_register_handler(nsbmp_mime_types[i], + &nsbmp_content_handler); + if (error != NSERROR_OK) + goto error; + } + + return NSERROR_OK; + +error: + nsbmp_fini(); + + return error; +} + +void nsbmp_fini(void) +{ + uint32_t i; + + for (i = 0; i < NOF_ELEMENTS(nsbmp_mime_types); i++) { + if (nsbmp_mime_types[i] != NULL) + lwc_string_unref(nsbmp_mime_types[i]); + } +} + +nserror nsbmp_create(const content_handler *handler, + lwc_string *imime_type, const struct http_parameter *params, + llcache_handle *llcache, const char *fallback_charset, + bool quirks, struct content **c) +{ + nsbmp_content *bmp; + nserror error; + + bmp = talloc_zero(0, nsbmp_content); + if (bmp == NULL) + return NSERROR_NOMEM; + + error = content__init(&bmp->base, handler, imime_type, params, + llcache, fallback_charset, quirks); + if (error != NSERROR_OK) { + talloc_free(bmp); + return error; + } + + error = nsbmp_create_bmp_data(bmp); + if (error != NSERROR_OK) { + talloc_free(bmp); + return error; + } + + *c = (struct content *) bmp; + + return NSERROR_OK; +} + +nserror nsbmp_create_bmp_data(nsbmp_content *bmp) +{ union content_msg_data msg_data; - c->data.bmp.bmp = calloc(sizeof(struct bmp_image), 1); - if (!c->data.bmp.bmp) { + bmp->bmp = calloc(sizeof(struct bmp_image), 1); + if (bmp->bmp == NULL) { msg_data.error = messages_get("NoMemory"); - content_broadcast(c, CONTENT_MSG_ERROR, msg_data); - return false; + content_broadcast(&bmp->base, CONTENT_MSG_ERROR, msg_data); + return NSERROR_NOMEM; } - bmp_create(c->data.bmp.bmp, &bmp_bitmap_callbacks); - return true; -} + bmp_create(bmp->bmp, &bmp_bitmap_callbacks); + + return NSERROR_OK; +} bool nsbmp_convert(struct content *c) { + nsbmp_content *bmp = (nsbmp_content *) c; bmp_result res; - bmp_image *bmp; union content_msg_data msg_data; uint32_t swidth; const char *data; @@ -75,12 +208,10 @@ bool nsbmp_convert(struct content *c) char title[100]; /* set the bmp data */ - bmp = c->data.bmp.bmp; - data = content__get_source_data(c, &size); /* analyse the BMP */ - res = bmp_analyse(bmp, size, (unsigned char *) data); + res = bmp_analyse(bmp->bmp, size, (unsigned char *) data); switch (res) { case BMP_OK: break; @@ -96,17 +227,18 @@ bool nsbmp_convert(struct content *c) } /* Store our content width and description */ - c->width = bmp->width; - c->height = bmp->height; + c->width = bmp->bmp->width; + c->height = bmp->bmp->height; LOG(("BMP width %u height %u", c->width, c->height)); snprintf(title, sizeof(title), messages_get("BMPTitle"), c->width, c->height, size); content__set_title(c, title); - swidth = bmp->bitmap_callbacks.bitmap_get_bpp(bmp->bitmap) * bmp->width; - c->size += (swidth * bmp->height) + 16 + 44; + swidth = bmp->bmp->bitmap_callbacks.bitmap_get_bpp(bmp->bmp->bitmap) * + bmp->bmp->width; + c->size += (swidth * bmp->bmp->height) + 16 + 44; /* exit as a success */ - c->bitmap = bmp->bitmap; + c->bitmap = bmp->bmp->bitmap; bitmap_modified(c->bitmap); content_set_ready(c); @@ -122,11 +254,14 @@ bool nsbmp_redraw(struct content *c, int x, int y, int width, int height, const struct rect *clip, float scale, colour background_colour) { + nsbmp_content *bmp = (nsbmp_content *) c; - if (!c->data.bmp.bmp->decoded) - if (bmp_decode(c->data.bmp.bmp) != BMP_OK) + if (bmp->bmp->decoded == false) + if (bmp_decode(bmp->bmp) != BMP_OK) return false; - c->bitmap = c->data.bmp.bmp->bitmap; + + c->bitmap = bmp->bmp->bitmap; + return plot.bitmap(x, y, width, height, c->bitmap, background_colour, BITMAPF_NONE); } @@ -137,13 +272,14 @@ bool nsbmp_redraw_tiled(struct content *c, int x, int y, float scale, colour background_colour, bool repeat_x, bool repeat_y) { + nsbmp_content *bmp = (nsbmp_content *) c; bitmap_flags_t flags = BITMAPF_NONE; - if (!c->data.bmp.bmp->decoded) - if (bmp_decode(c->data.bmp.bmp) != BMP_OK) + if (bmp->bmp->decoded == false) + if (bmp_decode(bmp->bmp) != BMP_OK) return false; - c->bitmap = c->data.bmp.bmp->bitmap; + c->bitmap = bmp->bmp->bitmap; if (repeat_x) flags |= BITMAPF_REPEAT_X; @@ -157,27 +293,52 @@ bool nsbmp_redraw_tiled(struct content *c, int x, int y, void nsbmp_destroy(struct content *c) { - bmp_finalise(c->data.bmp.bmp); - free(c->data.bmp.bmp); -} + nsbmp_content *bmp = (nsbmp_content *) c; + bmp_finalise(bmp->bmp); + free(bmp->bmp); +} -bool nsbmp_clone(const struct content *old, struct content *new_content) +nserror nsbmp_clone(const struct content *old, struct content **newc) { + nsbmp_content *new_bmp; + nserror error; + + new_bmp = talloc_zero(0, nsbmp_content); + if (new_bmp == NULL) + return NSERROR_NOMEM; + + error = content__clone(old, &new_bmp->base); + if (error != NSERROR_OK) { + content_destroy(&new_bmp->base); + return error; + } + /* We "clone" the old content by replaying creation and conversion */ - if (nsbmp_create(new_content, NULL) == false) - return false; + error = nsbmp_create_bmp_data(new_bmp); + if (error != NSERROR_OK) { + content_destroy(&new_bmp->base); + return error; + } if (old->status == CONTENT_STATUS_READY || old->status == CONTENT_STATUS_DONE) { - if (nsbmp_convert(new_content) == false) - return false; + if (nsbmp_convert(&new_bmp->base) == false) { + content_destroy(&new_bmp->base); + return NSERROR_CLONE_FAILED; + } } - return true; + *newc = (struct content *) new_bmp; + + return NSERROR_OK; } +content_type nsbmp_content_type(lwc_string *mime_type) +{ + return CONTENT_IMAGE; +} /** * Callback for libnsbmp; forwards the call to bitmap_create() |