comparison libgfx.c @ 464:358776103ceb

Add support for IFF PBMs.
author Matti Hamalainen <ccr@tnsp.org>
date Sun, 04 Nov 2012 16:36:21 +0200
parents ab401a5087f9
children ffd5e730d313
comparison
equal deleted inserted replaced
463:4204e9ea8ae1 464:358776103ceb
1147 } 1147 }
1148 1148
1149 1149
1150 #define IFF_ID_FORM 0x464F524D // "FORM" 1150 #define IFF_ID_FORM 0x464F524D // "FORM"
1151 #define IFF_ID_ILBM 0x494C424D // "ILBM" 1151 #define IFF_ID_ILBM 0x494C424D // "ILBM"
1152 #define IFF_ID_PBM 0x50424D20 // "PBM "
1152 #define IFF_ID_BMHD 0x424D4844 // "BMHD" 1153 #define IFF_ID_BMHD 0x424D4844 // "BMHD"
1153 #define IFF_ID_CMAP 0x434D4150 // "CMAP" 1154 #define IFF_ID_CMAP 0x434D4150 // "CMAP"
1154 #define IFF_ID_BODY 0x424F4459 // "BODY" 1155 #define IFF_ID_BODY 0x424F4459 // "BODY"
1155 #define IFF_ID_CAMG 0x43414D47 // "CAMG" 1156 #define IFF_ID_CAMG 0x43414D47 // "CAMG"
1156 1157
1194 DMIFFChunk chBMHD, chCMAP, chBODY; 1195 DMIFFChunk chBMHD, chCMAP, chBODY;
1195 DMIFFBMHD bmhd; 1196 DMIFFBMHD bmhd;
1196 Uint32 camg; 1197 Uint32 camg;
1197 int ncolors; 1198 int ncolors;
1198 DMColor *pal; 1199 DMColor *pal;
1199 BOOL paletted; 1200 BOOL paletted, planar;
1200 } DMIFF; 1201 } DMIFF;
1201 1202
1202 1203
1203 static BOOL dmReadIFFChunk(FILE *fp, DMIFFChunk *chunk) 1204 static BOOL dmReadIFFChunk(FILE *fp, DMIFFChunk *chunk)
1204 { 1205 {
1348 for (plane = 0; plane < nplanes; plane++) 1349 for (plane = 0; plane < nplanes; plane++)
1349 { 1350 {
1350 // Decompress or read data 1351 // Decompress or read data
1351 if (!dmIFFReadOneRow(fp, iff, buf, bufLen)) 1352 if (!dmIFFReadOneRow(fp, iff, buf, bufLen))
1352 { 1353 {
1353 dmError("ILBM: Error in reading image plane #%d.\n", plane); 1354 dmError("ILBM: Error in reading image plane #%d @ %d.\n", plane, yc);
1354 res = DMERR_FREAD; 1355 res = DMERR_FREAD;
1355 goto error; 1356 goto error;
1356 } 1357 }
1357 1358
1358 // Decode bitplane 1359 // Decode bitplane
1388 } 1389 }
1389 } 1390 }
1390 1391
1391 error: 1392 error:
1392 dmFree(buf); 1393 dmFree(buf);
1394 return res;
1395 }
1396
1397
1398 int dmDecodePBMBody(FILE *fp, DMIFF *iff, DMImage **pimg, Uint32 *read)
1399 {
1400 DMImage *img;
1401 int yc, res = DMERR_OK;
1402
1403 *read = 0;
1404
1405 // Allocate image
1406 if ((*pimg = img = dmImageAlloc(iff->bmhd.w, iff->bmhd.h)) == NULL)
1407 return DMERR_MALLOC;
1408
1409 // Decode the chunk
1410 for (yc = 0; yc < img->height; yc++)
1411 {
1412 Uint8 *dp = img->data + (yc * img->pitch);
1413
1414 if (!dmIFFReadOneRow(fp, iff, dp, img->width))
1415 {
1416 dmError("ILBM: Error in reading image row #%d.\n", yc);
1417 res = DMERR_FREAD;
1418 goto error;
1419 }
1420
1421 *read += img->width;
1422 }
1423
1424 error:
1393 return res; 1425 return res;
1394 } 1426 }
1395 1427
1396 1428
1397 int dmReadILBMImageFILE(FILE *fp, DMImage **pimg) 1429 int dmReadILBMImageFILE(FILE *fp, DMImage **pimg)
1414 return DMERR_FREAD; 1446 return DMERR_FREAD;
1415 } 1447 }
1416 1448
1417 // Check IFF ILBM signature 1449 // Check IFF ILBM signature
1418 if (!dm_fread_be32(fp, &idILBM) || 1450 if (!dm_fread_be32(fp, &idILBM) ||
1419 idILBM != IFF_ID_ILBM) 1451 (idILBM != IFF_ID_ILBM && idILBM != IFF_ID_PBM))
1420 { 1452 {
1421 dmError("ILBM: Not a ILBM file.\n"); 1453 dmError("ILBM: Not a ILBM file.\n");
1422 return DMERR_INVALID_DATA; 1454 return DMERR_INVALID_DATA;
1423 } 1455 }
1456
1457 iff.planar = (idILBM == IFF_ID_ILBM);
1424 1458
1425 while (!parsed && !feof(fp)) 1459 while (!parsed && !feof(fp))
1426 { 1460 {
1427 if (!dmReadIFFChunk(fp, &chunk)) 1461 if (!dmReadIFFChunk(fp, &chunk))
1428 { 1462 {
1525 } 1559 }
1526 1560
1527 dmMsg(2, "ILBM: BODY chunk size %d bytes\n", chunk.size); 1561 dmMsg(2, "ILBM: BODY chunk size %d bytes\n", chunk.size);
1528 1562
1529 // Decode the body 1563 // Decode the body
1530 if ((res = dmDecodeILBMBody(fp, &iff, pimg, &read)) != DMERR_OK) 1564 if (iff.planar)
1531 return res; 1565 {
1566 if ((res = dmDecodeILBMBody(fp, &iff, pimg, &read)) != DMERR_OK)
1567 return res;
1568 }
1569 else
1570 {
1571 if ((res = dmDecodePBMBody(fp, &iff, pimg, &read)) != DMERR_OK)
1572 return res;
1573 }
1532 1574
1533 if (!dmSkipIFFChunkRest(fp, &chunk, read)) 1575 if (!dmSkipIFFChunkRest(fp, &chunk, read))
1534 return DMERR_FREAD; 1576 return DMERR_FREAD;
1535 1577
1536 if (iff.chCMAP.count) 1578 if (iff.chCMAP.count)
1661 1703
1662 static int fmtProbeILBM(const Uint8 *buf, const size_t len) 1704 static int fmtProbeILBM(const Uint8 *buf, const size_t len)
1663 { 1705 {
1664 if (len > 32 && 1706 if (len > 32 &&
1665 buf[ 0] == 'F' && buf[ 1] == 'O' && 1707 buf[ 0] == 'F' && buf[ 1] == 'O' &&
1666 buf[ 2] == 'R' && buf[ 3] == 'M' && 1708 buf[ 2] == 'R' && buf[ 3] == 'M' && (
1667 buf[ 8] == 'I' && buf[ 9] == 'L' && 1709 (buf[ 8] == 'I' && buf[ 9] == 'L' && buf[10] == 'B' && buf[11] == 'M') ||
1668 buf[10] == 'B' && buf[11] == 'M') 1710 (buf[ 8] == 'P' && buf[ 9] == 'B' && buf[10] == 'M' && buf[11] == 0x20)
1711 ))
1669 { 1712 {
1670 if (buf[12] == 'B' && buf[13] == 'M' && 1713 if (buf[12] == 'B' && buf[13] == 'M' &&
1671 buf[14] == 'H' && buf[15] == 'D') 1714 buf[14] == 'H' && buf[15] == 'D')
1672 return DM_PROBE_SCORE_MAX; 1715 return DM_PROBE_SCORE_MAX;
1673 else 1716 else