# HG changeset patch # User Matti Hamalainen # Date 1543871158 -7200 # Node ID 6dfbe976d7402a04649e4d568080d3f01974bbad # Parent aa8df4f1b785cf49ec569811eed81e6291687f7f Implement basic initial support for IFF ACBM format images. diff -r aa8df4f1b785 -r 6dfbe976d740 tools/libgfx.c --- a/tools/libgfx.c Mon Dec 03 19:24:32 2018 +0200 +++ b/tools/libgfx.c Mon Dec 03 23:05:58 2018 +0200 @@ -1454,6 +1454,8 @@ #define IFF_ID_CMAP 0x434D4150 // "CMAP" #define IFF_ID_BODY 0x424F4459 // "BODY" #define IFF_ID_CAMG 0x43414D47 // "CAMG" +#define IFF_ID_ACBM 0x4143424D // "ACBM" +#define IFF_ID_ABIT 0x41424954 // "ABIT" #define IFF_MASK_NONE 0 #define IFF_MASK_HAS_MASK 1 @@ -1499,6 +1501,7 @@ Uint32 camg; int ncolors; DMColor *pal; + Uint32 idsig; } DMIFF; @@ -1577,7 +1580,7 @@ } -static int dmCheckIFFChunk(DMIFFChunk *dest, DMIFFChunk *chunk, +static int dmCheckIFFChunk(DMIFFChunk *dest, const DMIFFChunk *chunk, const BOOL multi, const Uint32 minSize) { if (dest->count > 0 && !multi) @@ -1664,22 +1667,53 @@ int res = DMERR_OK; const int nplanes = iff->bmhd.nplanes; - if (iff->planar) + if (iff->idsig == IFF_ID_ILBM) { - // Allocate planar decoding buffer bufLen = ((img->width + 15) / 16) * 2; - if ((buf = dmMalloc(bufLen)) == NULL) - return DMERR_MALLOC; - dmMsg(2, "IFF: Line / plane row size %d bytes.\n", bufLen); + } + else + if (iff->idsig == IFF_ID_ACBM) + { + bufLen = (img->width * img->height) / 8; + dmMsg(2, "IFF: Plane buffer size %d bytes.\n", bufLen); + } + + if (bufLen > 0 && (buf = dmMalloc(bufLen)) == NULL) + return DMERR_MALLOC; // Decode the chunk + if (iff->idsig == IFF_ID_ACBM) + { + for (int plane = 0; plane < nplanes; plane++) + { + if (!dmf_read_str(fp, buf, bufLen)) + { + res = dmError(DMERR_FREAD, + "IFF: Error in reading image plane #%d.\n", + plane); + goto out; + } + + for (int yc = 0; yc < img->height; yc++) + { + Uint8 *dp = img->data + (yc * img->pitch); + for (int xc = 0; xc < img->width; xc++) + { + const Uint8 data = dmDecodeBit(buf + yc * 40, xc); + if (data) + dp[xc] |= 1 << plane; + } + } + } + } + else for (int yc = 0; yc < img->height; yc++) { Uint8 *dp = img->data + (yc * img->pitch); - if (iff->planar) + if (iff->idsig == IFF_ID_ILBM) { // Clear planar decoding buffer dmMemset(dp, 0, img->pitch); @@ -1723,6 +1757,7 @@ } } else + if (iff->idsig == IFF_ID_PBM) { if (!dmIFFReadOneRow(fp, iff, dp, img->width)) { @@ -1743,7 +1778,6 @@ { DMIFFChunk chunk; DMIFF iff; - Uint32 idsig; BOOL parsed = FALSE; int res = DMERR_OK; @@ -1761,17 +1795,18 @@ } // Check IFF ILBM/PBM signature - if (!dmf_read_be32(fp, &idsig) || - (idsig != IFF_ID_ILBM && idsig != IFF_ID_PBM)) + if (!dmf_read_be32(fp, &iff.idsig) || + (iff.idsig != IFF_ID_ILBM && + iff.idsig != IFF_ID_PBM && + iff.idsig != IFF_ID_ACBM)) { return dmError(DMERR_INVALID_DATA, - "IFF: Not a IFF ILBM/PBM file.\n"); + "IFF: Not a IFF ILBM/PBM/ACBM file.\n"); } - iff.planar = (idsig == IFF_ID_ILBM); - dmMsg(3, "IFF: FORM is %s format image, with size %d bytes.\n", - iff.planar ? "ILBM" : "PBM", chunk.size); + iff.idsig == IFF_ID_ILBM ? "ILBM" : (iff.idsig == IFF_ID_PBM ? "PBM" : "ACBM"), + chunk.size); while (!parsed && !dmfeof(fp)) { @@ -1865,6 +1900,7 @@ break; case IFF_ID_BODY: + case IFF_ID_ABIT: // Check for multiple occurences of BODY if ((res = dmCheckIFFChunk(&iff.chBODY, &chunk, FALSE, 1)) != DMERR_OK) return res; @@ -1873,10 +1909,10 @@ if (!iff.chBMHD.count) { return dmError(DMERR_INVALID_DATA, - "IFF: BODY chunk before BMHD?\n"); + "IFF: %s chunk before BMHD?\n", chunk.idStr); } - dmMsg(2, "IFF: BODY chunk size %d bytes\n", chunk.size); + dmMsg(2, "IFF: %s chunk size %d bytes\n", chunk.idStr, chunk.size); // Allocate image if ((*pimg = dmImageAlloc(iff.bmhd.w, iff.bmhd.h, @@ -1902,7 +1938,6 @@ parsed = TRUE; break; - case IFF_ID_CAMG: if (!dmf_read_be32(fp, &iff.camg)) { @@ -1950,7 +1985,7 @@ if (iff.camg & IFF_CAMG_HALFBRITE) { void *ptmp; - if (!iff.planar) + if (iff.idsig != IFF_ID_ILBM) { dmErrorMsg("IFF: Non-planar PBM file with Halfbrite enabled! This might not work.\n"); } @@ -2161,7 +2196,6 @@ int dmWriteIFFImage(DMResource *fp, const DMImage *img, const DMImageConvSpec *cpspec) { - Uint32 idsig; DMIFF iff; Uint8 *buf = NULL; size_t bufLen; @@ -2196,7 +2230,7 @@ iff.bmhd.compression = spec->compression ? IFF_COMP_BYTERUN1 : IFF_COMP_NONE; iff.bmhd.transp = (img->ctransp >= 0 && spec->mask == IFF_MASK_TRANSP) ? img->ctransp : 0xffff; iff.bmhd.nplanes = spec->nplanes; - idsig = spec->planar ? IFF_ID_ILBM : IFF_ID_PBM; + iff.idsig = spec->planar ? IFF_ID_ILBM : IFF_ID_PBM; dmMsg(2, "IFF: nplanes=%d, comp=%d, mask=%d\n", iff.bmhd.nplanes, iff.bmhd.compression, iff.bmhd.masking); @@ -2206,7 +2240,7 @@ goto out; // Write IFF ILBM/PBM signature - if (!dmf_write_be32(fp, idsig)) + if (!dmf_write_be32(fp, iff.idsig)) { res = dmError(DMERR_FWRITE, "IFF: Error writing %s signature.\n", @@ -2392,7 +2426,7 @@ fmtProbePCX, dmReadPCXImage, dmWritePCXImage, }, { - "iff", "IFF ILBM / PBM", + "iff", "IFF ILBM/PBM/ACBM", DM_IMGFMT_IFF, DM_FMT_RDWR, fmtProbeIFF, dmReadIFFImage, dmWriteIFFImage, },