diff options
author | Vincent Sanders <vince@kyllikki.org> | 2016-05-23 23:32:16 +0100 |
---|---|---|
committer | Vincent Sanders <vince@kyllikki.org> | 2016-05-23 23:32:16 +0100 |
commit | 3224d7121aff91ab8d888831dc493ef621e3dd39 (patch) | |
tree | 5e4585fd78b6b247a5e602ea1a1d55e0dfe206fb /image | |
parent | 93be8d805e7e1f32638015770446476fef22ceac (diff) | |
download | netsurf-3224d7121aff91ab8d888831dc493ef621e3dd39.tar.gz netsurf-3224d7121aff91ab8d888831dc493ef621e3dd39.tar.bz2 |
move image content handlers to accomodate core build changes
Diffstat (limited to 'image')
-rw-r--r-- | image/Makefile | 15 | ||||
-rw-r--r-- | image/bitmap.h | 177 | ||||
-rw-r--r-- | image/bmp.c | 282 | ||||
-rw-r--r-- | image/bmp.h | 33 | ||||
-rw-r--r-- | image/gif.c | 455 | ||||
-rw-r--r-- | image/gif.h | 29 | ||||
-rw-r--r-- | image/ico.c | 300 | ||||
-rw-r--r-- | image/ico.h | 28 | ||||
-rw-r--r-- | image/image.c | 159 | ||||
-rw-r--r-- | image/image.h | 43 | ||||
-rw-r--r-- | image/image_cache.c | 797 | ||||
-rw-r--r-- | image/image_cache.h | 189 | ||||
-rw-r--r-- | image/jpeg.c | 393 | ||||
-rw-r--r-- | image/jpeg.h | 28 | ||||
-rw-r--r-- | image/nssprite.c | 259 | ||||
-rw-r--r-- | image/nssprite.h | 28 | ||||
-rw-r--r-- | image/png.c | 614 | ||||
-rw-r--r-- | image/png.h | 25 | ||||
-rw-r--r-- | image/rsvg.c | 326 | ||||
-rw-r--r-- | image/rsvg.h | 28 | ||||
-rw-r--r-- | image/svg.c | 353 | ||||
-rw-r--r-- | image/svg.h | 28 | ||||
-rw-r--r-- | image/video.c | 201 | ||||
-rw-r--r-- | image/video.h | 26 |
24 files changed, 0 insertions, 4816 deletions
diff --git a/image/Makefile b/image/Makefile deleted file mode 100644 index 5851a1c43..000000000 --- a/image/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# Image content handlers sources - -# S_IMAGE are sources related to image management -S_IMAGE_YES := image.c image_cache.c -S_IMAGE_NO := -S_IMAGE_$(NETSURF_USE_BMP) += bmp.c ico.c -S_IMAGE_$(NETSURF_USE_GIF) += gif.c -S_IMAGE_$(NETSURF_USE_JPEG) += jpeg.c -S_IMAGE_$(NETSURF_USE_ROSPRITE) += nssprite.c -S_IMAGE_$(NETSURF_USE_PNG) += png.c -S_IMAGE_$(NETSURF_USE_NSSVG) += svg.c -S_IMAGE_$(NETSURF_USE_RSVG) += rsvg.c -S_IMAGE_$(NETSURF_USE_VIDEO) += video.c - -S_IMAGE := $(addprefix image/,$(S_IMAGE_YES)) diff --git a/image/bitmap.h b/image/bitmap.h deleted file mode 100644 index ef6c1b49b..000000000 --- a/image/bitmap.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright 2004 James Bursa <bursa@users.sourceforge.net> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/** - * \file - * Generic bitmap handling interface. - * - * This interface wraps the native platform-specific image format, so that - * portable image convertors can be written. - * - * Bitmaps are required to be 32bpp with components in the order RR GG BB AA. - * - * For example, an opaque 1x1 pixel image would yield the following bitmap - * data: - * - * > Red : 0xff 0x00 0x00 0x00 - * > Green: 0x00 0xff 0x00 0x00 - * > Blue : 0x00 0x00 0xff 0x00 - * - * Any attempt to read pixels by casting bitmap data to uint32_t or similar - * will need to cater for the order of bytes in a word being different on - * big and little endian systems. To avoid confusion, it is recommended - * that pixel data is loaded as follows: - * - * uint32_t read_pixel(const uint8_t *bmp) - * { - * // red green blue alpha - * return bmp[0] | (bmp[1] << 8) | (bmp[2] << 16) | (bmp[3] << 24); - * } - * - * and *not* as follows: - * - * uint32_t read_pixel(const uint8_t *bmp) - * { - * return *((uint32_t *) bmp); - * } - */ - -#ifndef _NETSURF_IMAGE_BITMAP_H_ -#define _NETSURF_IMAGE_BITMAP_H_ - -#define BITMAP_NEW 0 -#define BITMAP_OPAQUE (1 << 0) /**< image is opaque */ -#define BITMAP_MODIFIED (1 << 1) /**< buffer has been modified */ -#define BITMAP_CLEAR_MEMORY (1 << 2) /**< memory should be wiped */ - -struct content; -struct bitmap; -struct hlcache_handle; - -/** - * Bitmap operations. - */ -struct gui_bitmap_table { - /* Mandantory entries */ - - /** - * Create a new bitmap. - * - * \param width width of image in pixels - * \param height width of image in pixels - * \param state The state to create the bitmap in. - * \return A bitmap structure or NULL on error. - */ - void *(*create)(int width, int height, unsigned int state); - - /** - * Destroy a bitmap. - * - * \param bitmap The bitmap to destroy. - */ - void (*destroy)(void *bitmap); - - /** - * Set the opacity of a bitmap. - * - * \param bitmap The bitmap to set opacity on. - * \param opaque The bitmap opacity to set. - */ - void (*set_opaque)(void *bitmap, bool opaque); - - /** - * Get the opacity of a bitmap. - * - * \param bitmap The bitmap to examine. - * \return The bitmap opacity. - */ - bool (*get_opaque)(void *bitmap); - - /** - * Test if a bitmap is opaque. - * - * \param bitmap The bitmap to examine. - * \return The bitmap opacity. - */ - bool (*test_opaque)(void *bitmap); - - /** - * Get the image buffer from a bitmap - * - * \param bitmap The bitmap to get the buffer from. - * \return The image buffer or NULL if there is none. - */ - unsigned char *(*get_buffer)(void *bitmap); - - /** - * Get the number of bytes per row of the image - * - * \param bitmap The bitmap - * \return The number of bytes for a row of the bitmap. - */ - size_t (*get_rowstride)(void *bitmap); - - /** - * Get the bitmap width - * - * \param bitmap The bitmap - * \return The bitmap width in pixels. - */ - int (*get_width)(void *bitmap); - - /** - * Get the bitmap height - * - * \param bitmap The bitmap - * \return The bitmap height in pixels. - */ - int (*get_height)(void *bitmap); - - /** - * The the *bytes* per pixel. - * - * \param bitmap The bitmap - */ - size_t (*get_bpp)(void *bitmap); - - /** - * Savde a bitmap to disc. - * - * \param bitmap The bitmap to save - * \param path The path to save the bitmap to. - * \param flags Flags affectin the save. - */ - bool (*save)(void *bitmap, const char *path, unsigned flags); - - /** - * Marks a bitmap as modified. - * - * \param bitmap The bitmap set as modified. - */ - void (*modified)(void *bitmap); - - /** - * Render content into a bitmap. - * - * \param bitmap The bitmap to render into. - * \param content The content to render. - */ - nserror (*render)(struct bitmap *bitmap, struct hlcache_handle *content); -}; - -#endif diff --git a/image/bmp.c b/image/bmp.c deleted file mode 100644 index 2468b4d72..000000000 --- a/image/bmp.c +++ /dev/null @@ -1,282 +0,0 @@ -/* - * Copyright 2006 Richard Wilson <info@tinct.net> - * Copyright 2008 Sean Fox <dyntryx@gmail.com> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/** - * \file - * implementation of content handler for BMP images. - */ - -#include <stdbool.h> -#include <stdlib.h> -#include <libnsbmp.h> - -#include "utils/utils.h" -#include "utils/messages.h" -#include "content/content_protected.h" -#include "desktop/gui_internal.h" -#include "desktop/plotters.h" - -#include "image/bitmap.h" -#include "image/bmp.h" - -/** bmp context. */ -typedef struct nsbmp_content { - struct content base; - - bmp_image *bmp; /** BMP image data */ - - struct bitmap *bitmap; /**< Created NetSurf bitmap */ -} nsbmp_content; - -/** - * Callback for libnsbmp; forwards the call to bitmap_create() - * - * \param width width of image in pixels - * \param height width of image in pixels - * \param bmp_state A flag word indicating the initial state - * \return An opaque struct bitmap, or NULL on memory exhaustion - */ -static void *nsbmp_bitmap_create(int width, int height, unsigned int bmp_state) -{ - unsigned int bitmap_state = BITMAP_NEW; - - /* set bitmap state based on bmp state */ - bitmap_state |= (bmp_state & BMP_OPAQUE) ? BITMAP_OPAQUE : 0; - bitmap_state |= (bmp_state & BMP_CLEAR_MEMORY) ? - BITMAP_CLEAR_MEMORY : 0; - - /* return the created bitmap */ - return guit->bitmap->create(width, height, bitmap_state); -} - -static nserror nsbmp_create_bmp_data(nsbmp_content *bmp) -{ - union content_msg_data msg_data; - bmp_bitmap_callback_vt bmp_bitmap_callbacks = { - .bitmap_create = nsbmp_bitmap_create, - .bitmap_destroy = guit->bitmap->destroy, - .bitmap_get_buffer = guit->bitmap->get_buffer, - .bitmap_get_bpp = guit->bitmap->get_bpp - }; - - bmp->bmp = calloc(sizeof(struct bmp_image), 1); - if (bmp->bmp == NULL) { - msg_data.error = messages_get("NoMemory"); - content_broadcast(&bmp->base, CONTENT_MSG_ERROR, msg_data); - return NSERROR_NOMEM; - } - - bmp_create(bmp->bmp, &bmp_bitmap_callbacks); - - return NSERROR_OK; -} - -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) -{ - nsbmp_content *bmp; - nserror error; - - bmp = calloc(1, sizeof(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) { - free(bmp); - return error; - } - - error = nsbmp_create_bmp_data(bmp); - if (error != NSERROR_OK) { - free(bmp); - return error; - } - - *c = (struct content *) bmp; - - return NSERROR_OK; -} - -static bool nsbmp_convert(struct content *c) -{ - nsbmp_content *bmp = (nsbmp_content *) c; - bmp_result res; - union content_msg_data msg_data; - uint32_t swidth; - const char *data; - unsigned long size; - char *title; - - /* set the bmp data */ - data = content__get_source_data(c, &size); - - /* analyse the BMP */ - res = bmp_analyse(bmp->bmp, size, (unsigned char *) data); - switch (res) { - case BMP_OK: - break; - case BMP_INSUFFICIENT_MEMORY: - msg_data.error = messages_get("NoMemory"); - content_broadcast(c, CONTENT_MSG_ERROR, msg_data); - return false; - case BMP_INSUFFICIENT_DATA: - case BMP_DATA_ERROR: - msg_data.error = messages_get("BadBMP"); - content_broadcast(c, CONTENT_MSG_ERROR, msg_data); - return false; - } - - /* Store our content width and description */ - c->width = bmp->bmp->width; - c->height = bmp->bmp->height; - swidth = bmp->bmp->bitmap_callbacks.bitmap_get_bpp(bmp->bmp->bitmap) * - bmp->bmp->width; - c->size += (swidth * bmp->bmp->height) + 16 + 44; - - /* set title text */ - title = messages_get_buff("BMPTitle", - nsurl_access_leaf(llcache_handle_get_url(c->llcache)), - c->width, c->height); - if (title != NULL) { - content__set_title(c, title); - free(title); - } - - /* exit as a success */ - bmp->bitmap = bmp->bmp->bitmap; - guit->bitmap->modified(bmp->bitmap); - - content_set_ready(c); - content_set_done(c); - - /* Done: update status bar */ - content_set_status(c, ""); - return true; -} - -static bool nsbmp_redraw(struct content *c, struct content_redraw_data *data, - const struct rect *clip, const struct redraw_context *ctx) -{ - nsbmp_content *bmp = (nsbmp_content *) c; - bitmap_flags_t flags = BITMAPF_NONE; - - if (bmp->bmp->decoded == false) - if (bmp_decode(bmp->bmp) != BMP_OK) - return false; - - bmp->bitmap = bmp->bmp->bitmap; - - if (data->repeat_x) - flags |= BITMAPF_REPEAT_X; - if (data->repeat_y) - flags |= BITMAPF_REPEAT_Y; - - return ctx->plot->bitmap(data->x, data->y, data->width, data->height, - bmp->bitmap, data->background_colour, flags); -} - - -static void nsbmp_destroy(struct content *c) -{ - nsbmp_content *bmp = (nsbmp_content *) c; - - bmp_finalise(bmp->bmp); - free(bmp->bmp); -} - - -static nserror nsbmp_clone(const struct content *old, struct content **newc) -{ - nsbmp_content *new_bmp; - nserror error; - - new_bmp = calloc(1, sizeof(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 */ - 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_bmp->base) == false) { - content_destroy(&new_bmp->base); - return NSERROR_CLONE_FAILED; - } - } - - *newc = (struct content *) new_bmp; - - return NSERROR_OK; -} - -static void *nsbmp_get_internal(const struct content *c, void *context) -{ - nsbmp_content *bmp = (nsbmp_content *)c; - - return bmp->bitmap; -} - -static content_type nsbmp_content_type(void) -{ - return CONTENT_IMAGE; -} - - -static const content_handler nsbmp_content_handler = { - .create = nsbmp_create, - .data_complete = nsbmp_convert, - .destroy = nsbmp_destroy, - .redraw = nsbmp_redraw, - .clone = nsbmp_clone, - .get_internal = nsbmp_get_internal, - .type = nsbmp_content_type, - .no_share = 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" -}; - -CONTENT_FACTORY_REGISTER_TYPES(nsbmp, nsbmp_types, nsbmp_content_handler); diff --git a/image/bmp.h b/image/bmp.h deleted file mode 100644 index f3b398584..000000000 --- a/image/bmp.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2006 Richard Wilson <info@tinct.net> - * Copyright 2008 Sean Fox <dyntryx@gmail.com> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/** \file - * Content for image/bmp (interface). - */ - -#ifndef _NETSURF_IMAGE_BMP_H_ -#define _NETSURF_IMAGE_BMP_H_ - -#include <libnsbmp.h> - -extern bmp_bitmap_callback_vt bmp_bitmap_callbacks; /** Only to be used by ICO code. */ - -nserror nsbmp_init(void); - -#endif diff --git a/image/gif.c b/image/gif.c deleted file mode 100644 index 878a42a3c..000000000 --- a/image/gif.c +++ /dev/null @@ -1,455 +0,0 @@ -/* - * Copyright 2003 John M Bell <jmb202@ecs.soton.ac.uk> - * Copyright 2004 Richard Wilson <not_ginger_matt@users.sourceforge.net> - * Copyright 2008 Sean Fox <dyntryx@gmail.com> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/** - * \file - * - * Content for image/gif implementation - * - * All GIFs are dynamically decompressed using the routines that gifread.c - * provides. Whilst this allows support for progressive decoding, it is - * not implemented here as NetSurf currently does not provide such support. - * - * [rjw] - Sun 4th April 2004 - */ - -#include <assert.h> -#include <string.h> -#include <stdbool.h> -#include <stdlib.h> -#include <libnsgif.h> - -#include "utils/utils.h" -#include "utils/messages.h" -#include "utils/nsoption.h" -#include "content/content_protected.h" -#include "desktop/gui_misc.h" -#include "desktop/gui_internal.h" - -#include "image/image.h" -#include "image/bitmap.h" -#include "image/gif.h" - -typedef struct nsgif_content { - struct content base; - - struct gif_animation *gif; /**< GIF animation data */ - int current_frame; /**< current frame to display [0...(max-1)] */ -} nsgif_content; - - -/** - * Callback for libnsgif; forwards the call to bitmap_create() - * - * \param width width of image in pixels - * \param height width of image in pixels - * \return an opaque struct bitmap, or NULL on memory exhaustion - */ -static void *nsgif_bitmap_create(int width, int height) -{ - return guit->bitmap->create(width, height, BITMAP_NEW); -} - - -static nserror nsgif_create_gif_data(nsgif_content *c) -{ - union content_msg_data msg_data; - gif_bitmap_callback_vt gif_bitmap_callbacks = { - .bitmap_create = nsgif_bitmap_create, - .bitmap_destroy = guit->bitmap->destroy, - .bitmap_get_buffer = guit->bitmap->get_buffer, - .bitmap_set_opaque = guit->bitmap->set_opaque, - .bitmap_test_opaque = guit->bitmap->test_opaque, - .bitmap_modified = guit->bitmap->modified - }; - - /* Initialise our data structure */ - c->gif = calloc(sizeof(gif_animation), 1); - if (c->gif == NULL) { - msg_data.error = messages_get("NoMemory"); - content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data); - return NSERROR_NOMEM; - } - gif_create(c->gif, &gif_bitmap_callbacks); - return NSERROR_OK; -} - - - -static nserror nsgif_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) -{ - nsgif_content *result; - nserror error; - - result = calloc(1, sizeof(nsgif_content)); - if (result == NULL) - return NSERROR_NOMEM; - - error = content__init(&result->base, handler, imime_type, params, - llcache, fallback_charset, quirks); - if (error != NSERROR_OK) { - free(result); - return error; - } - - error = nsgif_create_gif_data(result); - if (error != NSERROR_OK) { - free(result); - return error; - } - - *c = (struct content *) result; - - return NSERROR_OK; -} - -/** - * Performs any necessary animation. - * - * \param p The content to animate -*/ -static void nsgif_animate(void *p) -{ - nsgif_content *gif = p; - union content_msg_data data; - int delay; - int f; - - /* Advance by a frame, updating the loop count accordingly */ - gif->current_frame++; - if (gif->current_frame == (int)gif->gif->frame_count_partial) { - gif->current_frame = 0; - - /* A loop count of 0 has a special meaning of infinite */ - if (gif->gif->loop_count != 0) { - gif->gif->loop_count--; - if (gif->gif->loop_count == 0) { - gif->current_frame = - gif->gif->frame_count_partial - 1; - gif->gif->loop_count = -1; - } - } - } - - /* Continue animating if we should */ - if (gif->gif->loop_count >= 0) { - delay = gif->gif->frames[gif->current_frame].frame_delay; - if (delay < nsoption_int(minimum_gif_delay)) - delay = nsoption_int(minimum_gif_delay); - guit->misc->schedule(delay * 10, nsgif_animate, gif); - } - - if ((!nsoption_bool(animate_images)) || - (!gif->gif->frames[gif->current_frame].display)) { - return; - } - - /* area within gif to redraw */ - f = gif->current_frame; - data.redraw.x = gif->gif->frames[f].redraw_x; - data.redraw.y = gif->gif->frames[f].redraw_y; - data.redraw.width = gif->gif->frames[f].redraw_width; - data.redraw.height = gif->gif->frames[f].redraw_height; - - /* redraw background (true) or plot on top (false) */ - if (gif->current_frame > 0) { - data.redraw.full_redraw = - gif->gif->frames[f - 1].redraw_required; - /* previous frame needed clearing: expand the redraw area to - * cover it */ - if (data.redraw.full_redraw) { - if (data.redraw.x > - (int)(gif->gif->frames[f - 1].redraw_x)) { - data.redraw.width += data.redraw.x - - gif->gif->frames[f - 1].redraw_x; - data.redraw.x = - gif->gif->frames[f - 1].redraw_x; - } - if (data.redraw.y > - (int)(gif->gif->frames[f - 1].redraw_y)) { - data.redraw.height += (data.redraw.y - - gif->gif->frames[f - 1].redraw_y); - data.redraw.y = - gif->gif->frames[f - 1].redraw_y; - } - if ((int)(gif->gif->frames[f - 1].redraw_x + - gif->gif->frames[f - 1].redraw_width) > - (data.redraw.x + data.redraw.width)) - data.redraw.width = - gif->gif->frames[f - 1].redraw_x - - data.redraw.x + - gif->gif->frames[f - 1].redraw_width; - if ((int)(gif->gif->frames[f - 1].redraw_y + - gif->gif->frames[f - 1].redraw_height) > - (data.redraw.y + data.redraw.height)) - data.redraw.height = - gif->gif->frames[f - 1].redraw_y - - data.redraw.y + - gif->gif->frames[f - 1].redraw_height; - } - } else { - /* do advanced check */ - if ((data.redraw.x == 0) && (data.redraw.y == 0) && - (data.redraw.width == (int)(gif->gif->width)) && - (data.redraw.height == (int)(gif->gif->height))) { - data.redraw.full_redraw = !gif->gif->frames[f].opaque; - } else { - data.redraw.full_redraw = true; - data.redraw.x = 0; - data.redraw.y = 0; - data.redraw.width = gif->gif->width; - data.redraw.height = gif->gif->height; - } - } - - /* other data */ - data.redraw.object = (struct content *) gif; - data.redraw.object_x = 0; - data.redraw.object_y = 0; - data.redraw.object_width = gif->base.width; - data.redraw.object_height = gif->base.height; - - content_broadcast(&gif->base, CONTENT_MSG_REDRAW, data); -} - -static bool nsgif_convert(struct content *c) -{ - nsgif_content *gif = (nsgif_content *) c; - int res; - union content_msg_data msg_data; - const char *data; - unsigned long size; - char *title; - - /* Get the animation */ - data = content__get_source_data(c, &size); - - /* Initialise the GIF */ - do { - res = gif_initialise(gif->gif, size, (unsigned char *) data); - if (res != GIF_OK && res != GIF_WORKING && - res != GIF_INSUFFICIENT_FRAME_DATA) { - switch (res) { - case GIF_FRAME_DATA_ERROR: - case GIF_INSUFFICIENT_DATA: - case GIF_DATA_ERROR: - msg_data.error = messages_get("BadGIF"); - break; - case GIF_INSUFFICIENT_MEMORY: - msg_data.error = messages_get("NoMemory"); - break; - } - content_broadcast(c, CONTENT_MSG_ERROR, msg_data); - return false; - } - } while (res != GIF_OK && res != GIF_INSUFFICIENT_FRAME_DATA); - - /* Abort on bad GIFs */ - if ((gif->gif->frame_count_partial == 0) || (gif->gif->width == 0) || - (gif->gif->height == 0)) { - msg_data.error = messages_get("BadGIF"); - content_broadcast(c, CONTENT_MSG_ERROR, msg_data); - return false; - } - - /* Store our content width, height and calculate size */ - c->width = gif->gif->width; - c->height = gif->gif->height; - c->size += (gif->gif->width * gif->gif->height * 4) + 16 + 44; - - /* set title text */ - title = messages_get_buff("GIFTitle", - nsurl_access_leaf(llcache_handle_get_url(c->llcache)), - c->width, c->height); - if (title != NULL) { - content__set_title(c, title); - free(title); - } - - /* Schedule the animation if we have one */ - gif->current_frame = 0; - if (gif->gif->frame_count_partial > 1) - guit->misc->schedule(gif->gif->frames[0].frame_delay * 10, - nsgif_animate, - c); - - /* Exit as a success */ - content_set_ready(c); - content_set_done(c); - - /* Done: update status bar */ - content_set_status(c, ""); - return true; -} - - -/** - * Updates the GIF bitmap to display the current frame - * - * \param gif The gif context to update. - * \return GIF_OK on success else apropriate error code. - */ -static gif_result nsgif_get_frame(nsgif_content *gif) -{ - int previous_frame, current_frame, frame; - gif_result res = GIF_OK; - - current_frame = gif->current_frame; - if (!nsoption_bool(animate_images)) { - current_frame = 0; - } - - if (current_frame < gif->gif->decoded_frame) { - previous_frame = 0; - } else { - previous_frame = gif->gif->decoded_frame + 1; - } - - for (frame = previous_frame; frame <= current_frame; frame++) { - res = gif_decode_frame(gif->gif, frame); - } - - return res; -} - -static bool nsgif_redraw(struct content *c, struct content_redraw_data *data, - const struct rect *clip, const struct redraw_context *ctx) -{ - nsgif_content *gif = (nsgif_content *) c; - - if (gif->current_frame != gif->gif->decoded_frame) { - if (nsgif_get_frame(gif) != GIF_OK) { - return false; - } - } - - return image_bitmap_plot(gif->gif->frame_image, data, clip, ctx); -} - - -static void nsgif_destroy(struct content *c) -{ - nsgif_content *gif = (nsgif_content *) c; - - /* Free all the associated memory buffers */ - guit->misc->schedule(-1, nsgif_animate, c); - gif_finalise(gif->gif); - free(gif->gif); -} - - -static nserror nsgif_clone(const struct content *old, struct content **newc) -{ - nsgif_content *gif; - nserror error; - - gif = calloc(1, sizeof(nsgif_content)); - if (gif == NULL) - return NSERROR_NOMEM; - - error = content__clone(old, &gif->base); - if (error != NSERROR_OK) { - content_destroy(&gif->base); - return error; - } - - /* Simply replay creation and conversion of content */ - error = nsgif_create_gif_data(gif); - if (error != NSERROR_OK) { - content_destroy(&gif->base); - return error; - } - - if (old->status == CONTENT_STATUS_READY || - old->status == CONTENT_STATUS_DONE) { - if (nsgif_convert(&gif->base) == false) { - content_destroy(&gif->base); - return NSERROR_CLONE_FAILED; - } - } - - *newc = (struct content *) gif; - - return NSERROR_OK; -} - -static void nsgif_add_user(struct content *c) -{ - nsgif_content *gif = (nsgif_content *) c; - - /* Ensure this content has already been converted. - * If it hasn't, the animation will start at the conversion phase instead. */ - if (gif->gif == NULL) return; - - if (content_count_users(c) == 1) { - /* First user, and content already converted, so start the animation. */ - if (gif->gif->frame_count_partial > 1) { - guit->misc->schedule(gif->gif->frames[0].frame_delay * 10, - nsgif_animate, c); - } - } -} - -static void nsgif_remove_user(struct content *c) -{ - if (content_count_users(c) == 1) { - /* Last user is about to be removed from this content, so stop the animation. */ - guit->misc->schedule(-1, nsgif_animate, c); - } -} - -static void *nsgif_get_internal(const struct content *c, void *context) -{ - nsgif_content *gif = (nsgif_content *) c; - - if (gif->current_frame != gif->gif->decoded_frame) { - if (nsgif_get_frame(gif) != GIF_OK) - return NULL; - } - - return gif->gif->frame_image; -} - -static content_type nsgif_content_type(void) -{ - return CONTENT_IMAGE; -} - -static const content_handler nsgif_content_handler = { - .create = nsgif_create, - .data_complete = nsgif_convert, - .destroy = nsgif_destroy, - .redraw = nsgif_redraw, - .clone = nsgif_clone, - .add_user = nsgif_add_user, - .remove_user = nsgif_remove_user, - .get_internal = nsgif_get_internal, - .type = nsgif_content_type, - .no_share = false, -}; - -static const char *nsgif_types[] = { - "image/gif" -}; - -CONTENT_FACTORY_REGISTER_TYPES(nsgif, nsgif_types, nsgif_content_handler); diff --git a/image/gif.h b/image/gif.h deleted file mode 100644 index a75821a96..000000000 --- a/image/gif.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2004 Richard Wilson <not_ginger_matt@users.sourceforge.net> - * Copyright 2008 Sean Fox <dyntryx@gmail.com> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/** \file - * Content for image/gif (interface). - */ - -#ifndef _NETSURF_IMAGE_GIF_H_ -#define _NETSURF_IMAGE_GIF_H_ - -nserror nsgif_init(void); - -#endif diff --git a/image/ico.c b/image/ico.c deleted file mode 100644 index 5f453bc9e..000000000 --- a/image/ico.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright 2006 Richard Wilson <info@tinct.net> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/** \file - * Content for image/ico (implementation) - */ - -#include <stdbool.h> -#include <stdlib.h> -#include <libnsbmp.h> - -#include "utils/utils.h" -#include "utils/log.h" -#include "utils/messages.h" -#include "content/content_protected.h" -#include "desktop/gui_internal.h" - -#include "image/image.h" -#include "image/bitmap.h" -#include "image/ico.h" - -typedef struct nsico_content { - struct content base; - - struct ico_collection *ico; /** ICO collection data */ - -} nsico_content; - -/** - * Callback for libnsbmp; forwards the call to bitmap_create() - * - * \param width width of image in pixels - * \param height width of image in pixels - * \param bmp_state A flag word indicating the initial state - * \return an opaque struct bitmap, or NULL on memory exhaustion - */ -static void *nsico_bitmap_create(int width, int height, unsigned int bmp_state) -{ - unsigned int bitmap_state = BITMAP_NEW; - - /* set bitmap state based on bmp state */ - bitmap_state |= (bmp_state & BMP_OPAQUE) ? BITMAP_OPAQUE : 0; - bitmap_state |= (bmp_state & BMP_CLEAR_MEMORY) ? - BITMAP_CLEAR_MEMORY : 0; - - /* return the created bitmap */ - return guit->bitmap->create(width, height, bitmap_state); -} - -static nserror nsico_create_ico_data(nsico_content *c) -{ - union content_msg_data msg_data; - bmp_bitmap_callback_vt bmp_bitmap_callbacks = { - .bitmap_create = nsico_bitmap_create, - .bitmap_destroy = guit->bitmap->destroy, - .bitmap_get_buffer = guit->bitmap->get_buffer, - .bitmap_get_bpp = guit->bitmap->get_bpp - }; - - c->ico = calloc(sizeof(ico_collection), 1); - if (c->ico == NULL) { - msg_data.error = messages_get("NoMemory"); - content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data); - return NSERROR_NOMEM; - } - ico_collection_create(c->ico, &bmp_bitmap_callbacks); - return NSERROR_OK; -} - - -static nserror nsico_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) -{ - nsico_content *result; - nserror error; - - result = calloc(1, sizeof(nsico_content)); - if (result == NULL) - return NSERROR_NOMEM; - - error = content__init(&result->base, handler, imime_type, params, - llcache, fallback_charset, quirks); - if (error != NSERROR_OK) { - free(result); - return error; - } - - error = nsico_create_ico_data(result); - if (error != NSERROR_OK) { - free(result); - return error; - } - - *c = (struct content *) result; - - return NSERROR_OK; -} - - - -static bool nsico_convert(struct content *c) -{ - nsico_content *ico = (nsico_content *) c; - struct bmp_image *bmp; - bmp_result res; - union content_msg_data msg_data; - const char *data; - unsigned long size; - char *title; - - /* set the ico data */ - data = content__get_source_data(c, &size); - - /* analyse the ico */ - res = ico_analyse(ico->ico, size, (unsigned char *) data); - - switch (res) { - case BMP_OK: - break; - case BMP_INSUFFICIENT_MEMORY: - msg_data.error = messages_get("NoMemory"); - content_broadcast(c, CONTENT_MSG_ERROR, msg_data); - return false; - case BMP_INSUFFICIENT_DATA: - case BMP_DATA_ERROR: - msg_data.error = messages_get("BadICO"); - content_broadcast(c, CONTENT_MSG_ERROR, msg_data); - return false; - } - - /* Store our content width, height and calculate size */ - c->width = ico->ico->width; - c->height = ico->ico->height; - c->size += (ico->ico->width * ico->ico->height * 4) + 16 + 44; - - /* set title text */ - title = messages_get_buff("ICOTitle", - nsurl_access_leaf(llcache_handle_get_url(c->llcache)), - c->width, c->height); - if (title != NULL) { - content__set_title(c, title); - free(title); - } - - /* select largest icon to ensure one can be selected */ - bmp = ico_find(ico->ico, 255, 255); - if (bmp == NULL) { - /* return error */ - LOG("Failed to select icon"); - return false; - } - - content_set_ready(c); - content_set_done(c); - - /* Done: update status bar */ - content_set_status(c, ""); - return true; -} - - -static bool nsico_redraw(struct content *c, struct content_redraw_data *data, - const struct rect *clip, const struct redraw_context *ctx) -{ - nsico_content *ico = (nsico_content *)c; - struct bmp_image *bmp; - - /* select most appropriate sized icon for size */ - bmp = ico_find(ico->ico, data->width, data->height); - if (bmp == NULL) { - /* return error */ - LOG("Failed to select icon"); - return false; - } - - /* ensure its decided */ - if (bmp->decoded == false) { - if (bmp_decode(bmp) != BMP_OK) { - return false; - } else { - LOG("Decoding bitmap"); - guit->bitmap->modified(bmp->bitmap); - } - - } - - return image_bitmap_plot(bmp->bitmap, data, clip, ctx); -} - - -static void nsico_destroy(struct content *c) -{ - nsico_content *ico = (nsico_content *) c; - - ico_finalise(ico->ico); - free(ico->ico); -} - -static nserror nsico_clone(const struct content *old, struct content **newc) -{ - nsico_content *ico; - nserror error; - - ico = calloc(1, sizeof(nsico_content)); - if (ico == NULL) - return NSERROR_NOMEM; - - error = content__clone(old, &ico->base); - if (error != NSERROR_OK) { - content_destroy(&ico->base); - return error; - } - - /* Simply replay creation and conversion */ - error = nsico_create_ico_data(ico); - if (error != NSERROR_OK) { - content_destroy(&ico->base); - return error; - } - - if (old->status == CONTENT_STATUS_READY || - old->status == CONTENT_STATUS_DONE) { - if (nsico_convert(&ico->base) == false) { - content_destroy(&ico->base); - return NSERROR_CLONE_FAILED; - } - } - - *newc = (struct content *) ico; - - return NSERROR_OK; -} - -static void *nsico_get_internal(const struct content *c, void *context) -{ - nsico_content *ico = (nsico_content *) c; - /* TODO: Pick best size for purpose. - * Currently assumes it's for a URL bar. */ - struct bmp_image *bmp; - - bmp = ico_find(ico->ico, 16, 16); - if (bmp == NULL) { - /* return error */ - LOG("Failed to select icon"); - return NULL; - } - - if (bmp->decoded == false) { - if (bmp_decode(bmp) != BMP_OK) { - return NULL; - } else { - guit->bitmap->modified(bmp->bitmap); - } - } - - return bmp->bitmap; -} - -static content_type nsico_content_type(void) -{ - return CONTENT_IMAGE; -} - -static const content_handler nsico_content_handler = { - .create = nsico_create, - .data_complete = nsico_convert, - .destroy = nsico_destroy, - .redraw = nsico_redraw, - .clone = nsico_clone, - .get_internal = nsico_get_internal, - .type = nsico_content_type, - .no_share = false, -}; - -static const char *nsico_types[] = { - "application/ico", - "application/x-ico", - "image/ico", - "image/vnd.microsoft.icon", - "image/x-icon" -}; - -CONTENT_FACTORY_REGISTER_TYPES(nsico, nsico_types, nsico_content_handler); diff --git a/image/ico.h b/image/ico.h deleted file mode 100644 index 21e9bdb6e..000000000 --- a/image/ico.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2006 Richard Wilson <info@tinct.net> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/** \file - * Content for image/ico (interface). - */ - -#ifndef _NETSURF_IMAGE_ICO_H_ -#define _NETSURF_IMAGE_ICO_H_ - -nserror nsico_init(void); - -#endif diff --git a/image/image.c b/image/image.c deleted file mode 100644 index b9bcf1e97..000000000 --- a/image/image.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2011 John-Mark Bell <jmb@netsurf-browser.org> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <stdbool.h> -#include <stdlib.h> - -#include "utils/utils.h" -#include "utils/log.h" -#include "utils/messages.h" -#include "content/content.h" -#include "desktop/plotters.h" -#include "desktop/gui_internal.h" - -#include "image/bitmap.h" -#include "image/bmp.h" -#include "image/gif.h" -#include "image/ico.h" -#include "image/jpeg.h" -#include "image/nssprite.h" -#include "image/png.h" -#include "image/rsvg.h" -#include "image/svg.h" -#include "image/image.h" - -/** - * Initialise image content handlers - * - * \return NSERROR_OK on success, appropriate error otherwise. - */ -nserror image_init(void) -{ - nserror error = NSERROR_OK; - -#ifdef WITH_BMP - error = nsbmp_init(); - if (error != NSERROR_OK) - return error; -#endif - -#ifdef WITH_GIF - error = nsgif_init(); - if (error != NSERROR_OK) - return error; -#endif - -#ifdef WITH_BMP - error = nsico_init(); - if (error != NSERROR_OK) - return error; -#endif - -#ifdef WITH_JPEG - error = nsjpeg_init(); - if (error != NSERROR_OK) - return error; -#endif - -#ifdef WITH_PNG - error = nspng_init(); - if (error != NSERROR_OK) - return error; -#endif - -#ifdef WITH_NSSPRITE - error = nssprite_init(); - if (error != NSERROR_OK) - return error; -#endif - - /* Prefer rsvg over libsvgtiny for svgs */ -#ifdef WITH_NS_SVG - error = svg_init(); - if (error != NSERROR_OK) - return error; -#endif -#ifdef WITH_RSVG - error = nsrsvg_init(); - if (error != NSERROR_OK) - return error; -#endif - - return error; -} - - -bool image_bitmap_plot(struct bitmap *bitmap, - struct content_redraw_data *data, - const struct rect *clip, - const struct redraw_context *ctx) -{ - bitmap_flags_t flags = BITMAPF_NONE; - - int width; - int height; - unsigned char *pixel; - plot_style_t fill_style; - struct rect area; - - width = guit->bitmap->get_width(bitmap); - if (width == 1) { - height = guit->bitmap->get_height(bitmap); - if (height == 1) { - /* optimise 1x1 bitmap plot */ - pixel = guit->bitmap->get_buffer(bitmap); - fill_style.fill_colour = pixel_to_colour(pixel); - - if (guit->bitmap->get_opaque(bitmap) || - ((fill_style.fill_colour & 0xff000000) == 0xff000000)) { - - area = *clip; - - if (data->repeat_x != true) { - area.x0 = data->x; - area.x1 = data->x + data->width; - } - - if (data->repeat_y != true) { - area.y0 = data->y; - area.y1 = data->y + data->height; - } - - fill_style.stroke_type = PLOT_OP_TYPE_NONE; - fill_style.fill_type = PLOT_OP_TYPE_SOLID; - - return ctx->plot->rectangle(area.x0, area.y0, - area.x1, area.y1, - &fill_style); - - } else if ((fill_style.fill_colour & 0xff000000) == 0) { - /* transparent pixel used as spacer, skip it */ - return true; - } - } - } - - /* do the plot */ - if (data->repeat_x) - flags |= BITMAPF_REPEAT_X; - if (data->repeat_y) - flags |= BITMAPF_REPEAT_Y; - - return ctx->plot->bitmap(data->x, data->y, data->width, data->height, - bitmap, data->background_colour, flags); -} diff --git a/image/image.h b/image/image.h deleted file mode 100644 index eb9482583..000000000 --- a/image/image.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2011 John-Mark Bell <jmb@netsurf-browser.org> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/** \file - * Initialisation/finalisation of image handlers. - */ - -#ifndef NETSURF_IMAGE_IMAGE_H_ -#define NETSURF_IMAGE_IMAGE_H_ - -#include "utils/errors.h" - -/** Initialise the content handlers for image types. - */ -nserror image_init(void); - -/** Common image content handler bitmap plot call. - * - * This plots the specified bitmap controlled by the redraw context - * and specific content redraw data. It is a helper specifically - * provided for image content handlers redraw callback. - */ -bool image_bitmap_plot(struct bitmap *bitmap, - struct content_redraw_data *data, - const struct rect *clip, - const struct redraw_context *ctx); - -#endif diff --git a/image/image_cache.c b/image/image_cache.c deleted file mode 100644 index 9f217f860..000000000 --- a/image/image_cache.c +++ /dev/null @@ -1,797 +0,0 @@ -/* - * Copyright 2011 Vincent Sanders <vince@netsurf-browser.org> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <assert.h> -#include <inttypes.h> -#include <stdint.h> -#include <stdbool.h> -#include <string.h> -#include <stdlib.h> - -#include "utils/utils.h" -#include "utils/log.h" -#include "content/content_protected.h" -#include "desktop/gui_misc.h" -#include "desktop/gui_internal.h" - -#include "image/bitmap.h" -#include "image/image_cache.h" -#include "image/image.h" - -/** Age of an entry within the cache - * - * type deffed away so it can be readily changed later perhaps to a - * wallclock time structure. - */ -typedef unsigned int cache_age; - -/** Image cache entry - */ -struct image_cache_entry_s { - struct image_cache_entry_s *next; /* next cache entry in list */ - struct image_cache_entry_s *prev; /* previous cache entry in list */ - - struct content *content; /** content is used as a key */ - struct bitmap *bitmap; /** associated bitmap entry */ - /** Conversion routine */ - image_cache_convert_fn *convert; - - /* Statistics for replacement algorithm */ - - unsigned int redraw_count; /**< number of times object has been drawn */ - cache_age redraw_age; /**< Age of last redraw */ - size_t bitmap_size; /**< size if storage occupied by bitmap */ - cache_age bitmap_age; /**< Age of last conversion to a bitmap by cache*/ - - int conversion_count; /**< Number of times image has been converted */ -}; - -/** Current state of the cache. - * - * Global state of the cache. entries "age" is determined based on a - * monotonically incrementing operation count. This avoids issues with - * using wall clock time while allowing the LRU algorithm to work - * sensibly. - */ -struct image_cache_s { - /** Cache parameters */ - struct image_cache_parameters params; - - /** The "age" of the current operation */ - cache_age current_age; - - /* The objects the cache holds */ - struct image_cache_entry_s *entries; - - - /* Statistics for management algorithm */ - - /** total size of bitmaps currently allocated */ - size_t total_bitmap_size; - - /** Total count of bitmaps currently allocated */ - int bitmap_count; - - /** Maximum size of bitmaps allocated at any one time */ - size_t max_bitmap_size; - /** The number of objects when maximum bitmap usage occoured */ - int max_bitmap_size_count; - - /** Maximum count of bitmaps allocated at any one time */ - int max_bitmap_count; - /** The size of the bitmaps when the max count occoured */ - size_t max_bitmap_count_size; - - /** Bitmap was not available at plot time required conversion */ - int miss_count; - uint64_t miss_size; - /** Bitmap was available at plot time required no conversion */ - int hit_count; - uint64_t hit_size; - /** Bitmap was not available at plot time and required - * conversion which failed. - */ - int fail_count; - uint64_t fail_size; - - /* Cache entry freed without ever being redrawn */ - int total_unrendered; - /** Bitmap was available but never required - wasted conversions */ - int specultive_miss_count; - - /** Total number of additional (after the first) conversions */ - int total_extra_conversions; - /** counts total number of images with more than one conversion */ - int total_extra_conversions_count; - - /** Bitmap with most conversions was converted this many times */ - int peak_conversions; - /** Size of bitmap with most conversions */ - unsigned int peak_conversions_size; -}; - -/** image cache state */ -static struct image_cache_s *image_cache = NULL; - - -/** Find the nth cache entry - */ -static struct image_cache_entry_s *image_cache__findn(int entryn) -{ - struct image_cache_entry_s *found; - - found = image_cache->entries; - while ((found != NULL) && (entryn > 0)) { - entryn--; - found = found->next; - } - return found; -} - -/** Find the cache entry for a content - */ -static struct image_cache_entry_s *image_cache__find(const struct content *c) -{ - struct image_cache_entry_s *found; - - found = image_cache->entries; - while ((found != NULL) && (found->content != c)) { - found = found->next; - } - return found; -} - -static void image_cache_stats_bitmap_add(struct image_cache_entry_s *centry) -{ - centry->bitmap_age = image_cache->current_age; - centry->conversion_count++; - - image_cache->total_bitmap_size += centry->bitmap_size; - image_cache->bitmap_count++; - - if (image_cache->total_bitmap_size > image_cache->max_bitmap_size) { - image_cache->max_bitmap_size = image_cache->total_bitmap_size; - image_cache->max_bitmap_size_count = image_cache->bitmap_count; - - } - - if (image_cache->bitmap_count > image_cache->max_bitmap_count) { - image_cache->max_bitmap_count = image_cache->bitmap_count; - image_cache->max_bitmap_count_size = image_cache->total_bitmap_size; - } - - if (centry->conversion_count == 2) { - image_cache->total_extra_conversions_count++; - } - - if (centry->conversion_count > 1) { - image_cache->total_extra_conversions++; - } - - if ((centry->conversion_count > image_cache->peak_conversions) || - (centry->conversion_count == image_cache->peak_conversions && - centry->bitmap_size > image_cache->peak_conversions_size)) { - image_cache->peak_conversions = centry->conversion_count; - image_cache->peak_conversions_size = centry->bitmap_size; - } -} - -static void image_cache__link(struct image_cache_entry_s *centry) -{ - centry->next = image_cache->entries; - centry->prev = NULL; - if (centry->next != NULL) { - centry->next->prev = centry; - } - image_cache->entries = centry; -} - -static void image_cache__unlink(struct image_cache_entry_s *centry) -{ - /* unlink entry */ - if (centry->prev == NULL) { - /* first in list */ - if (centry->next != NULL) { - centry->next->prev = centry->prev; - image_cache->entries = centry->next; - } else { - /* empty list */ - image_cache->entries = NULL; - } - } else { - centry->prev->next = centry->next; - - if (centry->next != NULL) { - centry->next->prev = centry->prev; - } - } -} - -static void image_cache__free_bitmap(struct image_cache_entry_s *centry) -{ - if (centry->bitmap != NULL) { -#ifdef IMAGE_CACHE_VERBOSE - LOG("Freeing bitmap %p size %d age %d redraw count %d", centry->bitmap, centry->bitmap_size, image_cache->current_age - centry->bitmap_age, centry->redraw_count); -#endif - guit->bitmap->destroy(centry->bitmap); - centry->bitmap = NULL; - image_cache->total_bitmap_size -= centry->bitmap_size; - image_cache->bitmap_count--; - if (centry->redraw_count == 0) { - image_cache->specultive_miss_count++; - } - } - -} - -/* free cache entry */ -static void image_cache__free_entry(struct image_cache_entry_s *centry) -{ -#ifdef IMAGE_CACHE_VERBOSE - LOG("freeing %p ", centry); -#endif - - if (centry->redraw_count == 0) { - image_cache->total_unrendered++; - } - - image_cache__free_bitmap(centry); - - image_cache__unlink(centry); - - free(centry); -} - -/** Cache cleaner */ -static void image_cache__clean(struct image_cache_s *icache) -{ - struct image_cache_entry_s *centry = icache->entries; - - while (centry != NULL) { - if ((icache->current_age - centry->redraw_age) > - icache->params.bg_clean_time) { - /* only consider older entries, avoids active entries */ - if ((icache->total_bitmap_size > - (icache->params.limit - icache->params.hysteresis)) && - (rand() > (RAND_MAX / 2))) { - image_cache__free_bitmap(centry); - } - } - centry=centry->next; - } -} - -/** Cache background scheduled callback. */ -static void image_cache__background_update(void *p) -{ - struct image_cache_s *icache = p; - - /* increment current cache age */ - icache->current_age += icache->params.bg_clean_time; - -#ifdef IMAGE_CACHE_VERBOSE - LOG("Cache age %ds", icache->current_age / 1000); -#endif - - image_cache__clean(icache); - - guit->misc->schedule(icache->params.bg_clean_time, - image_cache__background_update, - icache); -} - -/* exported interface documented in image_cache.h */ -struct bitmap *image_cache_get_bitmap(const struct content *c) -{ - struct image_cache_entry_s *centry; - - centry = image_cache__find(c); - if (centry == NULL) { - return NULL; - } - - if (centry->bitmap == NULL) { - if (centry->convert != NULL) { - centry->bitmap = centry->convert(centry->content); - } - - if (centry->bitmap != NULL) { - image_cache_stats_bitmap_add(centry); - image_cache->miss_count++; - image_cache->miss_size += centry->bitmap_size; - } else { - image_cache->fail_count++; - image_cache->fail_size += centry->bitmap_size; - } - } else { - image_cache->hit_count++; - image_cache->hit_size += centry->bitmap_size; - } - - return centry->bitmap; -} - -/* exported interface documented in image_cache.h */ -bool image_cache_speculate(struct content *c) -{ - bool decision = false; - - /* If the cache is below its target usage and the bitmap is - * small enough speculate. - */ - if ((image_cache->total_bitmap_size < image_cache->params.limit) && - (c->size <= image_cache->params.speculative_small)) { -#ifdef IMAGE_CACHE_VERBOSE - LOG("content size (%d) is smaller than minimum (%d)", c->size, SPECULATE_SMALL); -#endif - decision = true; - } - -#ifdef IMAGE_CACHE_VERBOSE - LOG("returning %d", decision); -#endif - return decision; -} - -/* exported interface documented in image_cache.h */ -struct bitmap *image_cache_find_bitmap(struct content *c) -{ - struct image_cache_entry_s *centry; - - centry = image_cache__find(c); - if (centry == NULL) { - return NULL; - } - - return centry->bitmap; -} - -/* exported interface documented in image_cache.h */ -nserror -image_cache_init(const struct image_cache_parameters *image_cache_parameters) -{ - image_cache = calloc(1, sizeof(struct image_cache_s)); - if (image_cache == NULL) { - return NSERROR_NOMEM; - } - - image_cache->params = *image_cache_parameters; - - guit->misc->schedule(image_cache->params.bg_clean_time, - image_cache__background_update, - image_cache); - - LOG("Image cache initilised with a limit of %" PRIsizet " hysteresis of %"PRIsizet, - image_cache->params.limit, image_cache->params.hysteresis); - - return NSERROR_OK; -} - -/* exported interface documented in image_cache.h */ -nserror image_cache_fini(void) -{ - unsigned int op_count; - - guit->misc->schedule(-1, image_cache__background_update, image_cache); - - LOG("Size at finish %" PRIsizet " (in %d)", - image_cache->total_bitmap_size, image_cache->bitmap_count); - - while (image_cache->entries != NULL) { - image_cache__free_entry(image_cache->entries); - } - - op_count = image_cache->hit_count + - image_cache->miss_count + - image_cache->fail_count; - - LOG("Age %ds", image_cache->current_age / 1000); - LOG("Peak size %" PRIsizet " (in %d)", - image_cache->max_bitmap_size, image_cache->max_bitmap_size_count); - LOG("Peak image count %d (size %" PRIsizet ")", - image_cache->max_bitmap_count, image_cache->max_bitmap_count_size); - - if (op_count > 0) { - uint64_t op_size; - - op_size = image_cache->hit_size + - image_cache->miss_size + - image_cache->fail_size; - - LOG("Cache total/hit/miss/fail (counts) %d/%d/%d/%d (100%%/%d%%/%d%%/%d%%)", - op_count, - image_cache->hit_count, - image_cache->miss_count, - image_cache->fail_count, - (image_cache->hit_count * 100) / op_count, - (image_cache->miss_count * 100) / op_count, - (image_cache->fail_count * 100) / op_count); - LOG("Cache total/hit/miss/fail (size) %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64" (100%%/%"PRId64"%%/%"PRId64"%%/%"PRId64"%%)", - op_size, - image_cache->hit_size, - image_cache->miss_size, - image_cache->fail_size, - (image_cache->hit_size * 100) / op_size, - (image_cache->miss_size * 100) / op_size, - (image_cache->fail_size * 100) / op_size); - } - - LOG("Total images never rendered: %d (includes %d that were converted)", - image_cache->total_unrendered, - image_cache->specultive_miss_count); - - LOG("Total number of excessive conversions: %d (from %d images converted more than once)", - image_cache->total_extra_conversions, - image_cache->total_extra_conversions_count); - - LOG("Bitmap of size %d had most (%d) conversions", - image_cache->peak_conversions_size, - image_cache->peak_conversions); - - free(image_cache); - - return NSERROR_OK; -} - -/* exported interface documented in image_cache.h */ -nserror image_cache_add(struct content *content, - struct bitmap *bitmap, - image_cache_convert_fn *convert) -{ - struct image_cache_entry_s *centry; - - /* bump the cache age by a ms to ensure multiple items are not - * added at exactly the same time - */ - image_cache->current_age++; - - centry = image_cache__find(content); - if (centry == NULL) { - /* new cache entry, content not previously added */ - centry = calloc(1, sizeof(struct image_cache_entry_s)); - if (centry == NULL) { - return NSERROR_NOMEM; - } - image_cache__link(centry); - centry->content = content; - - centry->bitmap_size = content->width * content->height * 4; - } - - LOG("centry %p, content %p, bitmap %p", centry, content, bitmap); - - centry->convert = convert; - - /* set bitmap entry if one is passed, free extant one if present */ - if (bitmap != NULL) { - if (centry->bitmap != NULL) { - guit->bitmap->destroy(centry->bitmap); - } else { - image_cache_stats_bitmap_add(centry); - } - centry->bitmap = bitmap; - } else { - /* no bitmap, check to see if we should speculatively convert */ - if ((centry->convert != NULL) && - (image_cache_speculate(content) == true)) { - centry->bitmap = centry->convert(centry->content); - - if (centry->bitmap != NULL) { - image_cache_stats_bitmap_add(centry); - } else { - image_cache->fail_count++; - } - } - } - - - - return NSERROR_OK; -} - -/* exported interface documented in image_cache.h */ -nserror image_cache_remove(struct content *content) -{ - struct image_cache_entry_s *centry; - - /* get the cache entry */ - centry = image_cache__find(content); - if (centry == NULL) { - LOG("Could not find cache entry for content (%p)", content); - return NSERROR_NOT_FOUND; - } - - image_cache__free_entry(centry); - - return NSERROR_OK; -} - -/* exported interface documented in image_cache.h */ -int image_cache_snsummaryf(char *string, size_t size, const char *fmt) -{ - size_t slen = 0; /* current output string length */ - int fmtc = 0; /* current index into format string */ - bool pct; - unsigned int op_count; - uint64_t op_size; - - op_count = image_cache->hit_count + - image_cache->miss_count + - image_cache->fail_count; - - op_size = image_cache->hit_size + - image_cache->miss_size + - image_cache->fail_size; - - while((slen < size) && (fmt[fmtc] != 0)) { - if (fmt[fmtc] == '%') { - fmtc++; - - /* check for percentage modifier */ - if (fmt[fmtc] == 'p') { - fmtc++; - pct = true; - } else { - pct = false; - } - -#define FMTCHR(chr,fmt,var) case chr : \ -slen += snprintf(string + slen, size - slen, "%"fmt, image_cache->var); break - -#define FMTPCHR(chr,fmt,var,div) \ -case chr : \ - if (pct) { \ - if (div > 0) { \ - slen += snprintf(string + slen, size - slen, "%"PRId64, (uint64_t)((image_cache->var * 100) / div)); \ - } else { \ - slen += snprintf(string + slen, size - slen, "100"); \ - } \ - } else { \ - slen += snprintf(string + slen, size - slen, "%"fmt, image_cache->var); \ - } break - - - switch (fmt[fmtc]) { - case '%': - string[slen] = '%'; - slen++; - break; - - FMTCHR('a', PRIssizet, params.limit); - FMTCHR('b', PRIssizet, params.hysteresis); - FMTCHR('c', PRIssizet, total_bitmap_size); - FMTCHR('d', "d", bitmap_count); - FMTCHR('e', "d", current_age / 1000); - FMTCHR('f', PRIssizet, max_bitmap_size); - FMTCHR('g', "d", max_bitmap_size_count); - FMTCHR('h', "d", max_bitmap_count); - FMTCHR('i', PRIssizet, max_bitmap_count_size); - - - case 'j': - slen += snprintf(string + slen, size - slen, - "%d", pct?100:op_count); - break; - - FMTPCHR('k', "d", hit_count, op_count); - FMTPCHR('l', "d", miss_count, op_count); - FMTPCHR('m', "d", fail_count, op_count); - - case 'n': - slen += snprintf(string + slen, size - slen, - "%"PRId64, pct?100:op_size); - break; - - FMTPCHR('o', PRId64, hit_size, op_size); - FMTPCHR('q', PRId64, miss_size, op_size); - FMTPCHR('r', PRId64, fail_size, op_size); - - FMTCHR('s', "d", total_unrendered); - FMTCHR('t', "d", specultive_miss_count); - FMTCHR('u', "d", total_extra_conversions); - FMTCHR('v', "d", total_extra_conversions_count); - FMTCHR('w', "d", peak_conversions_size); - FMTCHR('x', "d", peak_conversions); - - - } -#undef FMTCHR -#undef FMTPCHR - - fmtc++; - } else { - string[slen] = fmt[fmtc]; - slen++; - fmtc++; - } - } - - /* Ensure that we NUL-terminate the output */ - string[min(slen, size - 1)] = '\0'; - - return slen; -} - -/* exported interface documented in image_cache.h */ -int image_cache_snentryf(char *string, size_t size, unsigned int entryn, - const char *fmt) -{ - struct image_cache_entry_s *centry; - size_t slen = 0; /* current output string length */ - int fmtc = 0; /* current index into format string */ - lwc_string *origin; /* current entry's origin */ - - centry = image_cache__findn(entryn); - if (centry == NULL) - return -1; - - while((slen < size) && (fmt[fmtc] != 0)) { - if (fmt[fmtc] == '%') { - fmtc++; - switch (fmt[fmtc]) { - case 'e': - slen += snprintf(string + slen, size - slen, - "%d", entryn); - break; - - case 'r': - slen += snprintf(string + slen, size - slen, - "%u", centry->redraw_count); - break; - - case 'a': - slen += snprintf(string + slen, size - slen, - "%.2f", (float)((image_cache->current_age - centry->redraw_age)) / 1000); - break; - - - case 'c': - slen += snprintf(string + slen, size - slen, - "%d", centry->conversion_count); - break; - - case 'g': - slen += snprintf(string + slen, size - slen, - "%.2f", (float)((image_cache->current_age - centry->bitmap_age)) / 1000); - break; - - case 'k': - slen += snprintf(string + slen, size - slen, - "%p", centry->content); - break; - - case 'U': - slen += snprintf(string + slen, size - slen, - "%s", nsurl_access(llcache_handle_get_url(centry->content->llcache))); - break; - - case 'o': - if (nsurl_has_component(llcache_handle_get_url( - centry->content->llcache), - NSURL_HOST)) { - origin = nsurl_get_component( - llcache_handle_get_url( - centry->content-> - llcache), - NSURL_HOST); - - slen += snprintf(string + slen, - size - slen, "%s", - lwc_string_data( - origin)); - - lwc_string_unref(origin); - } else { - slen += snprintf(string + slen, - size - slen, "%s", - "localhost"); - } - break; - - case 's': - if (centry->bitmap != NULL) { - slen += snprintf(string + slen, - size - slen, - "%" PRIssizet, - centry->bitmap_size); - } else { - slen += snprintf(string + slen, - size - slen, - "0"); - } - break; - } - fmtc++; - } else { - string[slen] = fmt[fmtc]; - slen++; - fmtc++; - } - } - - /* Ensure that we NUL-terminate the output */ - string[min(slen, size - 1)] = '\0'; - - return slen; -} - - -/* exported interface documented in image_cache.h */ -bool image_cache_redraw(struct content *c, - struct content_redraw_data *data, - const struct rect *clip, - const struct redraw_context *ctx) -{ - struct image_cache_entry_s *centry; - - /* get the cache entry */ - centry = image_cache__find(c); - if (centry == NULL) { - LOG("Could not find cache entry for content (%p)", c); - return false; - } - - if (centry->bitmap == NULL) { - if (centry->convert != NULL) { - centry->bitmap = centry->convert(centry->content); - } - - if (centry->bitmap != NULL) { - image_cache_stats_bitmap_add(centry); - image_cache->miss_count++; - image_cache->miss_size += centry->bitmap_size; - } else { - image_cache->fail_count++; - image_cache->fail_size += centry->bitmap_size; - return false; - } - } else { - image_cache->hit_count++; - image_cache->hit_size += centry->bitmap_size; - } - - - /* update statistics */ - centry->redraw_count++; - centry->redraw_age = image_cache->current_age; - - return image_bitmap_plot(centry->bitmap, data, clip, ctx); -} - -void image_cache_destroy(struct content *content) -{ - struct image_cache_entry_s *centry; - - /* get the cache entry */ - centry = image_cache__find(content); - if (centry == NULL) { - LOG("Could not find cache entry for content (%p)", content); - } else { - image_cache__free_entry(centry); - } -} - -void *image_cache_get_internal(const struct content *c, void *context) -{ - return image_cache_get_bitmap(c); -} - -content_type image_cache_content_type(void) -{ - return CONTENT_IMAGE; -} diff --git a/image/image_cache.h b/image/image_cache.h deleted file mode 100644 index 2f1a5caee..000000000 --- a/image/image_cache.h +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright 2011 John-Mark Bell <jmb@netsurf-browser.org> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/** \file - * The image content handler intermediate image cache. - * - * This cache allows netsurf to use a generic intermediate bitmap - * format without keeping the - * intermediate representation in memory. - * - * The bitmap structure is opaque to the rest of netsurf and is - * controlled by the platform-specific code (see image/bitmap.h for - * detials). All image content handlers convert into this format and - * pass it to the plot functions for display, - * - * This cache maintains a link between the underlying original content - * and the intermediate representation. It is intended to be flexable - * and either manage the bitmap plotting completely or give the image - * content handler complete control. - */ - -#ifndef NETSURF_IMAGE_IMAGE_CACHE_H_ -#define NETSURF_IMAGE_IMAGE_CACHE_H_ - -#include "utils/errors.h" - -struct content_redraw_data; -struct redraw_context; - -typedef struct bitmap * (image_cache_convert_fn) (struct content *content); - -struct image_cache_parameters { - /** How frequently the background cache clean process is run (ms) */ - unsigned int bg_clean_time; - - /** The target upper bound for the image cache size */ - size_t limit; - - /** The hysteresis allowed round the target size */ - size_t hysteresis; - - /** The speculative conversion "small" size */ - size_t speculative_small; -}; - -/** Initialise the image cache - * - * @param image_cache_parameters The control parameters for the image cache - */ -nserror image_cache_init(const struct image_cache_parameters *image_cache_parameters); -nserror image_cache_fini(void); - -/** adds an image content to be cached. - * - * @param content The content handle used as a key - * @param bitmap A bitmap representing the already converted content or NULL. - * @param convert A function pointer to convert the content into a bitmap or NULL. - * @return A netsurf error code. - */ -nserror image_cache_add(struct content *content, - struct bitmap *bitmap, - image_cache_convert_fn *convert); - -nserror image_cache_remove(struct content *content); - - -/** Obtain a bitmap from a content converting from source if neccessary. */ -struct bitmap *image_cache_get_bitmap(const struct content *c); - -/** Obtain a bitmap from a content with no conversion */ -struct bitmap *image_cache_find_bitmap(struct content *c); - -/** Decide if a content should be speculatively converted. - * - * This allows for image content handlers to ask the cache if a bitmap - * should be generated before it is added to the cache. This is the - * same decision logic used to decide to perform an immediate - * conversion when a content is initially added to the cache. - * - * @param c The content to be considered. - * @return true if a speculative conversion is desired false otherwise. - */ -bool image_cache_speculate(struct content *c); - -/** - * Fill a buffer with information about a cache entry using a format. - * - * The format string is copied into the output buffer with the - * following replaced: - * %e - The entry number - * %k - The content key - * %r - The number of redraws of this bitmap - * %c - The number of times this bitmap has been converted - * %s - The size of the current bitmap allocation - * - * \param string The buffer in which to place the results. - * \param size The size of the string buffer. - * \param entryn The opaque entry number. - * \param fmt The format string. - * \return The number of bytes written to \a string or -1 on error - */ -int image_cache_snentryf(char *string, size_t size, unsigned int entryn, - const char *fmt); - -/** - * Fill a buffer with information about the image cache using a format. - * - * The format string is copied into the output buffer with the - * following replaced: - * - * a Configured cache limit size - * b Configured cache hysteresis size - * c Current caches total consumed size - * d Number of images currently in the cache - * e The age of the cache - * f The largest amount of space the cache has occupied since initialisation - * g The number of objetcs when the cache was at its largest - * h The largest number of images in the cache since initialisation - * i The size of the cache when the largest number of objects occoured - * j The total number of read operations performed on the cache - * k The total number of read operations satisfied from the cache without - * conversion. - * l The total number of read operations satisfied from the cache which - * required a conversion. - * m The total number of read operations which could not be sucessfully - * returned. ie. not available in cache and conversion failed. - * n The total size of read operations performed on the cache - * o The total size of read operations satisfied from the cache without - * conversion. - * q The total size of read operations satisfied from the cache which - * required a conversion. - * r The total size of read operations which could not be sucessfully - * returned. ie. not available in cache and conversion failed. - * s The number of images which were placed in the cache but never read. - * t The number of images that were converted on insertion into the cache which were subsequently never used. - * u The number of times an image was converted after the first - * v The number of images that had extra conversions performed. - * w Size of the image that was converted (read missed cache) highest number - * of times. - * x The number of times the image that was converted (read missed cache) - * highest number of times. - * - * format modifiers: - * A p before the value modifies the replacement to be a percentage. - * - * - * \param string The buffer in which to place the results. - * \param size The size of the string buffer. - * \param fmt The format string. - * \return The number of bytes written to \a string or -1 on error - */ - -int image_cache_snsummaryf(char *string, size_t size, const char *fmt); - -/********* Image content handler generic cache callbacks ************/ - -/** Generic content redraw callback - * - * May be used by image content handlers as their redraw - * callback. Performs all neccissary cache lookups and conversions and - * calls the bitmap plot function in the redraw context. - */ -bool image_cache_redraw(struct content *c, - struct content_redraw_data *data, - const struct rect *clip, - const struct redraw_context *ctx); - -void image_cache_destroy(struct content *c); - -void *image_cache_get_internal(const struct content *c, void *context); - -content_type image_cache_content_type(void); - -#endif diff --git a/image/jpeg.c b/image/jpeg.c deleted file mode 100644 index cf265b47a..000000000 --- a/image/jpeg.c +++ /dev/null @@ -1,393 +0,0 @@ -/* - * Copyright 2004 James Bursa <bursa@users.sourceforge.net> - * Copyright 2004 John M Bell <jmb202@ecs.soton.ac.uk> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/** \file - * Content for image/jpeg (implementation). - * - * This implementation uses the IJG JPEG library. - */ - -#include <stdbool.h> -#include <stdlib.h> -#include <setjmp.h> - -#include "utils/utils.h" -#include "utils/log.h" -#include "utils/messages.h" -#include "content/content_protected.h" -#include "desktop/gui_internal.h" - -#include "image/image_cache.h" -#include "image/bitmap.h" - -#define JPEG_INTERNAL_OPTIONS -#include "jpeglib.h" -#include "image/jpeg.h" - -/** absolute minimum size of a jpeg below which it is not even worth - * trying to read header data - */ -#define MIN_JPEG_SIZE 20 - -#ifdef riscos -/* We prefer the library to be configured with these options to save - * copying data during decoding. */ -#if RGB_RED != 0 || RGB_GREEN != 1 || RGB_BLUE != 2 || RGB_PIXELSIZE != 4 -#warning JPEG library not optimally configured. Decoding will be slower. -#endif -/* but we don't care if we're not on RISC OS */ -#endif - -static char nsjpeg_error_buffer[JMSG_LENGTH_MAX]; - -static unsigned char nsjpeg_eoi[] = { 0xff, JPEG_EOI }; - -/** - * Content create entry point. - */ -static nserror nsjpeg_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) -{ - struct content *jpeg; - nserror error; - - jpeg = calloc(1, sizeof(struct content)); - if (jpeg == NULL) - return NSERROR_NOMEM; - - error = content__init(jpeg, handler, imime_type, params, - llcache, fallback_charset, quirks); - if (error != NSERROR_OK) { - free(jpeg); - return error; - } - - *c = jpeg; - - return NSERROR_OK; -} - -/** - * JPEG data source manager: initialize source. - */ -static void nsjpeg_init_source(j_decompress_ptr cinfo) -{ -} - - -/** - * JPEG data source manager: fill the input buffer. - * - * This can only occur if the JPEG data was truncated or corrupted. Insert a - * fake EOI marker to allow the decompressor to output as much as possible. - */ -static boolean nsjpeg_fill_input_buffer(j_decompress_ptr cinfo) -{ - cinfo->src->next_input_byte = nsjpeg_eoi; - cinfo->src->bytes_in_buffer = 2; - return TRUE; -} - - -/** - * JPEG data source manager: skip num_bytes worth of data. - */ - -static void nsjpeg_skip_input_data(j_decompress_ptr cinfo, long num_bytes) -{ - if ((long) cinfo->src->bytes_in_buffer < num_bytes) { - cinfo->src->next_input_byte = 0; - cinfo->src->bytes_in_buffer = 0; - } else { - cinfo->src->next_input_byte += num_bytes; - cinfo->src->bytes_in_buffer -= num_bytes; - } -} - - -/** - * JPEG data source manager: terminate source. - */ -static void nsjpeg_term_source(j_decompress_ptr cinfo) -{ -} - - -/** - * Error output handler for JPEG library. - * - * This logs to NetSurf log instead of stderr. - * Warnings only - fatal errors are trapped by nsjpeg_error_exit - * and do not call the output handler. - */ -static void nsjpeg_error_log(j_common_ptr cinfo) -{ - cinfo->err->format_message(cinfo, nsjpeg_error_buffer); - LOG("%s", nsjpeg_error_buffer); -} - - -/** - * Fatal error handler for JPEG library. - * - * This prevents jpeglib calling exit() on a fatal error. - */ -static void nsjpeg_error_exit(j_common_ptr cinfo) -{ - jmp_buf *setjmp_buffer = (jmp_buf *) cinfo->client_data; - - cinfo->err->format_message(cinfo, nsjpeg_error_buffer); - LOG("%s", nsjpeg_error_buffer); - - longjmp(*setjmp_buffer, 1); -} - -static struct bitmap * -jpeg_cache_convert(struct content *c) -{ - uint8_t *source_data; /* Jpeg source data */ - unsigned long source_size; /* length of Jpeg source data */ - struct jpeg_decompress_struct cinfo; - struct jpeg_error_mgr jerr; - jmp_buf setjmp_buffer; - unsigned int height; - unsigned int width; - struct bitmap * volatile bitmap = NULL; - uint8_t * volatile pixels = NULL; - size_t rowstride; - struct jpeg_source_mgr source_mgr = { - 0, - 0, - nsjpeg_init_source, - nsjpeg_fill_input_buffer, - nsjpeg_skip_input_data, - jpeg_resync_to_restart, - nsjpeg_term_source }; - - /* obtain jpeg source data and perfom minimal sanity checks */ - source_data = (uint8_t *)content__get_source_data(c, &source_size); - - if ((source_data == NULL) || - (source_size < MIN_JPEG_SIZE)) { - return NULL; - } - - /* setup a JPEG library error handler */ - cinfo.err = jpeg_std_error(&jerr); - jerr.error_exit = nsjpeg_error_exit; - jerr.output_message = nsjpeg_error_log; - - /* handler for fatal errors during decompression */ - if (setjmp(setjmp_buffer)) { - jpeg_destroy_decompress(&cinfo); - return bitmap; - } - - jpeg_create_decompress(&cinfo); - cinfo.client_data = &setjmp_buffer; - - /* setup data source */ - source_mgr.next_input_byte = source_data; - source_mgr.bytes_in_buffer = source_size; - cinfo.src = &source_mgr; - - /* read JPEG header information */ - jpeg_read_header(&cinfo, TRUE); - - /* set output processing parameters */ - cinfo.out_color_space = JCS_RGB; - cinfo.dct_method = JDCT_ISLOW; - - /* commence the decompression, output parameters now valid */ - jpeg_start_decompress(&cinfo); - - width = cinfo.output_width; - height = cinfo.output_height; - - /* create opaque bitmap (jpegs cannot be transparent) */ - bitmap = guit->bitmap->create(width, height, BITMAP_NEW | BITMAP_OPAQUE); - if (bitmap == NULL) { - /* empty bitmap could not be created */ - jpeg_destroy_decompress(&cinfo); - return NULL; - } - - pixels = guit->bitmap->get_buffer(bitmap); - if (pixels == NULL) { - /* bitmap with no buffer available */ - guit->bitmap->destroy(bitmap); - jpeg_destroy_decompress(&cinfo); - return NULL; - } - - /* Convert scanlines from jpeg into bitmap */ - rowstride = guit->bitmap->get_rowstride(bitmap); - do { - JSAMPROW scanlines[1]; - - scanlines[0] = (JSAMPROW) (pixels + - rowstride * cinfo.output_scanline); - jpeg_read_scanlines(&cinfo, scanlines, 1); - -#if RGB_RED != 0 || RGB_GREEN != 1 || RGB_BLUE != 2 || RGB_PIXELSIZE != 4 -{ - /* Missmatch between configured libjpeg pixel format and - * NetSurf pixel format. Convert to RGBA */ - int i; - for (i = width - 1; 0 <= i; i--) { - int r = scanlines[0][i * RGB_PIXELSIZE + RGB_RED]; - int g = scanlines[0][i * RGB_PIXELSIZE + RGB_GREEN]; - int b = scanlines[0][i * RGB_PIXELSIZE + RGB_BLUE]; - scanlines[0][i * 4 + 0] = r; - scanlines[0][i * 4 + 1] = g; - scanlines[0][i * 4 + 2] = b; - scanlines[0][i * 4 + 3] = 0xff; - } -} -#endif - } while (cinfo.output_scanline != cinfo.output_height); - guit->bitmap->modified(bitmap); - - jpeg_finish_decompress(&cinfo); - jpeg_destroy_decompress(&cinfo); - - return bitmap; -} - -/** - * Convert a CONTENT_JPEG for display. - */ -static bool nsjpeg_convert(struct content *c) -{ - struct jpeg_decompress_struct cinfo; - struct jpeg_error_mgr jerr; - jmp_buf setjmp_buffer; - struct jpeg_source_mgr source_mgr = { 0, 0, - nsjpeg_init_source, nsjpeg_fill_input_buffer, - nsjpeg_skip_input_data, jpeg_resync_to_restart, - nsjpeg_term_source }; - union content_msg_data msg_data; - const char *data; - unsigned long size; - char *title; - - /* check image header is valid and get width/height */ - data = content__get_source_data(c, &size); - - cinfo.err = jpeg_std_error(&jerr); - jerr.error_exit = nsjpeg_error_exit; - jerr.output_message = nsjpeg_error_log; - - if (setjmp(setjmp_buffer)) { - jpeg_destroy_decompress(&cinfo); - - msg_data.error = nsjpeg_error_buffer; - content_broadcast(c, CONTENT_MSG_ERROR, msg_data); - return false; - } - - jpeg_create_decompress(&cinfo); - cinfo.client_data = &setjmp_buffer; - source_mgr.next_input_byte = (unsigned char *) data; - source_mgr.bytes_in_buffer = size; - cinfo.src = &source_mgr; - jpeg_read_header(&cinfo, TRUE); - cinfo.out_color_space = JCS_RGB; - cinfo.dct_method = JDCT_ISLOW; - - jpeg_calc_output_dimensions(&cinfo); - - c->width = cinfo.output_width; - c->height = cinfo.output_height; - c->size = c->width * c->height * 4; - - jpeg_destroy_decompress(&cinfo); - - image_cache_add(c, NULL, jpeg_cache_convert); - - /* set title text */ - title = messages_get_buff("JPEGTitle", - nsurl_access_leaf(llcache_handle_get_url(c->llcache)), - c->width, c->height); - if (title != NULL) { - content__set_title(c, title); - free(title); - } - - content_set_ready(c); - content_set_done(c); - content_set_status(c, ""); /* Done: update status bar */ - - return true; -} - - - -/** - * Clone content. - */ -static nserror nsjpeg_clone(const struct content *old, struct content **newc) -{ - struct content *jpeg_c; - nserror error; - - jpeg_c = calloc(1, sizeof(struct content)); - if (jpeg_c == NULL) - return NSERROR_NOMEM; - - error = content__clone(old, jpeg_c); - if (error != NSERROR_OK) { - content_destroy(jpeg_c); - return error; - } - - /* re-convert if the content is ready */ - if ((old->status == CONTENT_STATUS_READY) || - (old->status == CONTENT_STATUS_DONE)) { - if (nsjpeg_convert(jpeg_c) == false) { - content_destroy(jpeg_c); - return NSERROR_CLONE_FAILED; - } - } - - *newc = jpeg_c; - - return NSERROR_OK; -} - -static const content_handler nsjpeg_content_handler = { - .create = nsjpeg_create, - .data_complete = nsjpeg_convert, - .destroy = image_cache_destroy, - .redraw = image_cache_redraw, - .clone = nsjpeg_clone, - .get_internal = image_cache_get_internal, - .type = image_cache_content_type, - .no_share = false, -}; - -static const char *nsjpeg_types[] = { - "image/jpeg", - "image/jpg", - "image/pjpeg" -}; - -CONTENT_FACTORY_REGISTER_TYPES(nsjpeg, nsjpeg_types, nsjpeg_content_handler); diff --git a/image/jpeg.h b/image/jpeg.h deleted file mode 100644 index 8c054732b..000000000 --- a/image/jpeg.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2004 James Bursa <bursa@users.sourceforge.net> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/** \file - * Content for image/jpeg (interface). - */ - -#ifndef _NETSURF_IMAGE_JPEG_H_ -#define _NETSURF_IMAGE_JPEG_H_ - -nserror nsjpeg_init(void); - -#endif diff --git a/image/nssprite.c b/image/nssprite.c deleted file mode 100644 index 0fe25270b..000000000 --- a/image/nssprite.c +++ /dev/null @@ -1,259 +0,0 @@ - /* - * Copyright 2008 James Shaw <js102@zepler.net> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/** \file - * Content for image/x-riscos-sprite (librosprite implementation). - * - */ - -#include <stdbool.h> -#include <stdlib.h> -#include <librosprite.h> - -#include "utils/utils.h" -#include "utils/log.h" -#include "utils/messages.h" -#include "content/content_protected.h" -#include "desktop/gui_internal.h" -#include "desktop/plotters.h" - -#include "image/bitmap.h" -#include "image/nssprite.h" - -typedef struct nssprite_content { - struct content base; - struct bitmap *bitmap; /**< Created NetSurf bitmap */ - - struct rosprite_area* sprite_area; -} nssprite_content; - - -#define ERRCHK(x) do { \ - rosprite_error err = x; \ - if (err == ROSPRITE_EOF) { \ - LOG("Got ROSPRITE_EOF when loading sprite file"); \ - return false; \ - } else if (err == ROSPRITE_BADMODE) { \ - LOG("Got ROSPRITE_BADMODE when loading sprite file"); \ - return false; \ - } else if (err == ROSPRITE_OK) { \ - } else { \ - return false; \ - } \ -} while(0) - - - - -static nserror nssprite_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) -{ - nssprite_content *sprite; - nserror error; - - sprite = calloc(1, sizeof(nssprite_content)); - if (sprite == NULL) - return NSERROR_NOMEM; - - error = content__init(&sprite->base, handler, imime_type, params, - llcache, fallback_charset, quirks); - if (error != NSERROR_OK) { - free(sprite); - return error; - } - - *c = (struct content *) sprite; - - return NSERROR_OK; -} - -/** - * Convert a CONTENT_SPRITE for display. - * - * No conversion is necessary. We merely read the sprite dimensions. - */ - -static bool nssprite_convert(struct content *c) -{ - nssprite_content *nssprite = (nssprite_content *) c; - union content_msg_data msg_data; - - struct rosprite_mem_context* ctx; - - const char *data; - unsigned long size; - char *title; - - data = content__get_source_data(c, &size); - - ERRCHK(rosprite_create_mem_context((uint8_t *) data, size, &ctx)); - - struct rosprite_area* sprite_area; - ERRCHK(rosprite_load(rosprite_mem_reader, ctx, &sprite_area)); - rosprite_destroy_mem_context(ctx); - nssprite->sprite_area = sprite_area; - - assert(sprite_area->sprite_count > 0); - - struct rosprite* sprite = sprite_area->sprites[0]; - - nssprite->bitmap = guit->bitmap->create(sprite->width, sprite->height, BITMAP_NEW); - if (!nssprite->bitmap) { - msg_data.error = messages_get("NoMemory"); - content_broadcast(c, CONTENT_MSG_ERROR, msg_data); - return false; - } - uint32_t* imagebuf = (uint32_t *)guit->bitmap->get_buffer(nssprite->bitmap); - if (!imagebuf) { - msg_data.error = messages_get("NoMemory"); - content_broadcast(c, CONTENT_MSG_ERROR, msg_data); - return false; - } - unsigned char *spritebuf = (unsigned char *)sprite->image; - - /* reverse byte order of each word */ - for (uint32_t y = 0; y < sprite->height; y++) { - for (uint32_t x = 0; x < sprite->width; x++) { - int offset = 4 * (y * sprite->width + x); - - *imagebuf = (spritebuf[offset] << 24) | - (spritebuf[offset + 1] << 16) | - (spritebuf[offset + 2] << 8) | - (spritebuf[offset + 3]); - - imagebuf++; - } - } - - c->width = sprite->width; - c->height = sprite->height; - - /* set title text */ - title = messages_get_buff("SpriteTitle", - nsurl_access_leaf(llcache_handle_get_url(c->llcache)), - c->width, c->height); - if (title != NULL) { - content__set_title(c, title); - free(title); - } - - guit->bitmap->modified(nssprite->bitmap); - - content_set_ready(c); - content_set_done(c); - content_set_status(c, ""); /* Done: update status bar */ - - return true; -} - - -/** - * Destroy a CONTENT_SPRITE and free all resources it owns. - */ - -static void nssprite_destroy(struct content *c) -{ - nssprite_content *nssprite = (nssprite_content *) c; - - if (nssprite->sprite_area != NULL) - rosprite_destroy_sprite_area(nssprite->sprite_area); - if (nssprite->bitmap != NULL) - guit->bitmap->destroy(nssprite->bitmap); -} - - -/** - * Redraw a CONTENT_SPRITE. - */ - -static bool nssprite_redraw(struct content *c, struct content_redraw_data *data, - const struct rect *clip, const struct redraw_context *ctx) -{ - nssprite_content *nssprite = (nssprite_content *) c; - bitmap_flags_t flags = BITMAPF_NONE; - - if (data->repeat_x) - flags |= BITMAPF_REPEAT_X; - if (data->repeat_y) - flags |= BITMAPF_REPEAT_Y; - - return ctx->plot->bitmap(data->x, data->y, data->width, data->height, - nssprite->bitmap, data->background_colour, flags); -} - - -static nserror nssprite_clone(const struct content *old, struct content **newc) -{ - nssprite_content *sprite; - nserror error; - - sprite = calloc(1, sizeof(nssprite_content)); - if (sprite == NULL) - return NSERROR_NOMEM; - - error = content__clone(old, &sprite->base); - if (error != NSERROR_OK) { - content_destroy(&sprite->base); - return error; - } - - /* Simply replay convert */ - if (old->status == CONTENT_STATUS_READY || - old->status == CONTENT_STATUS_DONE) { - if (nssprite_convert(&sprite->base) == false) { - content_destroy(&sprite->base); - return NSERROR_CLONE_FAILED; - } - } - - *newc = (struct content *) sprite; - - return NSERROR_OK; -} - -static void *nssprite_get_internal(const struct content *c, void *context) -{ - nssprite_content *nssprite = (nssprite_content *) c; - - return nssprite->bitmap; -} - -static content_type nssprite_content_type(void) -{ - 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, - .get_internal = nssprite_get_internal, - .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); diff --git a/image/nssprite.h b/image/nssprite.h deleted file mode 100644 index 38226f84e..000000000 --- a/image/nssprite.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2008 James Shaw <js102@zepler.net> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/** \file - * Content for image/x-riscos-sprite (librosprite interface). - */ - -#ifndef _NETSURF_NS_SPRITE_H_ -#define _NETSURF_NS_SPRITE_H_ - -nserror nssprite_init(void); - -#endif diff --git a/image/png.c b/image/png.c deleted file mode 100644 index 11903cbd3..000000000 --- a/image/png.c +++ /dev/null @@ -1,614 +0,0 @@ -/* - * Copyright 2004 James Bursa <bursa@users.sourceforge.net> - * Copyright 2004 Richard Wilson <not_ginger_matt@hotmail.com> - * Copyright 2008 Daniel Silverstone <dsilvers@netsurf-browser.org> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <stdbool.h> -#include <stdlib.h> -#include <png.h> - -#include "utils/utils.h" -#include "utils/log.h" -#include "utils/messages.h" -#include "content/content_protected.h" -#include "desktop/gui_internal.h" - -#include "image/image_cache.h" -#include "image/bitmap.h" -#include "image/png.h" - -/* accommodate for old versions of libpng (beware security holes!) */ - -#ifndef png_jmpbuf -#warning you have an antique libpng -#define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) -#endif - -#if PNG_LIBPNG_VER < 10209 -#define png_set_expand_gray_1_2_4_to_8(png) png_set_gray_1_2_4_to_8(png) -#endif - -typedef struct nspng_content { - struct content base; /**< base content type */ - - bool no_process_data; /**< Do not continue to process data as it arrives */ - png_structp png; - png_infop info; - int interlace; - struct bitmap *bitmap; /**< Created NetSurf bitmap */ - size_t rowstride, bpp; /**< Bitmap rowstride and bpp */ - size_t rowbytes; /**< Number of bytes per row */ -} nspng_content; - -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}; -static unsigned int interlace_row_step[8] = {8, 8, 8, 4, 4, 2, 2}; - -/** Callbak error numbers*/ -enum nspng_cberr { - CBERR_NONE = 0, /* no error */ - CBERR_LIBPNG, /* error from png library */ - CBERR_NOPRE, /* no pre-conversion performed */ -}; - -/** - * nspng_warning -- callback for libpng warnings - */ -static void nspng_warning(png_structp png_ptr, png_const_charp warning_message) -{ - LOG("%s", warning_message); -} - -/** - * nspng_error -- callback for libpng errors - */ -static void nspng_error(png_structp png_ptr, png_const_charp error_message) -{ - LOG("%s", error_message); - longjmp(png_jmpbuf(png_ptr), CBERR_LIBPNG); -} - -static void nspng_setup_transforms(png_structp png_ptr, png_infop info_ptr) -{ - int bit_depth, color_type, intent; - double gamma; - - bit_depth = png_get_bit_depth(png_ptr, info_ptr); - color_type = png_get_color_type(png_ptr, info_ptr); - - /* Set up our transformations */ - if (color_type == PNG_COLOR_TYPE_PALETTE) { - png_set_palette_to_rgb(png_ptr); - } - - if ((color_type == PNG_COLOR_TYPE_GRAY) && (bit_depth < 8)) { - png_set_expand_gray_1_2_4_to_8(png_ptr); - } - - if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { - png_set_tRNS_to_alpha(png_ptr); - } - - if (bit_depth == 16) { - png_set_strip_16(png_ptr); - } - - if (color_type == PNG_COLOR_TYPE_GRAY || - color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { - png_set_gray_to_rgb(png_ptr); - } - - if (!(color_type & PNG_COLOR_MASK_ALPHA)) { - png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); - } - - /* gamma correction - we use 2.2 as our screen gamma - * this appears to be correct (at least in respect to !Browse) - * see http://www.w3.org/Graphics/PNG/all_seven.html for a test case - */ - if (png_get_sRGB(png_ptr, info_ptr, &intent)) { - png_set_gamma(png_ptr, 2.2, 0.45455); - } else { - if (png_get_gAMA(png_ptr, info_ptr, &gamma)) { - png_set_gamma(png_ptr, 2.2, gamma); - } else { - png_set_gamma(png_ptr, 2.2, 0.45455); - } - } - - png_read_update_info(png_ptr, info_ptr); -} - -/** - * info_callback -- PNG header has been completely received, prepare to process - * image data - */ -static void info_callback(png_structp png_s, png_infop info) -{ - int interlace; - png_uint_32 width, height; - nspng_content *png_c = png_get_progressive_ptr(png_s); - - width = png_get_image_width(png_s, info); - height = png_get_image_height(png_s, info); - interlace = png_get_interlace_type(png_s, info); - - png_c->base.width = width; - png_c->base.height = height; - png_c->base.size += width * height * 4; - - /* see if progressive-conversion should continue */ - if (image_cache_speculate((struct content *)png_c) == false) { - longjmp(png_jmpbuf(png_s), CBERR_NOPRE); - } - - /* Claim the required memory for the converted PNG */ - png_c->bitmap = guit->bitmap->create(width, height, BITMAP_NEW); - if (png_c->bitmap == NULL) { - /* Failed to create bitmap skip pre-conversion */ - longjmp(png_jmpbuf(png_s), CBERR_NOPRE); - } - - png_c->rowstride = guit->bitmap->get_rowstride(png_c->bitmap); - png_c->bpp = guit->bitmap->get_bpp(png_c->bitmap); - - nspng_setup_transforms(png_s, info); - - png_c->rowbytes = png_get_rowbytes(png_s, info); - png_c->interlace = (interlace == PNG_INTERLACE_ADAM7); - - LOG("size %li * %li, rowbytes %" PRIsizet, - (unsigned long)width, - (unsigned long)height, - png_c->rowbytes); -} - -static void row_callback(png_structp png_s, png_bytep new_row, - png_uint_32 row_num, int pass) -{ - nspng_content *png_c = png_get_progressive_ptr(png_s); - unsigned long rowbytes = png_c->rowbytes; - unsigned char *buffer, *row; - - /* Give up if there's no bitmap */ - if (png_c->bitmap == NULL) - return; - - /* Abort if we've not got any data */ - if (new_row == NULL) - return; - - /* Get bitmap buffer */ - buffer = guit->bitmap->get_buffer(png_c->bitmap); - if (buffer == NULL) { - /* No buffer, bail out */ - longjmp(png_jmpbuf(png_s), 1); - } - - /* Calculate address of row start */ - row = buffer + (png_c->rowstride * row_num); - - /* Handle interlaced sprites using the Adam7 algorithm */ - if (png_c->interlace) { - unsigned long dst_off; - unsigned long src_off = 0; - unsigned int start, step; - - start = interlace_start[pass]; - step = interlace_step[pass]; - row_num = interlace_row_start[pass] + - interlace_row_step[pass] * row_num; - - /* Copy the data to our current row taking interlacing - * into consideration */ - row = buffer + (png_c->rowstride * row_num); - - for (dst_off = start; dst_off < rowbytes; dst_off += step) { - row[dst_off++] = new_row[src_off++]; - row[dst_off++] = new_row[src_off++]; - row[dst_off++] = new_row[src_off++]; - row[dst_off++] = new_row[src_off++]; - } - } else { - /* Do a fast memcpy of the row data */ - memcpy(row, new_row, rowbytes); - } -} - - -static void end_callback(png_structp png_s, png_infop info) -{ -} - -static nserror nspng_create_png_data(nspng_content *png_c) -{ - union content_msg_data msg_data; - - png_c->bitmap = NULL; - - png_c->png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); - if (png_c->png == NULL) { - msg_data.error = messages_get("NoMemory"); - content_broadcast(&png_c->base, CONTENT_MSG_ERROR, msg_data); - return NSERROR_NOMEM; - } - - png_set_error_fn(png_c->png, NULL, nspng_error, nspng_warning); - - png_c->info = png_create_info_struct(png_c->png); - if (png_c->info == NULL) { - png_destroy_read_struct(&png_c->png, &png_c->info, 0); - - msg_data.error = messages_get("NoMemory"); - content_broadcast(&png_c->base, CONTENT_MSG_ERROR, msg_data); - return NSERROR_NOMEM; - } - - if (setjmp(png_jmpbuf(png_c->png))) { - png_destroy_read_struct(&png_c->png, &png_c->info, 0); - LOG("Failed to set callbacks"); - png_c->png = NULL; - png_c->info = NULL; - - msg_data.error = messages_get("PNGError"); - content_broadcast(&png_c->base, CONTENT_MSG_ERROR, msg_data); - return NSERROR_NOMEM; - } - - png_set_progressive_read_fn(png_c->png, png_c, - info_callback, row_callback, end_callback); - - return NSERROR_OK; -} - -static nserror nspng_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) -{ - nspng_content *png_c; - nserror error; - - png_c = calloc(1, sizeof(nspng_content)); - if (png_c == NULL) - return NSERROR_NOMEM; - - error = content__init(&png_c->base, - handler, - imime_type, - params, - llcache, - fallback_charset, - quirks); - if (error != NSERROR_OK) { - free(png_c); - return error; - } - - error = nspng_create_png_data(png_c); - if (error != NSERROR_OK) { - free(png_c); - return error; - } - - *c = (struct content *)png_c; - - return NSERROR_OK; -} - - -static bool nspng_process_data(struct content *c, const char *data, - unsigned int size) -{ - nspng_content *png_c = (nspng_content *)c; - union content_msg_data msg_data; - volatile bool ret = true; - - if (png_c->no_process_data) { - return ret; - } - - switch (setjmp(png_jmpbuf(png_c->png))) { - case CBERR_NONE: /* direct return */ - png_process_data(png_c->png, png_c->info, (uint8_t *)data, size); - break; - - case CBERR_NOPRE: /* not going to progressive convert */ - png_c->no_process_data = true; - break; - - default: /* fatal error from library processing png */ - if (png_c->bitmap != NULL) { - /* A bitmap managed to get created so - * operation is past header and possibly some - * conversion happened before faliure. - * - * In this case keep the partial - * conversion. This is usually seen if a png - * has been truncated (often jsut lost its - * last byte and hence end of image marker) - */ - png_c->no_process_data = true; - } else { - /* not managed to progress past header, clean - * up png conversion and signal the content - * error - */ - LOG("Fatal PNG error during header, error content"); - - png_destroy_read_struct(&png_c->png, &png_c->info, 0); - png_c->png = NULL; - png_c->info = NULL; - - msg_data.error = messages_get("PNGError"); - content_broadcast(c, CONTENT_MSG_ERROR, msg_data); - - ret = false; - - } - break; - } - - return ret; -} - -struct png_cache_read_data_s { - const char *data; - unsigned long size; -}; - -/** PNG library read fucntion to read data from a memory array - */ -static void -png_cache_read_fn(png_structp png_ptr, png_bytep data, png_size_t length) -{ - struct png_cache_read_data_s *png_cache_read_data; - png_cache_read_data = png_get_io_ptr(png_ptr); - - if (length > png_cache_read_data->size) { - length = png_cache_read_data->size; - } - - if (length == 0) { - png_error(png_ptr, "Read Error"); - } - - memcpy(data, png_cache_read_data->data, length); - - png_cache_read_data->data += length; - png_cache_read_data->size -= length; -} - -/** calculate an array of row pointers into a bitmap data area - */ -static png_bytep *calc_row_pointers(struct bitmap *bitmap) -{ - int height = guit->bitmap->get_height(bitmap); - unsigned char *buffer= guit->bitmap->get_buffer(bitmap); - size_t rowstride = guit->bitmap->get_rowstride(bitmap); - png_bytep *row_ptrs; - int hloop; - - /* The buffer allocation may occour when the buffer is aquired - * and therefore may fail. - */ - if (buffer == NULL) { - return NULL; - } - - row_ptrs = malloc(sizeof(png_bytep) * height); - - if (row_ptrs != NULL) { - for (hloop = 0; hloop < height; hloop++) { - row_ptrs[hloop] = buffer + (rowstride * hloop); - } - } - - return row_ptrs; -} - -/** PNG content to bitmap conversion. - * - * This routine generates a bitmap object from a PNG image content - */ -static struct bitmap * -png_cache_convert(struct content *c) -{ - png_structp png_ptr; - png_infop info_ptr; - png_infop end_info_ptr; - volatile struct bitmap * volatile bitmap = NULL; - struct png_cache_read_data_s png_cache_read_data; - png_uint_32 width, height; - volatile png_bytep * volatile row_pointers = NULL; - - png_cache_read_data.data = - content__get_source_data(c, &png_cache_read_data.size); - - if ((png_cache_read_data.data == NULL) || - (png_cache_read_data.size <= 8)) { - return NULL; - } - - png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, - nspng_error, nspng_warning); - if (png_ptr == NULL) { - return NULL; - } - - info_ptr = png_create_info_struct(png_ptr); - if (info_ptr == NULL) { - png_destroy_read_struct(&png_ptr, NULL, NULL); - return NULL; - } - - end_info_ptr = png_create_info_struct(png_ptr); - if (end_info_ptr == NULL) { - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); - return NULL; - } - - /* setup error exit path */ - if (setjmp(png_jmpbuf(png_ptr))) { - /* cleanup and bail */ - goto png_cache_convert_error; - } - - /* read from a buffer instead of stdio */ - png_set_read_fn(png_ptr, &png_cache_read_data, png_cache_read_fn); - - /* ensure the png info structure is populated */ - png_read_info(png_ptr, info_ptr); - - /* setup output transforms */ - nspng_setup_transforms(png_ptr, info_ptr); - - width = png_get_image_width(png_ptr, info_ptr); - height = png_get_image_height(png_ptr, info_ptr); - - /* Claim the required memory for the converted PNG */ - bitmap = guit->bitmap->create(width, height, BITMAP_NEW); - if (bitmap == NULL) { - /* cleanup and bail */ - goto png_cache_convert_error; - } - - row_pointers = calc_row_pointers((struct bitmap *) bitmap); - - if (row_pointers != NULL) { - png_read_image(png_ptr, (png_bytep *) row_pointers); - } else { - guit->bitmap->destroy((struct bitmap *)bitmap); - bitmap = NULL; - } - -png_cache_convert_error: - - /* cleanup png read */ - png_destroy_read_struct(&png_ptr, &info_ptr, &end_info_ptr); - - if (row_pointers != NULL) { - free((png_bytep *) row_pointers); - } - - if (bitmap != NULL) { - guit->bitmap->modified((struct bitmap *)bitmap); - } - - return (struct bitmap *)bitmap; -} - -static bool nspng_convert(struct content *c) -{ - nspng_content *png_c = (nspng_content *) c; - char *title; - - assert(png_c->png != NULL); - assert(png_c->info != NULL); - - /* clean up png structures */ - png_destroy_read_struct(&png_c->png, &png_c->info, 0); - - /* set title text */ - title = messages_get_buff("PNGTitle", - nsurl_access_leaf(llcache_handle_get_url(c->llcache)), - c->width, c->height); - if (title != NULL) { - content__set_title(c, title); - free(title); - } - - if (png_c->bitmap != NULL) { - guit->bitmap->set_opaque(png_c->bitmap, guit->bitmap->test_opaque(png_c->bitmap)); - guit->bitmap->modified(png_c->bitmap); - } - - image_cache_add(c, png_c->bitmap, png_cache_convert); - - content_set_ready(c); - content_set_done(c); - content_set_status(c, ""); - - return true; -} - - -static nserror nspng_clone(const struct content *old_c, struct content **new_c) -{ - nspng_content *clone_png_c; - nserror error; - const char *data; - unsigned long size; - - clone_png_c = calloc(1, sizeof(nspng_content)); - if (clone_png_c == NULL) - return NSERROR_NOMEM; - - error = content__clone(old_c, &clone_png_c->base); - if (error != NSERROR_OK) { - content_destroy(&clone_png_c->base); - return error; - } - - /* Simply replay create/process/convert */ - error = nspng_create_png_data(clone_png_c); - if (error != NSERROR_OK) { - content_destroy(&clone_png_c->base); - return error; - } - - data = content__get_source_data(&clone_png_c->base, &size); - if (size > 0) { - if (nspng_process_data(&clone_png_c->base, data, size) == false) { - content_destroy(&clone_png_c->base); - return NSERROR_NOMEM; - } - } - - if ((old_c->status == CONTENT_STATUS_READY) || - (old_c->status == CONTENT_STATUS_DONE)) { - if (nspng_convert(&clone_png_c->base) == false) { - content_destroy(&clone_png_c->base); - return NSERROR_CLONE_FAILED; - } - } - - *new_c = (struct content *)clone_png_c; - - return NSERROR_OK; -} - -static const content_handler nspng_content_handler = { - .create = nspng_create, - .process_data = nspng_process_data, - .data_complete = nspng_convert, - .clone = nspng_clone, - .destroy = image_cache_destroy, - .redraw = image_cache_redraw, - .get_internal = image_cache_get_internal, - .type = image_cache_content_type, - .no_share = false, -}; - -static const char *nspng_types[] = { - "image/png", - "image/x-png" -}; - -CONTENT_FACTORY_REGISTER_TYPES(nspng, nspng_types, nspng_content_handler); diff --git a/image/png.h b/image/png.h deleted file mode 100644 index 3a2e3741f..000000000 --- a/image/png.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2003 James Bursa <bursa@users.sourceforge.net> - * Copyright 2008 Daniel Silverstone <dsilvers@netsurf-browser.org> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef _NETSURF_RISCOS_PNG_H_ -#define _NETSURF_RISCOS_PNG_H_ - -nserror nspng_init(void); - -#endif diff --git a/image/rsvg.c b/image/rsvg.c deleted file mode 100644 index b781125bf..000000000 --- a/image/rsvg.c +++ /dev/null @@ -1,326 +0,0 @@ -/* - * Copyright 2007 Rob Kendrick <rjek@netsurf-browser.org> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/** \file - * Content handler for image/svg using librsvg (implementation). - * - * SVG files are rendered to a NetSurf bitmap by creating a Cairo rendering - * surface (content_rsvg_data.cs) over the bitmap's data, creating a Cairo - * drawing context using that surface, and then passing that drawing context - * to librsvg which then uses Cairo calls to plot the graphic to the bitmap. - * We store this in content->bitmap, and then use the usual bitmap plotter - * function to render it for redraw requests. - */ - -#include <stdlib.h> -#include <stdbool.h> -#include <assert.h> -#include <string.h> -#include <sys/types.h> - -#include <librsvg/rsvg.h> -#ifndef RSVG_CAIRO_H -#include <librsvg/rsvg-cairo.h> -#endif - -#include "utils/log.h" -#include "utils/utils.h" -#include "utils/messages.h" -#include "content/content_protected.h" -#include "desktop/plotters.h" -#include "desktop/gui_internal.h" - -#include "image/bitmap.h" -#include "image/rsvg.h" - -typedef struct rsvg_content { - struct content base; - - RsvgHandle *rsvgh; /**< Context handle for RSVG renderer */ - cairo_surface_t *cs; /**< The surface built inside a nsbitmap */ - cairo_t *ct; /**< Cairo drawing context */ - struct bitmap *bitmap; /**< Created NetSurf bitmap */ -} rsvg_content; - -static nserror rsvg_create_svg_data(rsvg_content *c) -{ - union content_msg_data msg_data; - - c->rsvgh = NULL; - c->cs = NULL; - c->ct = NULL; - c->bitmap = NULL; - - if ((c->rsvgh = rsvg_handle_new()) == NULL) { - LOG("rsvg_handle_new() returned NULL."); - msg_data.error = messages_get("NoMemory"); - content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data); - return NSERROR_NOMEM; - } - - return NSERROR_OK; -} - - -static nserror rsvg_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) -{ - rsvg_content *svg; - nserror error; - - svg = calloc(1, sizeof(rsvg_content)); - if (svg == NULL) - return NSERROR_NOMEM; - - error = content__init(&svg->base, handler, imime_type, params, - llcache, fallback_charset, quirks); - if (error != NSERROR_OK) { - free(svg); - return error; - } - - error = rsvg_create_svg_data(svg); - if (error != NSERROR_OK) { - free(svg); - return error; - } - - *c = (struct content *) svg; - - return NSERROR_OK; -} - - -static bool rsvg_process_data(struct content *c, const char *data, - unsigned int size) -{ - rsvg_content *d = (rsvg_content *) c; - union content_msg_data msg_data; - GError *err = NULL; - - if (rsvg_handle_write(d->rsvgh, (const guchar *)data, (gsize)size, - &err) == FALSE) { - LOG("rsvg_handle_write returned an error: %s", err->message); - msg_data.error = err->message; - content_broadcast(c, CONTENT_MSG_ERROR, msg_data); - return false; - } - - return true; -} - -/** Convert Cairo's ARGB output to NetSurf's favoured ABGR format. It converts - * the data in-place. - * - * \param pixels Pixel data, in the form of ARGB. This will - * be overwritten with new data in the form of ABGR. - * \param width Width of the bitmap - * \param height Height of the bitmap - * \param rowstride Number of bytes to skip after each row (this - * implementation requires this to be a multiple of 4.) - */ -static inline void rsvg_argb_to_abgr(uint8_t *pixels, - int width, int height, size_t rowstride) -{ - uint8_t *p = pixels; - - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - /* Swap R and B */ - const uint8_t r = p[x+3]; - - p[x+3] = p[x]; - - p[x] = r; - } - - p += rowstride; - } -} - -static bool rsvg_convert(struct content *c) -{ - rsvg_content *d = (rsvg_content *) c; - union content_msg_data msg_data; - RsvgDimensionData rsvgsize; - GError *err = NULL; - - if (rsvg_handle_close(d->rsvgh, &err) == FALSE) { - LOG("rsvg_handle_close returned an error: %s", err->message); - msg_data.error = err->message; - content_broadcast(c, CONTENT_MSG_ERROR, msg_data); - return false; - } - - assert(err == NULL); - - /* we should now be able to query librsvg for the natural size of the - * graphic, so we can create our bitmap. - */ - - rsvg_handle_get_dimensions(d->rsvgh, &rsvgsize); - c->width = rsvgsize.width; - c->height = rsvgsize.height; - - if ((d->bitmap = guit->bitmap->create(c->width, c->height, - BITMAP_NEW)) == NULL) { - LOG("Failed to create bitmap for rsvg render."); - msg_data.error = messages_get("NoMemory"); - content_broadcast(c, CONTENT_MSG_ERROR, msg_data); - return false; - } - - if ((d->cs = cairo_image_surface_create_for_data( - (unsigned char *)guit->bitmap->get_buffer(d->bitmap), - CAIRO_FORMAT_ARGB32, - c->width, c->height, - guit->bitmap->get_rowstride(d->bitmap))) == NULL) { - LOG("Failed to create Cairo image surface for rsvg render."); - msg_data.error = messages_get("NoMemory"); - content_broadcast(c, CONTENT_MSG_ERROR, msg_data); - return false; - } - - if ((d->ct = cairo_create(d->cs)) == NULL) { - LOG("Failed to create Cairo drawing context for rsvg render."); - msg_data.error = messages_get("NoMemory"); - content_broadcast(c, CONTENT_MSG_ERROR, msg_data); - return false; - } - - rsvg_handle_render_cairo(d->rsvgh, d->ct); - rsvg_argb_to_abgr(guit->bitmap->get_buffer(d->bitmap), - c->width, c->height, - guit->bitmap->get_rowstride(d->bitmap)); - - guit->bitmap->modified(d->bitmap); - content_set_ready(c); - content_set_done(c); - /* Done: update status bar */ - content_set_status(c, ""); - - return true; -} - -static bool rsvg_redraw(struct content *c, struct content_redraw_data *data, - const struct rect *clip, const struct redraw_context *ctx) -{ - rsvg_content *rsvgcontent = (rsvg_content *) c; - bitmap_flags_t flags = BITMAPF_NONE; - - assert(rsvgcontent->bitmap != NULL); - - if (data->repeat_x) - flags |= BITMAPF_REPEAT_X; - if (data->repeat_y) - flags |= BITMAPF_REPEAT_Y; - - return ctx->plot->bitmap(data->x, data->y, data->width, data->height, - rsvgcontent->bitmap, data->background_colour, flags); -} - -static void rsvg_destroy(struct content *c) -{ - rsvg_content *d = (rsvg_content *) c; - - if (d->bitmap != NULL) guit->bitmap->destroy(d->bitmap); - if (d->rsvgh != NULL) g_object_unref(d->rsvgh); - if (d->ct != NULL) cairo_destroy(d->ct); - if (d->cs != NULL) cairo_surface_destroy(d->cs); - - return; -} - -static nserror rsvg_clone(const struct content *old, struct content **newc) -{ - rsvg_content *svg; - nserror error; - const char *data; - unsigned long size; - - svg = calloc(1, sizeof(rsvg_content)); - if (svg == NULL) - return NSERROR_NOMEM; - - error = content__clone(old, &svg->base); - if (error != NSERROR_OK) { - content_destroy(&svg->base); - return error; - } - - /* Simply replay create/process/convert */ - error = rsvg_create_svg_data(svg); - if (error != NSERROR_OK) { - content_destroy(&svg->base); - return error; - } - - data = content__get_source_data(&svg->base, &size); - if (size > 0) { - if (rsvg_process_data(&svg->base, data, size) == false) { - content_destroy(&svg->base); - return NSERROR_NOMEM; - } - } - - if (old->status == CONTENT_STATUS_READY || - old->status == CONTENT_STATUS_DONE) { - if (rsvg_convert(&svg->base) == false) { - content_destroy(&svg->base); - return NSERROR_CLONE_FAILED; - } - } - - *newc = (struct content *) svg; - - return NSERROR_OK; -} - -static void *rsvg_get_internal(const struct content *c, void *context) -{ - rsvg_content *d = (rsvg_content *) c; - - return d->bitmap; -} - -static content_type rsvg_content_type(void) -{ - return CONTENT_IMAGE; -} - -static const content_handler rsvg_content_handler = { - .create = rsvg_create, - .process_data = rsvg_process_data, - .data_complete = rsvg_convert, - .destroy = rsvg_destroy, - .redraw = rsvg_redraw, - .clone = rsvg_clone, - .get_internal = rsvg_get_internal, - .type = rsvg_content_type, - .no_share = false, -}; - -static const char *rsvg_types[] = { - "image/svg", - "image/svg+xml" -}; - -CONTENT_FACTORY_REGISTER_TYPES(nsrsvg, rsvg_types, rsvg_content_handler); - diff --git a/image/rsvg.h b/image/rsvg.h deleted file mode 100644 index f38f8b0e8..000000000 --- a/image/rsvg.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2007 Rob Kendrick <rjek@netsurf-browser.org> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/** \file - * Content handler for image/svg using librsvg (interface). - */ - -#ifndef _NETSURF_IMAGE_RSVG_H_ -#define _NETSURF_IMAGE_RSVG_H_ - -nserror nsrsvg_init(void); - -#endif diff --git a/image/svg.c b/image/svg.c deleted file mode 100644 index 63cdb3bf8..000000000 --- a/image/svg.c +++ /dev/null @@ -1,353 +0,0 @@ -/* - * Copyright 2007-2008 James Bursa <bursa@users.sourceforge.net> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/** \file - * Content for image/svg (implementation). - */ - -#include <assert.h> -#include <limits.h> -#include <string.h> - -#include <svgtiny.h> - -#include "utils/messages.h" -#include "utils/utils.h" -#include "content/content_protected.h" -#include "css/css.h" -#include "desktop/plotters.h" - -#include "image/svg.h" - -typedef struct svg_content { - struct content base; - - struct svgtiny_diagram *diagram; - - int current_width; - int current_height; -} svg_content; - - - -static 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->current_width = INT_MAX; - c->current_height = INT_MAX; - - return NSERROR_OK; - -no_memory: - msg_data.error = messages_get("NoMemory"); - content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data); - return NSERROR_NOMEM; -} - - -/** - * Create a CONTENT_SVG. - */ - -static nserror svg_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) -{ - svg_content *svg; - nserror error; - - svg = calloc(1, sizeof(svg_content)); - if (svg == NULL) - return NSERROR_NOMEM; - - error = content__init(&svg->base, handler, imime_type, params, - llcache, fallback_charset, quirks); - if (error != NSERROR_OK) { - free(svg); - return error; - } - - error = svg_create_svg_data(svg); - if (error != NSERROR_OK) { - free(svg); - return error; - } - - *c = (struct content *) svg; - - return NSERROR_OK; -} - - - -/** - * Convert a CONTENT_SVG for display. - */ - -static bool svg_convert(struct content *c) -{ - /*c->title = malloc(100); - if (c->title) - snprintf(c->title, 100, messages_get("svgTitle"), - width, height, c->source_size);*/ - //c->size += ?; - content_set_ready(c); - content_set_done(c); - /* Done: update status bar */ - content_set_status(c, ""); - - return true; -} - -/** - * Reformat a CONTENT_SVG. - */ - -static void svg_reformat(struct content *c, int width, int height) -{ - svg_content *svg = (svg_content *) c; - const char *source_data; - unsigned long source_size; - - assert(svg->diagram); - - /* Avoid reformats to same width/height as we already reformatted to */ - if (width != svg->current_width || height != svg->current_height) { - source_data = content__get_source_data(c, &source_size); - - svgtiny_parse(svg->diagram, source_data, source_size, - nsurl_access(content_get_url(c)), - width, height); - - svg->current_width = width; - svg->current_height = height; - } - - c->width = svg->diagram->width; - c->height = svg->diagram->height; -} - - -/** - * Redraw a CONTENT_SVG. - */ - -static bool svg_redraw_internal(struct content *c, int x, int y, - int width, int height, const struct rect *clip, - const struct redraw_context *ctx, float scale, - colour background_colour) -{ - svg_content *svg = (svg_content *) c; - float transform[6]; - struct svgtiny_diagram *diagram = svg->diagram; - bool ok; - int px, py; - unsigned int i; - plot_font_style_t fstyle = *plot_style_font; - - assert(diagram); - - transform[0] = (float) width / (float) c->width; - transform[1] = 0; - transform[2] = 0; - transform[3] = (float) height / (float) c->height; - transform[4] = x; - transform[5] = y; - -#define BGR(c) ((c) == svgtiny_TRANSPARENT ? NS_TRANSPARENT : \ - ((svgtiny_RED((c))) | \ - (svgtiny_GREEN((c)) << 8) | \ - (svgtiny_BLUE((c)) << 16))) - - for (i = 0; i != diagram->shape_count; i++) { - if (diagram->shape[i].path) { - ok = ctx->plot->path(diagram->shape[i].path, - diagram->shape[i].path_length, - BGR(diagram->shape[i].fill), - diagram->shape[i].stroke_width, - BGR(diagram->shape[i].stroke), - transform); - if (!ok) - return false; - - } else if (diagram->shape[i].text) { - px = transform[0] * diagram->shape[i].text_x + - transform[2] * diagram->shape[i].text_y + - transform[4]; - py = transform[1] * diagram->shape[i].text_x + - transform[3] * diagram->shape[i].text_y + - transform[5]; - - fstyle.background = 0xffffff; - fstyle.foreground = 0x000000; - fstyle.size = (8 * FONT_SIZE_SCALE) * scale; - - ok = ctx->plot->text(px, py, - diagram->shape[i].text, - strlen(diagram->shape[i].text), - &fstyle); - if (!ok) - return false; - } - } - -#undef BGR - - return true; -} - - -/** - * Redraw a CONTENT_SVG. - */ - -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; - int y = data->y; - - if ((data->width <= 0) && (data->height <= 0)) { - /* No point trying to plot SVG if it does not occupy a valid - * area */ - return true; - } - - if ((data->repeat_x == false) && (data->repeat_y == false)) { - /* Simple case: SVG is not tiled */ - return svg_redraw_internal(c, x, y, - data->width, data->height, - clip, ctx, data->scale, - data->background_colour); - } else { - /* Tiled redraw required. SVG repeats to extents of clip - * rectangle, in x, y or both directions */ - int x0, y0, x1, y1; - - /* Find the redraw boundaries to loop within */ - x0 = x; - if (data->repeat_x) { - for (; x0 > clip->x0; x0 -= data->width); - x1 = clip->x1; - } else { - x1 = x + 1; - } - y0 = y; - if (data->repeat_y) { - for (; y0 > clip->y0; y0 -= data->height); - y1 = clip->y1; - } else { - y1 = y + 1; - } - - /* Repeatedly plot the SVG across the area */ - for (y = y0; y < y1; y += data->height) { - for (x = x0; x < x1; x += data->width) { - if (!svg_redraw_internal(c, x, y, - data->width, data->height, - clip, ctx, data->scale, - data->background_colour)) { - return false; - } - } - } - } - - return true; -} - - -/** - * Destroy a CONTENT_SVG and free all resources it owns. - */ - -static void svg_destroy(struct content *c) -{ - svg_content *svg = (svg_content *) c; - - if (svg->diagram != NULL) - svgtiny_free(svg->diagram); -} - - -static nserror svg_clone(const struct content *old, struct content **newc) -{ - svg_content *svg; - nserror error; - - svg = calloc(1, sizeof(svg_content)); - if (svg == NULL) - return NSERROR_NOMEM; - - error = content__clone(old, &svg->base); - if (error != NSERROR_OK) { - content_destroy(&svg->base); - return error; - } - - /* Simply replay create/convert */ - error = svg_create_svg_data(svg); - if (error != NSERROR_OK) { - content_destroy(&svg->base); - return error; - } - - if (old->status == CONTENT_STATUS_READY || - old->status == CONTENT_STATUS_DONE) { - if (svg_convert(&svg->base) == false) { - content_destroy(&svg->base); - return NSERROR_CLONE_FAILED; - } - } - - *newc = (struct content *) svg; - - return NSERROR_OK; -} - -static content_type svg_content_type(void) -{ - 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 = true -}; - -static const char *svg_types[] = { - "image/svg", - "image/svg+xml" -}; - - -CONTENT_FACTORY_REGISTER_TYPES(svg, svg_types, svg_content_handler); - - diff --git a/image/svg.h b/image/svg.h deleted file mode 100644 index 96b9c3879..000000000 --- a/image/svg.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2007-2008 James Bursa <bursa@users.sourceforge.net> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/** \file - * Content for image/svg (interface). - */ - -#ifndef _NETSURF_IMAGE_SVG_H_ -#define _NETSURF_IMAGE_SVG_H_ - -nserror svg_init(void); - -#endif diff --git a/image/video.c b/image/video.c deleted file mode 100644 index 1cbbeebf0..000000000 --- a/image/video.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright 2011 John-Mark Bell <jmb@netsurf-browser.org> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <gst/gst.h> - -#include "content/content_factory.h" -#include "content/content_protected.h" -#include "image/video.h" - -typedef struct nsvideo_content { - struct content base; - - GstElement *playbin; - GstElement *appsrc; -} nsvideo_content; - -static gboolean nsvideo_bus_call(GstBus *bus, GstMessage *msg, - nsvideo_content *video) -{ - switch (GST_MESSAGE_TYPE(msg)) { - case GST_MESSAGE_ERROR: - break; - case GST_MESSAGE_EOS: - break; - default: - break; - } - - return TRUE; -} - -static void nsvideo_need_data_event(GstElement *playbin, guint size, - nsvideo_content *video) -{ -} - -static void nsvideo_enough_data_event(GstElement *playbin, - nsvideo_content *video) -{ -} - -static void nsvideo_source_event(GObject *object, GObject *orig, - GParamSpec *pspec, nsvideo_content *video) -{ - g_object_get(orig, pspec->name, &video->appsrc, NULL); - - g_signal_connect(video->appsrc, "need-data", - G_CALLBACK(nsvideo_need_data_event), video); - g_signal_connect(video->appsrc, "enough-data", - G_CALLBACK(nsvideo_enough_data_event), video); -} - -static nserror nsvideo_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) -{ - nsvideo_content *video; - nserror error; - GstBus *bus; - - video = calloc(1, sizeof(nsvideo_content)); - if (video == NULL) - return NSERROR_NOMEM; - - error = content__init(&video->base, handler, imime_type, params, - llcache, fallback_charset, quirks); - if (error != NSERROR_OK) { - free(video); - return error; - } - - error = llcache_handle_force_stream(llcache); - if (error != NSERROR_OK) { - free(video); - return error; - } - - video->playbin = gst_element_factory_make("playbin2", NULL); - if (video->playbin == NULL) { - free(video); - return NSERROR_NOMEM; - } - - bus = gst_pipeline_get_bus(GST_PIPELINE(video->playbin)); - gst_bus_add_watch(bus, (GstBusFunc) nsvideo_bus_call, video); - gst_object_unref(bus); - - g_object_set(video->playbin, "uri", "appsrc://", NULL); - g_signal_connect(video->playbin, "deep-notify::source", - G_CALLBACK(nsvideo_source_event), video); - - /** \todo Create appsink & register with playbin */ - - gst_element_set_state(video->playbin, GST_STATE_PLAYING); - - *c = (struct content *) video; - - return NSERROR_OK; -} - -static bool nsvideo_process_data(struct content *c, const char *data, - unsigned int size) -{ - nsvideo_content *video = (nsvideo_content *) c; - GstBuffer *buffer; - GstFlowReturn ret; - - buffer = gst_buffer_new(); - GST_BUFFER_DATA(buffer) = (guint8 *) data; - GST_BUFFER_SIZE(buffer) = (gsize) size; - - /* Send data to appsrc */ - g_signal_emit_by_name(video->appsrc, "push-buffer", buffer, &ret); - - return ret == GST_FLOW_OK; -} - -static bool nsvideo_convert(struct content *c) -{ - nsvideo_content *video = (nsvideo_content *) c; - GstFlowReturn ret; - - /* Tell appsrc we're done */ - g_signal_emit_by_name(video->appsrc, "end-of-stream", &ret); - - /* Appsink will flag DONE on receipt of first frame */ - - return ret == GST_FLOW_OK; -} - -static void nsvideo_destroy(struct content *c) -{ - nsvideo_content *video = (nsvideo_content *) c; - - gst_element_set_state(video->playbin, GST_STATE_NULL); - gst_object_unref(video->playbin); -} - -static bool nsvideo_redraw(struct content *c, struct content_redraw_data *data, - const struct rect *clip, const struct redraw_context *ctx) -{ - /** \todo Implement */ - return true; -} - -static nserror nsvideo_clone(const struct content *old, struct content **newc) -{ - /** \todo Implement */ - return NSERROR_CLONE_FAILED; -} - -static content_type nsvideo_type(void) -{ - /** \todo Lies */ - return CONTENT_IMAGE; -} - -static void *nsvideo_get_internal(const struct content *c, void *context) -{ - /** \todo Return pointer to bitmap containing current frame, if any? */ - return NULL; -} - -static const content_handler nsvideo_content_handler = { - .create = nsvideo_create, - .process_data = nsvideo_process_data, - .data_complete = nsvideo_convert, - .destroy = nsvideo_destroy, - .redraw = nsvideo_redraw, - .clone = nsvideo_clone, - .type = nsvideo_type, - .get_internal = nsvideo_get_internal, - /* Can't share videos because we stream them */ - .no_share = true -}; - -static const char *nsvideo_types[] = { - "video/mp4", - "video/webm" -}; - -CONTENT_FACTORY_REGISTER_TYPES(nsvideo, nsvideo_types, - nsvideo_content_handler); - diff --git a/image/video.h b/image/video.h deleted file mode 100644 index 376c837ba..000000000 --- a/image/video.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2011 John-Mark Bell <jmb@netsurf-browser.org> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef NETSURF_IMAGE_VIDEO_H_ -#define NETSURF_IMAGE_VIDEO_H_ - -#include "utils/errors.h" - -nserror nsvideo_init(void); - -#endif |