font2png, iffexplore: Misc. cleanup
This commit is contained in:
55
font2png.cc
55
font2png.cc
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user