comparison tools/libgfx.c @ 1892:cbc911ffd21e

Rename ILBM functions to IFF, which is more approriate as we support both ILBM and PBM variants of the IFF images.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 25 Jun 2018 19:36:26 +0300
parents 297aa8f0ca7f
children 2e3f188c6bf0
comparison
equal deleted inserted replaced
1891:91b80990043c 1892:cbc911ffd21e
1426 int ncolors; 1426 int ncolors;
1427 DMColor *pal; 1427 DMColor *pal;
1428 } DMIFF; 1428 } DMIFF;
1429 1429
1430 1430
1431 static int fmtProbeILBM(const Uint8 *buf, const size_t len) 1431 static int fmtProbeIFF(const Uint8 *buf, const size_t len)
1432 { 1432 {
1433 if (len > 32 && 1433 if (len > 32 &&
1434 buf[ 0] == 'F' && buf[ 1] == 'O' && 1434 buf[ 0] == 'F' && buf[ 1] == 'O' &&
1435 buf[ 2] == 'R' && buf[ 3] == 'M' && ( 1435 buf[ 2] == 'R' && buf[ 3] == 'M' && (
1436 (buf[ 8] == 'I' && buf[ 9] == 'L' && buf[10] == 'B' && buf[11] == 'M') || 1436 (buf[ 8] == 'I' && buf[ 9] == 'L' && buf[10] == 'B' && buf[11] == 'M') ||
1462 { 1462 {
1463 if (!dmf_read_be32(fp, &chunk->id) || 1463 if (!dmf_read_be32(fp, &chunk->id) ||
1464 !dmf_read_be32(fp, &chunk->size)) 1464 !dmf_read_be32(fp, &chunk->size))
1465 { 1465 {
1466 return dmError(DMERR_FREAD, 1466 return dmError(DMERR_FREAD,
1467 "ILBM: Could not read IFF chunk header.\n"); 1467 "IFF: Could not read IFF chunk header.\n");
1468 } 1468 }
1469 else 1469 else
1470 { 1470 {
1471 dmMakeIFFChunkIDStr(chunk); 1471 dmMakeIFFChunkIDStr(chunk);
1472 return DMERR_OK; 1472 return DMERR_OK;
1476 1476
1477 static int dmSkipIFFChunkRest(DMResource *fp, const DMIFFChunk *chunk, const Uint32 used) 1477 static int dmSkipIFFChunkRest(DMResource *fp, const DMIFFChunk *chunk, const Uint32 used)
1478 { 1478 {
1479 if (chunk->size > used) 1479 if (chunk->size > used)
1480 { 1480 {
1481 dmMsg(4, "ILBM: Skipping %d bytes (%d of %d consumed)\n", 1481 dmMsg(4, "IFF: Skipping %d bytes (%d of %d consumed)\n",
1482 chunk->size - used, used, chunk->size); 1482 chunk->size - used, used, chunk->size);
1483 1483
1484 if (dmfseek(fp, chunk->size - used, SEEK_CUR) != 0) 1484 if (dmfseek(fp, chunk->size - used, SEEK_CUR) != 0)
1485 { 1485 {
1486 return dmError(DMERR_FSEEK, 1486 return dmError(DMERR_FSEEK,
1487 "ILBM: Failed to skip chunk end.\n"); 1487 "IFF: Failed to skip chunk end.\n");
1488 } 1488 }
1489 else 1489 else
1490 return DMERR_OK; 1490 return DMERR_OK;
1491 } 1491 }
1492 else 1492 else
1498 const BOOL multi, const Uint32 minSize) 1498 const BOOL multi, const Uint32 minSize)
1499 { 1499 {
1500 if (dest->count > 0 && !multi) 1500 if (dest->count > 0 && !multi)
1501 { 1501 {
1502 return dmError(DMERR_INVALID_DATA, 1502 return dmError(DMERR_INVALID_DATA,
1503 "ILBM: Multiple instances of chunk %s found.\n", 1503 "IFF: Multiple instances of chunk %s found.\n",
1504 chunk->idStr); 1504 chunk->idStr);
1505 } 1505 }
1506 1506
1507 dest->count++; 1507 dest->count++;
1508 1508
1509 if (chunk->size < minSize) 1509 if (chunk->size < minSize)
1510 { 1510 {
1511 return dmError(DMERR_OUT_OF_DATA, 1511 return dmError(DMERR_OUT_OF_DATA,
1512 "ILBM: Chunk is too small.\n"); 1512 "IFF: Chunk is too small.\n");
1513 } 1513 }
1514 1514
1515 return DMERR_OK; 1515 return DMERR_OK;
1516 } 1516 }
1517 1517
1593 // Allocate planar decoding buffer 1593 // Allocate planar decoding buffer
1594 bufLen = ((img->width + 15) / 16) * 2; 1594 bufLen = ((img->width + 15) / 16) * 2;
1595 if ((buf = dmMalloc(bufLen)) == NULL) 1595 if ((buf = dmMalloc(bufLen)) == NULL)
1596 return DMERR_MALLOC; 1596 return DMERR_MALLOC;
1597 1597
1598 dmMsg(2, "ILBM: plane row size %d bytes.\n", bufLen); 1598 dmMsg(2, "IFF: plane row size %d bytes.\n", bufLen);
1599 1599
1600 // Decode the chunk 1600 // Decode the chunk
1601 for (int yc = 0; yc < img->height; yc++) 1601 for (int yc = 0; yc < img->height; yc++)
1602 { 1602 {
1603 Uint8 *dp = img->data + (yc * img->pitch); 1603 Uint8 *dp = img->data + (yc * img->pitch);
1608 { 1608 {
1609 // Decompress or read data 1609 // Decompress or read data
1610 if (!dmIFFReadOneRow(fp, iff, buf, bufLen)) 1610 if (!dmIFFReadOneRow(fp, iff, buf, bufLen))
1611 { 1611 {
1612 res = dmError(DMERR_FREAD, 1612 res = dmError(DMERR_FREAD,
1613 "ILBM: Error in reading image plane #%d @ %d.\n", 1613 "IFF: Error in reading image plane #%d @ %d.\n",
1614 plane, yc); 1614 plane, yc);
1615 goto error; 1615 goto error;
1616 } 1616 }
1617 1617
1618 // Decode bitplane 1618 // Decode bitplane
1626 { 1626 {
1627 // Decompress or read data 1627 // Decompress or read data
1628 if (!dmIFFReadOneRow(fp, iff, buf, bufLen)) 1628 if (!dmIFFReadOneRow(fp, iff, buf, bufLen))
1629 { 1629 {
1630 res = dmError(DMERR_FREAD, 1630 res = dmError(DMERR_FREAD,
1631 "ILBM: Error in reading mask plane.\n"); 1631 "IFF: Error in reading mask plane.\n");
1632 goto error; 1632 goto error;
1633 } 1633 }
1634 1634
1635 // Decode mask 1635 // Decode mask
1636 for (int xc = 0; xc < img->width; xc++) 1636 for (int xc = 0; xc < img->width; xc++)
1664 Uint8 *dp = img->data + (yc * img->pitch); 1664 Uint8 *dp = img->data + (yc * img->pitch);
1665 1665
1666 if (!dmIFFReadOneRow(fp, iff, dp, img->width)) 1666 if (!dmIFFReadOneRow(fp, iff, dp, img->width))
1667 { 1667 {
1668 res = dmError(DMERR_FREAD, 1668 res = dmError(DMERR_FREAD,
1669 "ILBM: Error in reading image row #%d.\n", yc); 1669 "IFF: Error in reading image row #%d.\n", yc);
1670 goto error; 1670 goto error;
1671 } 1671 }
1672 1672
1673 *read += img->width; 1673 *read += img->width;
1674 } 1674 }
1676 error: 1676 error:
1677 return res; 1677 return res;
1678 } 1678 }
1679 1679
1680 1680
1681 int dmReadILBMImage(DMResource *fp, DMImage **pimg) 1681 int dmReadIFFImage(DMResource *fp, DMImage **pimg)
1682 { 1682 {
1683 DMIFFChunk chunk; 1683 DMIFFChunk chunk;
1684 DMIFF iff; 1684 DMIFF iff;
1685 Uint32 read, idsig; 1685 Uint32 read, idsig;
1686 BOOL parsed = FALSE, planar; 1686 BOOL parsed = FALSE, planar;
1693 return res; 1693 return res;
1694 1694
1695 if (chunk.id != IFF_ID_FORM || chunk.size < 32) 1695 if (chunk.id != IFF_ID_FORM || chunk.size < 32)
1696 { 1696 {
1697 return dmError(DMERR_NOT_SUPPORTED, 1697 return dmError(DMERR_NOT_SUPPORTED,
1698 "ILBM: Not a IFF file (%08X vs %08X / %d).\n", 1698 "IFF: Not a IFF file (%08X vs %08X / %d).\n",
1699 chunk.id, IFF_ID_FORM, chunk.size); 1699 chunk.id, IFF_ID_FORM, chunk.size);
1700 } 1700 }
1701 1701
1702 // Check IFF ILBM signature 1702 // Check IFF ILBM/PBM signature
1703 if (!dmf_read_be32(fp, &idsig) || 1703 if (!dmf_read_be32(fp, &idsig) ||
1704 (idsig != IFF_ID_ILBM && idsig != IFF_ID_PBM)) 1704 (idsig != IFF_ID_ILBM && idsig != IFF_ID_PBM))
1705 { 1705 {
1706 return dmError(DMERR_INVALID_DATA, 1706 return dmError(DMERR_INVALID_DATA,
1707 "ILBM: Not a ILBM file.\n"); 1707 "IFF: Not a IFF ILBM/PBM file.\n");
1708 } 1708 }
1709 1709
1710 planar = (idsig == IFF_ID_ILBM); 1710 planar = (idsig == IFF_ID_ILBM);
1711 1711
1712 while (!parsed && !dmfeof(fp)) 1712 while (!parsed && !dmfeof(fp))
1735 !dmf_read_byte(fp, &iff.bmhd.yasp) || 1735 !dmf_read_byte(fp, &iff.bmhd.yasp) ||
1736 !dmf_read_be16(fp, (Uint16 *) &iff.bmhd.pagew) || 1736 !dmf_read_be16(fp, (Uint16 *) &iff.bmhd.pagew) ||
1737 !dmf_read_be16(fp, (Uint16 *) &iff.bmhd.pageh)) 1737 !dmf_read_be16(fp, (Uint16 *) &iff.bmhd.pageh))
1738 { 1738 {
1739 return dmError(DMERR_FREAD, 1739 return dmError(DMERR_FREAD,
1740 "ILBM: Error reading BMHD chunk.\n"); 1740 "IFF: Error reading BMHD chunk.\n");
1741 } 1741 }
1742 1742
1743 dmMsg(1, "ILBM: BMHD %d x %d @ %d, %d : nplanes=%d, comp=%d, mask=%d, transp=%d\n", 1743 dmMsg(1, "IFF: BMHD %d x %d @ %d, %d : nplanes=%d, comp=%d, mask=%d, transp=%d\n",
1744 iff.bmhd.w, iff.bmhd.h, iff.bmhd.x, iff.bmhd.y, 1744 iff.bmhd.w, iff.bmhd.h, iff.bmhd.x, iff.bmhd.y,
1745 iff.bmhd.nplanes, iff.bmhd.compression, iff.bmhd.masking, 1745 iff.bmhd.nplanes, iff.bmhd.compression, iff.bmhd.masking,
1746 iff.bmhd.transp); 1746 iff.bmhd.transp);
1747 1747
1748 // Sanity check 1748 // Sanity check
1752 (iff.bmhd.masking != IFF_MASK_NONE && 1752 (iff.bmhd.masking != IFF_MASK_NONE &&
1753 iff.bmhd.masking != IFF_MASK_HAS_MASK && 1753 iff.bmhd.masking != IFF_MASK_HAS_MASK &&
1754 iff.bmhd.masking != IFF_MASK_TRANSP)) 1754 iff.bmhd.masking != IFF_MASK_TRANSP))
1755 { 1755 {
1756 return dmError(DMERR_NOT_SUPPORTED, 1756 return dmError(DMERR_NOT_SUPPORTED,
1757 "ILBM: Unsupported features, refusing to load.\n"); 1757 "IFF: Unsupported features, refusing to load.\n");
1758 } 1758 }
1759 1759
1760 if ((res = dmSkipIFFChunkRest(fp, &chunk, sizeof(iff.bmhd))) != DMERR_OK) 1760 if ((res = dmSkipIFFChunkRest(fp, &chunk, sizeof(iff.bmhd))) != DMERR_OK)
1761 return res; 1761 return res;
1762 break; 1762 break;
1770 // Check for sanity 1770 // Check for sanity
1771 if (chunk.size % 3 != 0) 1771 if (chunk.size % 3 != 0)
1772 { 1772 {
1773 // Non-fatal 1773 // Non-fatal
1774 dmError(DMERR_INVALID_DATA, 1774 dmError(DMERR_INVALID_DATA,
1775 "ILBM: CMAP chunk size not divisible by 3, possibly broken file.\n"); 1775 "IFF: CMAP chunk size not divisible by 3, possibly broken file.\n");
1776 } 1776 }
1777 1777
1778 iff.ncolors = chunk.size / 3; 1778 iff.ncolors = chunk.size / 3;
1779 dmMsg(2, "ILBM: CMAP %d entries (%d bytes)\n", 1779 dmMsg(2, "IFF: CMAP %d entries (%d bytes)\n",
1780 iff.ncolors, chunk.size); 1780 iff.ncolors, chunk.size);
1781 1781
1782 if (iff.bmhd.nplanes > 0 && iff.ncolors != 1 << iff.bmhd.nplanes) 1782 if (iff.bmhd.nplanes > 0 && iff.ncolors != 1 << iff.bmhd.nplanes)
1783 dmMsg(2, "ILBM: Expected %d entries in CMAP.\n", 1 << iff.bmhd.nplanes); 1783 dmMsg(2, "IFF: Expected %d entries in CMAP.\n", 1 << iff.bmhd.nplanes);
1784 1784
1785 // Read palette 1785 // Read palette
1786 if (iff.ncolors > 0) 1786 if (iff.ncolors > 0)
1787 { 1787 {
1788 if (!dmPaletteAlloc(&iff.pal, iff.ncolors, 1788 if (!dmPaletteAlloc(&iff.pal, iff.ncolors,
1789 (iff.bmhd.masking == IFF_MASK_TRANSP) ? iff.bmhd.transp : -1)) 1789 (iff.bmhd.masking == IFF_MASK_TRANSP) ? iff.bmhd.transp : -1))
1790 { 1790 {
1791 return dmError(DMERR_MALLOC, 1791 return dmError(DMERR_MALLOC,
1792 "ILBM: Could not allocate palette data.\n"); 1792 "IFF: Could not allocate palette data.\n");
1793 } 1793 }
1794 if (!dmPaletteReadData(fp, iff.pal, iff.ncolors)) 1794 if (!dmPaletteReadData(fp, iff.pal, iff.ncolors))
1795 { 1795 {
1796 return dmError(DMERR_FREAD, 1796 return dmError(DMERR_FREAD,
1797 "ILBM: Error reading CMAP.\n"); 1797 "IFF: Error reading CMAP.\n");
1798 } 1798 }
1799 } 1799 }
1800 1800
1801 if (iff.chBMHD.count && iff.chBODY.count) 1801 if (iff.chBMHD.count && iff.chBODY.count)
1802 parsed = TRUE; 1802 parsed = TRUE;
1809 1809
1810 // Check for sanity 1810 // Check for sanity
1811 if (!iff.chBMHD.count) 1811 if (!iff.chBMHD.count)
1812 { 1812 {
1813 return dmError(DMERR_INVALID_DATA, 1813 return dmError(DMERR_INVALID_DATA,
1814 "ILBM: BODY chunk before BMHD?\n"); 1814 "IFF: BODY chunk before BMHD?\n");
1815 } 1815 }
1816 1816
1817 dmMsg(2, "ILBM: BODY chunk size %d bytes\n", chunk.size); 1817 dmMsg(2, "IFF: BODY chunk size %d bytes\n", chunk.size);
1818 1818
1819 // Allocate image 1819 // Allocate image
1820 if ((*pimg = dmImageAlloc(iff.bmhd.w, iff.bmhd.h, 1820 if ((*pimg = dmImageAlloc(iff.bmhd.w, iff.bmhd.h,
1821 iff.bmhd.nplanes <= 8 ? DM_COLFMT_PALETTE : DM_COLFMT_RGBA, 1821 iff.bmhd.nplanes <= 8 ? DM_COLFMT_PALETTE : DM_COLFMT_RGBA,
1822 // XXX TODO? When/if we ever handle < 8bit indexed correctly, we can use the actual bpp 1822 // XXX TODO? When/if we ever handle < 8bit indexed correctly, we can use the actual bpp
1851 1851
1852 case IFF_ID_CAMG: 1852 case IFF_ID_CAMG:
1853 if (!dmf_read_be32(fp, &iff.camg)) 1853 if (!dmf_read_be32(fp, &iff.camg))
1854 { 1854 {
1855 return dmError(DMERR_FREAD, 1855 return dmError(DMERR_FREAD,
1856 "ILBM: Error reading CAMG chunk.\n"); 1856 "IFF: Error reading CAMG chunk.\n");
1857 } 1857 }
1858 1858
1859 dmMsg(2, "ILBM: CAMG value 0x%08x\n", iff.camg); 1859 dmMsg(2, "IFF: CAMG value 0x%08x\n", iff.camg);
1860 1860
1861 if ((iff.camg & IFF_CAMG_HAM)) 1861 if ((iff.camg & IFF_CAMG_HAM))
1862 { 1862 {
1863 return dmError(DMERR_NOT_SUPPORTED, 1863 return dmError(DMERR_NOT_SUPPORTED,
1864 "ILBM: HAM files are not supported.\n"); 1864 "IFF: HAM files are not supported.\n");
1865 } 1865 }
1866 1866
1867 if ((res = dmSkipIFFChunkRest(fp, &chunk, sizeof(Uint32))) != DMERR_OK) 1867 if ((res = dmSkipIFFChunkRest(fp, &chunk, sizeof(Uint32))) != DMERR_OK)
1868 return res; 1868 return res;
1869 break; 1869 break;
1875 chunk.idStr, chunk.size); 1875 chunk.idStr, chunk.size);
1876 1876
1877 if (dmfseek(fp, chunk.size, SEEK_CUR) != 0) 1877 if (dmfseek(fp, chunk.size, SEEK_CUR) != 0)
1878 { 1878 {
1879 return dmError(DMERR_FSEEK, 1879 return dmError(DMERR_FSEEK,
1880 "ILBM: Error skipping in file."); 1880 "IFF: Error skipping in file.");
1881 } 1881 }
1882 } 1882 }
1883 break; 1883 break;
1884 } 1884 }
1885 1885
1894 if (iff.camg & IFF_CAMG_HALFBRITE) 1894 if (iff.camg & IFF_CAMG_HALFBRITE)
1895 { 1895 {
1896 void *ptmp; 1896 void *ptmp;
1897 if (!planar) 1897 if (!planar)
1898 { 1898 {
1899 dmErrorMsg("ILBM: Non-planar PBM file with Halfbrite enabled! This might not work.\n"); 1899 dmErrorMsg("IFF: Non-planar PBM file with Halfbrite enabled! This might not work.\n");
1900 } 1900 }
1901 1901
1902 if (iff.ncolors > 128) 1902 if (iff.ncolors > 128)
1903 { 1903 {
1904 return dmError(DMERR_NOT_SUPPORTED, 1904 return dmError(DMERR_NOT_SUPPORTED,
1905 "ILBM: Halfbrite enabled, but ncolors > 128.\n"); 1905 "IFF: Halfbrite enabled, but ncolors > 128.\n");
1906 } 1906 }
1907 1907
1908 if ((ptmp = dmRealloc(iff.pal, sizeof(DMColor) * iff.ncolors * 2)) == NULL) 1908 if ((ptmp = dmRealloc(iff.pal, sizeof(DMColor) * iff.ncolors * 2)) == NULL)
1909 { 1909 {
1910 dmFree(iff.pal); 1910 dmFree(iff.pal);
1952 "pcx", "Z-Soft Paintbrush", 1952 "pcx", "Z-Soft Paintbrush",
1953 DM_IMGFMT_PCX, DM_FMT_RDWR, 1953 DM_IMGFMT_PCX, DM_FMT_RDWR,
1954 fmtProbePCX, dmReadPCXImage, dmWritePCXImage, 1954 fmtProbePCX, dmReadPCXImage, dmWritePCXImage,
1955 }, 1955 },
1956 { 1956 {
1957 "ilbm", "IFF ILBM / PBM", 1957 "iff", "IFF ILBM / PBM",
1958 DM_IMGFMT_ILBM, DM_FMT_RDWR, 1958 DM_IMGFMT_IFF, DM_FMT_RDWR,
1959 fmtProbeILBM, dmReadILBMImage, 1959 fmtProbeIFF, dmReadIFFImage,
1960 NULL, 1960 NULL,
1961 }, 1961 },
1962 { 1962 {
1963 "raw", "Plain bitplaned (planar or non-planar) RAW", 1963 "raw", "Plain bitplaned (planar or non-planar) RAW",
1964 DM_IMGFMT_RAW, DM_FMT_WR, 1964 DM_IMGFMT_RAW, DM_FMT_WR,