Jump to content
  • Advertisement
Sign in to follow this  
glGLU

How to saving TGA

This topic is 4842 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
Are you talking about in game, like screenshots, or outside of game? If in game, you should probably use a image library. I believe DevIL supports saving compressed TGA. If outside of game you can use a number of image editing programs. I prefer the Gimp.

Share this post


Link to post
Share on other sites
Quote:
Original post by SiCrane
Are you talking about in game, like screenshots, or outside of game? If in game, you should probably use a image library. I believe DevIL supports saving compressed TGA. If outside of game you can use a number of image editing programs. I prefer the Gimp.

In game, it is desirable without additional libraries... If who has an example of saving compress tga?

[Edited by - glGLU on August 17, 2005 9:09:23 AM]

Share this post


Link to post
Share on other sites
Both the projects I linked to are open source. You can get their source code for saving compressed targa files.

Share this post


Link to post
Share on other sites
Hang on... you don't want to write it yourself, but you don't want to use a library - instead you want to paste in code from somewhere else. I assume this is because you want to make sure you don't have the reusability and stability a library can offer, but want to make sure you don't learn anything implementing it yourself?

What's wrong with libraries?

Share this post


Link to post
Share on other sites
the link philipptr posted contains all the information needed to implement a loader/saver for compressed tga i will implement the 4 data types describe on this page into my own image library as well

thx phillipptr thats an excellent resource for TGAs :)

Share this post


Link to post
Share on other sites
The matter is that I need to create the format on the basis of tga. And the ready library does not approach for this problem...

Share this post


Link to post
Share on other sites
Here is some code of my upcoming library, it shall be able to load .tga, .bmp, .raw,.img*(a image format that i setup kind of like DDS just with support for pregenerated mipmaps)*
the library will support tga raw and .img saving later on
maybe i ll even support jpgs

the loading code for uncompressed RGB tgas works i have used it in several engine projects

the code for run length encoded TGAs should work since i exactly followed the documentation philipptr posted above but it is *UNTESTED* so don t blaim me if a bug occurs :)

anyways have fun with it


*EDIT: forgot to mention you probably have to switch the red and blue components
after loading the RLE compressed TGA *just moved the swap code out of the uncompressed loading code*

namespace cross
{
//the standard cross image class
class image
{
public:
enum
{
MAX_TGA_HEADER_SIZE = 12,
MAX_FILENAME_LENGTH = 128,
PIXEL_PACKET_HEADER_FLAG = 0x80,
PIXEL_PACKET_HEADER_COUNT = 0x7F,
MAX_BYTES_PER_PIXEL = 4,
};
enum tga_m
{
IMG_TGA_UNCOMPRESSED_COLORMAP = 1,
IMG_TGA_UNCOMPRESSED_RGB = 2,
IMG_TAG_COMPRESSED_RLE_COLORMAP = 9,
IMG_TGA_COMPRESSED_RLE_RGB = 10,
};
enum img_colors_m
{
COLOR_RGB = 1,
COLOR_RGBA = 2,
COLOR_GRAYSCALE = 3,
COLOR_GRAYSCALE_ALPHA = 4,
};

class headerTGA
{
public:
ubyte8 m_uiIdentificationFieldLendth;
ubyte8 m_uiColorMapType;
ubyte8 m_uiImageType;
uint16 m_uiColorMapOrigin;
uint16 m_uiColorMapLength;
ubyte8 m_uiColorMapDepth;
uint16 m_uiLowerLeftCornerX;
uint16 m_uiLowerLeftCornerY;
uint16 m_uiWidth;
uint16 m_uiHeight;
ubyte8 m_uiPixelDepth;
ubyte8 m_uiImageDescriptorByte;
};
public:
// constructor
image()
{
m_uiBytes = 0;
m_uiFlags = 0;
m_uiWidth = 0;
m_uiHeight = 0;
m_uiVersion = 0;
m_uiBits = 0;
m_uiBytesPerPixel = 0;
m_uiType = 0;
m_pBuffer = NULL;
m_strFilename.reserve(MAX_FILENAME_LENGTH);
};

// load an arbitrary image
BOOL loadimage(const std::string strFilename, uint32 uiWidth = 0, uint32 uiHeight = 0)
{
if(strFilename.length() == 0)
return FALSE;


// search for file extensions to find the correct image loading function
//load .tga images
if(strFilename.find(".tga")!=std::string.npos)
{
if(loadtga(strFilename)==FALSE)
return FALSE;
}
//load .raw images
else if(strFilename.find(".raw") != std::string.npos)
{
if(uiWidth == 0 || uiHeight == 0)
return FALSE;

if(loadraw(strFilename, uiWidth, uiHeight) == FALSE)
return FALSE;
}
//load .img images
else if(strFilename.find(".img") != std::string.npos)
{
loadimg(strFilename);
}
//load .bmp images
else if(strFilename.find(".bmp") != std::string.npos)
{
loadbmp(strFilename);
}
m_strFilename = strFilename;

return TRUE;
};

// load .tga files
BOOL loadtga(const std::string strFilename)
{
std::ifstream file;
std::ios::pos_type sSize = 0;
uint32 i=0;
uint32 a=0;
uint32 b=0;
uint32 pixels;
ubyte8 ubSwap = 0;
ubyte8 ubHeader = 0;
ubyte8 ubCount =0;
ubyte8 ubPixel[MAX_BYTES_PER_PIXEL];

file.open(strFilename.c_str());

if(!file)
return FALSE;

//extract the header
file.read(reinterpret_cast<byte8*>(&header.tga),sizeof(headerTGA));

//set image properties
setbits(header.tga.m_uiPixelDepth);
setwidth(static_cast<uint32>(header.tga.m_uiWidth));
setheight(static_cast<uint32>(header.tga.m_uiHeight));

//calculate the number of pixels we have to read
pixels = m_uiWidth*m_uiHeight;

//try to create a buffer
if(createbuffer(pixels*m_uiBytesPerPixel) == FALSE)
{
file.close();
return FALSE;
}

switch(header.tga.m_uiImageType)
{
case IMG_TGA_UNCOMPRESSED_RGB:

//seek to the beginning of the image data field
file.seekg(18,std::ios::beg);

//read in the buffer
file.read(reinterpret_cast<byte8*>(m_pBuffer),m_uiBytes);

break;
case IMG_TGA_COMPRESSED_RLE_RGB:

//seek to the beginning of the image data field
file.seekg(18,std::ios::beg);

i=0;
//read until pixels pixels have been read
while(i<pixels)
{
//read the pixel header
file.read(reinterpret_cast<byte8*>(&ubHeader),sizeof(ubyte8));

//RLE encoded?
if(ubHeader & PIXEL_PACKET_HEADER_FLAG)
{
ubCount = ubHeader &PIXEL_PACKET_HEADER_COUNT + 1;

file.read(reinterpret_cast<byte8*>(ubPixel),m_uiBytesPerPixel);

for(a=0;a<ubCount;a++,i+=m_uiBytesPerPixel)
{
for(b=0;b<m_uiBytesPerPixel;b++)
{
m_pBuffer[i+b] = ubPixel;
}
}
}
}
break;
case IMG_TAG_COMPRESSED_RLE_COLORMAP:
break;
case IMG_TGA_UNCOMPRESSED_COLORMAP:
break;
}

//swap the red and blue components
for(i=0;i<m_uiBytes;i+=m_uiBytesPerPixel)
{
ubSwap = m_pBuffer;
m_pBuffer = m_pBuffer[i+2];
m_pBuffer[i+2] = ubSwap;
}

file.close();

return TRUE;
};

// load .raw files without header
BOOL loadraw(const std::string strFilename, uint32 uiWidth, uint32 uiHeight)
{
std::ifstream file;
std::ios::pos_type sSize = 0;

file.open(strFilename.c_str());

if(!file)
return FALSE;

if(createbuffer(uiWidth*uiHeight) == FALSE)
{
file.close();
return FALSE;
}

//get the file size
file.seekg(0,std::ios::end);
sSize = file.tellg();
file.seekg(0,std::ios::beg);
file.clear();

//see if the file is as large as specified
if(sSize < static_cast<int32>(uiWidth*uiHeight) )
{
file.close();
return FALSE;
}

file.read(reinterpret_cast<byte8*>(m_pBuffer),sSize);

file.close();

//set image dimensions
setwidth(uiWidth);
setheight(uiHeight);
setbits(8);

return TRUE;
};

//load .bmp files
BOOL loadbmp(const std::string strFilename)
{
return FALSE;
};

// load .img files, the standard format of the cross library
BOOL loadimg(const std::string strFilename)
{
return FALSE;
};

// save as .img file (used for converting images
BOOL saveimg(const std::string strFilename)
{
return FALSE;
};
private:
// create the storage buffer
BOOL createbuffer(uint32 uiSize)
{
if(uiSize == 0)
return FALSE;

if((m_pBuffer = new ubyte8[uiSize]) == NULL)
return FALSE;

m_uiBytes = uiSize;

return TRUE;
};

//set the image width
void setwidth(uint32 uiWidth)
{
m_uiWidth = uiWidth;
};

//set the image height
void setheight(uint32 uiHeight)
{
m_uiHeight = uiHeight;
};

//set the bits per pixel
void setbits(ubyte8 bits)
{
m_uiBits = bits;
setbytes_per_pixel(m_uiBits/8);
};

//set bytes per pixel
void setbytes_per_pixel(ubyte8 bytes)
{
m_uiBytesPerPixel = bytes;
};
private:
uint32 m_uiBytes;
uint32 m_uiFlags;
uint16 m_uiWidth;
uint16 m_uiHeight;
uint16 m_uiVersion;
ubyte8 m_uiBits;
ubyte8 m_uiBytesPerPixel;
ubyte8 m_uiType;
union imageHeaders
{
headerTGA tga;
}header;

ubyte8 *m_pBuffer;

std::string m_strFilename;
};
};

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

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

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!