From 81c52ad4947c2b658473f8f87e244660a72c002a Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Sat, 27 Aug 2011 08:43:51 +0000 Subject: Initial image content handler refactor svn path=/trunk/netsurf/; revision=12671 --- image/bmp.c | 72 +---- image/gif.c | 46 +-- image/ico.c | 56 +--- image/image.c | 7 +- image/image.h | 1 + image/jpeg.c | 52 +--- image/mng.c | 876 ++++++++++++++++++++++++++----------------------------- image/mng.h | 4 + image/nssprite.c | 90 ++---- image/png.c | 47 +-- image/rsvg.c | 51 +--- image/svg.c | 119 +++----- image/webp.c | 93 ++---- 13 files changed, 543 insertions(+), 971 deletions(-) (limited to 'image') diff --git a/image/bmp.c b/image/bmp.c index 816884e83..fb62da89f 100644 --- a/image/bmp.c +++ b/image/bmp.c @@ -46,26 +46,6 @@ typedef struct nsbmp_content { bmp_image *bmp; /** BMP image data */ } nsbmp_content; - - - -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)]; - static nserror nsbmp_create_bmp_data(nsbmp_content *bmp) { union content_msg_data msg_data; @@ -279,43 +259,21 @@ static const content_handler nsbmp_content_handler = { .no_share = false, }; -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; +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" +}; - for (i = 0; i < NOF_ELEMENTS(nsbmp_mime_types); i++) { - if (nsbmp_mime_types[i] != NULL) - lwc_string_unref(nsbmp_mime_types[i]); - } -} +CONTENT_FACTORY_REGISTER_TYPES(nsbmp, nsbmp_types, nsbmp_content_handler); #endif diff --git a/image/gif.c b/image/gif.c index 38ba03dda..214a7bcff 100644 --- a/image/gif.c +++ b/image/gif.c @@ -56,11 +56,6 @@ typedef struct nsgif_content { int current_frame; /**< current frame to display [0...(max-1)] */ } nsgif_content; -static const char *nsgif_types[] = { - "image/gif" -}; - -static lwc_string *nsgif_mime_types[NOF_ELEMENTS(nsgif_types)]; /** * Callback for libnsgif; forwards the call to bitmap_create() @@ -425,43 +420,10 @@ static const content_handler nsgif_content_handler = { .no_share = false, }; -nserror nsgif_init(void) -{ - uint32_t i; - lwc_error lerror; - nserror error; - - for (i = 0; i < NOF_ELEMENTS(nsgif_mime_types); i++) { - lerror = lwc_intern_string(nsgif_types[i], - strlen(nsgif_types[i]), - &nsgif_mime_types[i]); - if (lerror != lwc_error_ok) { - error = NSERROR_NOMEM; - goto error; - } - - error = content_factory_register_handler(nsgif_mime_types[i], - &nsgif_content_handler); - if (error != NSERROR_OK) - goto error; - } - - return NSERROR_OK; - -error: - nsgif_fini(); - - return error; -} - -void nsgif_fini(void) -{ - uint32_t i; +static const char *nsgif_types[] = { + "image/gif" +}; - for (i = 0; i < NOF_ELEMENTS(nsgif_mime_types); i++) { - if (nsgif_mime_types[i] != NULL) - lwc_string_unref(nsgif_mime_types[i]); - } -} +CONTENT_FACTORY_REGISTER_TYPES(nsgif, nsgif_types, nsgif_content_handler); #endif diff --git a/image/ico.c b/image/ico.c index cae5e07f5..9f9aeb0f1 100644 --- a/image/ico.c +++ b/image/ico.c @@ -46,16 +46,6 @@ typedef struct nsico_content { struct ico_collection *ico; /** ICO collection data */ } nsico_content; -static const char *nsico_types[] = { - "application/ico", - "application/x-ico", - "image/ico", - "image/vnd.microsoft.icon", - "image/x-icon" -}; - -static lwc_string *nsico_mime_types[NOF_ELEMENTS(nsico_types)]; - static nserror nsico_create_ico_data(nsico_content *c) { @@ -238,44 +228,14 @@ static const content_handler nsico_content_handler = { .no_share = false, }; +static const char *nsico_types[] = { + "application/ico", + "application/x-ico", + "image/ico", + "image/vnd.microsoft.icon", + "image/x-icon" +}; -nserror nsico_init(void) -{ - uint32_t i; - lwc_error lerror; - nserror error; - - for (i = 0; i < NOF_ELEMENTS(nsico_mime_types); i++) { - lerror = lwc_intern_string(nsico_types[i], - strlen(nsico_types[i]), - &nsico_mime_types[i]); - if (lerror != lwc_error_ok) { - error = NSERROR_NOMEM; - goto error; - } - - error = content_factory_register_handler(nsico_mime_types[i], - &nsico_content_handler); - if (error != NSERROR_OK) - goto error; - } - - return NSERROR_OK; - -error: - nsico_fini(); - - return error; -} - -void nsico_fini(void) -{ - uint32_t i; - - for (i = 0; i < NOF_ELEMENTS(nsico_mime_types); i++) { - if (nsico_mime_types[i] != NULL) - lwc_string_unref(nsico_mime_types[i]); - } -} +CONTENT_FACTORY_REGISTER_TYPES(nsico, nsico_types, nsico_content_handler); #endif diff --git a/image/image.c b/image/image.c index 23853f133..8ef96eeba 100644 --- a/image/image.c +++ b/image/image.c @@ -54,8 +54,12 @@ nserror image_init(void) if (error != NSERROR_OK) return error; - /* Prefer libpng over libmng for pngs */ error = nsmng_init(); + if (error != NSERROR_OK) + return error; + + /* Prefer libpng over libmng for pngs by registering later */ + error = nsjpng_init(); if (error != NSERROR_OK) return error; error = nspng_init(); @@ -91,6 +95,7 @@ void image_fini(void) nsico_fini(); nsjpeg_fini(); nsmng_fini(); + nsjpng_fini(); nssprite_fini(); nspng_fini(); nsrsvg_fini(); diff --git a/image/image.h b/image/image.h index 44ea148a8..6c2163121 100644 --- a/image/image.h +++ b/image/image.h @@ -28,4 +28,5 @@ nserror image_init(void); void image_fini(void); + #endif diff --git a/image/jpeg.c b/image/jpeg.c index 7e75c6cf6..622e2c5db 100644 --- a/image/jpeg.c +++ b/image/jpeg.c @@ -66,14 +66,6 @@ struct nsjpeg_error_mgr { jmp_buf setjmp_buffer; }; -static const char *nsjpeg_types[] = { - "image/jpeg", - "image/jpg", - "image/pjpeg" -}; - -static lwc_string *nsjpeg_mime_types[NOF_ELEMENTS(nsjpeg_types)]; - static unsigned char nsjpeg_eoi[] = { 0xff, JPEG_EOI }; /** @@ -358,44 +350,12 @@ static const content_handler nsjpeg_content_handler = { .no_share = false, }; -nserror nsjpeg_init(void) -{ - uint32_t i; - lwc_error lerror; - nserror error; - - for (i = 0; i < NOF_ELEMENTS(nsjpeg_mime_types); i++) { - lerror = lwc_intern_string(nsjpeg_types[i], - strlen(nsjpeg_types[i]), - &nsjpeg_mime_types[i]); - if (lerror != lwc_error_ok) { - error = NSERROR_NOMEM; - goto error; - } - - error = content_factory_register_handler(nsjpeg_mime_types[i], - &nsjpeg_content_handler); - if (error != NSERROR_OK) - goto error; - } - - return NSERROR_OK; - -error: - nsjpeg_fini(); - - return error; -} - -void nsjpeg_fini(void) -{ - uint32_t i; +static const char *nsjpeg_types[] = { + "image/jpeg", + "image/jpg", + "image/pjpeg" +}; - for (i = 0; i < NOF_ELEMENTS(nsjpeg_mime_types); i++) { - if (nsjpeg_mime_types[i] != NULL) { - lwc_string_unref(nsjpeg_mime_types[i]); - } - } -} +CONTENT_FACTORY_REGISTER_TYPES(nsjpeg, nsjpeg_types, nsjpeg_content_handler); #endif /* WITH_JPEG */ diff --git a/image/mng.c b/image/mng.c index 69c13fe97..44b62f203 100644 --- a/image/mng.c +++ b/image/mng.c @@ -41,9 +41,9 @@ #include "utils/talloc.h" #include "utils/utils.h" -/* We do not currently support any form of colour/gamma correction, nor do - we support dynamic MNGs. -*/ +/* This implementation does not currently support dynamic MNGs or any + * form of colour/gamma correction, + */ typedef struct nsmng_content { @@ -58,263 +58,64 @@ typedef struct nsmng_content void *handle; } nsmng_content; -static nserror nsmng_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 nsmng_create_mng_data(nsmng_content *c); -static bool nsmng_process_data(struct content *c, const char *data, - unsigned int size); -static bool nsmng_convert(struct content *c); -static void nsmng_destroy(struct content *c); -static bool nsmng_redraw(struct content *c, struct content_redraw_data *data, - const struct rect *clip, const struct redraw_context *ctx); -static nserror nsmng_clone(const struct content *old, struct content **newc); -static content_type nsmng_content_type(lwc_string *mime_type); - -static mng_bool nsmng_openstream(mng_handle mng); -static mng_bool nsmng_readdata(mng_handle mng, mng_ptr buffer, - mng_uint32 size, mng_uint32 *bytesread); -static mng_bool nsmng_closestream(mng_handle mng); -static mng_bool nsmng_processheader(mng_handle mng, mng_uint32 width, - mng_uint32 height); -static mng_ptr nsmng_getcanvasline(mng_handle mng, mng_uint32 line); -static mng_uint32 nsmng_gettickcount(mng_handle mng); -static mng_bool nsmng_refresh(mng_handle mng, mng_uint32 x, mng_uint32 y, - mng_uint32 w, mng_uint32 h); -static mng_bool nsmng_settimer(mng_handle mng, mng_uint32 msecs); -static void nsmng_animate(void *p); -static nserror nsmng_broadcast_error(nsmng_content *c, mng_retcode code); -static mng_bool nsmng_errorproc(mng_handle mng, mng_int32 code, - mng_int8 severity, mng_chunkid chunktype, mng_uint32 chunkseq, - mng_int32 extra1, mng_int32 extra2, mng_pchar text); -#ifndef MNG_INTERNAL_MEMMNGMT -static mng_ptr nsmng_alloc(mng_size_t n); -static void nsmng_free(mng_ptr p, mng_size_t n); -#endif - -static const content_handler nsmng_content_handler = { - .create = nsmng_create, - .process_data = nsmng_process_data, - .data_complete = nsmng_convert, - .destroy = nsmng_destroy, - .redraw = nsmng_redraw, - .clone = nsmng_clone, - .type = nsmng_content_type, - .no_share = false, -}; - -static const char *jng_types[] = { - "image/jng", - "image/x-jng" -}; - -static const char *mng_types[] = { - "image/mng", - "image/x-mng", - "video/mng", - "video/x-mng" -}; -static const char *png_types[] = { - "image/png" -}; +#ifndef MNG_INTERNAL_MEMMNGMT -static lwc_string *jng_mime_types[NOF_ELEMENTS(jng_types)]; -static lwc_string *mng_mime_types[NOF_ELEMENTS(mng_types)]; -static lwc_string *png_mime_types[NOF_ELEMENTS(png_types)]; +/** + * Memory allocation callback for libmng. + */ -nserror nsmng_init(void) +static mng_ptr nsmng_alloc(mng_size_t n) { - uint32_t i; - lwc_error lerror; - nserror error; - -#define register_types(type) \ - for (i = 0; i < NOF_ELEMENTS(type##_mime_types); i++) { \ - lerror = lwc_intern_string(type##_types[i], \ - strlen(type##_types[i]), \ - &type##_mime_types[i]); \ - if (lerror != lwc_error_ok) { \ - error = NSERROR_NOMEM; \ - goto error; \ - } \ - \ - error = content_factory_register_handler( \ - type##_mime_types[i], \ - &nsmng_content_handler); \ - if (error != NSERROR_OK) \ - goto error; \ - } - - register_types(jng) - register_types(mng) - register_types(png) - - return NSERROR_OK; - -error: - nsmng_fini(); - - return error; + return calloc(1, n); } -void nsmng_fini(void) -{ - uint32_t i; - - for (i = 0; i < NOF_ELEMENTS(jng_mime_types); i++) { - if (jng_mime_types[i] != NULL) - lwc_string_unref(jng_mime_types[i]); - } - - for (i = 0; i < NOF_ELEMENTS(mng_mime_types); i++) { - if (mng_mime_types[i] != NULL) - lwc_string_unref(mng_mime_types[i]); - } - for (i = 0; i < NOF_ELEMENTS(png_mime_types); i++) { - if (png_mime_types[i] != NULL) - lwc_string_unref(png_mime_types[i]); - } -} +/** + * Memory free callback for libmng. + */ -nserror nsmng_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 void nsmng_free(mng_ptr p, mng_size_t n) { - nsmng_content *mng; - nserror error; - - mng = talloc_zero(0, nsmng_content); - if (mng == NULL) - return NSERROR_NOMEM; - - error = content__init(&mng->base, handler, imime_type, params, - llcache, fallback_charset, quirks); - if (error != NSERROR_OK) { - talloc_free(mng); - return error; - } - - error = nsmng_create_mng_data(mng); - if (error != NSERROR_OK) { - talloc_free(mng); - return error; - } - - *c = (struct content *) mng; - - return NSERROR_OK; + free(p); } -nserror nsmng_create_mng_data(nsmng_content *c) +#endif + +/** + * Broadcasts an error message and returns false + * + * \param c the content to broadcast for + * \return Appropriate error + */ +static nserror nsmng_broadcast_error(nsmng_content *c, mng_retcode code) { - mng_retcode code; union content_msg_data msg_data; + char error[100]; assert(c != NULL); - /* Initialise the library - */ -#ifdef MNG_INTERNAL_MEMMNGMT - c->handle = mng_initialize(c, MNG_NULL, MNG_NULL, MNG_NULL); -#else - c->handle = mng_initialize(c, nsmng_alloc, nsmng_free, MNG_NULL); -#endif - if (c->handle == MNG_NULL) { - LOG(("Unable to initialise MNG library.")); + if (code == MNG_OUTOFMEMORY) { msg_data.error = messages_get("NoMemory"); content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data); return NSERROR_NOMEM; } - /* We need to decode in suspension mode - */ - code = mng_set_suspensionmode(c->handle, MNG_TRUE); - if (code) { - LOG(("Unable to set suspension mode.")); - return nsmng_broadcast_error(c, code); - } - - /* We need to register our callbacks - */ - code = mng_setcb_openstream(c->handle, nsmng_openstream); - if (code) { - LOG(("Unable to set openstream callback.")); - return nsmng_broadcast_error(c, code); - } - code = mng_setcb_readdata(c->handle, nsmng_readdata); - if (code) { - LOG(("Unable to set readdata callback.")); - return nsmng_broadcast_error(c, code); - } - code = mng_setcb_closestream(c->handle, nsmng_closestream); - if (code) { - LOG(("Unable to set closestream callback.")); - return nsmng_broadcast_error(c, code); - } - code = mng_setcb_processheader(c->handle, nsmng_processheader); - if (code) { - LOG(("Unable to set processheader callback.")); - return nsmng_broadcast_error(c, code); - } - - /* Register our callbacks for displaying - */ - code = mng_setcb_getcanvasline(c->handle, nsmng_getcanvasline); - if (code) { - LOG(("Unable to set getcanvasline callback.")); - return nsmng_broadcast_error(c, code); - } - code = mng_setcb_refresh(c->handle, nsmng_refresh); - if (code) { - LOG(("Unable to set refresh callback.")); - return nsmng_broadcast_error(c, code); - } - code = mng_setcb_gettickcount(c->handle, nsmng_gettickcount); - if (code) { - LOG(("Unable to set gettickcount callback.")); - return nsmng_broadcast_error(c, code); - } - code = mng_setcb_settimer(c->handle, nsmng_settimer); - if (code) { - LOG(("Unable to set settimer callback.")); - return nsmng_broadcast_error(c, code); - } - - /* register error handling function */ - code = mng_setcb_errorproc(c->handle, nsmng_errorproc); - if (code) { - LOG(("Unable to set errorproc")); - return nsmng_broadcast_error(c, code); - } - - /* Initialise the reading - */ - c->read_start = true; - c->read_resume = false; - c->read_size = 0; - c->waiting = false; - - c->displayed = false; - - return NSERROR_OK; + snprintf(error, sizeof error, messages_get("MNGError"), code); + msg_data.error = error; + content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data); + return NSERROR_MNG_ERROR; } +/* CALLBACKS REQUIRED FOR libmng READING */ -/* START OF CALLBACKS REQUIRED FOR READING -*/ - - -mng_bool nsmng_openstream(mng_handle mng) +static mng_bool nsmng_openstream(mng_handle mng) { assert(mng != NULL); return MNG_TRUE; } -mng_bool nsmng_readdata(mng_handle mng, mng_ptr buffer, mng_uint32 size, +static mng_bool nsmng_readdata(mng_handle mng, mng_ptr buffer, mng_uint32 size, mng_uint32 *bytesread) { nsmng_content *c; @@ -347,13 +148,13 @@ mng_bool nsmng_readdata(mng_handle mng, mng_ptr buffer, mng_uint32 size, return MNG_TRUE; } -mng_bool nsmng_closestream(mng_handle mng) +static mng_bool nsmng_closestream(mng_handle mng) { assert(mng != NULL); return MNG_TRUE; } -mng_bool nsmng_processheader(mng_handle mng, mng_uint32 width, +static mng_bool nsmng_processheader(mng_handle mng, mng_uint32 width, mng_uint32 height) { nsmng_content *c; @@ -407,7 +208,7 @@ mng_bool nsmng_processheader(mng_handle mng, mng_uint32 width, */ -bool nsmng_process_data(struct content *c, const char *data, unsigned int size) +static bool nsmng_process_data(struct content *c, const char *data, unsigned int size) { nsmng_content *mng = (nsmng_content *) c; mng_retcode status; @@ -439,107 +240,11 @@ bool nsmng_process_data(struct content *c, const char *data, unsigned int size) return true; } - -bool nsmng_convert(struct content *c) -{ - nsmng_content *mng = (nsmng_content *) c; - mng_retcode status; - unsigned long size; - lwc_string *content_type; - bool match; - bool is_mng = false; - uint32_t i; - char title[100]; - - assert(c != NULL); - - content__get_source_data(c, &size); - - /* by this point, the png should have been parsed - * and the bitmap created, so ensure that's the case - */ - if (content__get_bitmap(c) == NULL) - return nsmng_broadcast_error(mng, -1) == NSERROR_OK; - - /* Set the title - */ - content_type = content__get_mime_type(c); - - for (i = 0; i < NOF_ELEMENTS(mng_mime_types); i++) { - if (lwc_string_caseless_isequal(content_type, mng_mime_types[i], - &match) == lwc_error_ok && match) { - is_mng = true; - break; - } - } - - if (is_mng) { - snprintf(title, sizeof(title), messages_get("MNGTitle"), - c->width, c->height, size); - } else if (lwc_string_caseless_isequal(content_type, png_mime_types[0], - &match) == lwc_error_ok && match) { - snprintf(title, sizeof(title), messages_get("PNGTitle"), - c->width, c->height, size); - } else { - snprintf(title, sizeof(title), messages_get("JNGTitle"), - c->width, c->height, size); - } - content__set_title(c, title); - - lwc_string_unref(content_type); - - c->size += c->width * c->height * 4; - content_set_ready(c); - content_set_done(c); - /* Done: update status bar */ - content_set_status(c, ""); - - /* jmb: I'm really not sure that this should be here. - * The *_convert functions are for converting a content into a - * displayable format. They should not, however, do anything which - * could cause the content to be displayed; the content may have - * hidden visibility or be a fallback for an object; this - * information is not available here (nor is there any need for it - * to be). - * The specific issue here is that mng_display calls the display - * callbacks, which include nsmng_refresh. nsmng_refresh forces - * a content to be redrawn regardless of whether it should be - * displayed or not. - */ - /* Start displaying - */ - status = mng_display(mng->handle); - if ((status != MNG_NOERROR) && (status != MNG_NEEDTIMERWAIT)) { - LOG(("Unable to start display (%i)", status)); - return nsmng_broadcast_error(mng, status) == NSERROR_OK; - } - bitmap_modified(c->bitmap); - - /* Optimise the plotting of JNG/PNGs - */ - mng->opaque_test_pending = (is_mng == false); - if (mng->opaque_test_pending) - bitmap_set_opaque(c->bitmap, false); - - /* free associated memory except for mngs where it may be subsequently needed for - * animation decoding. */ - if (is_mng == false) { - mng_handle handle = mng->handle; - - mng_cleanup(&handle); - - mng->handle = NULL; - } - - return true; -} - - /* START OF CALLBACKS REQUIRED FOR DISPLAYING */ -mng_ptr nsmng_getcanvasline(mng_handle mng, mng_uint32 line) +static mng_ptr nsmng_getcanvasline(mng_handle mng, mng_uint32 line) { nsmng_content *c; @@ -556,39 +261,8 @@ mng_ptr nsmng_getcanvasline(mng_handle mng, mng_uint32 line) bitmap_get_rowstride(c->base.bitmap) * line; } - -/** - * Get the wall-clock time in milliseconds since some fixed time. - */ - -mng_uint32 nsmng_gettickcount(mng_handle mng) -{ - static bool start = true; - static time_t t0; - struct timeval tv; -#if defined(__SVR4) && defined(__sun) || defined(__NetBSD__) || \ - defined(__APPLE__) - /* Solaris, NetBSD, and OS X don't have this structure, and ignore the - * second parameter to gettimeofday() - */ - int tz; -#else - struct timezone tz; -#endif - assert(mng != NULL); - - gettimeofday(&tv, &tz); - if (start) { - t0 = tv.tv_sec; - start = false; - } - - return (tv.tv_sec - t0) * 1000 + tv.tv_usec / 1000; -} - - -mng_bool nsmng_refresh(mng_handle mng, mng_uint32 x, mng_uint32 y, - mng_uint32 w, mng_uint32 h) +static mng_bool nsmng_refresh(mng_handle mng, mng_uint32 x, mng_uint32 y, + mng_uint32 w, mng_uint32 h) { union content_msg_data data; nsmng_content *c; @@ -639,7 +313,31 @@ mng_bool nsmng_refresh(mng_handle mng, mng_uint32 x, mng_uint32 y, return MNG_TRUE; } -mng_bool nsmng_settimer(mng_handle mng, mng_uint32 msecs) +/** + * Animates to the next frame + */ +static void nsmng_animate(void *p) +{ + nsmng_content *c; + + assert(p != NULL); + + c = (nsmng_content *) p; + + /* If we used the last animation we advance, if not we try again later + */ + if (c->base.user_list->next == NULL) { + c->waiting = true; + } else { + c->waiting = false; + mng_display_resume(c->handle); + c->opaque_test_pending = true; + if (c->base.bitmap) + bitmap_modified(c->base.bitmap); + } +} + +static mng_bool nsmng_settimer(mng_handle mng, mng_uint32 msecs) { nsmng_content *c; @@ -656,12 +354,316 @@ mng_bool nsmng_settimer(mng_handle mng, mng_uint32 msecs) return MNG_TRUE; } +/** + * Get the wall-clock time in milliseconds since some fixed time. + */ + +static mng_uint32 nsmng_gettickcount(mng_handle mng) +{ + static bool start = true; + static time_t t0; + struct timeval tv; +#if defined(__SVR4) && defined(__sun) || defined(__NetBSD__) || \ + defined(__APPLE__) + /* Solaris, NetBSD, and OS X don't have this structure, and ignore the + * second parameter to gettimeofday() + */ + int tz; +#else + struct timezone tz; +#endif + assert(mng != NULL); + + gettimeofday(&tv, &tz); + if (start) { + t0 = tv.tv_sec; + start = false; + } + + return (tv.tv_sec - t0) * 1000 + tv.tv_usec / 1000; +} /* END OF CALLBACKS REQUIRED FOR DISPLAYING */ +static mng_bool nsmng_errorproc(mng_handle mng, mng_int32 code, + mng_int8 severity, mng_chunkid chunktype, mng_uint32 chunkseq, + mng_int32 extra1, mng_int32 extra2, mng_pchar text) +{ + nsmng_content *c; + char chunk[5]; + + assert(mng != NULL); + + c = (nsmng_content *) mng_get_userdata(mng); + assert(c != NULL); + + chunk[0] = (char)((chunktype >> 24) & 0xFF); + chunk[1] = (char)((chunktype >> 16) & 0xFF); + chunk[2] = (char)((chunktype >> 8) & 0xFF); + chunk[3] = (char)((chunktype ) & 0xFF); + chunk[4] = '\0'; + + LOG(("error playing '%s' chunk %s (%d):", + content__get_url(&c->base), chunk, chunkseq)); + LOG(("code %d severity %d extra1 %d extra2 %d text:'%s'", code, + severity, extra1, extra2, text)); + + return (0); +} -void nsmng_destroy(struct content *c) +static nserror nsmng_create_mng_data(nsmng_content *c) +{ + mng_retcode code; + union content_msg_data msg_data; + + assert(c != NULL); + + /* Initialise the library + */ +#ifdef MNG_INTERNAL_MEMMNGMT + c->handle = mng_initialize(c, MNG_NULL, MNG_NULL, MNG_NULL); +#else + c->handle = mng_initialize(c, nsmng_alloc, nsmng_free, MNG_NULL); +#endif + if (c->handle == MNG_NULL) { + LOG(("Unable to initialise MNG library.")); + msg_data.error = messages_get("NoMemory"); + content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data); + return NSERROR_NOMEM; + } + + /* We need to decode in suspension mode + */ + code = mng_set_suspensionmode(c->handle, MNG_TRUE); + if (code) { + LOG(("Unable to set suspension mode.")); + return nsmng_broadcast_error(c, code); + } + + /* We need to register our callbacks + */ + code = mng_setcb_openstream(c->handle, nsmng_openstream); + if (code) { + LOG(("Unable to set openstream callback.")); + return nsmng_broadcast_error(c, code); + } + code = mng_setcb_readdata(c->handle, nsmng_readdata); + if (code) { + LOG(("Unable to set readdata callback.")); + return nsmng_broadcast_error(c, code); + } + code = mng_setcb_closestream(c->handle, nsmng_closestream); + if (code) { + LOG(("Unable to set closestream callback.")); + return nsmng_broadcast_error(c, code); + } + code = mng_setcb_processheader(c->handle, nsmng_processheader); + if (code) { + LOG(("Unable to set processheader callback.")); + return nsmng_broadcast_error(c, code); + } + + /* Register our callbacks for displaying + */ + code = mng_setcb_getcanvasline(c->handle, nsmng_getcanvasline); + if (code) { + LOG(("Unable to set getcanvasline callback.")); + return nsmng_broadcast_error(c, code); + } + code = mng_setcb_refresh(c->handle, nsmng_refresh); + if (code) { + LOG(("Unable to set refresh callback.")); + return nsmng_broadcast_error(c, code); + } + code = mng_setcb_gettickcount(c->handle, nsmng_gettickcount); + if (code) { + LOG(("Unable to set gettickcount callback.")); + return nsmng_broadcast_error(c, code); + } + code = mng_setcb_settimer(c->handle, nsmng_settimer); + if (code) { + LOG(("Unable to set settimer callback.")); + return nsmng_broadcast_error(c, code); + } + + /* register error handling function */ + code = mng_setcb_errorproc(c->handle, nsmng_errorproc); + if (code) { + LOG(("Unable to set errorproc")); + return nsmng_broadcast_error(c, code); + } + + /* Initialise the reading + */ + c->read_start = true; + c->read_resume = false; + c->read_size = 0; + c->waiting = false; + + c->displayed = false; + + return NSERROR_OK; +} + +static nserror nsmng_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) +{ + nsmng_content *mng; + nserror error; + + mng = talloc_zero(0, nsmng_content); + if (mng == NULL) + return NSERROR_NOMEM; + + error = content__init(&mng->base, handler, imime_type, params, + llcache, fallback_charset, quirks); + if (error != NSERROR_OK) { + talloc_free(mng); + return error; + } + + error = nsmng_create_mng_data(mng); + if (error != NSERROR_OK) { + talloc_free(mng); + return error; + } + + *c = (struct content *) mng; + + return NSERROR_OK; +} + + + +static bool nsmng_convert(struct content *c) +{ + nsmng_content *mng = (nsmng_content *) c; + mng_retcode status; + unsigned long size; + char title[100]; + + assert(c != NULL); + + content__get_source_data(c, &size); + + /* by this point, the png should have been parsed + * and the bitmap created, so ensure that's the case + */ + if (content__get_bitmap(c) == NULL) { + return nsmng_broadcast_error(mng, -1) == NSERROR_OK; + } + + /* Set the title + */ + snprintf(title, sizeof(title), + messages_get("MNGTitle"), + c->width, c->height, size); + content__set_title(c, title); + + c->size += c->width * c->height * 4; + content_set_ready(c); + content_set_done(c); + /* Done: update status bar */ + content_set_status(c, ""); + + /* jmb: I'm really not sure that this should be here. + * The *_convert functions are for converting a content into a + * displayable format. They should not, however, do anything which + * could cause the content to be displayed; the content may have + * hidden visibility or be a fallback for an object; this + * information is not available here (nor is there any need for it + * to be). + * The specific issue here is that mng_display calls the display + * callbacks, which include nsmng_refresh. nsmng_refresh forces + * a content to be redrawn regardless of whether it should be + * displayed or not. + */ + /* Start displaying + */ + status = mng_display(mng->handle); + if ((status != MNG_NOERROR) && (status != MNG_NEEDTIMERWAIT)) { + LOG(("Unable to start display (%i)", status)); + return nsmng_broadcast_error(mng, status) == NSERROR_OK; + } + bitmap_modified(c->bitmap); + + /* Optimise the plotting of MNG */ + mng->opaque_test_pending = false; + + return true; +} + +static bool nsjpng_convert(struct content *c) +{ + nsmng_content *mng = (nsmng_content *) c; + mng_retcode status; + unsigned long size; + char title[100]; + + assert(c != NULL); + + content__get_source_data(c, &size); + + /* by this point, the png should have been parsed + * and the bitmap created, so ensure that's the case + */ + if (content__get_bitmap(c) == NULL) { + return nsmng_broadcast_error(mng, -1) == NSERROR_OK; + } + + /* Set the title */ + snprintf(title, sizeof(title), + messages_get("PNGTitle"), + c->width, c->height, size); + content__set_title(c, title); + + c->size += c->width * c->height * 4; + content_set_ready(c); + content_set_done(c); + /* Done: update status bar */ + content_set_status(c, ""); + + /* jmb: I'm really not sure that this should be here. + * The *_convert functions are for converting a content into a + * displayable format. They should not, however, do anything which + * could cause the content to be displayed; the content may have + * hidden visibility or be a fallback for an object; this + * information is not available here (nor is there any need for it + * to be). + * The specific issue here is that mng_display calls the display + * callbacks, which include nsmng_refresh. nsmng_refresh forces + * a content to be redrawn regardless of whether it should be + * displayed or not. + */ + /* Start displaying + */ + status = mng_display(mng->handle); + if ((status != MNG_NOERROR) && (status != MNG_NEEDTIMERWAIT)) { + LOG(("Unable to start display (%i)", status)); + return nsmng_broadcast_error(mng, status) == NSERROR_OK; + } + bitmap_modified(c->bitmap); + + /* Optimise the plotting of JNG/PNGs + */ + mng->opaque_test_pending = true; + bitmap_set_opaque(c->bitmap, false); + + /* free associated memory */ + + mng_handle handle = mng->handle; + + mng_cleanup(&handle); + + mng->handle = NULL; + + return true; +} + +static void nsmng_destroy(struct content *c) { nsmng_content *mng = (nsmng_content *) c; @@ -684,7 +686,7 @@ void nsmng_destroy(struct content *c) } -bool nsmng_redraw(struct content *c, struct content_redraw_data *data, +static bool nsmng_redraw(struct content *c, struct content_redraw_data *data, const struct rect *clip, const struct redraw_context *ctx) { nsmng_content *mng = (nsmng_content *) c; @@ -707,8 +709,7 @@ bool nsmng_redraw(struct content *c, struct content_redraw_data *data, ret = ctx->plot->bitmap(data->x, data->y, data->width, data->height, c->bitmap, data->background_colour, flags); - /* Check if we need to restart the animation - */ + /* Check if we need to restart the animation */ if ((mng->waiting) && (option_animate_images)) nsmng_animate(c); @@ -716,7 +717,7 @@ bool nsmng_redraw(struct content *c, struct content_redraw_data *data, } -nserror nsmng_clone(const struct content *old, struct content **newc) +static nserror nsmng_clone(const struct content *old, struct content **newc) { nsmng_content *mng; nserror error; @@ -761,111 +762,54 @@ nserror nsmng_clone(const struct content *old, struct content **newc) return NSERROR_OK; } -content_type nsmng_content_type(lwc_string *mime_type) +static content_type nsmng_content_type(lwc_string *mime_type) { return CONTENT_IMAGE; } -/** - * Animates to the next frame - */ -void nsmng_animate(void *p) -{ - nsmng_content *c; - - assert(p != NULL); - - c = (nsmng_content *) p; - - /* If we used the last animation we advance, if not we try again later - */ - if (c->base.user_list->next == NULL) { - c->waiting = true; - } else { - c->waiting = false; - mng_display_resume(c->handle); - c->opaque_test_pending = true; - if (c->base.bitmap) - bitmap_modified(c->base.bitmap); - } -} - - - -/** - * Broadcasts an error message and returns false - * - * \param c the content to broadcast for - * \return Appropriate error - */ -nserror nsmng_broadcast_error(nsmng_content *c, mng_retcode code) -{ - union content_msg_data msg_data; - char error[100]; - - assert(c != NULL); - - if (code == MNG_OUTOFMEMORY) { - msg_data.error = messages_get("NoMemory"); - content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data); - return NSERROR_NOMEM; - } - - snprintf(error, sizeof error, messages_get("MNGError"), code); - msg_data.error = error; - content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data); - return NSERROR_MNG_ERROR; -} - - -mng_bool nsmng_errorproc(mng_handle mng, mng_int32 code, - mng_int8 severity, mng_chunkid chunktype, mng_uint32 chunkseq, - mng_int32 extra1, mng_int32 extra2, mng_pchar text) -{ - nsmng_content *c; - char chunk[5]; - - assert(mng != NULL); - - c = (nsmng_content *) mng_get_userdata(mng); - assert(c != NULL); - - chunk[0] = (char)((chunktype >> 24) & 0xFF); - chunk[1] = (char)((chunktype >> 16) & 0xFF); - chunk[2] = (char)((chunktype >> 8) & 0xFF); - chunk[3] = (char)((chunktype ) & 0xFF); - chunk[4] = '\0'; - - LOG(("error playing '%s' chunk %s (%d):", - content__get_url(&c->base), chunk, chunkseq)); - LOG(("code %d severity %d extra1 %d extra2 %d text:'%s'", code, - severity, extra1, extra2, text)); - - return (0); -} - - -#ifndef MNG_INTERNAL_MEMMNGMT +/* register handler for mng types */ +static const content_handler nsmng_content_handler = { + .create = nsmng_create, + .process_data = nsmng_process_data, + .data_complete = nsmng_convert, + .destroy = nsmng_destroy, + .redraw = nsmng_redraw, + .clone = nsmng_clone, + .type = nsmng_content_type, + .no_share = false, +}; -/** - * Memory allocation callback for libmng. - */ +static const char *nsmng_types[] = { + /* MNG types*/ + "image/mng", + "image/x-mng", + "video/mng", + "video/x-mng", +}; -mng_ptr nsmng_alloc(mng_size_t n) -{ - return calloc(1, n); -} +CONTENT_FACTORY_REGISTER_TYPES(nsmng, nsmng_types, nsmng_content_handler); +/* register handler for jng and png types */ +static const content_handler nsjpng_content_handler = { + .create = nsmng_create, + .process_data = nsmng_process_data, + .data_complete = nsjpng_convert, + .destroy = nsmng_destroy, + .redraw = nsmng_redraw, + .clone = nsmng_clone, + .type = nsmng_content_type, + .no_share = false, +}; -/** - * Memory free callback for libmng. - */ -void nsmng_free(mng_ptr p, mng_size_t n) -{ - free(p); -} +static const char *nsjpng_types[] = { + /* JNG types*/ + "image/jng", + "image/x-jng", + /* PNG types*/ + "image/png" +}; -#endif +CONTENT_FACTORY_REGISTER_TYPES(nsjpng, nsjpng_types, nsjpng_content_handler); #endif diff --git a/image/mng.h b/image/mng.h index a3318615b..458150644 100644 --- a/image/mng.h +++ b/image/mng.h @@ -30,11 +30,15 @@ nserror nsmng_init(void); void nsmng_fini(void); +nserror nsjpng_init(void); +void nsjpng_fini(void); #else #define nsmng_init() NSERROR_OK #define nsmng_fini() ((void) 0) +#define nsjpng_init() NSERROR_OK +#define nsjpng_fini() ((void) 0) #endif /* WITH_MNG */ diff --git a/image/nssprite.c b/image/nssprite.c index 3282e821b..b8dd649a6 100644 --- a/image/nssprite.c +++ b/image/nssprite.c @@ -44,16 +44,6 @@ typedef struct nssprite_content { struct rosprite_area* sprite_area; } nssprite_content; -static nserror nssprite_create(const content_handler *handler, - lwc_string *imime_type, const http_parameter *params, - llcache_handle *llcache, const char *fallback_charset, - bool quirks, struct content **c); -static bool nssprite_convert(struct content *c); -static void nssprite_destroy(struct content *c); -static bool nssprite_redraw(struct content *c, struct content_redraw_data *data, - const struct rect *clip, const struct redraw_context *ctx); -static nserror nssprite_clone(const struct content *old, struct content **newc); -static content_type nssprite_content_type(lwc_string *mime_type); #define ERRCHK(x) do { \ rosprite_error err = x; \ @@ -69,62 +59,10 @@ static content_type nssprite_content_type(lwc_string *mime_type); } \ } while(0) -static const content_handler nssprite_content_handler = { - .create = nssprite_create, - .data_complete = nssprite_convert, - .destroy = nssprite_destroy, - .redraw = nssprite_redraw, - .clone = nssprite_clone, - .type = nssprite_content_type, - .no_share = false, -}; - -static const char *nssprite_types[] = { - "image/x-riscos-sprite" -}; - -static lwc_string *nssprite_mime_types[NOF_ELEMENTS(nssprite_types)]; - -nserror nssprite_init(void) -{ - uint32_t i; - lwc_error lerror; - nserror error; - - for (i = 0; i < NOF_ELEMENTS(nssprite_mime_types); i++) { - lerror = lwc_intern_string(nssprite_types[i], - strlen(nssprite_types[i]), - &nssprite_mime_types[i]); - if (lerror != lwc_error_ok) { - error = NSERROR_NOMEM; - goto error; - } - - error = content_factory_register_handler(nssprite_mime_types[i], - &nssprite_content_handler); - if (error != NSERROR_OK) - goto error; - } - - return NSERROR_OK; -error: - nssprite_fini(); - return error; -} -void nssprite_fini(void) -{ - uint32_t i; - - for (i = 0; i < NOF_ELEMENTS(nssprite_mime_types); i++) { - if (nssprite_mime_types[i] != NULL) - lwc_string_unref(nssprite_mime_types[i]); - } -} - -nserror nssprite_create(const content_handler *handler, +static nserror nssprite_create(const content_handler *handler, lwc_string *imime_type, const http_parameter *params, llcache_handle *llcache, const char *fallback_charset, bool quirks, struct content **c) @@ -154,7 +92,7 @@ nserror nssprite_create(const content_handler *handler, * No conversion is necessary. We merely read the sprite dimensions. */ -bool nssprite_convert(struct content *c) +static bool nssprite_convert(struct content *c) { nssprite_content *nssprite = (nssprite_content *) c; union content_msg_data msg_data; @@ -223,7 +161,7 @@ bool nssprite_convert(struct content *c) * Destroy a CONTENT_SPRITE and free all resources it owns. */ -void nssprite_destroy(struct content *c) +static void nssprite_destroy(struct content *c) { nssprite_content *sprite = (nssprite_content *) c; @@ -238,7 +176,7 @@ void nssprite_destroy(struct content *c) * Redraw a CONTENT_SPRITE. */ -bool nssprite_redraw(struct content *c, struct content_redraw_data *data, +static bool nssprite_redraw(struct content *c, struct content_redraw_data *data, const struct rect *clip, const struct redraw_context *ctx) { bitmap_flags_t flags = BITMAPF_NONE; @@ -253,7 +191,7 @@ bool nssprite_redraw(struct content *c, struct content_redraw_data *data, } -nserror nssprite_clone(const struct content *old, struct content **newc) +static nserror nssprite_clone(const struct content *old, struct content **newc) { nssprite_content *sprite; nserror error; @@ -282,9 +220,25 @@ nserror nssprite_clone(const struct content *old, struct content **newc) return NSERROR_OK; } -content_type nssprite_content_type(lwc_string *mime_type) +static content_type nssprite_content_type(lwc_string *mime_type) { return CONTENT_IMAGE; } +static const content_handler nssprite_content_handler = { + .create = nssprite_create, + .data_complete = nssprite_convert, + .destroy = nssprite_destroy, + .redraw = nssprite_redraw, + .clone = nssprite_clone, + .type = nssprite_content_type, + .no_share = false, +}; + +static const char *nssprite_types[] = { + "image/x-riscos-sprite" +}; + +CONTENT_FACTORY_REGISTER_TYPES(nssprite, nssprite_types, nssprite_content_handler); + #endif diff --git a/image/png.c b/image/png.c index 15c6e07aa..f88b8fcfc 100644 --- a/image/png.c +++ b/image/png.c @@ -63,12 +63,6 @@ typedef struct nspng_content { size_t rowbytes; /**< Number of bytes per row */ } nspng_content; -static const char *nspng_types[] = { - "image/png" -}; - -static lwc_string *nspng_mime_types[NOF_ELEMENTS(nspng_types)]; - static unsigned int interlace_start[8] = {0, 16, 0, 8, 0, 4, 0}; static unsigned int interlace_step[8] = {28, 28, 12, 12, 4, 4, 0}; static unsigned int interlace_row_start[8] = {0, 0, 4, 0, 2, 0, 1}; @@ -439,43 +433,10 @@ static const content_handler nspng_content_handler = { .no_share = false, }; -nserror nspng_init(void) -{ - uint32_t i; - lwc_error lerror; - nserror error; - - for (i = 0; i < NOF_ELEMENTS(nspng_mime_types); i++) { - lerror = lwc_intern_string(nspng_types[i], - strlen(nspng_types[i]), - &nspng_mime_types[i]); - if (lerror != lwc_error_ok) { - error = NSERROR_NOMEM; - goto error; - } - - error = content_factory_register_handler(nspng_mime_types[i], - &nspng_content_handler); - if (error != NSERROR_OK) - goto error; - } - - return NSERROR_OK; - -error: - nspng_fini(); - - return error; -} - -void nspng_fini(void) -{ - uint32_t i; +static const char *nspng_types[] = { + "image/png" +}; - for (i = 0; i < NOF_ELEMENTS(nspng_mime_types); i++) { - if (nspng_mime_types[i] != NULL) - lwc_string_unref(nspng_mime_types[i]); - } -} +CONTENT_FACTORY_REGISTER_TYPES(nspng, nspng_types, nspng_content_handler); #endif diff --git a/image/rsvg.c b/image/rsvg.c index 5af3c1bc2..678cd862d 100644 --- a/image/rsvg.c +++ b/image/rsvg.c @@ -56,16 +56,6 @@ typedef struct rsvg_content { struct bitmap *bitmap; /**< Created NetSurf bitmap */ } rsvg_content; - - -static const char *rsvg_types[] = { - "image/svg", - "image/svg+xml" -}; - -static lwc_string *rsvg_mime_types[NOF_ELEMENTS(rsvg_types)]; - - static nserror rsvg_create_svg_data(rsvg_content *c) { union content_msg_data msg_data; @@ -318,43 +308,12 @@ static const content_handler rsvg_content_handler = { .no_share = false, }; -nserror nsrsvg_init(void) -{ - uint32_t i; - lwc_error lerror; - nserror error; - - for (i = 0; i < NOF_ELEMENTS(rsvg_mime_types); i++) { - lerror = lwc_intern_string(rsvg_types[i], - strlen(rsvg_types[i]), - &rsvg_mime_types[i]); - if (lerror != lwc_error_ok) { - error = NSERROR_NOMEM; - goto error; - } - - error = content_factory_register_handler(rsvg_mime_types[i], - &rsvg_content_handler); - if (error != NSERROR_OK) - goto error; - } - - return NSERROR_OK; - -error: - nsrsvg_fini(); - - return error; -} +static const char *rsvg_types[] = { + "image/svg", + "image/svg+xml" +}; -void nsrsvg_fini(void) -{ - uint32_t i; +CONTENT_FACTORY_REGISTER_TYPES(nsrsvg, rsvg_types, rsvg_content_handler); - for (i = 0; i < NOF_ELEMENTS(rsvg_mime_types); i++) { - if (rsvg_mime_types[i] != NULL) - lwc_string_unref(rsvg_mime_types[i]); - } -} #endif /* WITH_RSVG */ diff --git a/image/svg.c b/image/svg.c index cc1762ddb..3bcb2709a 100644 --- a/image/svg.c +++ b/image/svg.c @@ -43,81 +43,32 @@ typedef struct svg_content { bool done_parse; } svg_content; -static nserror svg_create(const content_handler *handler, - lwc_string *imime_type, const http_parameter *params, - llcache_handle *llcache, const char *fallback_charset, - bool quirks, struct content **c); -static nserror svg_create_svg_data(svg_content *c); -static bool svg_convert(struct content *c); -static void svg_destroy(struct content *c); -static void svg_reformat(struct content *c, int width, int height); -static bool svg_redraw(struct content *c, struct content_redraw_data *data, - const struct rect *clip, const struct redraw_context *ctx); -static nserror svg_clone(const struct content *old, struct content **newc); -static content_type svg_content_type(lwc_string *mime_type); -static const content_handler svg_content_handler = { - .create = svg_create, - .data_complete = svg_convert, - .reformat = svg_reformat, - .destroy = svg_destroy, - .redraw = svg_redraw, - .clone = svg_clone, - .type = svg_content_type, - .no_share = false, -}; - -static const char *svg_types[] = { - "image/svg", - "image/svg+xml" -}; -static lwc_string *svg_mime_types[NOF_ELEMENTS(svg_types)]; - -nserror svg_init(void) +static nserror svg_create_svg_data(svg_content *c) { - uint32_t i; - lwc_error lerror; - nserror error; + union content_msg_data msg_data; - for (i = 0; i < NOF_ELEMENTS(svg_mime_types); i++) { - lerror = lwc_intern_string(svg_types[i], - strlen(svg_types[i]), - &svg_mime_types[i]); - if (lerror != lwc_error_ok) { - error = NSERROR_NOMEM; - goto error; - } + c->diagram = svgtiny_create(); + if (c->diagram == NULL) + goto no_memory; - error = content_factory_register_handler(svg_mime_types[i], - &svg_content_handler); - if (error != NSERROR_OK) - goto error; - } + c->done_parse = false; return NSERROR_OK; -error: - svg_fini(); - - return error; +no_memory: + msg_data.error = messages_get("NoMemory"); + content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data); + return NSERROR_NOMEM; } -void svg_fini(void) -{ - uint32_t i; - - for (i = 0; i < NOF_ELEMENTS(svg_mime_types); i++) { - if (svg_mime_types[i] != NULL) - lwc_string_unref(svg_mime_types[i]); - } -} /** * Create a CONTENT_SVG. */ -nserror svg_create(const content_handler *handler, +static nserror svg_create(const content_handler *handler, lwc_string *imime_type, const http_parameter *params, llcache_handle *llcache, const char *fallback_charset, bool quirks, struct content **c) @@ -147,30 +98,13 @@ nserror svg_create(const content_handler *handler, return NSERROR_OK; } -nserror svg_create_svg_data(svg_content *c) -{ - union content_msg_data msg_data; - - c->diagram = svgtiny_create(); - if (c->diagram == NULL) - goto no_memory; - - c->done_parse = false; - - return NSERROR_OK; - -no_memory: - msg_data.error = messages_get("NoMemory"); - content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data); - return NSERROR_NOMEM; -} /** * Convert a CONTENT_SVG for display. */ -bool svg_convert(struct content *c) +static bool svg_convert(struct content *c) { /*c->title = malloc(100); if (c->title) @@ -189,7 +123,7 @@ bool svg_convert(struct content *c) * Reformat a CONTENT_SVG. */ -void svg_reformat(struct content *c, int width, int height) +static void svg_reformat(struct content *c, int width, int height) { svg_content *svg = (svg_content *) c; const char *source_data; @@ -284,7 +218,7 @@ static bool svg_redraw_internal(struct content *c, int x, int y, * Redraw a CONTENT_SVG. */ -bool svg_redraw(struct content *c, struct content_redraw_data *data, +static bool svg_redraw(struct content *c, struct content_redraw_data *data, const struct rect *clip, const struct redraw_context *ctx) { int x = data->x; @@ -344,7 +278,7 @@ bool svg_redraw(struct content *c, struct content_redraw_data *data, * Destroy a CONTENT_SVG and free all resources it owns. */ -void svg_destroy(struct content *c) +static void svg_destroy(struct content *c) { svg_content *svg = (svg_content *) c; @@ -353,7 +287,7 @@ void svg_destroy(struct content *c) } -nserror svg_clone(const struct content *old, struct content **newc) +static nserror svg_clone(const struct content *old, struct content **newc) { svg_content *svg; nserror error; @@ -388,9 +322,28 @@ nserror svg_clone(const struct content *old, struct content **newc) return NSERROR_OK; } -content_type svg_content_type(lwc_string *mime_type) +static content_type svg_content_type(lwc_string *mime_type) { return CONTENT_IMAGE; } +static const content_handler svg_content_handler = { + .create = svg_create, + .data_complete = svg_convert, + .reformat = svg_reformat, + .destroy = svg_destroy, + .redraw = svg_redraw, + .clone = svg_clone, + .type = svg_content_type, + .no_share = false, +}; + +static const char *svg_types[] = { + "image/svg", + "image/svg+xml" +}; + + +CONTENT_FACTORY_REGISTER_TYPES(svg, svg_types, svg_content_handler); + #endif /* WITH_NS_SVG */ diff --git a/image/webp.c b/image/webp.c index cabd40a3f..90c7121ac 100644 --- a/image/webp.c +++ b/image/webp.c @@ -41,73 +41,8 @@ typedef struct webp_content struct content base; } webp_content; -static nserror webp_create(const content_handler *handler, - lwc_string *imime_type, const http_parameter *params, - llcache_handle *llcache, const char *fallback_charset, - bool quirks, struct content **c); -static bool webp_convert(struct content *c); -static void webp_destroy(struct content *c); -static bool webp_redraw(struct content *c, struct content_redraw_data *data, - const struct rect *clip, const struct redraw_context *ctx); -static nserror webp_clone(const struct content *old, struct content **newc); -static content_type webp_content_type(lwc_string *mime_type); - -static const content_handler webp_content_handler = { - .create = webp_create, - .data_complete = webp_convert, - .destroy = webp_destroy, - .redraw = webp_redraw, - .clone = webp_clone, - .type = webp_content_type, - .no_share = false, -}; -static const char *webp_types[] = { - "image/webp" -}; - -static lwc_string *webp_mime_types[NOF_ELEMENTS(webp_types)]; - -nserror webp_init(void) -{ - uint32_t i; - lwc_error lerror; - nserror error; - - for (i = 0; i < NOF_ELEMENTS(webp_mime_types); i++) { - lerror = lwc_intern_string(webp_types[i], - strlen(webp_types[i]), - &webp_mime_types[i]); - if (lerror != lwc_error_ok) { - error = NSERROR_NOMEM; - goto error; - } - - error = content_factory_register_handler(webp_mime_types[i], - &webp_content_handler); - if (error != NSERROR_OK) - goto error; - } - - return NSERROR_OK; - -error: - webp_fini(); - - return error; -} - -void webp_fini(void) -{ - uint32_t i; - - for (i = 0; i < NOF_ELEMENTS(webp_mime_types); i++) { - if (webp_mime_types[i] != NULL) - lwc_string_unref(webp_mime_types[i]); - } -} - -nserror webp_create(const content_handler *handler, +static nserror webp_create(const content_handler *handler, lwc_string *imime_type, const http_parameter *params, llcache_handle *llcache, const char *fallback_charset, bool quirks, struct content **c) @@ -137,7 +72,7 @@ nserror webp_create(const content_handler *handler, * No conversion is necessary. We merely read the WebP dimensions. */ -bool webp_convert(struct content *c) +static bool webp_convert(struct content *c) { union content_msg_data msg_data; const uint8_t *data; @@ -200,7 +135,7 @@ bool webp_convert(struct content *c) * Destroy a CONTENT_WEBP and free all resources it owns. */ -void webp_destroy(struct content *c) +static void webp_destroy(struct content *c) { if (c->bitmap != NULL) bitmap_destroy(c->bitmap); @@ -211,7 +146,7 @@ void webp_destroy(struct content *c) * Redraw a CONTENT_WEBP. */ -bool webp_redraw(struct content *c, struct content_redraw_data *data, +static bool webp_redraw(struct content *c, struct content_redraw_data *data, const struct rect *clip, const struct redraw_context *ctx) { bitmap_flags_t flags = BITMAPF_NONE; @@ -226,7 +161,7 @@ bool webp_redraw(struct content *c, struct content_redraw_data *data, } -nserror webp_clone(const struct content *old, struct content **newc) +static nserror webp_clone(const struct content *old, struct content **newc) { webp_content *webp; nserror error; @@ -255,9 +190,25 @@ nserror webp_clone(const struct content *old, struct content **newc) return NSERROR_OK; } -content_type webp_content_type(lwc_string *mime_type) +static content_type webp_content_type(lwc_string *mime_type) { return CONTENT_IMAGE; } +static const content_handler webp_content_handler = { + .create = webp_create, + .data_complete = webp_convert, + .destroy = webp_destroy, + .redraw = webp_redraw, + .clone = webp_clone, + .type = webp_content_type, + .no_share = false, +}; + +static const char *webp_types[] = { + "image/webp" +}; + +CONTENT_FACTORY_REGISTER_TYPES(webp, webp_types, webp_content_handler); + #endif -- cgit v1.2.3