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