From cdea281ca67ff2e0c11ce0f2df0e2245b5f65b1f Mon Sep 17 00:00:00 2001 From: Giel van Schijndel Date: Sun, 27 May 2007 15:50:56 +0000 Subject: [PATCH] * now load resources of type "IMG" directly from their file rather than an intermediate memory buffer * make definitions of IMAGEHEADER and IMAGEDEF safe for loading on systems with different sizes for datatypes * Allocate IMAGEDEF in a function of its own: iV_AllocImageFile (uses only one malloc call so we don't need to go and toy with lots free() calls on failure) * Use PHYSFS_read* functions for endian correctness (rather than the endian_*word stuff) git-svn-id: svn+ssh://svn.gna.org/svn/warzone/trunk@1719 4a71c877-e1ca-e34f-864e-861f7616d084 --- lib/ivis_common/bitimage.c | 102 ++++++++++++++++++++----------------- lib/ivis_common/bitimage.h | 2 +- lib/ivis_common/ivisdef.h | 35 ++++++------- src/data.c | 13 ++--- 4 files changed, 79 insertions(+), 73 deletions(-) diff --git a/lib/ivis_common/bitimage.c b/lib/ivis_common/bitimage.c index 5f25a17be..7b7ceea71 100644 --- a/lib/ivis_common/bitimage.c +++ b/lib/ivis_common/bitimage.c @@ -26,6 +26,7 @@ #include "ivispatch.h" #include "bitimage.h" #include "lib/framework/frameresource.h" +#include static BOOL LoadTextureFile(const char *FileName, iTexture *pSprite, int *texPageID) @@ -59,82 +60,89 @@ static BOOL LoadTextureFile(const char *FileName, iTexture *pSprite, int *texPag return TRUE; } - -IMAGEFILE *iV_LoadImageFile(const char *FileData, WZ_DECL_UNUSED const UDWORD FileSize) +static inline IMAGEFILE* iV_AllocImageFile(size_t NumTPages, size_t NumImages) +{ + const size_t totalSize = sizeof(IMAGEFILE) + sizeof(iTexture) * NumTPages + sizeof(IMAGEDEF) * NumImages; + + IMAGEFILE* ImageFile = malloc(totalSize); + if (ImageFile == NULL) + { + debug(LOG_ERROR, "iV_AllocImageFile: Out of memory"); + return NULL; + } + + // Set member pointers to their respective areas in the allocated memory area + ImageFile->TexturePages = (iTexture*)(ImageFile + 1); + ImageFile->ImageDefs = (IMAGEDEF*)(ImageFile->TexturePages + NumTPages); + + return ImageFile; +} + +IMAGEFILE *iV_LoadImageFile(const char *fileName) { - const char *Ptr; - IMAGEHEADER *Header; IMAGEFILE *ImageFile; - IMAGEDEF *ImageDef; - unsigned int i = 0; + IMAGEDEF* ImageDef; + unsigned int i; - Ptr = FileData; + IMAGEHEADER Header; + PHYSFS_file* fileHandle; - Header = (IMAGEHEADER*)Ptr; - Ptr += sizeof(IMAGEHEADER); - - endian_uword(&Header->Version); - endian_uword(&Header->NumImages); - endian_uword(&Header->BitDepth); - endian_uword(&Header->NumTPages); - - ImageFile = (IMAGEFILE*)malloc(sizeof(IMAGEFILE)); - if(ImageFile == NULL) { - debug( LOG_ERROR, "Out of memory" ); + fileHandle = PHYSFS_openRead(fileName); + if (!fileHandle) + { + debug(LOG_ERROR, "iV_LoadImageFromFile: PHYSFS_openRead failed (opening %s) with error: %s", fileName, PHYSFS_getLastError()); return NULL; } + // Read header from file + PHYSFS_read (fileHandle, &Header.Type, sizeof(Header.Type), 1); + PHYSFS_readULE16 (fileHandle, &Header.Version); + PHYSFS_readULE16 (fileHandle, &Header.NumImages); + PHYSFS_readULE16 (fileHandle, &Header.BitDepth); + PHYSFS_readULE16 (fileHandle, &Header.NumTPages); + PHYSFS_read (fileHandle, &Header.TPageFiles, sizeof(Header.TPageFiles), 1); + PHYSFS_read (fileHandle, &Header.PalFile, sizeof(Header.PalFile), 1); - ImageFile->TexturePages = (iTexture*)malloc(sizeof(iTexture)*Header->NumTPages); - if(ImageFile->TexturePages == NULL) { - debug( LOG_ERROR, "Out of memory" ); + ImageFile = iV_AllocImageFile(Header.NumTPages, Header.NumImages); + if(ImageFile == NULL) + { return NULL; } - ImageFile->ImageDefs = (IMAGEDEF*)malloc(sizeof(IMAGEDEF)*Header->NumImages); - if(ImageFile->ImageDefs == NULL) { - debug( LOG_ERROR, "Out of memory" ); - return NULL; - } - - ImageFile->Header = *Header; + ImageFile->Header = Header; // Load the texture pages. - for (i = 0; i < Header->NumTPages; i++) { + for (i = 0; i < Header.NumTPages; i++) { int tmp=0; /* Workaround for MacOS gcc 4.0.0 bug. */ - LoadTextureFile((char*)Header->TPageFiles[i], + LoadTextureFile((char*)Header.TPageFiles[i], &ImageFile->TexturePages[i], &tmp); ImageFile->TPageIDs[i] = tmp; } - ImageDef = (IMAGEDEF*)Ptr; + for(ImageDef = &ImageFile->ImageDefs[0]; ImageDef != &ImageFile->ImageDefs[Header.NumImages]; ++ImageDef) + { + // Read image definition from file + PHYSFS_readULE16(fileHandle, &ImageDef->TPageID); + PHYSFS_readULE16(fileHandle, &ImageDef->PalID); + PHYSFS_readULE16(fileHandle, &ImageDef->Tu); + PHYSFS_readULE16(fileHandle, &ImageDef->Tv); + PHYSFS_readULE16(fileHandle, &ImageDef->Width); + PHYSFS_readULE16(fileHandle, &ImageDef->Height); + PHYSFS_readSLE16(fileHandle, &ImageDef->XOffset); + PHYSFS_readSLE16(fileHandle, &ImageDef->YOffset); - for(i=0; iNumImages; i++) { - endian_uword(&ImageDef->TPageID); - endian_uword(&ImageDef->PalID); - endian_uword(&ImageDef->Tu); - endian_uword(&ImageDef->Tv); - endian_uword(&ImageDef->Width); - endian_uword(&ImageDef->Height); - endian_sword(&ImageDef->XOffset); - endian_sword(&ImageDef->YOffset); - - ImageFile->ImageDefs[i] = *ImageDef; if( (ImageDef->Width <= 0) || (ImageDef->Height <= 0) ) { - debug( LOG_ERROR, "Illegal image size" ); + debug( LOG_ERROR, "iV_LoadImageFromFile: Illegal image size" ); + free(ImageFile); return NULL; } - ImageDef++; } return ImageFile; } - void iV_FreeImageFile(IMAGEFILE *ImageFile) { - free(ImageFile->TexturePages); - free(ImageFile->ImageDefs); free(ImageFile); } diff --git a/lib/ivis_common/bitimage.h b/lib/ivis_common/bitimage.h index 8afb91439..fde16a03a 100644 --- a/lib/ivis_common/bitimage.h +++ b/lib/ivis_common/bitimage.h @@ -63,7 +63,7 @@ WZ_DECL_PURE static inline unsigned short iV_GetImageCenterY(const IMAGEFILE *Im } -IMAGEFILE *iV_LoadImageFile(const char *FileData, const UDWORD FileSize); +IMAGEFILE *iV_LoadImageFile(const char *fileName); void iV_FreeImageFile(IMAGEFILE *ImageFile); #endif diff --git a/lib/ivis_common/ivisdef.h b/lib/ivis_common/ivisdef.h index fe937ce41..95f3c76ab 100644 --- a/lib/ivis_common/ivisdef.h +++ b/lib/ivis_common/ivisdef.h @@ -140,33 +140,34 @@ typedef struct iIMDShape { //************************************************************************* typedef struct { - UBYTE Type[4]; - UWORD Version; - UWORD NumImages; - UWORD BitDepth; - UWORD NumTPages; - UBYTE TPageFiles[16][16]; - UBYTE PalFile[16]; + char Type[4]; + uint16_t Version; + uint16_t NumImages; + uint16_t BitDepth; + uint16_t NumTPages; + char TPageFiles[16][16]; + char PalFile[16]; } IMAGEHEADER; typedef struct { - UWORD TPageID; - UWORD PalID; - UWORD Tu,Tv; - unsigned short Width; - unsigned short Height; - short XOffset; - short YOffset; + uint16_t TPageID; + uint16_t PalID; + uint16_t Tu; + uint16_t Tv; + uint16_t Width; + uint16_t Height; + int16_t XOffset; + int16_t YOffset; } IMAGEDEF; typedef struct { IMAGEHEADER Header; iTexture *TexturePages; - UWORD NumCluts; - UWORD TPageIDs[16]; - UWORD ClutIDs[48]; + unsigned short NumCluts; + unsigned short TPageIDs[16]; + unsigned short ClutIDs[48]; IMAGEDEF *ImageDefs; } IMAGEFILE; diff --git a/src/data.c b/src/data.c index 78fb832eb..de91ca2e4 100644 --- a/src/data.c +++ b/src/data.c @@ -825,17 +825,14 @@ static void dataHWTERTILESRelease(void *pData) } -static BOOL dataIMGLoad(char *pBuffer, UDWORD size, void **ppData) +static BOOL dataIMGLoad(const char *fileName, void **ppData) { - IMAGEFILE *ImageFile; - - ImageFile = iV_LoadImageFile(pBuffer,size); - if(ImageFile == NULL) { + *ppData = iV_LoadImageFile(fileName); + if(*ppData == NULL) + { return FALSE; } - *ppData = ImageFile; - return TRUE; } @@ -1160,7 +1157,6 @@ static const RES_TYPE_MIN_BUF BufferResourceTypes[] = {"SCRIPTVAL", dataScriptLoadVals, NULL}, {"STR_RES", dataStrResLoad, dataStrResRelease}, {"TERTILES", NULL, NULL}, // This version was used when running with the software renderer. - {"IMG", dataIMGLoad, dataIMGRelease}, {"IMD", dataIMDBufferLoad, (RES_FREE)iV_IMDRelease}, }; @@ -1179,6 +1175,7 @@ static const RES_TYPE_MIN_FILE FileResourceTypes[] = {"ANIMCFG", dataAnimCfgLoad, NULL}, {"IMGPAGE", dataIMGPAGELoad, dataIMGPAGERelease}, {"HWTERTILES", dataHWTERTILESLoad, dataHWTERTILESRelease}, // freed by 3d shutdow},// Tertiles Files. This version used when running with hardware renderer. + {"IMG", dataIMGLoad, dataIMGRelease}, {"TEXPAGE", dataTexPageLoad, dataTexPageRelease}, };