reman3/Rayman_X/cpa/tempgrp/FIL/FIL_Tga.c

282 lines
13 KiB
C

#if defined(WIN32)
#include <direct.h>
#include <io.h>
#endif /* WIN32 */
#include "FIL_CPA.h"
#define D_FIL_StructureDefine
#include "ErmFil.h"
#include "FIL_Pub.h"
#include "FIL_Priv.h"
#include "FIL_Tga.h"
#include "MMG.h"
/**************************************************************************/
/*
EXTERN CPA_EXPORT void FIL_fn_vTGASaveInFile(char *p_szFileName, unsigned char ucNumberOfBytesInSource, FIL_tdstBitmapData *_p_stSource )
{
}
*/
/**************************************************************************/
FILE *FIL_fn_hTGAOpenFile( char *_p_szPath, char *_p_szFileName, FIL_tdstTga *_p_stTga )
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
FILE *p_stFile;
char szCompleteName[_MAX_PATH];
unsigned char ucBpp, ucDesc, ucCode;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
if ( *_p_szPath != 0)
sprintf(szCompleteName, "%s\\%s", _p_szPath, _p_szFileName);
else
sprintf(szCompleteName,"%s", _p_szFileName);
if ( (p_stFile = fopen(szCompleteName,"rb")) !=NULL)
{
fread(&_p_stTga->stFileHeader,sizeof(struct FIL_tdstTgaFileHeader_),1,p_stFile);
ucBpp = _p_stTga->stFileHeader.stImageSpecification.ucPixelSize;
ucDesc = _p_stTga->stFileHeader.stImageSpecification.ucDescriptorByte;
ucCode = _p_stTga->stFileHeader.ucImageTypeCode;
if (
( ucBpp != 24 || ucDesc != 0 ) && ( ucBpp != 32 || ( ucDesc != 0 && ucDesc != 8) ) && ( ucBpp!=8 || ( ucDesc != 0 && ucDesc != 8) )
||( ucCode !=1 &&ucCode!=2 && ucCode != 3 && ucCode != 10)
)
{
M_FILInformationErrorWithMessage(E_uwFILBadTgaFormat, szCompleteName);
fclose( p_stFile );
p_stFile = NULL;
}
}
return p_stFile;
}
/**************************************************************************/
void FIL_fn_vTGALoadInformationFromFile(char *p_szPath,char *p_szFileName, struct FIL_tdstGF_ *_p_stHeader )
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
FILE *p_stFile;
struct FIL_tdstTga_ stTga;
struct FIL_tdstFileHeader_ *p_stFileHeader = &(_p_stHeader -> stFileHeader);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
p_stFile = FIL_fn_hTGAOpenFile( p_szPath, p_szFileName, &stTga );
if (p_stFile == NULL)
{
p_stFileHeader->ucBpcInPalette = 0;
p_stFileHeader->ucBpp = 0;
p_stFileHeader->ulWidth = 0;
p_stFileHeader->ulHeight = 0;
return;
}
p_stFileHeader->ulWidth = (unsigned long)stTga.stFileHeader.stImageSpecification.uwWidth;
p_stFileHeader->ulHeight = (unsigned long)stTga.stFileHeader.stImageSpecification.uwHeight;
p_stFileHeader->ucBpp = (unsigned char)(stTga.stFileHeader.stImageSpecification.ucPixelSize/8);
p_stFileHeader->ucBpcInPalette = (unsigned char)(stTga.stFileHeader.stColorMapSpecification.ucEntrySize/8);
/*
if (stTga.stFileHeader.ucImageTypeCode==1) //*** No compression in palette ***
{
//VL
//*p_ucNumberOfBytesInDest = (unsigned char)(stTga.stFileHeader.stColorMapSpecification.ucEntrySize/8);
*p_ucNumberOfBytesInDest = (unsigned char)(stTga.stFileHeader.stImageSpecification.ucPixelSize/8);
*p_ucPaletteDepth = (unsigned char)(stTga.stFileHeader.stColorMapSpecification.ucEntrySize/8);
//EVL
}
else if (stTga.stFileHeader.ucImageTypeCode==3) //*** No compression 8 bits (gray levels) ***
*p_ucNumberOfBytesInDest = 3;
else
*p_ucNumberOfBytesInDest = (unsigned char)(stTga.stFileHeader.stImageSpecification.ucPixelSize/8);
*/
fclose(p_stFile);
}
/**************************************************************************/
#ifndef RETAIL
void FIL_fn_vTGALoadFromFileWithInvertPicture(char *p_szPath,char *p_szFileName, FIL_tdstGF *_p_stHeader )
{
FIL_fn_vTGALoadFromFileWithoutInvertPicture(p_szPath, p_szFileName, _p_stHeader );
if ( _p_stHeader->p_ucBitMap != NULL )
FIL_fn_vTGAInvert( _p_stHeader );
}
#endif /*RETAIL*/
/**************************************************************************/
void FIL_fn_vTGALoadFromFileWithoutInvertPicture(char *p_szPath, char *p_szFileName, FIL_tdstGF *_p_stHeader)
{
FILE *p_stFile;
struct FIL_tdstTga_ stTga;
unsigned long i,j;
unsigned char ucCount;
unsigned char ucColorTable[4]; /**** RGBA ****/
unsigned long ulBitmapSize;
struct FIL_tdstFileHeader_ *p_stFileHeader = &(_p_stHeader -> stFileHeader);
stTga.p_ucBitMap = NULL;
stTga.ucColorMapData = NULL;
memset( _p_stHeader, 0, sizeof( FIL_tdstGF ) );
p_stFile = FIL_fn_hTGAOpenFile( p_szPath, p_szFileName, &stTga );
if (p_stFile == NULL)
return;
p_stFileHeader->ulWidth = (unsigned long)stTga.stFileHeader.stImageSpecification.uwWidth;
p_stFileHeader->ulHeight = (unsigned long)stTga.stFileHeader.stImageSpecification.uwHeight;
p_stFileHeader->ucBpp = (unsigned char)(stTga.stFileHeader.stImageSpecification.ucPixelSize/8);
p_stFileHeader->ucBpcInPalette = (unsigned char)(stTga.stFileHeader.stColorMapSpecification.ucEntrySize/8);
p_stFileHeader->uwNbColorInPalette = stTga.stFileHeader.stColorMapSpecification.uwLength;
ulBitmapSize = p_stFileHeader->ulWidth * p_stFileHeader->ulHeight * p_stFileHeader->ucBpp;
if (stTga.stFileHeader.ucImageTypeCode==1) /**** No compression in palette ****/
{
if ( p_stFileHeader->ucBpp != 1 || p_stFileHeader->ucBpcInPalette != 3)
{
char szCompleteName[MAX_PATH];
sprintf( szCompleteName, "%s\\%s", p_szPath, p_szFileName );
M_FILInformationErrorWithMessage( E_uwFILBadTgaFormat, szCompleteName);
}
else
{
MMG_fn_vAddMemoryInfo (MMG_C_lTypeFile , MMG_C_lSubTypeTgaFile , NULL);
stTga.p_ucBitMap = (unsigned char *) TMP_M_p_Malloc (max(ulBitmapSize, p_stFileHeader->uwNbColorInPalette * sizeof(RGBQUAD)) );
fseek(p_stFile, sizeof(struct FIL_tdstTgaFileHeader_) + stTga.stFileHeader.ucNumberOfCharInIdentField, SEEK_SET);
MMG_fn_vAddMemoryInfo (MMG_C_lTypeFile , MMG_C_lSubTypeTgaFile , NULL);
stTga.ucColorMapData = (unsigned char *) TMP_M_p_Malloc ( p_stFileHeader->uwNbColorInPalette * sizeof(RGBQUAD) );
/*fread( stTga.ucColorMapData, p_stFileHeader->ucBpcInPalette, p_stFileHeader->uwNbColorInPalette, p_stFile);*/
/* We first put the colormap in the bitmap field, then we convert it into the colormap field */
fread( stTga.p_ucBitMap, p_stFileHeader->ucBpcInPalette, p_stFileHeader->uwNbColorInPalette, p_stFile);
for (i=0 ; i<p_stFileHeader->uwNbColorInPalette ; i++)
{
stTga.ucColorMapData[i*sizeof(RGBQUAD)+0] = stTga.p_ucBitMap[i*p_stFileHeader->ucBpcInPalette + 0];
stTga.ucColorMapData[i*sizeof(RGBQUAD)+1] = stTga.p_ucBitMap[i*p_stFileHeader->ucBpcInPalette + 1];
stTga.ucColorMapData[i*sizeof(RGBQUAD)+2] = stTga.p_ucBitMap[i*p_stFileHeader->ucBpcInPalette + 2];
stTga.ucColorMapData[i*sizeof(RGBQUAD)+3] = 0xff;
}
/* Then we read the bitmap */
fread( stTga.p_ucBitMap, 1, ulBitmapSize, p_stFile);
/*TMP_M_Free(stTga.ucColorMapData);*/
}
}
else if (stTga.stFileHeader.ucImageTypeCode == 2) /**** No compression 24 or 32 bits ****/
{
MMG_fn_vAddMemoryInfo (MMG_C_lTypeFile , MMG_C_lSubTypeTgaFile , NULL);
stTga.p_ucBitMap = (unsigned char *) TMP_M_p_Malloc( ulBitmapSize );
fseek(p_stFile, sizeof(struct FIL_tdstTgaFileHeader_) + stTga.stFileHeader.ucNumberOfCharInIdentField + stTga.stFileHeader.stColorMapSpecification.uwLength, SEEK_SET);
fread(stTga.p_ucBitMap, 1, ulBitmapSize, p_stFile);
}
else if (stTga.stFileHeader.ucImageTypeCode == 3) /**** No compression 8 bits (gray levels) ****/
{
p_stFileHeader->ucBpp = 3;
MMG_fn_vAddMemoryInfo (MMG_C_lTypeFile , MMG_C_lSubTypeTgaFile , NULL);
stTga.p_ucBitMap = (unsigned char *) TMP_M_p_Malloc( ulBitmapSize );
fseek(p_stFile, sizeof(struct FIL_tdstTgaFileHeader_) + stTga.stFileHeader.ucNumberOfCharInIdentField + stTga.stFileHeader.stColorMapSpecification.uwLength, SEEK_SET);
for(i=0;i < p_stFileHeader->ulWidth * p_stFileHeader->ulHeight ; i++)
{
fread(&ucCount,sizeof(unsigned char),1,p_stFile);
memset(stTga.p_ucBitMap + i * p_stFileHeader->ucBpp , ucCount, p_stFileHeader->ucBpp);
}
}
else if (stTga.stFileHeader.ucImageTypeCode==10) /**** RLE compression 24 or 32 bits ****/
{
MMG_fn_vAddMemoryInfo (MMG_C_lTypeFile , MMG_C_lSubTypeTgaFile , NULL);
stTga.p_ucBitMap = (unsigned char *)TMP_M_p_Malloc( ulBitmapSize );
fseek(p_stFile, sizeof(struct FIL_tdstTgaFileHeader_) +stTga.stFileHeader.ucNumberOfCharInIdentField +stTga.stFileHeader.stColorMapSpecification.uwLength, SEEK_SET);
for(i=0;i < p_stFileHeader->ulWidth * p_stFileHeader->ulHeight ;)
{
fread(&ucCount,sizeof(unsigned char),1,p_stFile);
if (ucCount&0x80) /**** RLE package ****/
{
ucCount = (unsigned char)((ucCount&0x7f)+1);
fread(ucColorTable,sizeof(unsigned char), p_stFileHeader->ucBpp, p_stFile);
for (j=0;j<(unsigned long)ucCount;j++)
{
memcpy(stTga.p_ucBitMap+i * p_stFileHeader->ucBpp, ucColorTable, p_stFileHeader->ucBpp );
i++;
}
}
else /**** Raw package ****/
{
ucCount = (unsigned char)((ucCount&0x7f)+1);
for (j=0;j<(unsigned long)ucCount;j++)
{
fread(ucColorTable,sizeof(unsigned char),p_stFileHeader->ucBpp,p_stFile);
memcpy(stTga.p_ucBitMap+i*p_stFileHeader->ucBpp,ucColorTable,p_stFileHeader->ucBpp);
i++;
}
}
}
}
fclose(p_stFile);
_p_stHeader->p_ucBitMap = stTga.p_ucBitMap;
_p_stHeader->p_ucPalette = stTga.ucColorMapData;
}
/**************************************************************************/
void FIL_fn_vTGALoadInformationFromConcatFile(FIL_tdxHandleToConcatFile hConcatFile,char *p_szPath,char *p_szFileName, struct FIL_tdstGF_ *_p_stHeader)
{
FIL_fn_vTGALoadInformationFromFile(p_szPath,p_szFileName, _p_stHeader );
}
/**************************************************************************/
void FIL_fn_vTGALoadFromConcatFileWithInvertPicture(FIL_tdxHandleToConcatFile hConcatFile,char *p_szPath,char *p_szFileName, struct FIL_tdstGF_ *_p_stHeader )
{
FIL_fn_vTGALoadFromConcatFileWithoutInvertPicture(hConcatFile, p_szPath, p_szFileName, _p_stHeader);
if ( _p_stHeader->p_ucBitMap != NULL)
FIL_fn_vTGAInvert( _p_stHeader );
}
/**************************************************************************/
void FIL_fn_vTGALoadFromConcatFileWithoutInvertPicture(FIL_tdxHandleToConcatFile hConcatFile,char *p_szPath,char *p_szFileName,struct FIL_tdstGF_ *_p_stHeader )
{
FIL_fn_vTGALoadFromFileWithoutInvertPicture(p_szPath,p_szFileName,_p_stHeader);
}
/**************************************************************************/
void FIL_fn_vTGAFree( unsigned char **pp_ucMemory )
{
if (*pp_ucMemory!=NULL)
TMP_M_Free(*pp_ucMemory);
*pp_ucMemory = NULL;
}
/**************************************************************************/
void FIL_fn_vTGAInvert( struct FIL_tdstGF_ *_p_stHeader )
{
unsigned char *p_ucOneLine,*p_ucBlockStart;
unsigned long y, ulLineSize;
struct FIL_tdstFileHeader_ *p_stFileHeader = &(_p_stHeader -> stFileHeader);
MMG_fn_vAddMemoryInfo (MMG_C_lTypeFile , MMG_C_lSubTypeTgaFile , NULL);
ulLineSize = p_stFileHeader->ulWidth * p_stFileHeader->ucBpp;
p_ucOneLine = (unsigned char *) TMP_M_p_Malloc ( ulLineSize );
p_ucBlockStart = _p_stHeader->p_ucBitMap;
/* GuS : palette is now stored into the filed ucColorMapData
if(p_stFileHeader->ucBpp == 1)
{
p_ucBlockStart += 256 * sizeof(RGBQUAD);
}
*/
for (y=0; y < p_stFileHeader->ulHeight / 2 ; y++)
{
memcpy( p_ucOneLine , p_ucBlockStart + y * ulLineSize , ulLineSize);
memcpy( p_ucBlockStart + y * ulLineSize , p_ucBlockStart+(p_stFileHeader->ulHeight - 1 - y) * ulLineSize, ulLineSize);
memcpy( p_ucBlockStart + (p_stFileHeader->ulHeight - 1 - y) * ulLineSize, p_ucOneLine , ulLineSize);
}
TMP_M_Free(p_ucOneLine);
}
/**************************************************************************/