diff --git a/include/devil1pld.h b/include/devil1pld.h index a128a81..d57bfd7 100644 --- a/include/devil1pld.h +++ b/include/devil1pld.h @@ -2,20 +2,27 @@ #define DEVIL1PLD_H #include +#include +#pragma pack(push, 1) + struct PldHeader { int32_t numOffset; // array of numOffset elements uint32_t *offsets; // }; -// input: contents of the .pld file. -// allocates heap memory -struct PldHeader *getpldh(const char*); +#pragma pack(pop) -// frees heap memory -void destroypldh(struct PldHeader*); +// input: pointer to a struct, contents of the .pld file. +// * = pass by reference of a struct PldHeader +bool getpldh(struct PldHeader*, const char*); + +// input: pointer to header, index of offset, filesize +// * = pass by reference of a struct PldHeader +int sizeofpldstruct(struct PldHeader*, unsigned int, unsigned int); // input: a pld header struct. -void showpldh(struct PldHeader*); +// * = pass by reference of a struct PldHeader +void printpldh(struct PldHeader*); #endif \ No newline at end of file diff --git a/src/devil1pld.c b/src/devil1pld.c index d7a760b..bc0e378 100644 --- a/src/devil1pld.c +++ b/src/devil1pld.c @@ -1,34 +1,32 @@ #include "devil1pld.h" #include -#include -#include -struct PldHeader *getpldh(const char *filedata) { - if (filedata == NULL) { - return NULL; +bool getpldh(struct PldHeader *ph, const char *filedata) { + bool good = false; + if (ph != NULL && filedata != NULL) { + ph -> numOffset = (int32_t)filedata[0]; + ph -> offsets = (uint32_t*)(filedata + sizeof(int32_t)); + good = true; } - int32_t *n = (int32_t*)filedata; - struct PldHeader *ph = (struct PldHeader*)malloc( - sizeof(struct PldHeader) - ); - uint32_t size_offsets = sizeof(uint32_t) * n[0]; - ph -> offsets = (uint32_t*)malloc(size_offsets); - if (ph -> offsets == NULL) { - perror("Error 4: "); - free(ph); - free(ph -> offsets); - return NULL; - } - // set data of struct. - ph -> numOffset = n[0]; - memcpy(ph -> offsets, filedata + sizeof(int32_t), size_offsets); - return ph; + return good; } -void destroypldh(struct PldHeader *ph) { - free(ph -> offsets); - free(ph); - ph = NULL; +// determine the size of the i-th pld structure +int sizeofpldstruct(struct PldHeader *ph, unsigned int i, unsigned int max) { + unsigned int size = -1; + if (ph == NULL) { + fprintf(stderr, "Error: given null pointer\n"); + return size; + } + if (i > ph -> numOffset) { + fprintf(stderr, "Error: i exceeds pldHeader -> numOffset\n"); + return size; + } + unsigned int start = 0, end = 0; + start = ph -> offsets[i]; + end = (i == (ph -> numOffset) - 1) ? max : ph -> offsets[i + 1]; + size = end - start; + return size; } void printpldh(struct PldHeader *ph) { @@ -36,6 +34,7 @@ void printpldh(struct PldHeader *ph) { return; } printf("number of offsets = %i\n", ph -> numOffset); + printf("offsets = %x\n", ph -> offsets); unsigned int i; for (i = 0; i < ph -> numOffset; i++) { printf("offset %i = %x\n", i, ph -> offsets[i]); diff --git a/test/main.c b/test/main.c index 25e8c21..6bf10b0 100644 --- a/test/main.c +++ b/test/main.c @@ -6,47 +6,6 @@ #include "devil1pld.h" #include "devil1tex.h" -bool writedata(const char *basename, - unsigned int id, - const char *data, - unsigned int dsize) { - bool status = false; - char *fn = (char*)malloc(sizeof(char) * strlen(basename) + 4); - sprintf(fn, "%s_%d", basename, id); - FILE *out = fopen(fn, "w"); - if (out != NULL) { - fwrite(data, sizeof(char), dsize, out); - fclose(out); - status = true; - } - free(fn); - return status; -} - -void splitpld(const char *filedata, - unsigned int filesize, - const struct PldHeader *ph, - const char *name) { - char *wbuffer = NULL; // write buffer that will change. - unsigned int wsize = 0; // size of wbuffer. - unsigned int i; - unsigned int start = 0; // ending offset for data - unsigned int end = 0; // ending offset for data - for (i = 0; (i + 1) < (ph -> numOffset) + 1; i++) { - start = ph -> offsets[i]; - // the last offset still has some data until the end of file - end = (i == (ph -> numOffset) - 1) ? - filesize : ph -> offsets[i + 1]; - // copy sector to write buffer - wsize = end - start; - wbuffer = (char*)malloc(sizeof(char) * wsize); - memcpy(wbuffer, filedata + start, wsize); - // create a file. - writedata(name, i, wbuffer, wsize); - free(wbuffer); - } -} - char *loadfile(const char *fname, unsigned int *s) { FILE *f = fopen(fname, "rb"); unsigned int size = 0; // number of elements to buffer; @@ -76,20 +35,6 @@ char *loadfile(const char *fname, unsigned int *s) { return buf; } -bool unpackpld (const char *filedata, - unsigned int filesize, - const char *filename) { - bool status = false; - printf("fsize is %i\n", filesize); - if (filedata != NULL && filesize != 0) { - struct PldHeader *pldh = getpldh(filedata); - splitpld(filedata, filesize, pldh, filename); - destroypldh(pldh); - status = true; - } - return status; -} - void write(const char *filename, const char* t, unsigned int size) { @@ -107,6 +52,27 @@ void write(const char *filename, } } +bool unpackpld(const char *filedata, + unsigned int filesize, + const char *filename) { + if (filedata == NULL || filesize <= 0) { + return false; + } + struct PldHeader h; + getpldh(&h, filedata); + char *fn = NULL; + fn = (char*)malloc(strlen(filename) + 3 + 4); + int size = 0; + unsigned int i = 0; + for (i = 0; i < h.numOffset; i++) { + size = sizeofpldstruct(&h, i, filesize); + sprintf(fn, "%s_%d", filename, i); + write(fn, filedata + h.offsets[i], size); + } + free(fn); + return true; +} + void exporttextures(const char *filedata, unsigned int filesize, const char *filename) { @@ -142,8 +108,8 @@ int main(int argc, char ** argv) { char *f = argv[1]; unsigned int bufsize = 0; char *buffer = loadfile(f, &bufsize); -// unpackpld(buffer, bufsize, f); - exporttextures(buffer, bufsize, f); + unpackpld(buffer, bufsize, f); +// exporttextures(buffer, bufsize, f); free(buffer); return 0; }