summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Shaw <jshaw@netsurf-browser.org>2007-11-23 16:50:41 +0000
committerJames Shaw <jshaw@netsurf-browser.org>2007-11-23 16:50:41 +0000
commit56bbfb5c6fbf7699c40e754a48d13d119483219b (patch)
treee7839074e49f018444c1f9137f6f369d09c11507
parent4478f2a06a10b2d0c1d74fcfc17d7f2ecdcc3fb0 (diff)
downloadlibrosprite-56bbfb5c6fbf7699c40e754a48d13d119483219b.tar.gz
librosprite-56bbfb5c6fbf7699c40e754a48d13d119483219b.tar.bz2
Get main() using sprite_area. Get low_colour image parsing working.
svn path=/import/jshaw/libsprite/; revision=9984
-rw-r--r--trunk/libsprite.c183
1 files changed, 122 insertions, 61 deletions
diff --git a/trunk/libsprite.c b/trunk/libsprite.c
index fe61a45..d3ce317 100644
--- a/trunk/libsprite.c
+++ b/trunk/libsprite.c
@@ -9,10 +9,10 @@
#define BTUINT(b) (b[0] | (b[1] << 8) | (b[2] << 16) | (b[3] << 24))
-struct sprite_area_control_block {
- uint32_t spriteCount;
- uint32_t extensionBytes; /* size of extensionWords byte array */
- unsigned char* extensionWords;
+struct sprite_area {
+ uint32_t sprite_count;
+ uint32_t extension_size; /* size of extension_words in bytes */
+ uint8_t* extension_words;
};
struct sprite_mode {
@@ -31,41 +31,21 @@ struct sprite {
uint32_t* palette;
uint32_t width; /* width and height in _pixels_ */
uint32_t height;
+ uint32_t* image;
};
struct sprite_header {
- uint32_t width_words; /* width and height in words */
- uint32_t height_words;
+ uint32_t width_words; /* width in words */
+ /* height defined in sprite struct */
uint32_t first_used_bit; /* old format only (spriteType = 0) */
uint32_t last_used_bit;
+ uint32_t image_size; /* bytes */
};
-uint32_t sprite_read_word(FILE* stream)
-{
- 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);
- }
+static struct sprite_mode oldmodes[256];
- return BTUINT(b);
-}
-
-void sprite_read_bytes(FILE* stream, uint8_t* buf, size_t count)
+void sprite_init()
{
- size_t bytesRead = fread(buf, 1, count, stream);
-
- if (bytesRead != count) {
- printf("Unexpected EOF\n");
- exit(EXIT_FAILURE);
- }
-}
-
-struct sprite_mode* sprite_get_mode(uint32_t spriteMode)
-{
- static struct sprite_mode oldmodes[256];
for (uint32_t i = 0; i < 256; i++) {
oldmodes[i].colorbpp = 0;
oldmodes[i].xdpi = 0;
@@ -122,7 +102,33 @@ struct sprite_mode* sprite_get_mode(uint32_t spriteMode)
for (uint32_t i = 0; i < 256; i++) {
oldmodes[i].maskbpp = oldmodes[i].colorbpp;
}
+}
+
+uint32_t sprite_read_word(FILE* stream)
+{
+ 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);
+ }
+
+ return BTUINT(b);
+}
+void sprite_read_bytes(FILE* stream, uint8_t* buf, size_t count)
+{
+ size_t bytesRead = fread(buf, 1, count, stream);
+
+ if (bytesRead != count) {
+ printf("Unexpected EOF\n");
+ exit(EXIT_FAILURE);
+ }
+}
+
+struct sprite_mode* sprite_get_mode(uint32_t spriteMode)
+{
struct sprite_mode* mode = malloc(sizeof(struct sprite_mode));
uint32_t spriteType = (spriteMode & 0x78000000) >> 27; /* preserve bits 27-30 only */
@@ -162,11 +168,49 @@ struct sprite_mode* sprite_get_mode(uint32_t spriteMode)
return mode;
}
-void sprite_load_image(uint8_t* image, uint8_t* mask, struct sprite* sprite, struct sprite_header* header)
+void sprite_load_high_color(uint8_t* image, uint8_t* mask, struct sprite* sprite, struct sprite_header* header)
{
image = image; mask = mask; sprite = sprite; header = header;
}
+void sprite_load_low_color(uint8_t* image_in, uint8_t* mask, struct sprite* sprite, struct sprite_header* header)
+{
+ mask = mask; /* TODO: mask */
+ /* TODO: left/right wastage */
+
+ sprite->image = malloc(sprite->width * sprite->height * 4); /* all image data is 32bpp going out */
+
+ uint32_t currentByteIndex = 0; /* only for standalone test -- fread() will maintain this */
+
+ uint32_t bpp = sprite->mode->colorbpp;
+
+ uint32_t bitmask = (1 << bpp) - 1; /* creates a mask of 1s that is bpp bits wide */
+ uint8_t currentbyte = image_in[currentByteIndex++];
+
+ for (uint32_t y = 0; y < sprite->height; y++) {
+ for (uint32_t x = 0; x < header->width_words * 32 /* 32 bits per word */; x+=bpp) {
+
+ bool waste = false;
+ if (x >= header->width_words * 32 - header->last_used_bit - 1) {
+ waste = true;
+ } /* TODO: left wastage */
+
+ uint32_t offset_into_byte = x % 8;
+
+ if (!waste) {
+ uint32_t pixel = (currentbyte & (bitmask << offset_into_byte)) >> offset_into_byte;
+ printf("%2x", pixel);
+ }
+
+ if (offset_into_byte + bpp == 8) {
+ /* TODO: assert not exceeding image size */
+ currentbyte = image_in[currentByteIndex++];
+ }
+ }
+ printf("\n");
+ }
+}
+
struct sprite* sprite_load_sprite(FILE* spritefile)
{
uint32_t nextSpriteOffset = sprite_read_word(spritefile);
@@ -178,9 +222,10 @@ struct sprite* sprite_load_sprite(FILE* spritefile)
sprite->name[12] = '\0';
header->width_words = sprite_read_word(spritefile) + 1; /* file has width - 1 and height - 1 */
- header->height_words = sprite_read_word(spritefile) + 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);
+ LOGDBG("first: %u last: %u\n", header->first_used_bit, header->last_used_bit);
uint32_t imageOffset = sprite_read_word(spritefile);
assert(imageOffset >= 44); /* should never be smaller than the size of the header) */
@@ -193,22 +238,30 @@ struct sprite* sprite_load_sprite(FILE* spritefile)
assert(sprite->mode->xdpi > 0);
assert(sprite->mode->ydpi > 0);
+ /* TODO l/r wastage */
+
+ assert((header->last_used_bit + 1) % sprite->mode->colorbpp == 0);
+ /*assert(header->width_words % sprite->mode->colorbpp == 0);*/
+ sprite->width = (header->width_words * 32 / sprite->mode->colorbpp) - ((header->last_used_bit + 1) / sprite->mode->colorbpp);
+
sprite->palettesize = imageOffset - 44;
sprite->haspalette = (sprite->palettesize > 0);
- uint32_t imageSize;
+ uint32_t image_size;
uint32_t maskSize;
if (imageOffset == maskOffset) {
sprite->hasmask = false;
- imageSize = nextSpriteOffset - 44 - sprite->palettesize;
+ image_size = nextSpriteOffset - 44 - sprite->palettesize;
maskSize = 0;
} else {
sprite->hasmask = true;
- imageSize = maskOffset - imageOffset;
- maskSize = nextSpriteOffset - 44 - sprite->palettesize - imageSize;
+ image_size = maskOffset - imageOffset;
+ maskSize = nextSpriteOffset - 44 - sprite->palettesize - image_size;
}
+ header->image_size = image_size;
+
if (sprite->hasmask) LOGDBG("maskSize %u\n", maskSize);
uint32_t* palette = NULL;
@@ -218,10 +271,10 @@ struct sprite* sprite_load_sprite(FILE* spritefile)
uint32_t paletteEntries = sprite->palettesize / 8;
/* Each palette entry is two words big
- * The second word is a duplicate of the first
- * I think this is in case you ever wanted flashing colours
- * PRM1-730
- */
+ * The second word is a duplicate of the first
+ * I think this is in case you ever wanted flashing colours
+ * PRM1-730
+ */
for (uint32_t j = 0; j < paletteEntries; j++) {
uint32_t word1 = sprite_read_word(spritefile);
uint32_t word2 = sprite_read_word(spritefile);
@@ -231,16 +284,20 @@ struct sprite* sprite_load_sprite(FILE* spritefile)
}
}
- uint8_t* image = malloc(imageSize);
- sprite_read_bytes(spritefile, image, imageSize);
+ uint8_t* image = malloc(image_size);
+ sprite_read_bytes(spritefile, image, image_size);
uint8_t* mask = malloc(maskSize);
sprite_read_bytes(spritefile, mask, maskSize);
/* sanity check imageSize */
- assert((header->width_words) * 4 * (header->height_words) == imageSize);
+ assert((header->width_words) * 4 * (sprite->height) == header->image_size);
/* TODO: sanity check maskSize */
- sprite_load_image(image, mask, sprite, header);
+ if (sprite->mode->colorbpp > 8) {
+ sprite_load_high_color(image, mask, sprite, header);
+ } else {
+ sprite_load_low_color(image, mask, sprite, header);
+ }
free(image);
free(mask);
@@ -265,29 +322,33 @@ int main(int argc, char *argv[])
}
LOGDBG("Loading %s\n", filename);
+ sprite_init();
+
+ struct sprite_area* sprite_area = malloc(sizeof(struct sprite_area));
+
+ sprite_area->sprite_count = sprite_read_word(spritefile);
- uint32_t spriteCount = sprite_read_word(spritefile);
uint32_t firstSpriteOffset = sprite_read_word(spritefile);
- uint32_t firstFreeWordOffset = sprite_read_word(spritefile);
- uint32_t extensionByteCount = 16 - firstSpriteOffset;
-
- LOGDBG("spriteCount %u\n", spriteCount);
- LOGDBG("firstSpriteOffset %u\n", firstSpriteOffset);
- LOGDBG("firstFreeWordOffset %u\n", firstFreeWordOffset);
- LOGDBG("extensionByteCount %u\n", extensionByteCount);
-
- unsigned char* extensionWords = NULL;
- if (extensionByteCount > 0) {
- extensionWords = malloc(extensionByteCount); /* where to free() this? */
- sprite_read_bytes(spritefile, extensionWords, extensionByteCount);
+ /*uint32_t firstFreeWordOffset = */sprite_read_word(spritefile); /* TODO: use this for some sanity checking? */
+ sprite_area->extension_size = 16 - firstSpriteOffset;
+
+ LOGDBG("sprite_count %u\n", sprite_area->sprite_count);
+ LOGDBG("extension_size %u\n", sprite_area->extension_size);
+
+ 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(spritefile, sprite_area->extension_words, (size_t) (sprite_area->extension_size));
}
- for (uint32_t i = 0; i < spriteCount; i++) {
+ for (uint32_t i = 0; i < sprite_area->sprite_count; i++) {
struct sprite* sprite = sprite_load_sprite(spritefile);
LOGDBG("\nname %s\n", sprite->name);
- LOGDBG("\tcolorbpp %u\n", sprite->mode->colorbpp);
- LOGDBG("\txdpi %u\n", sprite->mode->xdpi);
- LOGDBG("\tydpi %u\n", sprite->mode->ydpi);
+ LOGDBG("colorbpp %u\n", sprite->mode->colorbpp);
+ LOGDBG("xdpi %u\n", sprite->mode->xdpi);
+ LOGDBG("ydpi %u\n", sprite->mode->ydpi);
+ LOGDBG("width %u px\n", sprite->width);
+ LOGDBG("height %u px\n", sprite->height);
LOGDBG("hasPalette %s\n", sprite->haspalette ? "YES" : "NO");
if (sprite->haspalette) LOGDBG("paletteSize %u\n", sprite->palettesize);