Files
2025-11-24 14:19:51 +05:30

195 lines
5.1 KiB
C++

/*
* This file was taken from RakNet 4.082 without any modifications.
* Please see licenses/RakNet license.txt for the underlying license and related copyright.
*/
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include "DXTCompressor.h"
/* ------------------------------------------------------------------------------------------------------------------------------------ */
bool LoadTGAFromFile( const char* pFilename, void **image, int* width, int* height )
{
typedef struct
{
char identsize;
char colourmaptype;
char imagetype;
unsigned short colourmapstart;
unsigned short colourmaplength;
char colourmapbits;
unsigned short xstart;
unsigned short ystart;
unsigned short width;
unsigned short height;
char bits;
char descriptor;
} TGA_HEADER;
// Open the file
FILE* pic;
if((pic=fopen( pFilename, "rb"))==NULL )
{
return false;
}
// Zero out the header
TGA_HEADER TGAheader;
memset(&TGAheader,0,sizeof(TGA_HEADER));
// Read the header
fread(&TGAheader.identsize,sizeof(char),1,pic);
fread(&TGAheader.colourmaptype,sizeof(char),1,pic);
fread(&TGAheader.imagetype,sizeof(char),1,pic);
fread(&TGAheader.colourmapstart,sizeof(unsigned short),1,pic);
fread(&TGAheader.colourmaplength,sizeof(unsigned short),1,pic);
fread(&TGAheader.colourmapbits,sizeof(char),1,pic);
fread(&TGAheader.xstart,sizeof(unsigned short),1,pic);
fread(&TGAheader.ystart,sizeof(unsigned short),1,pic);
fread(&TGAheader.width,sizeof(unsigned short),1,pic);
fread(&TGAheader.height,sizeof(unsigned short),1,pic);
fread(&TGAheader.bits,sizeof(char),1,pic);
fread(&TGAheader.descriptor,sizeof(char),1,pic);
*width = TGAheader.width;
*height = TGAheader.height;
int DataSize = TGAheader.width*TGAheader.height*4;
// Read the pixels
*image = new char[DataSize];
if ((TGAheader.descriptor>>5) & 1)
{
// Right side up
fread(*image, sizeof(char),DataSize, pic);
}
else
{
//Upside down
for (int row=TGAheader.height-1; row >=0; row--)
{
fread(((char*) (*image))+row*TGAheader.width*TGAheader.bits/8, TGAheader.bits/8, TGAheader.width, pic);
}
}
// Close the file
fclose(pic);
// TGA is stored on disk BGRA
// Endian swap bits so that the image is actually in RGBA format
if( TGAheader.bits == 32 )
{
unsigned char* pRunner = (unsigned char*)*image;
for( int i = 0; i < DataSize; i+=4 )
{
char color[4] =
{
pRunner[ 0 ],
pRunner[ 1 ],
pRunner[ 2 ],
pRunner[ 3 ],
};
pRunner[ 0 ] = color[ 2 ];
pRunner[ 1 ] = color[ 1 ];
pRunner[ 2 ] = color[ 0 ];
pRunner[ 3 ] = color[ 3 ];
pRunner += 4;
}
}
return true;
}
/* ------------------------------------------------------------------------------------------------------------------------------------ */
int main( int argc, const char* argv[] )
{
// Initialize the compressor
DXTCompressor::Initialize();
// Load sample .tga
void* pSourceData;
int w, h;
//bool bFileLoaded = LoadTGAFromFile( "1600x1200.tga", &pSourceData, &w, &h );
bool bFileLoaded = LoadTGAFromFile( "320x200.tga", &pSourceData, &w, &h );
if( bFileLoaded )
{
// Test performance
// const int numIterations = 100;
// for( int i = 0; i < numIterations; i++ )
// {
// // Compress the data
// void* pOutputData;
// int outputLength;
// bool bCompressSuccess = DXTCompressor::CompressRGBAImageData( DXT1, pSourceData, w, h, &pOutputData, &outputLength, false );
//
// // Clean up
// delete [] pOutputData;
// pOutputData = NULL;
// }
// Print total stats
// printf( "\n\n****Total stats on %d iterations****\n", numIterations );
// DXTCompressor::PrintPerformanceLog();
// Now test saving to DDS memory file
{
// Compress the data
// void* pCompressedOutput;
// int compressedOutputLength;
// bool bCompressSuccess = DXTCompressor::CompressRGBAImageData( DXT1, pSourceData, w, h, &pCompressedOutput, &compressedOutputLength, false );
char *outputData;
int bufferSize = DXTCompressor::GetBufferSize(DXT1,
w,
h);
int ddsHeaderSize = DXTCompressor::GetDDSHeaderSize();
outputData = (char*) malloc(bufferSize + ddsHeaderSize );
bool bCompressSuccess = DXTCompressor::CompressRGBAImageData(
DXT1,
pSourceData,
w,
h,
outputData+ddsHeaderSize, false );
if( bCompressSuccess )
{
// Save DDS file
// void* pOutputDDSFile;
// int outputDDSFileLength;
// DXTCompressor::WriteDDSMemoryFile( DXT1, w, h, pCompressedOutput, compressedOutputLength, &pOutputDDSFile, &outputDDSFileLength );
// Clean up
// delete [] pCompressedOutput;
// pCompressedOutput = NULL;
// delete [] pOutputDDSFile;
// pOutputDDSFile = NULL;
DXTCompressor::WriteDDSHeader(DXT1,
w,
h,
bufferSize,
outputData);
FILE *fp = fopen("DXTCompressorTGAtoDDS.dds", "wb");
fwrite(outputData,1,bufferSize + ddsHeaderSize,fp);
fclose(fp);
free(outputData);
}
}
}
// Shutdown the compressor
DXTCompressor::Shutdown();
return 0;
}