From 20ce79aaf57b02dc63c70fb5c7c25ff3a30d0590 Mon Sep 17 00:00:00 2001 From: Sean Fox Date: Wed, 18 Jun 2008 22:11:17 +0000 Subject: Incorporated bitmap callbacks to make libnsbmp stand-alone svn path=/branches/dynis/libnsbmp/; revision=4396 --- libnsbmp.c | 99 ++++++++++++++++++++++++++++++++------------------------------ libnsbmp.h | 38 +++++++++++++++++++----- 2 files changed, 82 insertions(+), 55 deletions(-) diff --git a/libnsbmp.c b/libnsbmp.c index bff3116..b3d79c2 100644 --- a/libnsbmp.c +++ b/libnsbmp.c @@ -1,5 +1,6 @@ /* * Copyright 2006 Richard Wilson + * Copyright 2008 Sean Fox * * This file is part of NetSurf, http://www.netsurf-browser.org/ * @@ -22,21 +23,22 @@ #include #include #include -#include "image/bmpread.h" -#include "image/bitmap.h" +#include "libnsbmp.h" #include "utils/log.h" -#include "utils/config.h" #define READ_SHORT(a, o) (a[o]|(a[o+1]<<8)) #define READ_INT(a, o) (a[o]|(a[o+1]<<8)|(a[o+2]<<16)|(a[o+3]<<24)) -bmp_result bmp_analyse_header(struct bmp_image *bmp, char *data); -bmp_result bmp_decode_rgb24(struct bmp_image *bmp, char **start, int bytes); -bmp_result bmp_decode_rgb16(struct bmp_image *bmp, char **start, int bytes); -bmp_result bmp_decode_rgb(struct bmp_image *bmp, char **start, int bytes); -bmp_result bmp_decode_mask(struct bmp_image *bmp, char *data, int bytes); -bmp_result bmp_decode_rle(struct bmp_image *bmp, char *data, int bytes, int size); -void bmp_invalidate(struct bitmap *bitmap, void *private_word); +/* squashes unused variable compiler warnings */ +#define UNUSED(x) ((x)=(x)) + +bmp_result bmp_analyse_header(struct bmp_image *bmp, char *data, bmp_bitmap_callback_vt *bitmap_callbacks); +bmp_result bmp_decode_rgb24(struct bmp_image *bmp, char **start, int bytes, bmp_bitmap_callback_vt *bitmap_callbacks); +bmp_result bmp_decode_rgb16(struct bmp_image *bmp, char **start, int bytes, bmp_bitmap_callback_vt *bitmap_callbacks); +bmp_result bmp_decode_rgb(struct bmp_image *bmp, char **start, int bytes, bmp_bitmap_callback_vt *bitmap_callbacks); +bmp_result bmp_decode_mask(struct bmp_image *bmp, char *data, int bytes, bmp_bitmap_callback_vt *bitmap_callbacks); +bmp_result bmp_decode_rle(struct bmp_image *bmp, char *data, int bytes, int size, bmp_bitmap_callback_vt *bitmap_callbacks); +void bmp_invalidate(void *bitmap, void *private_word); /** @@ -51,7 +53,7 @@ void bmp_invalidate(struct bitmap *bitmap, void *private_word); * \param bmp the BMP image to analyse * \return BMP_OK on success */ -bmp_result bmp_analyse(struct bmp_image *bmp) { +bmp_result bmp_analyse(struct bmp_image *bmp, bmp_bitmap_callback_vt *bitmap_callbacks) { char *data = (char *) bmp->bmp_data; /* ensure we aren't already initialised */ @@ -73,7 +75,7 @@ bmp_result bmp_analyse(struct bmp_image *bmp) { bmp->bitmap_offset = READ_INT(data, 10); /* decode the BMP header */ - return bmp_analyse_header(bmp, data + 14); + return bmp_analyse_header(bmp, data + 14, bitmap_callbacks); } @@ -88,7 +90,7 @@ bmp_result bmp_analyse(struct bmp_image *bmp) { * \param ico the ICO image to analyse * \return BMP_OK on success */ -bmp_result ico_analyse(struct ico_collection *ico) { +bmp_result ico_analyse(struct ico_collection *ico, bmp_bitmap_callback_vt *bitmap_callbacks) { char *data = (char *) ico->ico_data; unsigned int count, i; bmp_result result; @@ -129,7 +131,7 @@ bmp_result ico_analyse(struct ico_collection *ico) { image->bmp.ico = true; data += 16; result = bmp_analyse_header(&image->bmp, - (char *) image->bmp.bmp_data); + (char *) image->bmp.bmp_data, bitmap_callbacks); if (result != BMP_OK) return result; area = image->bmp.width * image->bmp.height; @@ -143,7 +145,7 @@ bmp_result ico_analyse(struct ico_collection *ico) { } -bmp_result bmp_analyse_header(struct bmp_image *bmp, char *data) { +bmp_result bmp_analyse_header(struct bmp_image *bmp, char *data, bmp_bitmap_callback_vt *bitmap_callbacks) { unsigned int header_size; unsigned int i; int width, height, j; @@ -295,10 +297,10 @@ bmp_result bmp_analyse_header(struct bmp_image *bmp, char *data) { } /* create our bitmap */ - flags = BITMAP_NEW | BITMAP_CLEAR_MEMORY; + flags = BMP_NEW | BMP_CLEAR_MEMORY; if ((!bmp->ico) && (bmp->mask[3] == 0)) - flags |= BITMAP_OPAQUE; - bmp->bitmap = bitmap_create(bmp->width, bmp->height, flags); + flags |= BMP_OPAQUE; + bmp->bitmap = bitmap_callbacks->bitmap_create(bmp->width, bmp->height, flags); if (!bmp->bitmap) { if (bmp->colour_table) free(bmp->colour_table); @@ -306,7 +308,7 @@ bmp_result bmp_analyse_header(struct bmp_image *bmp, char *data) { return BMP_INSUFFICIENT_MEMORY; } bmp->bitmap_offset = (intptr_t)data - (intptr_t)bmp->bmp_data; - bitmap_set_suspendable(bmp->bitmap, bmp, bmp_invalidate); + bitmap_callbacks->bitmap_set_suspendable(bmp->bitmap, bmp, bmp_invalidate); return BMP_OK; } @@ -349,7 +351,8 @@ struct bmp_image *ico_find(struct ico_collection *ico, int width, int height) { * * \param bmp the BMP image to invalidate */ -void bmp_invalidate(struct bitmap *bitmap, void *private_word) { +void bmp_invalidate(void *bitmap, void *private_word) { + UNUSED(bitmap); struct bmp_image *bmp = (struct bmp_image *)private_word; bmp->decoded = false; @@ -366,7 +369,7 @@ void bmp_invalidate(struct bitmap *bitmap, void *private_word) { * \param bmp the BMP image to decode * \return BMP_OK on success */ -bmp_result bmp_decode(struct bmp_image *bmp) { +bmp_result bmp_decode(struct bmp_image *bmp, bmp_bitmap_callback_vt *bitmap_callbacks) { char *data; int bytes; bmp_result result = BMP_OK; @@ -379,23 +382,23 @@ bmp_result bmp_decode(struct bmp_image *bmp) { switch (bmp->encoding) { case BMP_ENCODING_RGB: if (bmp->bpp >= 24) - result = bmp_decode_rgb24(bmp, &data, bytes); + result = bmp_decode_rgb24(bmp, &data, bytes, bitmap_callbacks); else if (bmp->bpp > 8) - result = bmp_decode_rgb16(bmp, &data, bytes); + result = bmp_decode_rgb16(bmp, &data, bytes, bitmap_callbacks); else - result = bmp_decode_rgb(bmp, &data, bytes); + result = bmp_decode_rgb(bmp, &data, bytes, bitmap_callbacks); break; case BMP_ENCODING_RLE8: - result = bmp_decode_rle(bmp, data, bytes, 8); + result = bmp_decode_rle(bmp, data, bytes, 8, bitmap_callbacks); break; case BMP_ENCODING_RLE4: - result = bmp_decode_rle(bmp, data, bytes, 4); + result = bmp_decode_rle(bmp, data, bytes, 4, bitmap_callbacks); break; case BMP_ENCODING_BITFIELDS: if (bmp->bpp == 32) - result = bmp_decode_rgb24(bmp, &data, bytes); + result = bmp_decode_rgb24(bmp, &data, bytes, bitmap_callbacks); else if (bmp->bpp == 16) - result = bmp_decode_rgb16(bmp, &data, bytes); + result = bmp_decode_rgb16(bmp, &data, bytes, bitmap_callbacks); else return BMP_DATA_ERROR; } @@ -404,7 +407,7 @@ bmp_result bmp_decode(struct bmp_image *bmp) { return result; bytes = (intptr_t)bmp->bmp_data + bmp->buffer_size - (intptr_t)data; - return bmp_decode_mask(bmp, data, bytes); + return bmp_decode_mask(bmp, data, bytes, bitmap_callbacks); } @@ -416,7 +419,7 @@ bmp_result bmp_decode(struct bmp_image *bmp) { * \param bytes the number of bytes of data available * \return BMP_OK on success */ -bmp_result bmp_decode_rgb24(struct bmp_image *bmp, char **start, int bytes) { +bmp_result bmp_decode_rgb24(struct bmp_image *bmp, char **start, int bytes, bmp_bitmap_callback_vt *bitmap_callbacks) { char *top, *bottom, *end, *data; unsigned int *scanline; unsigned int x, y, swidth, skip; @@ -424,8 +427,8 @@ bmp_result bmp_decode_rgb24(struct bmp_image *bmp, char **start, int bytes) { unsigned int i, word; data = *start; - swidth = bitmap_get_rowstride(bmp->bitmap); - top = bitmap_get_buffer(bmp->bitmap); + swidth = bitmap_callbacks->bitmap_get_rowstride(bmp->bitmap); + top = bitmap_callbacks->bitmap_get_buffer(bmp->bitmap); if (!top) return BMP_INSUFFICIENT_MEMORY; bottom = top + swidth * (bmp->height - 1); @@ -478,7 +481,7 @@ bmp_result bmp_decode_rgb24(struct bmp_image *bmp, char **start, int bytes) { * \param bytes the number of bytes of data available * \return BMP_OK on success */ -bmp_result bmp_decode_rgb16(struct bmp_image *bmp, char **start, int bytes) { +bmp_result bmp_decode_rgb16(struct bmp_image *bmp, char **start, int bytes, bmp_bitmap_callback_vt *bitmap_callbacks) { char *top, *bottom, *end, *data; unsigned int *scanline; unsigned int x, y, swidth; @@ -486,8 +489,8 @@ bmp_result bmp_decode_rgb16(struct bmp_image *bmp, char **start, int bytes) { unsigned int word, i; data = *start; - swidth = bitmap_get_rowstride(bmp->bitmap); - top = bitmap_get_buffer(bmp->bitmap); + swidth = bitmap_callbacks->bitmap_get_rowstride(bmp->bitmap); + top = bitmap_callbacks->bitmap_get_buffer(bmp->bitmap); if (!top) return BMP_INSUFFICIENT_MEMORY; bottom = top + swidth * (bmp->height - 1); @@ -540,7 +543,7 @@ bmp_result bmp_decode_rgb16(struct bmp_image *bmp, char **start, int bytes) { * \param bytes the number of bytes of data available * \return BMP_OK on success */ -bmp_result bmp_decode_rgb(struct bmp_image *bmp, char **start, int bytes) { +bmp_result bmp_decode_rgb(struct bmp_image *bmp, char **start, int bytes, bmp_bitmap_callback_vt *bitmap_callbacks) { char *top, *bottom, *end, *data; unsigned int *scanline; intptr_t addr; @@ -555,8 +558,8 @@ bmp_result bmp_decode_rgb(struct bmp_image *bmp, char **start, int bytes) { bit_shifts[i] = 8 - ((i + 1) * bmp->bpp); data = *start; - swidth = bitmap_get_rowstride(bmp->bitmap); - top = bitmap_get_buffer(bmp->bitmap); + swidth = bitmap_callbacks->bitmap_get_rowstride(bmp->bitmap); + top = bitmap_callbacks->bitmap_get_buffer(bmp->bitmap); if (!top) return BMP_INSUFFICIENT_MEMORY; bottom = top + swidth * (bmp->height - 1); @@ -596,15 +599,15 @@ bmp_result bmp_decode_rgb(struct bmp_image *bmp, char **start, int bytes) { * \param bytes the number of bytes of data available * \return BMP_OK on success */ -bmp_result bmp_decode_mask(struct bmp_image *bmp, char *data, int bytes) { +bmp_result bmp_decode_mask(struct bmp_image *bmp, char *data, int bytes, bmp_bitmap_callback_vt *bitmap_callbacks) { char *top, *bottom, *end; unsigned int *scanline; intptr_t addr; unsigned int x, y, swidth; int cur_byte = 0; - swidth = bitmap_get_rowstride(bmp->bitmap); - top = bitmap_get_buffer(bmp->bitmap); + swidth = bitmap_callbacks->bitmap_get_rowstride(bmp->bitmap); + top = bitmap_callbacks->bitmap_get_buffer(bmp->bitmap); if (!top) return BMP_INSUFFICIENT_MEMORY; bottom = top + swidth * (bmp->height - 1); @@ -638,7 +641,7 @@ bmp_result bmp_decode_mask(struct bmp_image *bmp, char *data, int bytes) { * \param size the size of the RLE tokens (4 or 8) * \return BMP_OK on success */ -bmp_result bmp_decode_rle(struct bmp_image *bmp, char *data, int bytes, int size) { +bmp_result bmp_decode_rle(struct bmp_image *bmp, char *data, int bytes, int size, bmp_bitmap_callback_vt *bitmap_callbacks) { char *top, *bottom, *end; unsigned int *scanline; unsigned int swidth; @@ -649,8 +652,8 @@ bmp_result bmp_decode_rle(struct bmp_image *bmp, char *data, int bytes, int size if (bmp->ico) return BMP_DATA_ERROR; - swidth = bitmap_get_rowstride(bmp->bitmap); - top = bitmap_get_buffer(bmp->bitmap); + swidth = bitmap_callbacks->bitmap_get_rowstride(bmp->bitmap); + top = bitmap_callbacks->bitmap_get_buffer(bmp->bitmap); if (!top) return BMP_INSUFFICIENT_MEMORY; bottom = top + swidth * (bmp->height - 1); @@ -788,9 +791,9 @@ bmp_result bmp_decode_rle(struct bmp_image *bmp, char *data, int bytes, int size * * \param bmp the BMP image to finalise */ -void bmp_finalise(struct bmp_image *bmp) { +void bmp_finalise(struct bmp_image *bmp, bmp_bitmap_callback_vt *bitmap_callbacks) { if (bmp->bitmap) - bitmap_destroy(bmp->bitmap); + bitmap_callbacks->bitmap_destroy(bmp->bitmap); bmp->bitmap = NULL; if (bmp->colour_table) free(bmp->colour_table); @@ -803,11 +806,11 @@ void bmp_finalise(struct bmp_image *bmp) { * * \param ico the ICO image to finalise */ -void ico_finalise(struct ico_collection *ico) { +void ico_finalise(struct ico_collection *ico, bmp_bitmap_callback_vt *bitmap_callbacks) { struct ico_image *image; for (image = ico->first; image; image = image->next) - bmp_finalise(&image->bmp); + bmp_finalise(&image->bmp, bitmap_callbacks); while (ico->first) { image = ico->first; ico->first = image->next; diff --git a/libnsbmp.h b/libnsbmp.h index e1ed6c3..1708d08 100644 --- a/libnsbmp.h +++ b/libnsbmp.h @@ -1,5 +1,6 @@ /* * Copyright 2006 Richard Wilson + * Copyright 2008 Sean Fox * * This file is part of NetSurf, http://www.netsurf-browser.org/ * @@ -24,7 +25,11 @@ #define _NETSURF_IMAGE_BMPREAD_H_ #include -#include "image/bitmap.h" + +/* bmp flags */ +#define BMP_NEW 0 +#define BMP_OPAQUE (1 << 0) /** image is opaque */ +#define BMP_CLEAR_MEMORY (1 << 1) /** memory should be wiped */ /* error return values */ typedef enum { @@ -42,6 +47,25 @@ typedef enum { BMP_ENCODING_BITFIELDS = 3 } bmp_encoding; +/* API for Bitmap callbacks +*/ +typedef void* (*bitmap_cb_create)(int width, int height, unsigned int state); +typedef void (*bitmap_cb_destroy)(void *bitmap); +typedef void (*bitmap_cb_set_suspendable)(void *bitmap, void *private_word, + void (*invalidate)(void *bitmap, void *private_word)); +typedef char* (*bitmap_cb_get_buffer)(void *bitmap); +typedef size_t (*bitmap_cb_get_rowstride)(void *bitmap); + +/* The Bitmap callbacks function table +*/ +typedef struct bmp_bitmap_callback_vt_s { + bitmap_cb_create bitmap_create; /**< Create a bitmap. */ + bitmap_cb_destroy bitmap_destroy; /**< Free a bitmap. */ + bitmap_cb_set_suspendable bitmap_set_suspendable; /**< The bitmap image can be suspended. */ + bitmap_cb_get_buffer bitmap_get_buffer; /**< Return a pointer to the pixel data in a bitmap. */ + bitmap_cb_get_rowstride bitmap_get_rowstride; /**< Find the width of a pixel row in bytes. */ +} bmp_bitmap_callback_vt; + struct bmp_image { unsigned char *bmp_data; /** pointer to BMP data */ unsigned int buffer_size; /** total number of bytes of BMP data available */ @@ -57,7 +81,7 @@ struct bmp_image { bool ico; /** image is part of an ICO, mask follows */ unsigned int mask[4]; /** four bitwise mask */ int shift[4]; /** four bitwise shifts */ - struct bitmap *bitmap; /** decoded image */ + void *bitmap; /** decoded image */ }; struct ico_image { @@ -73,12 +97,12 @@ struct ico_collection { struct ico_image *first; }; -bmp_result bmp_analyse(struct bmp_image *bmp); -bmp_result bmp_decode(struct bmp_image *bmp); -void bmp_finalise(struct bmp_image *bmp); +bmp_result bmp_analyse(struct bmp_image *bmp, bmp_bitmap_callback_vt *bitmap_callbacks); +bmp_result bmp_decode(struct bmp_image *bmp, bmp_bitmap_callback_vt *bitmap_callbacks); +void bmp_finalise(struct bmp_image *bmp, bmp_bitmap_callback_vt *bitmap_callbacks); -bmp_result ico_analyse(struct ico_collection *ico); +bmp_result ico_analyse(struct ico_collection *ico, bmp_bitmap_callback_vt *bitmap_callbacks); struct bmp_image *ico_find(struct ico_collection *ico, int width, int height); -void ico_finalise(struct ico_collection *ico); +void ico_finalise(struct ico_collection *ico, bmp_bitmap_callback_vt *bitmap_callbacks); #endif -- cgit v1.2.3