summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbin/decode_bmpbin36588 -> 36323 bytes
-rw-r--r--examples/decode_bmp.c26
-rw-r--r--libnsbmp.c86
-rw-r--r--libnsbmp.h53
4 files changed, 83 insertions, 82 deletions
diff --git a/bin/decode_bmp b/bin/decode_bmp
index f0f6c23..d31e8a2 100755
--- a/bin/decode_bmp
+++ b/bin/decode_bmp
Binary files differ
diff --git a/examples/decode_bmp.c b/examples/decode_bmp.c
index 685d75a..7ee2f8b 100644
--- a/examples/decode_bmp.c
+++ b/examples/decode_bmp.c
@@ -38,20 +38,16 @@ unsigned char *bitmap_get_buffer(void *bitmap);
size_t bitmap_get_bpp(void *bitmap);
void bitmap_destroy(void *bitmap);
-/* The Bitmap callbacks function table;
- necessary for interaction with nsgiflib.
-*/
-bmp_bitmap_callback_vt bitmap_callbacks = {
- bitmap_create,
- bitmap_destroy,
- bitmap_set_suspendable,
- bitmap_get_buffer,
- bitmap_get_bpp
-};
-
int main(int argc, char *argv[])
{
+ bmp_bitmap_callback_vt bitmap_callbacks = {
+ bitmap_create,
+ bitmap_destroy,
+ bitmap_set_suspendable,
+ bitmap_get_buffer,
+ bitmap_get_bpp
+ };
bmp_result code;
bmp_image bmp;
size_t size;
@@ -62,7 +58,7 @@ int main(int argc, char *argv[])
}
/* create our bmp image */
- bmp_create(&bmp);
+ bmp_create(&bmp, &bitmap_callbacks);
/* load file into memory */
unsigned char *data = load_file(argv[1], &size);
@@ -72,7 +68,7 @@ int main(int argc, char *argv[])
bmp.buffer_size = size;
/* analyse the BMP */
- code = bmp_analyse(&bmp, &bitmap_callbacks);
+ code = bmp_analyse(&bmp);
if (code != BMP_OK) {
warning("bmp_analyse", code);
exit(1);
@@ -85,7 +81,7 @@ int main(int argc, char *argv[])
printf("%u %u 256\n", bmp.width, bmp.height);
/* decode the image */
- code = bmp_decode(&bmp, &bitmap_callbacks);
+ code = bmp_decode(&bmp);
if (code != BMP_OK) {
warning("bmp_decode", code);
exit(1);
@@ -107,7 +103,7 @@ int main(int argc, char *argv[])
}
/* clean up */
- bmp_finalise(&bmp, &bitmap_callbacks);
+ bmp_finalise(&bmp);
free(data);
return 0;
diff --git a/libnsbmp.c b/libnsbmp.c
index 1b56143..a9242e7 100644
--- a/libnsbmp.c
+++ b/libnsbmp.c
@@ -37,20 +37,21 @@ static inline int read_int(unsigned char *data, unsigned int o) {
return ((unsigned char)data[o] | ((unsigned char)data[o+1] << 8) | ((unsigned char)data[o+2] << 16) | ((unsigned char)data[o+3] << 24));
}
-bmp_result bmp_analyse_header(struct bmp_image *bmp, unsigned char *data, bmp_bitmap_callback_vt *bitmap_callbacks);
-bmp_result bmp_decode_rgb24(struct bmp_image *bmp, unsigned char **start, int bytes, bmp_bitmap_callback_vt *bitmap_callbacks);
-bmp_result bmp_decode_rgb16(struct bmp_image *bmp, unsigned char **start, int bytes, bmp_bitmap_callback_vt *bitmap_callbacks);
-bmp_result bmp_decode_rgb(struct bmp_image *bmp, unsigned char **start, int bytes, bmp_bitmap_callback_vt *bitmap_callbacks);
-bmp_result bmp_decode_mask(struct bmp_image *bmp, unsigned char *data, int bytes, bmp_bitmap_callback_vt *bitmap_callbacks);
-bmp_result bmp_decode_rle(struct bmp_image *bmp, unsigned char *data, int bytes, int size, bmp_bitmap_callback_vt *bitmap_callbacks);
+bmp_result bmp_analyse_header(struct bmp_image *bmp, unsigned char *data);
+bmp_result bmp_decode_rgb24(struct bmp_image *bmp, unsigned char **start, int bytes);
+bmp_result bmp_decode_rgb16(struct bmp_image *bmp, unsigned char **start, int bytes);
+bmp_result bmp_decode_rgb(struct bmp_image *bmp, unsigned char **start, int bytes);
+bmp_result bmp_decode_mask(struct bmp_image *bmp, unsigned char *data, int bytes);
+bmp_result bmp_decode_rle(struct bmp_image *bmp, unsigned char *data, int bytes, int size);
void bmp_invalidate(void *bitmap, void *private_word);
/** Initialises necessary bmp_image members.
*/
-void bmp_create(bmp_image *bmp) {
+void bmp_create(bmp_image *bmp, bmp_bitmap_callback_vt *bitmap_callbacks) {
memset(bmp, 0, sizeof(bmp_image));
+ bmp->bitmap_callbacks = *bitmap_callbacks;
}
@@ -66,7 +67,7 @@ void bmp_create(bmp_image *bmp) {
* \param bmp the BMP image to analyse
* \return BMP_OK on success
*/
-bmp_result bmp_analyse(struct bmp_image *bmp, bmp_bitmap_callback_vt *bitmap_callbacks) {
+bmp_result bmp_analyse(struct bmp_image *bmp) {
unsigned char *data = bmp->bmp_data;
/* ensure we aren't already initialised */
@@ -88,7 +89,7 @@ bmp_result bmp_analyse(struct bmp_image *bmp, bmp_bitmap_callback_vt *bitmap_cal
bmp->bitmap_offset = read_int(data, 10);
/* decode the BMP header */
- return bmp_analyse_header(bmp, data + 14, bitmap_callbacks);
+ return bmp_analyse_header(bmp, data + 14);
}
@@ -103,7 +104,7 @@ bmp_result bmp_analyse(struct bmp_image *bmp, bmp_bitmap_callback_vt *bitmap_cal
* \param ico the ICO image to analyse
* \return BMP_OK on success
*/
-bmp_result ico_analyse(struct ico_collection *ico, bmp_bitmap_callback_vt *bitmap_callbacks) {
+bmp_result ico_analyse(struct ico_collection *ico) {
unsigned char *data = ico->ico_data;
unsigned int count, i;
bmp_result result;
@@ -143,8 +144,7 @@ bmp_result ico_analyse(struct ico_collection *ico, bmp_bitmap_callback_vt *bitma
image->bmp.bmp_data = ico->ico_data + read_int(data, 12);
image->bmp.ico = true;
data += 16;
- result = bmp_analyse_header(&image->bmp,
- image->bmp.bmp_data, bitmap_callbacks);
+ result = bmp_analyse_header(&image->bmp, image->bmp.bmp_data);
if (result != BMP_OK)
return result;
area = image->bmp.width * image->bmp.height;
@@ -158,7 +158,7 @@ bmp_result ico_analyse(struct ico_collection *ico, bmp_bitmap_callback_vt *bitma
}
-bmp_result bmp_analyse_header(struct bmp_image *bmp, unsigned char *data, bmp_bitmap_callback_vt *bitmap_callbacks) {
+bmp_result bmp_analyse_header(struct bmp_image *bmp, unsigned char *data) {
unsigned int header_size;
unsigned int i;
int width, height, j;
@@ -311,7 +311,7 @@ bmp_result bmp_analyse_header(struct bmp_image *bmp, unsigned char *data, bmp_bi
flags = BMP_NEW | BMP_CLEAR_MEMORY;
if ((!bmp->ico) && (bmp->mask[3] == 0))
flags |= BMP_OPAQUE;
- bmp->bitmap = bitmap_callbacks->bitmap_create(bmp->width, bmp->height, flags);
+ bmp->bitmap = bmp->bitmap_callbacks.bitmap_create(bmp->width, bmp->height, flags);
if (!bmp->bitmap) {
if (bmp->colour_table)
free(bmp->colour_table);
@@ -319,7 +319,7 @@ bmp_result bmp_analyse_header(struct bmp_image *bmp, unsigned char *data, bmp_bi
return BMP_INSUFFICIENT_MEMORY;
}
bmp->bitmap_offset = (intptr_t)data - (intptr_t)bmp->bmp_data;
- bitmap_callbacks->bitmap_set_suspendable(bmp->bitmap, bmp, bmp_invalidate);
+ bmp->bitmap_callbacks.bitmap_set_suspendable(bmp->bitmap, bmp, bmp_invalidate);
return BMP_OK;
}
@@ -380,7 +380,7 @@ void bmp_invalidate(void *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_bitmap_callback_vt *bitmap_callbacks) {
+bmp_result bmp_decode(struct bmp_image *bmp) {
unsigned char *data;
int bytes;
bmp_result result = BMP_OK;
@@ -393,23 +393,23 @@ bmp_result bmp_decode(struct bmp_image *bmp, bmp_bitmap_callback_vt *bitmap_call
switch (bmp->encoding) {
case BMP_ENCODING_RGB:
if (bmp->bpp >= 24)
- result = bmp_decode_rgb24(bmp, &data, bytes, bitmap_callbacks);
+ result = bmp_decode_rgb24(bmp, &data, bytes);
else if (bmp->bpp > 8)
- result = bmp_decode_rgb16(bmp, &data, bytes, bitmap_callbacks);
+ result = bmp_decode_rgb16(bmp, &data, bytes);
else
- result = bmp_decode_rgb(bmp, &data, bytes, bitmap_callbacks);
+ result = bmp_decode_rgb(bmp, &data, bytes);
break;
case BMP_ENCODING_RLE8:
- result = bmp_decode_rle(bmp, data, bytes, 8, bitmap_callbacks);
+ result = bmp_decode_rle(bmp, data, bytes, 8);
break;
case BMP_ENCODING_RLE4:
- result = bmp_decode_rle(bmp, data, bytes, 4, bitmap_callbacks);
+ result = bmp_decode_rle(bmp, data, bytes, 4);
break;
case BMP_ENCODING_BITFIELDS:
if (bmp->bpp == 32)
- result = bmp_decode_rgb24(bmp, &data, bytes, bitmap_callbacks);
+ result = bmp_decode_rgb24(bmp, &data, bytes);
else if (bmp->bpp == 16)
- result = bmp_decode_rgb16(bmp, &data, bytes, bitmap_callbacks);
+ result = bmp_decode_rgb16(bmp, &data, bytes);
else
return BMP_DATA_ERROR;
}
@@ -418,7 +418,7 @@ bmp_result bmp_decode(struct bmp_image *bmp, bmp_bitmap_callback_vt *bitmap_call
return result;
bytes = (intptr_t)bmp->bmp_data + bmp->buffer_size - (intptr_t)data;
- return bmp_decode_mask(bmp, data, bytes, bitmap_callbacks);
+ return bmp_decode_mask(bmp, data, bytes);
}
@@ -430,7 +430,7 @@ bmp_result bmp_decode(struct bmp_image *bmp, bmp_bitmap_callback_vt *bitmap_call
* \param bytes the number of bytes of data available
* \return BMP_OK on success
*/
-bmp_result bmp_decode_rgb24(struct bmp_image *bmp, unsigned char **start, int bytes, bmp_bitmap_callback_vt *bitmap_callbacks) {
+bmp_result bmp_decode_rgb24(struct bmp_image *bmp, unsigned char **start, int bytes) {
unsigned char *top, *bottom, *end, *data;
unsigned int *scanline;
unsigned int x, y, swidth, skip;
@@ -438,8 +438,8 @@ bmp_result bmp_decode_rgb24(struct bmp_image *bmp, unsigned char **start, int by
unsigned int i, word;
data = *start;
- swidth = bitmap_callbacks->bitmap_get_bpp(bmp->bitmap) * bmp->width;
- top = bitmap_callbacks->bitmap_get_buffer(bmp->bitmap);
+ swidth = bmp->bitmap_callbacks.bitmap_get_bpp(bmp->bitmap) * bmp->width;
+ top = bmp->bitmap_callbacks.bitmap_get_buffer(bmp->bitmap);
if (!top)
return BMP_INSUFFICIENT_MEMORY;
bottom = top + swidth * (bmp->height - 1);
@@ -491,7 +491,7 @@ bmp_result bmp_decode_rgb24(struct bmp_image *bmp, unsigned char **start, int by
* \param bytes the number of bytes of data available
* \return BMP_OK on success
*/
-bmp_result bmp_decode_rgb16(struct bmp_image *bmp, unsigned char **start, int bytes, bmp_bitmap_callback_vt *bitmap_callbacks) {
+bmp_result bmp_decode_rgb16(struct bmp_image *bmp, unsigned char **start, int bytes) {
unsigned char *top, *bottom, *end, *data;
unsigned int *scanline;
unsigned int x, y, swidth;
@@ -499,8 +499,8 @@ bmp_result bmp_decode_rgb16(struct bmp_image *bmp, unsigned char **start, int by
unsigned int word, i;
data = *start;
- swidth = bitmap_callbacks->bitmap_get_bpp(bmp->bitmap) * bmp->width;
- top = bitmap_callbacks->bitmap_get_buffer(bmp->bitmap);
+ swidth = bmp->bitmap_callbacks.bitmap_get_bpp(bmp->bitmap) * bmp->width;
+ top = bmp->bitmap_callbacks.bitmap_get_buffer(bmp->bitmap);
if (!top)
return BMP_INSUFFICIENT_MEMORY;
bottom = top + swidth * (bmp->height - 1);
@@ -553,7 +553,7 @@ bmp_result bmp_decode_rgb16(struct bmp_image *bmp, unsigned char **start, int by
* \param bytes the number of bytes of data available
* \return BMP_OK on success
*/
-bmp_result bmp_decode_rgb(struct bmp_image *bmp, unsigned char **start, int bytes, bmp_bitmap_callback_vt *bitmap_callbacks) {
+bmp_result bmp_decode_rgb(struct bmp_image *bmp, unsigned char **start, int bytes) {
unsigned char *top, *bottom, *end, *data;
unsigned int *scanline;
intptr_t addr;
@@ -568,8 +568,8 @@ bmp_result bmp_decode_rgb(struct bmp_image *bmp, unsigned char **start, int byte
bit_shifts[i] = 8 - ((i + 1) * bmp->bpp);
data = *start;
- swidth = bitmap_callbacks->bitmap_get_bpp(bmp->bitmap) * bmp->width;
- top = bitmap_callbacks->bitmap_get_buffer(bmp->bitmap);
+ swidth = bmp->bitmap_callbacks.bitmap_get_bpp(bmp->bitmap) * bmp->width;
+ top = bmp->bitmap_callbacks.bitmap_get_buffer(bmp->bitmap);
if (!top)
return BMP_INSUFFICIENT_MEMORY;
bottom = top + swidth * (bmp->height - 1);
@@ -609,15 +609,15 @@ bmp_result bmp_decode_rgb(struct bmp_image *bmp, unsigned char **start, int byte
* \param bytes the number of bytes of data available
* \return BMP_OK on success
*/
-bmp_result bmp_decode_mask(struct bmp_image *bmp, unsigned char *data, int bytes, bmp_bitmap_callback_vt *bitmap_callbacks) {
+bmp_result bmp_decode_mask(struct bmp_image *bmp, unsigned char *data, int bytes) {
unsigned char *top, *bottom, *end;
unsigned int *scanline;
intptr_t addr;
unsigned int x, y, swidth;
int cur_byte = 0;
- swidth = bitmap_callbacks->bitmap_get_bpp(bmp->bitmap) * bmp->width;
- top = bitmap_callbacks->bitmap_get_buffer(bmp->bitmap);
+ swidth = bmp->bitmap_callbacks.bitmap_get_bpp(bmp->bitmap) * bmp->width;
+ top = bmp->bitmap_callbacks.bitmap_get_buffer(bmp->bitmap);
if (!top)
return BMP_INSUFFICIENT_MEMORY;
bottom = top + swidth * (bmp->height - 1);
@@ -651,7 +651,7 @@ bmp_result bmp_decode_mask(struct bmp_image *bmp, unsigned 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, unsigned char *data, int bytes, int size, bmp_bitmap_callback_vt *bitmap_callbacks) {
+bmp_result bmp_decode_rle(struct bmp_image *bmp, unsigned char *data, int bytes, int size) {
unsigned char *top, *bottom, *end;
unsigned int *scanline;
unsigned int swidth;
@@ -662,8 +662,8 @@ bmp_result bmp_decode_rle(struct bmp_image *bmp, unsigned char *data, int bytes,
if (bmp->ico)
return BMP_DATA_ERROR;
- swidth = bitmap_callbacks->bitmap_get_bpp(bmp->bitmap) * bmp->width;
- top = bitmap_callbacks->bitmap_get_buffer(bmp->bitmap);
+ swidth = bmp->bitmap_callbacks.bitmap_get_bpp(bmp->bitmap) * bmp->width;
+ top = bmp->bitmap_callbacks.bitmap_get_buffer(bmp->bitmap);
if (!top)
return BMP_INSUFFICIENT_MEMORY;
bottom = top + swidth * (bmp->height - 1);
@@ -801,9 +801,9 @@ bmp_result bmp_decode_rle(struct bmp_image *bmp, unsigned char *data, int bytes,
*
* \param bmp the BMP image to finalise
*/
-void bmp_finalise(struct bmp_image *bmp, bmp_bitmap_callback_vt *bitmap_callbacks) {
+void bmp_finalise(struct bmp_image *bmp) {
if (bmp->bitmap)
- bitmap_callbacks->bitmap_destroy(bmp->bitmap);
+ bmp->bitmap_callbacks.bitmap_destroy(bmp->bitmap);
bmp->bitmap = NULL;
if (bmp->colour_table)
free(bmp->colour_table);
@@ -816,11 +816,11 @@ void bmp_finalise(struct bmp_image *bmp, bmp_bitmap_callback_vt *bitmap_callback
*
* \param ico the ICO image to finalise
*/
-void ico_finalise(struct ico_collection *ico, bmp_bitmap_callback_vt *bitmap_callbacks) {
+void ico_finalise(struct ico_collection *ico) {
struct ico_image *image;
for (image = ico->first; image; image = image->next)
- bmp_finalise(&image->bmp, bitmap_callbacks);
+ bmp_finalise(&image->bmp);
while (ico->first) {
image = ico->first;
ico->first = image->next;
diff --git a/libnsbmp.h b/libnsbmp.h
index 61e9ef8..fc3dc39 100644
--- a/libnsbmp.h
+++ b/libnsbmp.h
@@ -63,25 +63,28 @@ typedef struct bmp_bitmap_callback_vt_s {
bmp_bitmap_cb_destroy bitmap_destroy; /**< Free a bitmap. */
bmp_bitmap_cb_set_suspendable bitmap_set_suspendable; /**< The bitmap image can be suspended. */
bmp_bitmap_cb_get_buffer bitmap_get_buffer; /**< Return a pointer to the pixel data in a bitmap. */
- bmp_bitmap_cb_get_bpp bitmap_get_bpp; /**< Find the width of a pixel row in bytes. */
+ bmp_bitmap_cb_get_bpp bitmap_get_bpp; /**< Find the width of a pixel row in bytes. */
} bmp_bitmap_callback_vt;
typedef struct bmp_image {
- unsigned char *bmp_data; /** pointer to BMP data */
- unsigned int buffer_size; /** total number of bytes of BMP data available */
- unsigned int width; /** width of BMP (valid after _analyse) */
- unsigned int height; /** heigth of BMP (valid after _analyse) */
- bmp_encoding encoding; /** pixel encoding type */
- unsigned int bitmap_offset; /** offset of bitmap data */
- unsigned int bpp; /** bits per pixel */
- unsigned int colours; /** number of colours */
- unsigned int *colour_table; /** colour table */
- bool reversed; /** scanlines are top to bottom */
- bool decoded; /** whether the image has been decoded */
- bool ico; /** image is part of an ICO, mask follows */
- unsigned int mask[4]; /** four bitwise mask */
- int shift[4]; /** four bitwise shifts */
- void *bitmap; /** decoded image */
+ bmp_bitmap_callback_vt bitmap_callbacks; /**< callbacks for bitmap functions */
+ unsigned int width; /** width of BMP (valid after _analyse) */
+ unsigned int height; /** heigth of BMP (valid after _analyse) */
+ bool decoded; /** whether the image has been decoded */
+ void *bitmap; /** decoded image */
+ /** Internal members are listed below
+ */
+ unsigned char *bmp_data; /** pointer to BMP data */
+ unsigned int buffer_size; /** total number of bytes of BMP data available */
+ bmp_encoding encoding; /** pixel encoding type */
+ unsigned int bitmap_offset; /** offset of bitmap data */
+ unsigned int bpp; /** bits per pixel */
+ unsigned int colours; /** number of colours */
+ unsigned int *colour_table; /** colour table */
+ bool reversed; /** scanlines are top to bottom */
+ bool ico; /** image is part of an ICO, mask follows */
+ unsigned int mask[4]; /** four bitwise mask */
+ int shift[4]; /** four bitwise shifts */
} bmp_image;
struct ico_image {
@@ -90,20 +93,22 @@ struct ico_image {
};
struct ico_collection {
- unsigned char *ico_data; /** pointer to ICO data */
- unsigned int buffer_size; /** total number of bytes of ICO data available */
unsigned int width; /** width of largest BMP */
unsigned int height; /** heigth of largest BMP */
+ /** Internal members are listed below
+ */
+ unsigned char *ico_data; /** pointer to ICO data */
+ unsigned int buffer_size; /** total number of bytes of ICO data available */
struct ico_image *first;
};
-void bmp_create(bmp_image *gif);
-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);
+void bmp_create(bmp_image *gif, bmp_bitmap_callback_vt *bitmap_callbacks);
+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 ico_analyse(struct ico_collection *ico, bmp_bitmap_callback_vt *bitmap_callbacks);
+bmp_result ico_analyse(struct ico_collection *ico);
struct bmp_image *ico_find(struct ico_collection *ico, int width, int height);
-void ico_finalise(struct ico_collection *ico, bmp_bitmap_callback_vt *bitmap_callbacks);
+void ico_finalise(struct ico_collection *ico);
#endif