summaryrefslogtreecommitdiff
path: root/image/bmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'image/bmp.c')
-rw-r--r--image/bmp.c225
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()