The pal (formerly wtf2) value indicates the presence of a palette: 0x1000 if
present; 0 otherwise. Then, immediately following the offsets comes the
palette header: 2 bytes always zero, 2 bytes for the number of entries.
Entries are sequential starting from zero.
This makes the logo images work.
struct lbx_image {
uint16_t width, height;
struct lbx_image {
uint16_t width, height;
if (fread(&tmp.wtf1, sizeof tmp.wtf1, 1, f) != 1) goto readerr;
if (fread(&tmp.offs, sizeof tmp.offs, 1, f) != 1) goto readerr;
if (fread(&tmp.frames, sizeof tmp.frames, 1, f) != 1) goto readerr;
if (fread(&tmp.wtf1, sizeof tmp.wtf1, 1, f) != 1) goto readerr;
if (fread(&tmp.offs, sizeof tmp.offs, 1, f) != 1) goto readerr;
if (fread(&tmp.frames, sizeof tmp.frames, 1, f) != 1) goto readerr;
- if (fread(&tmp.wtf2, sizeof tmp.wtf2, 1, f) != 1) goto readerr;
+ if (fread(&tmp.pal, sizeof tmp.pal, 1, f) != 1) goto readerr;
tmp.width = letohs(tmp.width); tmp.foff += sizeof tmp.width;
tmp.height = letohs(tmp.height); tmp.foff += sizeof tmp.height;
tmp.wtf1 = letohs(tmp.wtf1); tmp.foff += sizeof tmp.wtf1;
tmp.offs = letohs(tmp.offs); tmp.foff += sizeof tmp.offs;
tmp.frames = letohs(tmp.frames); tmp.foff += sizeof tmp.frames;
tmp.width = letohs(tmp.width); tmp.foff += sizeof tmp.width;
tmp.height = letohs(tmp.height); tmp.foff += sizeof tmp.height;
tmp.wtf1 = letohs(tmp.wtf1); tmp.foff += sizeof tmp.wtf1;
tmp.offs = letohs(tmp.offs); tmp.foff += sizeof tmp.offs;
tmp.frames = letohs(tmp.frames); tmp.foff += sizeof tmp.frames;
- tmp.wtf2 = letohs(tmp.wtf2); tmp.foff += sizeof tmp.wtf2;
+ tmp.pal = letohs(tmp.pal); tmp.foff += sizeof tmp.pal;
/* For some reason, the format seems to need this. */
tmp.offs++;
tmp.frames++;
/* For some reason, the format seems to need this. */
tmp.offs++;
tmp.frames++;
+ /* Format constraints. */
if (tmp.offs <= tmp.frames) {
lbx_errno = LBX_EFORMAT;
return NULL;
if (tmp.offs <= tmp.frames) {
lbx_errno = LBX_EFORMAT;
return NULL;
*/
_lbx_assert(tmp.wtf1 == 0);
_lbx_assert(tmp.offs == tmp.frames + 1);
*/
_lbx_assert(tmp.wtf1 == 0);
_lbx_assert(tmp.offs == tmp.frames + 1);
+ _lbx_assert(tmp.pal == 0 || tmp.pal == 0x1000);
new = malloc(sizeof *new + tmp.offs * sizeof *new->offsets);
if (!new) {
new = malloc(sizeof *new + tmp.offs * sizeof *new->offsets);
if (!new) {
int
lbximg_getpalette(struct lbx_image *img, struct lbx_colour palette[static 256])
{
int
lbximg_getpalette(struct lbx_image *img, struct lbx_colour palette[static 256])
{
+ size_t hdrlen = 6*(sizeof img->pal)+(img->offs)*(sizeof *img->offsets);
+ unsigned int i;
- size_t hdrlen = 6*(sizeof img->width)
- + (img->offs)*(sizeof *img->offsets);
-
- uint8_t entry[4];
+
+ uint16_t zero, count;
+ uint8_t entry[4];
+
+ /* Do nothing if the image doesn't have embedded palette data. */
+ if (img->pal == 0)
+ return 0;
/* Palette data is located right after the header. */
if (_lbx_fseek(img->f, &img->foff, hdrlen) == -1)
return -1;
/* 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]) {
+ /* Palette header */
+ if (fread(&zero, sizeof zero, 1, img->f) != 1) goto readerr;
+ if (fread(&count, sizeof count, 1, img->f) != 1) goto readerr;
+ zero = letohs(zero); img->foff += sizeof zero;
+ count = letohs(count); img->foff += sizeof count;
+
+ if (zero != 0 || count > 256) {
+ lbx_errno = LBX_EFORMAT;
+ return -1;
+ }
+
+ if (hdrlen + 2*(sizeof zero) + count*(sizeof entry) > img->offsets[0]) {
+ lbx_errno = LBX_EFORMAT;
+ return -1;
+ }
+
+ for (i = 0; i < count; i++) {
rc = fread(entry, 1, sizeof entry, img->f);
img->foff += rc;
rc = fread(entry, 1, sizeof entry, img->f);
img->foff += rc;
- if (entry[0] == 0) {
- index++;
- if (index >= 256) {
- lbx_errno = LBX_EFORMAT;
- return -1;
- }
- } else {
- index = entry[0];
+ if (entry[0] != 0) {
+ lbx_errno = LBX_EFORMAT;
+ return -1;
- palette[index] = (struct lbx_colour){
+ palette[i] = (struct lbx_colour){
.red = entry[1] << 2,
.green = entry[2] << 2,
.blue = entry[3] << 2,
.red = entry[1] << 2,
.green = entry[2] << 2,
.blue = entry[3] << 2,
- if (feof(img->f))
- lbx_errno = LBX_EEOF;
- else
- lbx_errno = -errno;
+ lbx_errno = feof(img->f) ? LBX_EEOF : -errno;