Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

drago

Targa (*.tga) info

This topic is 6927 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Advertisement
Here''s some source for reading Targas that works with RLE images. Don''t know how it''ll look but should cut and paste legibly. Does not handle 4-bit.

void SSImage::ReadTga( FILE *File, int ReadFlags )
{
Targa Header;
int EndOfImageData;
char Footer[ 26 ];
int Count;

fseek( File, -26, SEEK_END );
fread( (void *) Footer, 1, 26, File );
if ( strcmp( &Footer[ 8 ], "TRUEVISION-XFILE." ) != 0 )
{
EndOfImageData = ftell( File );
}
else
{
if ( ( ( long * )Footer )[ 0 ] )
{
EndOfImageData = ( ( long * )Footer )[ 0 ];
}
else
{
EndOfImageData = ftell( File ) - 26;
}
if ( ( ( long * )Footer )[ 1 ] )
{
if ( ( ( long * )Footer )[ 1 ] < EndOfImageData )
{
EndOfImageData = ( ( long * )Footer )[ 1 ];
}
}
}

fseek( File, 0, SEEK_SET );

if ( fread( (void *) &Header, 1, sizeof( Targa ), File ) != sizeof( Targa ) )
{
Flags /= SSI_READ_FAILED_F;
SSI_MESSAGEBOX( "FileHeader Read Failed", "Error", MB_ICONERROR );
}
else
{
Width = Header.Width;
Height = Header.Height;
BitCount = Header.PixelDepth;
RowLength = Width * BitCount / 8;

// Ignore the Image ID
if ( Header.IDLength )
{
fseek( File, Header.IDLength, SEEK_CUR );
}

// Check for a palette
if ( Header.ColorMapType )
{
unsigned int Length;
int ColorMapLength;

ColorMapLength = Header.ColorMapLength[ 0 ] / ( Header.ColorMapLength[ 1 ] << 8 );

ASSERT( !(Header.ColorMapEntrySize & 7) );
Length = ColorMapLength * ( Header.ColorMapEntrySize >> 3 );

if ( ReadFlags & RI_PALETTE_F )
{
Palette = new unsigned char [ Length ];

if ( fread( (void *) Palette, 1, Length, File ) != Length )
{
Flags /= SSI_READ_FAILED_F;
SSI_MESSAGEBOX( "Palette Read Failed", "Error", MB_ICONERROR );
}
else
{
Flags /= SSI_PALETTE_LOADED_F;
}
}
else
{
fseek( File, Length, SEEK_CUR );
}
}

if ( ReadFlags & RI_IMAGE_F )
{
// Read image
switch ( Header.ImageType )
{
case IT_RGB:
case IT_COLORMAPPED:
// Should handle 4-bit files at some point
ASSERT( !(BitCount & 7) );
Image = new unsigned char [ Width * Height * BitCount / 8 ];
ASSERT( ( Header.ImageDescriptor & 0x10 ) == 0 );
for ( Count = 0; Count < Height; Count++ )
{
if ( fread( (void *) &Image[ ( ( Header.ImageDescriptor & 0x20 ) ? Count : Height - 1 - Count ) * RowLength ], 1, RowLength, File ) != ( unsigned int ) RowLength )
{
Flags /= SSI_READ_FAILED_F;
SSI_MESSAGEBOX( "Couldn''t read uncompressed image", "Error", MB_ICONERROR );
break;
}
}
Flags /= SSI_IMAGE_LOADED_F;
break;
case IT_RLE_RGB:
case IT_RLE_COLORMAPPED:
char *Compressed;
unsigned int Length;
Length = EndOfImageData - ftell( File );
Compressed = new char [ Length ];
if ( fread( (void *) Compressed, 1, Length, File ) != Length )
{
Flags /= SSI_READ_FAILED_F;
SSI_MESSAGEBOX( "Couldn''t read compressed image", "Error", MB_ICONERROR );
}
else
{
unsigned int ImagePos;
unsigned int CompressedPos;
Image = new unsigned char [ Width * Height * BitCount / 8 ];
ImagePos = 0;
CompressedPos = 0;

while ( CompressedPos < Length && !( Flags & SSI_READ_FAILED_F ) )
{
int CopyCount;
unsigned char *CurrentRow;

CopyCount = ( ( Compressed[ CompressedPos ] & 0x7f ) + 1 ) * BitCount / 8;

CurrentRow = &Image[ ( ( Header.ImageDescriptor & 0x20 ) ? ImagePos / RowLength : ( Height - 1 - ImagePos / RowLength ) ) * RowLength ];
if ( Compressed[ CompressedPos ] & 0x80 )
{
for ( Count = 0; !( Flags & SSI_READ_FAILED_F ) && Count < CopyCount; Count++ )
{
CurrentRow[ ImagePos++ % RowLength ] = Compressed[ CompressedPos + 1 + ( Count % (BitCount/8) ) ];
}
CompressedPos += 1 + ( BitCount >> 3 );
}
else
{
memcpy( &CurrentRow[ ImagePos % RowLength ], &Compressed[ CompressedPos + 1 ], CopyCount );
ImagePos += CopyCount;
CompressedPos += 1 + CopyCount;
}
}

Flags /= SSI_IMAGE_LOADED_F;
ASSERT( int( ImagePos ) == Width * Height * BitCount / 8 );
}
delete [] Compressed;
break;
default:
Flags /= SSI_READ_FAILED_F;
SSI_MESSAGEBOX( "Unsupported TGA Image Type", "Error", MB_ICONERROR );
break;
}
}

if ( Flags & SSI_READ_FAILED_F )
{
if ( SSI_PALETTE_LOADED_F )
{
delete [] Palette;
Palette = NULL;
}
if ( SSI_IMAGE_LOADED_F )
{
delete [] Image;
Image = NULL;
}
Flags &= ~( SSI_INFO_LOADED_F / SSI_PALETTE_LOADED_F / SSI_IMAGE_LOADED_F );
}
else
{
// The image was read successfully
Flags /= SSI_INFO_LOADED_F;
}
}
}

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!