# HG changeset patch # User Matti Hamalainen # Date 1529971741 -10800 # Node ID eb03869a10d3d97adcc5346ef30db2667ef6465c # Parent 2e3f188c6bf022fc25a326b9dc48a52458763b2a Clean up the IFF reader and make it more robust. diff -r 2e3f188c6bf0 -r eb03869a10d3 tools/libgfx.c --- a/tools/libgfx.c Tue Jun 26 03:07:58 2018 +0300 +++ b/tools/libgfx.c Tue Jun 26 03:09:01 2018 +0300 @@ -1401,6 +1401,7 @@ Uint32 size; int count; char idStr[6]; + off_t offs; } DMIFFChunk; @@ -1468,20 +1469,22 @@ } else { + chunk->offs = dmftell(fp); dmMakeIFFChunkIDStr(chunk); return DMERR_OK; } } -static int dmSkipIFFChunkRest(DMResource *fp, const DMIFFChunk *chunk, const Uint32 used) +static int dmSkipIFFChunkRest(DMResource *fp, const DMIFFChunk *chunk) { - if (chunk->size > used) + off_t read = dmftell(fp) - chunk->offs; + if (chunk->size > read) { dmMsg(4, "IFF: Skipping %d bytes (%d of %d consumed)\n", - chunk->size - used, used, chunk->size); + chunk->size - read, read, chunk->size); - if (dmfseek(fp, chunk->size - used, SEEK_CUR) != 0) + if (dmfseek(fp, chunk->size - read, SEEK_CUR) != 0) { return dmError(DMERR_FSEEK, "IFF: Failed to skip chunk end.\n"); @@ -1581,15 +1584,13 @@ } -static int dmDecodeILBMBody(DMResource *fp, DMIFF *iff, DMImage *img, Uint32 *read) +static int dmDecodeILBMBody(DMResource *fp, DMIFF *iff, DMImage *img) { Uint8 *buf; size_t bufLen; int res = DMERR_OK; const int nplanes = iff->bmhd.nplanes; - *read = 0; - // Allocate planar decoding buffer bufLen = ((img->width + 15) / 16) * 2; if ((buf = dmMalloc(bufLen)) == NULL) @@ -1617,8 +1618,6 @@ // Decode bitplane dmDecodeBitPlane(dp, buf, img->width, plane); - - *read += bufLen; } // Read mask data @@ -1641,8 +1640,6 @@ if (!data) dp[xc] = img->ctransp < 0 ? 0 : img->ctransp; } - - *read += bufLen; } } @@ -1652,29 +1649,18 @@ } -static int dmDecodePBMBody(DMResource *fp, DMIFF *iff, DMImage *img, Uint32 *read) +static int dmDecodePBMBody(DMResource *fp, DMIFF *iff, DMImage *img) { - int res = DMERR_OK; - - *read = 0; - - // Decode the chunk for (int yc = 0; yc < img->height; yc++) { - Uint8 *dp = img->data + (yc * img->pitch); - - if (!dmIFFReadOneRow(fp, iff, dp, img->width)) + if (!dmIFFReadOneRow(fp, iff, img->data + (yc * img->pitch), img->width)) { - res = dmError(DMERR_FREAD, - "IFF: Error in reading image row #%d.\n", yc); - goto error; + return dmError(DMERR_FREAD, + "IFF: Error reading PBM image row #%d.\n", yc); } - - *read += img->width; } -error: - return res; + return DMERR_OK; } @@ -1682,7 +1668,7 @@ { DMIFFChunk chunk; DMIFF iff; - Uint32 read, idsig; + Uint32 idsig; BOOL parsed = FALSE, planar; int res = DMERR_OK; @@ -1711,6 +1697,7 @@ while (!parsed && !dmfeof(fp)) { + // Read chunk header if ((res = dmReadIFFChunkHdr(fp, &chunk)) != DMERR_OK) return res; @@ -1756,9 +1743,6 @@ return dmError(DMERR_NOT_SUPPORTED, "IFF: Unsupported features, refusing to load.\n"); } - - if ((res = dmSkipIFFChunkRest(fp, &chunk, sizeof(iff.bmhd))) != DMERR_OK) - return res; break; @@ -1832,16 +1816,16 @@ // Decode the body if (planar) { - if ((res = dmDecodeILBMBody(fp, &iff, *pimg, &read)) != DMERR_OK) + if ((res = dmDecodeILBMBody(fp, &iff, *pimg)) != DMERR_OK) return res; } else { - if ((res = dmDecodePBMBody(fp, &iff, *pimg, &read)) != DMERR_OK) + if ((res = dmDecodePBMBody(fp, &iff, *pimg)) != DMERR_OK) return res; } - if ((res = dmSkipIFFChunkRest(fp, &chunk, read)) != DMERR_OK) + if ((res = dmSkipIFFChunkRest(fp, &chunk)) != DMERR_OK) return res; if (iff.chCMAP.count) @@ -1863,9 +1847,6 @@ return dmError(DMERR_NOT_SUPPORTED, "IFF: HAM files are not supported.\n"); } - - if ((res = dmSkipIFFChunkRest(fp, &chunk, sizeof(Uint32))) != DMERR_OK) - return res; break; @@ -1883,8 +1864,8 @@ break; } - if (chunk.size & 1) - dmfgetc(fp); + if ((res = dmSkipIFFChunkRest(fp, &chunk)) != DMERR_OK) + return res; } // Set colormap after finishing