X-Git-Url: http://git.draconx.ca/gitweb/liblbx.git/blobdiff_plain/84ff721b88b3c2bc9fa50f97e85cdba5e5d74e8d..ea9655907d37782a2a505caee22f2458058784ee:/src/image.c diff --git a/src/image.c b/src/image.c index a5b8b05..81f66e0 100644 --- a/src/image.c +++ b/src/image.c @@ -51,8 +51,8 @@ struct lbx_image *lbximg_fopen(FILE *f) * If we never find any exceptions, we can replace the assertions with * assumptions. */ - assert(tmp.wtf1 == 0); - assert(tmp.offs == tmp.frames + 1); + _lbx_assert(tmp.wtf1 == 0); + _lbx_assert(tmp.offs == tmp.frames + 1); new = malloc(sizeof *new + tmp.offs * sizeof *new->offsets); if (!new) { @@ -110,8 +110,7 @@ static int _lbx_drawrow(int first, struct lbx_image *img) xval = letohs(xval); img->foff += sizeof xval; /* Ensure that the row fits in the image. */ - if (img->height - img->currenty <= yval - || xval >= img->width || count > img->width - xval) { + if (img->height - img->currenty <= yval || xval >= img->width) { lbx_errno = LBX_EFORMAT; return -1; } @@ -119,14 +118,22 @@ static int _lbx_drawrow(int first, struct lbx_image *img) img->currenty += yval; img->currentx = xval; } else { - count = 0; -/* - count = type; - if (count > img->width - img->currentx) { + if (fread(&xval, sizeof xval, 1, img->f) != 1) goto readerr; + xval = letohs(xval); img->foff += sizeof xval; + + if (img->width - img->currentx <= xval) { lbx_errno = LBX_EFORMAT; return -1; } -*/ + img->currentx += xval; + + count = type; + + } + + if (count > img->width - img->currentx) { + lbx_errno = LBX_EFORMAT; + return -1; } pos = &img->framedata[img->currenty][img->currentx]; @@ -215,6 +222,76 @@ unsigned char **lbximg_getframe(struct lbx_image *img, int frame) return img->framedata; } +int lbximg_loadpalette(FILE *f, struct lbx_colour palette[static 256]) +{ + uint8_t entry[4]; + int i; + + for (i = 0; i < 256; i++) { + if (fread(entry, sizeof entry, 1, f) != 1) { + lbx_errno = (feof(f)) ? LBX_EEOF : -errno; + return -1; + } + + if (entry[0] != 1) { + lbx_errno = LBX_EFORMAT; + return -1; + } + + palette[i] = (struct lbx_colour){ + .red = entry[1] << 2, + .green = entry[2] << 2, + .blue = entry[3] << 2, + }; + } + + return 0; +} + +int +lbximg_getpalette(struct lbx_image *img, struct lbx_colour palette[static 256]) +{ + int index = 0; + size_t rc; + size_t hdrlen = 6*(sizeof img->width) + + (img->offs)*(sizeof *img->offsets); + + uint8_t entry[4]; + + /* Palette data is located right after the header. */ + if (_lbx_fseek(img->f, &img->foff, hdrlen) == -1) + return -1; + + while (img->foff + sizeof entry <= img->offsets[0]) { + rc = fread(entry, 1, sizeof entry, img->f); + img->foff += rc; + + if (rc < sizeof entry) { + goto readerr; + } + + if (entry[0] == 0) { + index++; + } else { + index = entry[0]; + } + + palette[index] = (struct lbx_colour){ + .red = entry[1] << 2, + .green = entry[2] << 2, + .blue = entry[3] << 2, + }; + } + + return 0; +readerr: + if (feof(img->f)) + lbx_errno = LBX_EEOF; + else + lbx_errno = -errno; + return -1; +} + void lbximg_close(struct lbx_image *img) { if (!img) return;