summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Shaw <jshaw@netsurf-browser.org>2008-01-27 21:37:55 (GMT)
committer James Shaw <jshaw@netsurf-browser.org>2008-01-27 21:37:55 (GMT)
commite8ca4a328486334804d3c4d70e445cb0d6c1fac1 (patch)
tree2d3f9573f8dd3bbf6b297ca5db531e321296902d
parent5494a3040c58613d621fb3028f1bca813b96fc8d (diff)
downloadlibrosprite-e8ca4a328486334804d3c4d70e445cb0d6c1fac1.tar.gz
librosprite-e8ca4a328486334804d3c4d70e445cb0d6c1fac1.tar.bz2
Abstract reading interface to a function ptr and context struct
svn path=/import/jshaw/libsprite/; revision=10011
-rw-r--r--trunk/example.c11
-rw-r--r--trunk/libsprite.c86
-rw-r--r--trunk/libsprite.h12
-rw-r--r--trunk/palette2c.c11
4 files changed, 74 insertions, 46 deletions
diff --git a/trunk/example.c b/trunk/example.c
index ce50ade..317efb2 100644
--- a/trunk/example.c
+++ b/trunk/example.c
@@ -47,15 +47,17 @@ int main(int argc, char *argv[])
char* filename = argv[1];
- FILE* spritefile = fopen(filename, "rb");
- if (spritefile == NULL) {
+ FILE* f = fopen(filename, "rb");
+ if (f == NULL) {
printf("Can't load spritefile %s\n", filename);
exit(EXIT_FAILURE);
}
+ struct rosprite_file_context* ctx = rosprite_create_file_context(f);
+
printf("Loading %s\n", filename);
- struct rosprite_area* sprite_area = rosprite_load_file(spritefile);
+ struct rosprite_area* sprite_area = rosprite_load_file(rosprite_file_reader, ctx);
printf("sprite_count %u\n", sprite_area->sprite_count);
printf("extension_size %u\n", sprite_area->extension_size);
@@ -92,7 +94,8 @@ int main(int argc, char *argv[])
fgetc(stdin);
}
- fclose(spritefile);
+ fclose(f);
+ rosprite_destroy_file_context(ctx);
rosprite_destroy_sprite_area(sprite_area);
return EXIT_SUCCESS;
diff --git a/trunk/libsprite.c b/trunk/libsprite.c
index 9ed3fb1..8c01eb0 100644
--- a/trunk/libsprite.c
+++ b/trunk/libsprite.c
@@ -13,6 +13,9 @@
/* reverse the byte order of a word such that 0xAABBCCDD becomes 0xDDCCBBAA */
#define BSWAP(word) (((word & (0x000000ff)) << 24) | ((word & 0x0000ff00) << 8) | ((word & 0x00ff0000) >> 8) | ((word & 0xff000000) >> 24))
+#define ROSPRITE_OK 0;
+#define ROSPRITE_READ_FAILED 1;
+
struct rosprite_header {
uint32_t width_words; /* width in words */
/* height defined in sprite struct */
@@ -33,6 +36,10 @@ struct rosprite_mask_state {
uint32_t bpp;
};
+struct rosprite_file_context {
+ FILE* f;
+};
+
static const struct rosprite_mode oldmodes[] = {
/*0*/{ .colorbpp = 1, .maskbpp = 1, .mask_width = 1, .xdpi = 90, .ydpi = 45, .color_model = rosprite_rgb },
/*1*/{ .colorbpp = 2, .maskbpp = 1, .mask_width = 2, .xdpi = 45, .ydpi = 45, .color_model = rosprite_rgb },
@@ -180,27 +187,34 @@ static const uint32_t sprite_8bpp_palette[] = {
0xccccccff, 0xddddddff, 0xeeeeeeff, 0xffffffff
};
-uint32_t sprite_read_word(FILE* stream)
+struct rosprite_file_context* rosprite_create_file_context(FILE* f)
{
- unsigned char b[4];
- size_t bytesRead = fread(b, 1, 4, stream);
-
- if (bytesRead != 4) {
- printf("Unexpected EOF\n"); /* TODO, have better error handling, don't exit here */
- exit(EXIT_FAILURE);
- }
+ struct rosprite_file_context* ctx = malloc(sizeof(struct rosprite_file_context));
+ ctx->f = f;
+ return ctx;
+}
- return BTUINT(b);
+void rosprite_destroy_file_context(struct rosprite_file_context* ctx)
+{
+ free(ctx);
+}
+
+int rosprite_file_reader(uint8_t* buf, size_t count, void* ctx)
+{
+ return fread(buf, 1 /*size*/, count, ((struct rosprite_file_context*) ctx)->f);
}
-void sprite_read_bytes(FILE* stream, uint8_t* buf, size_t count)
+/* TODO: get rid of this method */
+uint32_t sprite_read_word(reader reader, void* ctx)
{
- size_t bytesRead = fread(buf, 1, count, stream);
+ unsigned char b[4];
- if (bytesRead != count) {
- printf("Unexpected EOF\n");
+ if (reader(b, 4, ctx) < 4) {
+ printf("Unexpected EOF\n"); /* TODO, have better error handling, don't exit here */
exit(EXIT_FAILURE);
}
+
+ return BTUINT(b);
}
static struct rosprite_mode sprite_get_mode(uint32_t spriteMode)
@@ -514,26 +528,26 @@ static void sprite_load_low_color(uint8_t* image_in, uint8_t* mask, struct rospr
if (sprite->has_mask) free(mask_state);
}
-struct rosprite* sprite_load_sprite(FILE* spritefile)
+struct rosprite* sprite_load_sprite(reader reader, void* ctx)
{
- uint32_t nextSpriteOffset = sprite_read_word(spritefile);
+ uint32_t nextSpriteOffset = sprite_read_word(reader, ctx);
struct rosprite* sprite = malloc(sizeof(struct rosprite));
struct rosprite_header* header = malloc(sizeof(struct rosprite_header));
- sprite_read_bytes(spritefile, sprite->name, 12);
+ reader(sprite->name, 12, ctx);
sprite->name[12] = '\0';
- header->width_words = sprite_read_word(spritefile) + 1; /* file has width - 1 and height - 1 */
- sprite->height = sprite_read_word(spritefile) + 1;
- header->first_used_bit = sprite_read_word(spritefile); /* old format only (spriteType = 0) */
- header->last_used_bit = sprite_read_word(spritefile);
+ header->width_words = sprite_read_word(reader, ctx) + 1; /* file has width - 1 and height - 1 */
+ sprite->height = sprite_read_word(reader, ctx) + 1;
+ header->first_used_bit = sprite_read_word(reader, ctx); /* old format only (spriteType = 0) */
+ header->last_used_bit = sprite_read_word(reader, ctx);
- uint32_t imageOffset = sprite_read_word(spritefile);
+ uint32_t imageOffset = sprite_read_word(reader, ctx);
assert(imageOffset >= 44); /* should never be smaller than the size of the header) */
- uint32_t maskOffset = sprite_read_word(spritefile);
- uint32_t spriteModeWord = sprite_read_word(spritefile);
+ uint32_t maskOffset = sprite_read_word(reader, ctx);
+ uint32_t spriteModeWord = sprite_read_word(reader, ctx);
sprite->mode = sprite_get_mode(spriteModeWord);
@@ -569,8 +583,8 @@ struct rosprite* sprite_load_sprite(FILE* spritefile)
* PRM1-730
*/
for (uint32_t j = 0; j < paletteEntries; j++) {
- uint32_t word1 = sprite_read_word(spritefile);
- uint32_t word2 = sprite_read_word(spritefile);
+ uint32_t word1 = sprite_read_word(reader, ctx);
+ uint32_t word2 = sprite_read_word(reader, ctx);
assert(word1 == word2); /* TODO: if they aren't, START FLASHING */
/* swap rr and bb parts -- PRM1-731 */
@@ -580,12 +594,12 @@ struct rosprite* sprite_load_sprite(FILE* spritefile)
}
uint8_t* image = malloc(header->image_size);
- sprite_read_bytes(spritefile, image, header->image_size);
+ reader(image, header->image_size, ctx);
uint8_t* mask = NULL;
if (sprite->has_mask) {
mask = malloc(header->mask_size);
- sprite_read_bytes(spritefile, mask, header->mask_size);
+ reader(mask, header->mask_size, ctx);
}
/* sanity check image_size */
@@ -604,25 +618,25 @@ struct rosprite* sprite_load_sprite(FILE* spritefile)
return sprite;
}
-struct rosprite_area* rosprite_load_file(FILE* f)
+struct rosprite_area* rosprite_load_file(reader reader, void* ctx)
{
struct rosprite_area* sprite_area = malloc(sizeof(struct rosprite_area));
- sprite_area->sprite_count = sprite_read_word(f);
+ sprite_area->sprite_count = sprite_read_word(reader, ctx);
- uint32_t firstSpriteOffset = sprite_read_word(f);
- /*uint32_t firstFreeWordOffset = */sprite_read_word(f); /* TODO: use this for some sanity checking? */
+ uint32_t firstSpriteOffset = sprite_read_word(reader, ctx);
+ /*uint32_t firstFreeWordOffset = */sprite_read_word(reader, ctx); /* TODO: use this for some sanity checking? */
sprite_area->extension_size = 16 - firstSpriteOffset;
sprite_area->extension_words = NULL;
if (sprite_area->extension_size > 0) {
sprite_area->extension_words = malloc(sprite_area->extension_size); /* where to free() this? */
- sprite_read_bytes(f, sprite_area->extension_words, (size_t) (sprite_area->extension_size));
+ reader(sprite_area->extension_words, (size_t) (sprite_area->extension_size), ctx); /* TODO: check return value */
}
sprite_area->sprites = malloc(sizeof(struct rosprite*) * sprite_area->sprite_count); /* allocate array of pointers */
for (uint32_t i = 0; i < sprite_area->sprite_count; i++) {
- struct rosprite* sprite = sprite_load_sprite(f);
+ struct rosprite* sprite = sprite_load_sprite(reader, ctx);
sprite_area->sprites[i] = sprite;
}
@@ -643,7 +657,7 @@ void rosprite_destroy_sprite_area(struct rosprite_area* sprite_area)
free(sprite_area);
}
-struct rosprite_palette* rosprite_load_palette(FILE* f)
+struct rosprite_palette* rosprite_load_palette(reader reader, void* ctx)
{
/* Palette file is in groups of 6 bytes, each is a VDU 19 (set palette)
* http://www.drobe.co.uk/show_manual.php?manual=/sh-cgi?manual=Vdu%26page=19 */
@@ -656,7 +670,7 @@ struct rosprite_palette* rosprite_load_palette(FILE* f)
uint32_t c = 0;
uint8_t b[6];
- size_t bytesRead = fread(&b, 1, 6, f); /* TODO: make this use a pluggable read function */
+ unsigned int bytesRead = reader(b, 6, ctx);
assert(bytesRead % 6 == 0);
while (bytesRead == 6) {
assert(b[0] == 19); /* VDU 19 */
@@ -672,7 +686,7 @@ struct rosprite_palette* rosprite_load_palette(FILE* f)
assert(c <= 256);
}
- bytesRead = fread(&b, 1, 6, f);
+ bytesRead = reader(b, 6, ctx);
assert(bytesRead % 6 == 0);
}
diff --git a/trunk/libsprite.h b/trunk/libsprite.h
index 3c33fb8..e8bcdee 100644
--- a/trunk/libsprite.h
+++ b/trunk/libsprite.h
@@ -7,6 +7,10 @@
typedef enum { rosprite_rgb, rosprite_cmyk } rosprite_color_model;
+typedef int (*reader)(uint8_t* buf, size_t count, void* ctx);
+
+struct rosprite_file_context;
+
struct rosprite_area {
uint32_t extension_size; /* size of extension_words in bytes */
uint8_t* extension_words;
@@ -46,10 +50,14 @@ struct rosprite {
uint32_t* image; /* image data in 0xRRGGBBAA words */
};
-struct rosprite_area* rosprite_load_file(FILE* f);
+struct rosprite_file_context* rosprite_create_file_context(FILE* f);
+void rosprite_destroy_file_context(struct rosprite_file_context* ctx);
+int rosprite_file_reader(uint8_t* buf, size_t count, void* ctx);
+
+struct rosprite_area* rosprite_load_file(reader reader, void* ctx);
void rosprite_destroy_sprite_area(struct rosprite_area *);
-struct rosprite_palette* rosprite_load_palette(FILE* f);
+struct rosprite_palette* rosprite_load_palette(reader reader, void* ctx);
void rosprite_destroy_palette(struct rosprite_palette *);
diff --git a/trunk/palette2c.c b/trunk/palette2c.c
index 663fcb0..5f668c0 100644
--- a/trunk/palette2c.c
+++ b/trunk/palette2c.c
@@ -12,20 +12,23 @@ int main(int argc, char *argv[])
char* filename = argv[1];
- FILE* palettefile = fopen(filename, "rb");
- if (palettefile == NULL) {
+ FILE* f = fopen(filename, "rb");
+ if (f == NULL) {
printf("Can't load palettefile %s\n", filename);
exit(EXIT_FAILURE);
}
+
+ struct rosprite_file_context* ctx = rosprite_create_file_context(f);
- struct rosprite_palette* palette = rosprite_load_palette(palettefile);
+ struct rosprite_palette* palette = rosprite_load_palette(rosprite_file_reader, ctx);
for (uint32_t i = 0; i < palette->size; i++) {
printf("0x%x, ", palette->palette[i]);
}
- fclose(palettefile);
+ fclose(f);
+ rosprite_destroy_file_context(ctx);
rosprite_destroy_palette(palette);
return EXIT_SUCCESS;