aboutsummaryrefslogtreecommitdiffstats
path: root/image-parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'image-parser.c')
-rw-r--r--image-parser.c63
1 files changed, 30 insertions, 33 deletions
diff --git a/image-parser.c b/image-parser.c
index cb385cc..b135101 100644
--- a/image-parser.c
+++ b/image-parser.c
@@ -16,24 +16,21 @@
#include <sys/stat.h>
#include <sys/mman.h>
-#define MAGIC 0xFEEDBABE
-
-struct Header { /* Big Endian */
- uint32_t magic; /* 0xFEEDBABE */
- uint32_t len; /* Length of file excluding header */
- uint32_t checksum; /* 32-bit sum of all bytes in file and header, excluding checksum */
- uint32_t counter; /* Unknown */
- uint32_t start_offset; /* Unknown */
- char name[0x80]; /* File name */
-} __attribute__((packed));
-
+#define RG_MAGIC 0xFEEDBABE
+#define HEADER_SIZE ( sizeof(uint32_t) * 5 + 0x80 )
struct File {
- struct Header header;
- uint8_t *data;
- uint32_t decompressed_size;
- uint8_t *decompressed_data;
+ uint32_t magic; /* FEEDBABE */
+ uint32_t size; /* Length of file excluding header */
+ uint32_t checksum; /* 32-bit sum of all bytes in file and header, excluding checksum */
+ uint32_t counter; /* Unknown */
+ uint32_t start_offset; /* Unknown */
+ char name[0x80]; /* Filename */
+ uint8_t *data; /* Pointer to mmap'd or allocated data of file */
+ uint32_t decompressed_size; /* Decompressed length of file */
+ uint8_t *decompressed_data; /* Pointer to allocated decompressed data */
};
+
uint8_t* decompress_data(uint8_t *data, uint32_t compressed_length, uint32_t decompressed_length)
{
uint8_t *decompressed_data;
@@ -81,7 +78,7 @@ uint32_t checksum(uint8_t *data, uint32_t length)
while (length--) {
/* The checksum does not include itself, so we skip that field. */
- if (length >= offsetof(struct Header, checksum) && length < offsetof(struct Header, counter))
+ if (length >= 8 && length < 12)
continue;
sum += data[length];
}
@@ -91,33 +88,33 @@ uint32_t checksum(uint8_t *data, uint32_t length)
bool read_file(uint8_t *data, struct File *file)
{
- memcpy(&file->header, data, sizeof(file->header));
- file->header.magic = be32toh(file->header.magic);
- file->header.len = be32toh(file->header.len);
- file->header.checksum = be32toh(file->header.checksum);
- file->header.counter = be32toh(file->header.counter);
- file->header.start_offset = be32toh(file->header.start_offset);
- file->header.name[0x7f] = '\0';
-
- file->data = data + sizeof(file->header);
+ uint32_t *packed_integers = (uint32_t *)data;
+ file->magic = be32toh(packed_integers[0]);
+ file->size = be32toh(packed_integers[1]);
+ file->checksum = be32toh(packed_integers[2]);
+ file->counter = be32toh(packed_integers[3]);
+ file->start_offset = be32toh(packed_integers[4]);
+ memcpy(&file->name, &packed_integers[5], sizeof(file->name));
+ file->name[0x7f] = '\0';
+ file->data = data + HEADER_SIZE;
file->decompressed_data = NULL;
file->decompressed_size = 0;
- if (!strcmp(file->header.name, "rg_conf")) {
+ if (!strcmp(file->name, "rg_conf")) {
/* When the file is gzipped, the length of the decompressed file is
* the first four bytes in big endian. */
file->decompressed_size = be32toh(*((uint32_t *)file->data));
- file->decompressed_data = decompress_data(file->data + sizeof(uint32_t), file->header.len - sizeof(uint32_t), file->decompressed_size);
+ file->decompressed_data = decompress_data(file->data + sizeof(uint32_t), file->size - sizeof(uint32_t), file->decompressed_size);
if (!file->decompressed_data)
file->decompressed_size = 0;
}
- return file->header.magic == MAGIC && file->header.checksum == checksum(data, sizeof(file->header) + file->header.len);
+ return file->magic == RG_MAGIC && file->checksum == checksum(data, HEADER_SIZE + file->size);
}
void print_file(struct File *file, bool valid)
{
- printf("==== %s (%s) ====\n", file->header.name, valid ? "Valid Checksum" : "INVALID CHECKSUM");
- printf("Length: %u bytes\n", file->header.len);
+ printf("==== %s (%s) ====\n", file->name, valid ? "Valid Checksum" : "INVALID CHECKSUM");
+ printf("Length: %u bytes\n", file->size);
if (file->decompressed_size)
printf("Decompressed Length: %u bytes\n", file->decompressed_size);
}
@@ -128,7 +125,7 @@ void save_file(struct File *file, bool valid, uint32_t offset)
char *slash;
int fd;
- sprintf(filename, "%#.8x-%s%s", offset, file->header.name, valid ? "" : ".corrupt");
+ sprintf(filename, "%#.8x-%s%s", offset, file->name, valid ? "" : ".corrupt");
for (slash = filename; (slash = strchr(slash, '/')) != NULL; ++slash)
*slash = '_';
@@ -145,7 +142,7 @@ void save_file(struct File *file, bool valid, uint32_t offset)
exit(EXIT_FAILURE);
}
} else {
- if (write(fd, file->data, file->header.len) < 0) {
+ if (write(fd, file->data, file->size) < 0) {
perror("write");
exit(EXIT_FAILURE);
}
@@ -184,7 +181,7 @@ int main(int argc, char *argv[])
return EXIT_FAILURE;
}
- needle = htobe32(MAGIC);
+ needle = htobe32(RG_MAGIC);
next = data;
for (;;) {
next = memmem(next, sbuf.st_size - (next - data), &needle, sizeof(needle));