Mercurial > hg > dmlib
comparison libgfx.c @ 444:7d588807f91d
Clean up the IFF parser a bit.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sun, 04 Nov 2012 06:52:42 +0200 |
parents | f7c9d1619c74 |
children | 1d65efb29986 |
comparison
equal
deleted
inserted
replaced
443:f7c9d1619c74 | 444:7d588807f91d |
---|---|
955 Uint8 xasp, yasp; | 955 Uint8 xasp, yasp; |
956 Sint16 pagew, pageh; | 956 Sint16 pagew, pageh; |
957 } DMIFFBMHD; | 957 } DMIFFBMHD; |
958 | 958 |
959 | 959 |
960 typedef struct | |
961 { | |
962 DMIFFChunk chBMHD, chCMAP, chBODY; | |
963 DMIFFBMHD bmhd; | |
964 int ncolors; | |
965 DMColor *pal; | |
966 DMImage *img; | |
967 BOOL paletted; | |
968 } DMIFF; | |
969 | |
970 | |
960 static BOOL dmReadIFFChunk(FILE *fp, DMIFFChunk *chunk) | 971 static BOOL dmReadIFFChunk(FILE *fp, DMIFFChunk *chunk) |
961 { | 972 { |
962 if (!dm_fread_be32(fp, &chunk->id) || | 973 if (!dm_fread_be32(fp, &chunk->id) || |
963 !dm_fread_be32(fp, &chunk->size)) | 974 !dm_fread_be32(fp, &chunk->size)) |
964 { | 975 { |
967 } | 978 } |
968 else | 979 else |
969 return TRUE; | 980 return TRUE; |
970 } | 981 } |
971 | 982 |
972 static char * dmGetIFFChunkID(DMIFFChunk *chunk, char *buf) | 983 static char * dmGetIFFChunkID(const DMIFFChunk *chunk, char *buf) |
973 { | 984 { |
974 buf[0] = (chunk->id >> 24) & 0xff; | 985 buf[0] = (chunk->id >> 24) & 0xff; |
975 buf[1] = (chunk->id >> 16) & 0xff; | 986 buf[1] = (chunk->id >> 16) & 0xff; |
976 buf[2] = (chunk->id >> 8) & 0xff; | 987 buf[2] = (chunk->id >> 8) & 0xff; |
977 buf[3] = (chunk->id) & 0xff; | 988 buf[3] = (chunk->id) & 0xff; |
978 buf[4] = 0; | 989 buf[4] = 0; |
979 return buf; | 990 return buf; |
980 } | 991 } |
981 | 992 |
982 static BOOL dmCheckIFFChunk(DMIFFChunk *dest, DMIFFChunk *chunk, BOOL multi, Uint32 minSize) | 993 static BOOL dmSkipIFFChunkRest(FILE *fp, const DMIFFChunk *chunk, const Uint32 used) |
994 { | |
995 if (chunk->size > used) | |
996 return fseeko(fp, chunk->size - used, SEEK_CUR) == 0; | |
997 else | |
998 return TRUE; | |
999 } | |
1000 | |
1001 static BOOL dmCheckIFFChunk(DMIFFChunk *dest, const DMIFFChunk *chunk, const BOOL multi, const Uint32 minSize) | |
983 { | 1002 { |
984 if (dest->count > 0 && !multi) | 1003 if (dest->count > 0 && !multi) |
985 { | 1004 { |
986 char buf[6]; | 1005 char buf[6]; |
987 dmError("ILBM: Multiple instances of chunk %s found.\n", | 1006 dmError("ILBM: Multiple instances of chunk %s found.\n", |
996 | 1015 |
997 return TRUE; | 1016 return TRUE; |
998 } | 1017 } |
999 | 1018 |
1000 | 1019 |
1020 int dmDecodeILBMBody(FILE *fp, DMIFF *iff) | |
1021 { | |
1022 return DMERR_OK; | |
1023 } | |
1024 | |
1025 | |
1001 int dmReadILBMImageFILE(FILE *fp, DMImage **pimg) | 1026 int dmReadILBMImageFILE(FILE *fp, DMImage **pimg) |
1002 { | 1027 { |
1003 Uint32 idILBM; | 1028 Uint32 idILBM; |
1004 DMIFFChunk chunk, chBMHD, chCMAP, chBODY; | 1029 DMIFFChunk chunk; |
1005 DMIFFBMHD bmhd; | 1030 DMIFF iff; |
1006 int ncolors, i; | 1031 BOOL parsed = FALSE; |
1007 DMColor *pal = NULL; | 1032 int i, res = DMERR_OK; |
1008 DMImage *img = NULL; | 1033 |
1009 BOOL paletted = FALSE, parsed = FALSE; | 1034 memset(&iff, 0, sizeof(iff)); |
1010 int res = DMERR_OK; | |
1011 | |
1012 memset(&chBMHD, 0, sizeof(DMIFFChunk)); | |
1013 memset(&chCMAP, 0, sizeof(DMIFFChunk)); | |
1014 memset(&chBODY, 0, sizeof(DMIFFChunk)); | |
1015 memset(&bmhd, 0, sizeof(bmhd)); | |
1016 | 1035 |
1017 // Read IFF FORM header | 1036 // Read IFF FORM header |
1018 if (!dmReadIFFChunk(fp, &chunk) || | 1037 if (!dmReadIFFChunk(fp, &chunk) || |
1019 chunk.id != IFF_ID_FORM || | 1038 chunk.id != IFF_ID_FORM || |
1020 chunk.size < 32) | 1039 chunk.size < 32) |
1040 } | 1059 } |
1041 | 1060 |
1042 switch (chunk.id) | 1061 switch (chunk.id) |
1043 { | 1062 { |
1044 case IFF_ID_BMHD: | 1063 case IFF_ID_BMHD: |
1045 if (!dmCheckIFFChunk(&chBMHD, &chunk, FALSE, sizeof(bmhd))) | 1064 if (!dmCheckIFFChunk(&iff.chBMHD, &chunk, FALSE, sizeof(iff.bmhd))) |
1046 return DMERR_FREAD; | 1065 return DMERR_FREAD; |
1047 | 1066 |
1048 if (!dm_fread_be16(fp, &bmhd.w) || | 1067 if (!dm_fread_be16(fp, &iff.bmhd.w) || |
1049 !dm_fread_be16(fp, &bmhd.h) || | 1068 !dm_fread_be16(fp, &iff.bmhd.h) || |
1050 !dm_fread_be16(fp, (Uint16 *) &bmhd.x) || | 1069 !dm_fread_be16(fp, (Uint16 *) &iff.bmhd.x) || |
1051 !dm_fread_be16(fp, (Uint16 *) &bmhd.y) || | 1070 !dm_fread_be16(fp, (Uint16 *) &iff.bmhd.y) || |
1052 !dm_fread_byte(fp, &bmhd.nplanes) || | 1071 !dm_fread_byte(fp, &iff.bmhd.nplanes) || |
1053 !dm_fread_byte(fp, &bmhd.masking) || | 1072 !dm_fread_byte(fp, &iff.bmhd.masking) || |
1054 !dm_fread_byte(fp, &bmhd.compression) || | 1073 !dm_fread_byte(fp, &iff.bmhd.compression) || |
1055 !dm_fread_byte(fp, &bmhd.pad1) || | 1074 !dm_fread_byte(fp, &iff.bmhd.pad1) || |
1056 !dm_fread_be16(fp, &bmhd.transp) || | 1075 !dm_fread_be16(fp, &iff.bmhd.transp) || |
1057 !dm_fread_byte(fp, &bmhd.xasp) || | 1076 !dm_fread_byte(fp, &iff.bmhd.xasp) || |
1058 !dm_fread_byte(fp, &bmhd.yasp) || | 1077 !dm_fread_byte(fp, &iff.bmhd.yasp) || |
1059 !dm_fread_be16(fp, (Uint16 *) &bmhd.pagew) || | 1078 !dm_fread_be16(fp, (Uint16 *) &iff.bmhd.pagew) || |
1060 !dm_fread_be16(fp, (Uint16 *) &bmhd.pageh)) | 1079 !dm_fread_be16(fp, (Uint16 *) &iff.bmhd.pageh)) |
1061 { | 1080 { |
1062 dmError("ILBM: Error reading BMHD chunk.\n"); | 1081 dmError("ILBM: Error reading BMHD chunk.\n"); |
1063 return DMERR_FREAD; | 1082 return DMERR_FREAD; |
1064 } | 1083 } |
1065 dmMsg(2, "ILBM: BMHD %d x %d @ %d, %d : nplanes=%d, comp=%d, mask=%d\n", | 1084 dmMsg(2, "ILBM: BMHD %d x %d @ %d, %d : nplanes=%d, comp=%d, mask=%d\n", |
1066 bmhd.w, bmhd.h, bmhd.x, bmhd.y, bmhd.nplanes, bmhd.compression, bmhd.masking); | 1085 iff.bmhd.w, iff.bmhd.h, iff.bmhd.x, iff.bmhd.y, iff.bmhd.nplanes, iff.bmhd.compression, iff.bmhd.masking); |
1086 | |
1087 if (!dmSkipIFFChunkRest(fp, &chunk, sizeof(iff.bmhd))) | |
1088 return DMERR_FREAD; | |
1067 break; | 1089 break; |
1068 | 1090 |
1069 | 1091 |
1070 case IFF_ID_CMAP: | 1092 case IFF_ID_CMAP: |
1071 // Check for multiple occurences of CMAP | 1093 // Check for multiple occurences of CMAP |
1072 if (!dmCheckIFFChunk(&chCMAP, &chunk, FALSE, 3)) | 1094 if (!dmCheckIFFChunk(&iff.chCMAP, &chunk, FALSE, 3)) |
1073 return DMERR_FREAD; | 1095 return DMERR_FREAD; |
1074 | 1096 |
1075 // Check for sanity | 1097 // Check for sanity |
1076 if (chunk.size % 3 != 0) | 1098 if (chunk.size % 3 != 0) |
1077 dmError("ILBM: CMAP chunk size not divisible by 3, possibly broken file.\n"); | 1099 dmError("ILBM: CMAP chunk size not divisible by 3, possibly broken file.\n"); |
1078 | 1100 |
1079 ncolors = chunk.size / 3; | 1101 iff.ncolors = chunk.size / 3; |
1080 dmMsg(2, "ILBM: CMAP %d entries (%d bytes)\n", | 1102 dmMsg(2, "ILBM: CMAP %d entries (%d bytes)\n", |
1081 ncolors, chunk.size, 1 << bmhd.nplanes); | 1103 iff.ncolors, chunk.size, 1 << iff.bmhd.nplanes); |
1082 | 1104 |
1083 if (bmhd.nplanes > 0 && ncolors != 1 << bmhd.nplanes) | 1105 if (iff.bmhd.nplanes > 0 && iff.ncolors != 1 << iff.bmhd.nplanes) |
1084 dmMsg(2, "ILBM: Expected %d entries in CMAP.\n", 1 << bmhd.nplanes); | 1106 dmMsg(2, "ILBM: Expected %d entries in CMAP.\n", 1 << iff.bmhd.nplanes); |
1085 | 1107 |
1086 if (ncolors == 0) | 1108 if (iff.ncolors == 0) |
1087 break; | 1109 break; |
1088 | 1110 |
1089 // Allocate palette | 1111 // Allocate palette |
1090 if ((pal = dmMalloc(sizeof(DMColor) * ncolors)) == NULL) | 1112 if ((iff.pal = dmMalloc(sizeof(DMColor) * iff.ncolors)) == NULL) |
1091 { | 1113 { |
1092 dmError("ILBM: Could not allocate memory for palette.\n"); | 1114 dmError("ILBM: Could not allocate memory for palette.\n"); |
1093 return DMERR_MALLOC; | 1115 return DMERR_MALLOC; |
1094 } | 1116 } |
1095 | 1117 |
1096 // Read palette | 1118 // Read palette |
1097 for (i = 0; i < ncolors; i++) | 1119 for (i = 0; i < iff.ncolors; i++) |
1098 { | 1120 { |
1099 Uint8 colR, colG, colB; | 1121 Uint8 colR, colG, colB; |
1100 if (!dm_fread_byte(fp, &colR) || | 1122 if (!dm_fread_byte(fp, &colR) || |
1101 !dm_fread_byte(fp, &colG) || | 1123 !dm_fread_byte(fp, &colG) || |
1102 !dm_fread_byte(fp, &colB)) | 1124 !dm_fread_byte(fp, &colB)) |
1103 { | 1125 { |
1104 dmError("ILBM: Error reading CMAP entry #%d, broken file.\n", i); | 1126 dmError("ILBM: Error reading CMAP entry #%d, broken file.\n", i); |
1105 return DMERR_FREAD; | 1127 return DMERR_FREAD; |
1106 } | 1128 } |
1107 | 1129 |
1108 pal[i].r = colR; | 1130 iff.pal[i].r = colR; |
1109 pal[i].g = colG; | 1131 iff.pal[i].g = colG; |
1110 pal[i].b = colB; | 1132 iff.pal[i].b = colB; |
1111 } | 1133 } |
1112 | 1134 |
1113 if (chBMHD.count && chBODY.count) | 1135 if (iff.chBMHD.count && iff.chBODY.count) |
1114 parsed = TRUE; | 1136 parsed = TRUE; |
1115 break; | 1137 break; |
1116 | 1138 |
1117 case IFF_ID_BODY: | 1139 case IFF_ID_BODY: |
1118 if (!dmCheckIFFChunk(&chBODY, &chunk, FALSE, 1)) | 1140 if (!dmCheckIFFChunk(&iff.chBODY, &chunk, FALSE, 1)) |
1119 return DMERR_FREAD; | 1141 return DMERR_FREAD; |
1120 | 1142 |
1121 if (!chBMHD.count) | 1143 if (!iff.chBMHD.count) |
1122 { | 1144 { |
1123 dmError("ILBM: BODY chunk before BMHD?\n"); | 1145 dmError("ILBM: BODY chunk before BMHD?\n"); |
1124 return DMERR_INVALID_DATA; | 1146 return DMERR_INVALID_DATA; |
1125 } | 1147 } |
1126 | 1148 |
1127 dmMsg(2, "ILBM: BODY chunk size %d bytes\n", chunk.size); | 1149 dmMsg(2, "ILBM: BODY chunk size %d bytes\n", chunk.size); |
1150 | |
1128 if (fseeko(fp, chunk.size, SEEK_CUR) != 0) | 1151 if (fseeko(fp, chunk.size, SEEK_CUR) != 0) |
1129 { | 1152 { |
1130 dmError("ILBM: Error skipping in file."); | 1153 dmError("ILBM: Error skipping in file."); |
1131 return DMERR_FREAD; | 1154 return DMERR_FREAD; |
1132 } | 1155 } |
1133 | 1156 |
1134 if (chCMAP.count) | 1157 if (iff.chCMAP.count) |
1135 parsed = TRUE; | 1158 parsed = TRUE; |
1136 break; | 1159 break; |
1137 | 1160 |
1138 default: | 1161 default: |
1139 { | 1162 { |