Mercurial > hg > dmlib
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, |