font2png, iffexplore: Misc. cleanup

This commit is contained in:
2015-04-17 15:39:19 +02:00
parent 6726488dda
commit ff7f5b2a0a
2 changed files with 49 additions and 56 deletions

View File

@@ -31,49 +31,28 @@ struct Font {
struct FontHeader { // little endian
uint32_t unknown1; // (always)? "1.\0\0"
uint32_t entries;
uint32_t charWidth;
uint32_t charHeight;
uint8_t bgColor;
char unknown3[3];
} __attribute__((__packed__));
Font parseFont(FILE* file, size_t length)
{
// if (fseeko(file, 16, SEEK_SET) != 0) {
// throw POSIXException(errno, "Could not seek");
// }
// uint32_t data, last_data = 0;
// int last_diff = -1, count = 0;
// size_t pos = 16;
// while (pos < length) {
// if (fread(&data, 4, 1, file) != 1) {
// if (feof(file))
// throw Exception{"Unexpected EOF"};
// throw POSIXException{errno, "Could not read"};
// }
// if ((last_diff == -1) ||
// (data-last_data == last_diff)) {
// ++count;
// last_diff = data-last_data;
// // printf("%.8x\n", data);
// } else {
// if ((count > 1) && last_diff )
// printf("%d times diff %d\n", count, last_diff);
// count = 0;
// last_diff = -1;
// }
// last_data = data;
// pos += 4;
// }
if (length < sizeof(FontHeader))
throw FormatException{"File smaller than header"};
FontHeader header;
if (fread(&header, sizeof(FontHeader), 1, file) != 1)
throw POSIXException{errno, "Could not read"};
if (header.unknown1 != 0x00002E31)
throw FormatException{"Not a font?"};
const unsigned index_start = sizeof(FontHeader);
const unsigned index_end = index_start+4*header.entries;
const unsigned char_width = header.charWidth;
if (index_end > length)
throw Exception{"Index table exceeds file length"};
std::vector<uint32_t> indices;
for (unsigned i = index_start;i < index_end;i+=4) {
@@ -87,9 +66,12 @@ Font parseFont(FILE* file, size_t length)
printf("Index range %u .. %u\n",
*minmax.first, *minmax.second);
if (*minmax.second > length)
throw FormatException{"Index exceeds file length"};
Font ret;
ret.numChars = header.entries;
ret.charHeight = char_width;
ret.charHeight = header.charHeight;
ret.maxCharWidth = 0;
ret.bgColor = header.bgColor;
for (auto const& index : indices) {
@@ -101,19 +83,22 @@ Font parseFont(FILE* file, size_t length)
throw POSIXException{errno, "Could not read"};
if (!len) {
ret.chars.push_back(Image{});
ret.chars.push_back(Image{0, 0, {}});
continue;
}
if (index+4+len*header.charHeight > length)
throw FormatException{"Glyph data exceeds file length"};
Image chr;
chr.height = char_width;
chr.height = header.charHeight;
chr.width = len;
chr.data.resize(char_width*len);
chr.data.resize(chr.height*chr.width);
if (chr.width > ret.maxCharWidth)
ret.maxCharWidth = chr.width;
if (fread(chr.data.data(), len*char_width, 1, file) != 1)
if (fread(chr.data.data(), chr.height*chr.width, 1, file) != 1)
throw POSIXException{errno, "Could not read"};
ret.chars.push_back(chr);

View File

@@ -13,10 +13,10 @@
struct ChunkHeader {
char typeID[4];
uint32_t length;
};
uint32_t length; // big endian!!
} __attribute__((__packed__));
void parseBlob(FILE *iffFile, off_t start, off_t length, char name[4], unsigned level)
void parseBlob(FILE *iffFile, off_t start, off_t length, char name[4], unsigned level, bool dump = false)
{
static unsigned count = 0;
@@ -74,16 +74,22 @@ void parseBlob(FILE *iffFile, off_t start, off_t length, char name[4], unsigned
filename.append(std::to_string(count) + "-");
filename.append(name, 4);
FILEUPtr outFile{fopen(filename.c_str(), "wb")};
if (!outFile)
throw POSIXException{errno, "Could not open " + filename};
if (dump) {
FILEUPtr outFile{fopen(filename.c_str(), "wb")};
if (!outFile)
throw POSIXException{errno, "Could not open " + filename};
for (unsigned i = 0;i < level;++i)
putchar('\t');
printf("Dumping BLOB of length %ld (0x%lx) to %s\n", length, length, filename.c_str());
for (unsigned i = 0;i < level;++i)
putchar('\t');
printf("Dumping BLOB of length %ld (0x%lx) to %s\n", length, length, filename.c_str());
if (fwrite(buf.data(), length, 1, outFile.get()) != 1)
throw POSIXException{errno, "Could not write data"};
if (fwrite(buf.data(), length, 1, outFile.get()) != 1)
throw POSIXException{errno, "Could not write data"};
} else {
for (unsigned i = 0;i < level;++i)
putchar('\t');
printf("BLOB of length %ld (0x%lx)\n", length, length);
}
++count;
}
@@ -97,6 +103,10 @@ void parseChunk(FILE* iffFile, off_t start, off_t length, unsigned level = 0)
throw POSIXException(errno, "Could not seek");
}
// pos < length due to loop condition, cast of difference to unsigned is OK
if (static_cast<unsigned>(length-pos) < sizeof(ChunkHeader))
throw FormatException{"Remaining size < header size"};
ChunkHeader header;
if (fread(&header, sizeof(ChunkHeader), 1, iffFile) != 1) {
@@ -109,11 +119,10 @@ void parseChunk(FILE* iffFile, off_t start, off_t length, unsigned level = 0)
for (unsigned i = 0;i < level;++i)
putchar('\t');
printf("Type: %.4s, Length: %u (0x%x)", header.typeID, header.length, header.length);
if (memcmp(header.typeID, "FORM", 4) == 0) {
if (header.length > (length-(pos+8))) {
throw FormatException{"Length in header > remaining parent size"};
}
if (header.length > (length-(pos+8)))
throw FormatException{"Length in header > remaining parent size"};
if (memcmp(header.typeID, "FORM", 4) == 0) {
char subType[4];
if (fread(&subType, 4, 1, iffFile) != 1) {
throw POSIXException(errno, "Could not read form subtype");
@@ -126,10 +135,9 @@ void parseChunk(FILE* iffFile, off_t start, off_t length, unsigned level = 0)
parseBlob(iffFile, start+pos+8, header.length, header.typeID, level+1);
}
if (header.length%2 != 0)
pos += 1;
pos += header.length+8;
if (pos%2 != 0)
++pos;
}
}