195 lines
5.1 KiB
C++
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;
|
|
}
|