* Libraries are now being compiled only as static or as shared, not both, quickening the compile process.

* Implemented the rewrite of the iff library, submitted by Propeng. The linked list has been completely replaced with vectors or normal arrays.
* Started work on the cur and tga parsers
This commit is contained in:
Fatbag 2012-04-29 00:44:41 -05:00
parent 5c7a36592e
commit 55659f43b5
25 changed files with 685 additions and 525 deletions

View file

@ -14,25 +14,57 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "iff.h"
#ifndef __inline
#define __inline
#endif
#ifndef __restrict
#define __restrict
#endif
/****
** Supported Chunks
*/
#define iff_register(x) \
int iff_parse_##x(IFFChunk *, const uint8_t *); \
void iff_free_##x(void *)
int iff_parse_rsmp(IFFChunk * ChunkInfo, const uint8_t * Buffer, unsigned IFFSize);
int iff_free_rsmp(void * FormattedData);
/* The order of these chunks must remain the same throughout this block: */
iff_register(bcon);
iff_register(str);
iff_register(trcn);
const char chunktypes[] =
"STR#" "CTSS" "FAMs" "TTAs"
"BCON"
"TRCN"
;
int (* const iff_parse_function[])(IFFChunk*, const uint8_t*) = {
iff_parse_str, iff_parse_str, iff_parse_str, iff_parse_str,
iff_parse_bcon,
iff_parse_trcn
};
void (* const iff_free_function[])(void*) = {
iff_free_str, iff_free_str, iff_free_str, iff_free_str,
iff_free_bcon,
iff_free_trcn
};
/* End */
/****
** API public functions
*/
IFFFile * iff_create()
{
IFFFile *ptr = malloc(sizeof(IFFFile));
IFFFile *ptr = calloc(1, sizeof(IFFFile));
if(ptr == NULL) return NULL;
memset(ptr, 0, sizeof(IFFFile));
ptr->Chunks = malloc(sizeof(IFFChunk));
if(ptr->Chunks == NULL){
free(ptr);
return NULL;
}
ptr->SizeAllocated = sizeof(IFFChunk);
return ptr;
}
@ -55,55 +87,20 @@ int iff_read_header(IFFFile * IFFFileInfo, const uint8_t * Buffer, unsigned File
return 1;
}
IFFChunkNode * iff_add_chunk(IFFFile * IFFFileInfo, int Position)
IFFChunk * iff_add_chunk(IFFFile * IFFFileInfo)
{
IFFChunkNode *ptr = malloc(sizeof(IFFChunkNode)), *node;
if(ptr == NULL) return NULL;
memset(ptr, 0, sizeof(IFFChunkNode));
if(IFFFileInfo == NULL) return ptr;
if(Position >= 0){
node = IFFFileInfo->FirstChunk;
if(node == NULL){
IFFFileInfo->FirstChunk = ptr;
IFFFileInfo->LastChunk = ptr;
}else{
/* Find the node we will take the place of */
while(Position-- && node->NextChunk != NULL)
node = node->NextChunk;
if(node->PrevChunk == NULL)
IFFFileInfo->FirstChunk = ptr;
/* Shift this node and all nodes after it above us */
ptr->PrevChunk = node->PrevChunk;
ptr->NextChunk = node;
node->PrevChunk = ptr;
}
}else{
node = IFFFileInfo->LastChunk;
if(node == NULL){
IFFFileInfo->FirstChunk = ptr;
IFFFileInfo->LastChunk = ptr;
}else{
/* Find the node we will take the place of */
while(++Position && node->PrevChunk != NULL)
node = node->PrevChunk;
if(node->NextChunk == NULL)
IFFFileInfo->LastChunk = ptr;
/* Shift this node and all nodes before it below us */
ptr->PrevChunk = node;
ptr->NextChunk = node->NextChunk;
node->NextChunk = ptr;
}
if((IFFFileInfo->ChunkCount+1)*sizeof(IFFChunk) > IFFFileInfo->SizeAllocated){
IFFChunk * ptr;
if(IFFFileInfo->SizeAllocated > SIZE_MAX/2) return NULL;
ptr = realloc(IFFFileInfo->Chunks, IFFFileInfo->SizeAllocated<<1);
if(ptr == NULL) return NULL;
IFFFileInfo->Chunks = ptr;
IFFFileInfo->SizeAllocated<<=1;
}
IFFFileInfo->ChunkCount++;
return ptr;
return IFFFileInfo->Chunks + IFFFileInfo->ChunkCount-1;
}
int iff_read_chunk(IFFChunk * ChunkInfo, const uint8_t * Buffer, unsigned MaxChunkSize)
@ -114,6 +111,7 @@ int iff_read_chunk(IFFChunk * ChunkInfo, const uint8_t * Buffer, unsigned MaxChu
return 0;
memcpy(ChunkInfo->Type, Buffer+0, 4);
ChunkInfo->Type[4] = 0x00;
ChunkInfo->Size = read_uint32be(Buffer+4);
ChunkInfo->ChunkID = read_uint16be(Buffer+8);
ChunkInfo->Flags = read_uint16be(Buffer+10);
@ -135,16 +133,62 @@ int iff_read_chunk(IFFChunk * ChunkInfo, const uint8_t * Buffer, unsigned MaxChu
int iff_enumerate_chunks(IFFFile * IFFFileInfo, const uint8_t * Buffer, unsigned BufferSize)
{
while(BufferSize){
IFFChunkNode * chunk = iff_add_chunk(IFFFileInfo, -1);
IFFChunk * chunk = iff_add_chunk(IFFFileInfo);
if(chunk == NULL)
return 0;
if(!iff_read_chunk(&chunk->Chunk, Buffer, BufferSize)){
free(chunk);
if(!iff_read_chunk(chunk, Buffer, BufferSize))
return 0;
}
Buffer += chunk->Chunk.Size;
BufferSize -= chunk->Chunk.Size;
Buffer += chunk->Size;
BufferSize -= chunk->Size;
}
return 1;
}
int iff_parse_chunk(IFFChunk * ChunkInfo, const uint8_t * Buffer){
unsigned i;
for(i=0; chunktypes[i*4] != '\0'; i++){
if(!memcmp(ChunkInfo->Type, chunktypes+i*4, 4)){
if(iff_parse_function[i](ChunkInfo, Buffer)) return 1;
iff_free_chunk(ChunkInfo->FormattedData);
return 0;
}
}
return 0;
}
void iff_free_chunk(IFFChunk * ChunkInfo){
unsigned i;
if(ChunkInfo == NULL || ChunkInfo->FormattedData) return;
for(i=0; chunktypes[i*4] != '\0'; i++){
if(!memcmp(ChunkInfo->Type, chunktypes+i*4, 4)){
if(iff_free_function[i])
iff_free_function[i](ChunkInfo->FormattedData);
free(ChunkInfo->FormattedData);
return;
}
}
}
void iff_delete(IFFFile * IFFFileInfo){
unsigned i;
if(IFFFileInfo == NULL) return;
if(IFFFileInfo->Chunks != NULL){
for(i=0; i<IFFFileInfo->ChunkCount; i++){
iff_free_chunk(IFFFileInfo->Chunks+i);
free(IFFFileInfo->Chunks[i].Data);
}
free(IFFFileInfo->Chunks);
}
if(IFFFileInfo->ResourceMap != NULL){
free(IFFFileInfo->ResourceMap->Data);
free(IFFFileInfo->ResourceMap->FormattedData);
free(IFFFileInfo->ResourceMap);
}
free(IFFFileInfo);
IFFFileInfo = NULL;
}