//////////////////////////////////////////////////////////////////// // 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 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; jread(pData, m_lineWidth)) return _INVALIDFILE; } else { // read image to a buffer and convert it CAutoPtrArr const buffer(new uint8_t[m_lineWidth]); for (Size j=0; jread(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