147 lines
4.2 KiB
C++
147 lines
4.2 KiB
C++
////////////////////////////////////////////////////////////////////
|
|
// ImageTGA.cpp
|
|
//
|
|
// Copyright 2007 cDc@seacave
|
|
// Distributed under the Boost Software License, Version 1.0
|
|
// (See http://www.boost.org/LICENSE_1_0.txt)
|
|
|
|
#include "Common.h"
|
|
|
|
#ifdef _IMAGE_TGA
|
|
#include "ImageTGA.h"
|
|
|
|
using namespace SEACAVE;
|
|
|
|
|
|
// D E F I N E S ///////////////////////////////////////////////////
|
|
|
|
#pragma pack(push, 1)
|
|
typedef struct TGAINFOHEADER_TYPE {
|
|
BYTE byIDLength; // ID length
|
|
BYTE byCMType; // Color map type
|
|
BYTE byType; // Image type
|
|
struct { // Color map specifications
|
|
uint16_t shCMIdx; // First entry index, offset into the color map table
|
|
uint16_t shCMLength; // Color map length, number of entries
|
|
BYTE byCMBPP; // Color map entry size, number of bits per pixel
|
|
};
|
|
struct { // Image specifications
|
|
uint16_t shXOrigin; // X-origin, absolute coordinate of lower-left corner for displays where origin is at the lower left
|
|
uint16_t shYOrigin; // Y-origin, as for X-origin
|
|
uint16_t shWidth; // Image width, width in pixels
|
|
uint16_t shHeight; // Image height, width in pixels
|
|
BYTE byBPP; // Pixel depth, bits per pixel
|
|
union {
|
|
BYTE byAlphaInfo; // Image descriptor, bits 3-0 give the alpha channel depth, bits 4-5 give direction
|
|
struct {
|
|
BYTE byAlphaBPP : 3;// alpha channel depth
|
|
BYTE bMirrored : 1;// alpha channel depth
|
|
BYTE bFlipped : 1;// alpha channel depth
|
|
BYTE : 0;// Force alignment to next boundary.
|
|
};
|
|
};
|
|
};
|
|
} TGAINFOHEADER;
|
|
#pragma pack(pop)
|
|
|
|
|
|
|
|
// S T R U C T S ///////////////////////////////////////////////////
|
|
|
|
CImageTGA::CImageTGA()
|
|
{
|
|
} // Constructor
|
|
|
|
CImageTGA::~CImageTGA()
|
|
{
|
|
} // Destructor
|
|
/*----------------------------------------------------------------*/
|
|
|
|
|
|
HRESULT CImageTGA::ReadHeader()
|
|
{
|
|
// read header
|
|
((ISTREAM*)m_pStream)->setPos(0);
|
|
TGAINFOHEADER tgaInfo;
|
|
m_pStream->read(&tgaInfo, sizeof(TGAINFOHEADER));
|
|
if (tgaInfo.byCMType != 0) { // paletted images not supported
|
|
LOG(LT_IMAGE, "error: invalid TGA image");
|
|
return _INVALIDFILE;
|
|
}
|
|
|
|
m_dataWidth = m_width = tgaInfo.shWidth;
|
|
m_dataHeight = m_height = tgaInfo.shHeight;
|
|
m_numLevels = 0;
|
|
m_level = 0;
|
|
|
|
// get the format
|
|
m_stride = (tgaInfo.byBPP>>3);
|
|
switch (tgaInfo.byType)
|
|
{
|
|
case 2: //uncompressed, true-color image
|
|
case 3: //uncompressed, black-and-white image
|
|
m_format = (m_stride == 3 ? PF_R8G8B8 : PF_R8G8B8A8);
|
|
m_bRLE = false;
|
|
break;
|
|
//case 10://run-length encoded, true-color image and
|
|
// m_format = IF_3DC;
|
|
// m_bRLE = true;
|
|
// break;
|
|
default:
|
|
ASSERT(0);
|
|
LOG(LT_IMAGE, "error: unsupported TGA image");
|
|
return _INVALIDFILE;
|
|
}
|
|
|
|
m_lineWidth = m_width * m_stride;
|
|
|
|
// read the id stuff, not using seeking to be able to use non seekable sources
|
|
if (tgaInfo.byIDLength) {
|
|
CAutoPtrArr<uint8_t> const buffer(new uint8_t[tgaInfo.byIDLength]);
|
|
m_pStream->read(buffer, tgaInfo.byIDLength);
|
|
}
|
|
|
|
return _OK;
|
|
} // ReadHeader
|
|
/*----------------------------------------------------------------*/
|
|
|
|
|
|
HRESULT CImageTGA::ReadData(void* pData, PIXELFORMAT dataFormat, Size nStride, Size lineWidth)
|
|
{
|
|
// read data
|
|
if (dataFormat == m_format && nStride == m_stride) {
|
|
// read image directly to the data buffer
|
|
(BYTE*&)pData += (m_height-1)*lineWidth;
|
|
for (Size j=0; j<m_height; ++j, (uint8_t*&)pData-=lineWidth)
|
|
if (m_lineWidth != m_pStream->read(pData, m_lineWidth))
|
|
return _INVALIDFILE;
|
|
} else {
|
|
// read image to a buffer and convert it
|
|
CAutoPtrArr<uint8_t> const buffer(new uint8_t[m_lineWidth]);
|
|
for (Size j=0; j<m_height; ++j) {
|
|
if (m_lineWidth != m_pStream->read(buffer, m_lineWidth))
|
|
return _INVALIDFILE;
|
|
if (!FilterFormat((BYTE*)pData+(m_height-j-1)*lineWidth, dataFormat, nStride, buffer, m_format, m_stride, m_width))
|
|
return _FAIL;
|
|
}
|
|
}
|
|
return _OK;
|
|
} // ReadData
|
|
/*----------------------------------------------------------------*/
|
|
|
|
|
|
HRESULT CImageTGA::WriteHeader(PIXELFORMAT imageFormat, Size width, Size height, BYTE numLevels)
|
|
{
|
|
return _FAIL;
|
|
} // WriteHeader
|
|
/*----------------------------------------------------------------*/
|
|
|
|
|
|
HRESULT CImageTGA::WriteData(void* pData, PIXELFORMAT dataFormat, Size nStride, Size lineWidth)
|
|
{
|
|
return _FAIL;
|
|
} // WriteData
|
|
/*----------------------------------------------------------------*/
|
|
|
|
#endif // _IMAGE_TGA
|