00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "Common/Assert.h"
00012 #include "Common/Error.h"
00013
00014 #include "Bitmap/Tga.h"
00015
00016
00017 KTga::KTga()
00018 : KBitmap()
00019 {
00020 }
00021
00022
00023 KTga::~KTga()
00024 {
00025 }
00026
00027
00028 s32 KTga::LoadTGA( const char* pFileName )
00029 {
00030 bool bHasPalette = false;
00031 bool bIsColorMapped = false;
00032 bool bCompressed = false;
00033 KRgba* pPalette = NULL;
00034
00035
00036 if( !Open( pFileName ) )
00037 return false;
00038
00039 *this >> m_Header;
00040
00041 switch( m_Header.m_ImageType )
00042 {
00043 case KFTT_NODATA:
00044 return true;
00045 case KFTT_COLORMAP:
00046 bHasPalette = true;
00047 bIsColorMapped = true;
00048 bCompressed = false;
00049 break;
00050 case KFTT_TRUECOLOR:
00051 bHasPalette = false;
00052 bIsColorMapped = false;
00053 bCompressed = false;
00054 break;
00055 case KFTT_BLACKWHITE:
00056 bHasPalette = true;
00057 bIsColorMapped = false;
00058 bCompressed = false;
00059 break;
00060 case KFTT_RLECOLORMAP:
00061 bHasPalette = true;
00062 bIsColorMapped = true;
00063 bCompressed = true;
00064 break;
00065 case KFTT_RLETRUECOLOR:
00066 bHasPalette = false;
00067 bIsColorMapped = false;
00068 bCompressed = true;
00069 break;
00070 case KFTT_RLEBLACKWHITE:
00071 bHasPalette = true;
00072 bIsColorMapped = false;
00073 bCompressed = true;
00074 break;
00075 default:
00076 KError::FatalError( NULL, "KTga::LoadTGA(...) : Unknown TGA image type : %i", m_Header.m_ImageType );
00077 break;
00078 }
00079
00080 m_Width = m_Header.m_ISWidth;
00081 m_Height = m_Header.m_ISHeight;
00082
00083 switch( m_Header.m_ISBpp )
00084 {
00085 case 8:
00086 m_Bpp = 32;
00087 m_bAlpha = false;
00088 break;
00089 case 15:
00090 m_Bpp = 32;
00091 m_bAlpha = false;
00092 break;
00093 case 16:
00094 m_Bpp = 32;
00095 m_bAlpha = true;
00096 break;
00097 case 24:
00098 m_Bpp = 32;
00099 m_bAlpha = false;
00100 break;
00101 case 32:
00102 m_Bpp = 32;
00103 m_bAlpha = true;
00104 break;
00105 }
00106
00107 m_OriginTop = (m_Header.m_ISDesc & 0x20) ? true : false;
00108 m_OriginRight = (m_Header.m_ISDesc & 0x10) ? true : false;
00109
00110
00111 if( bHasPalette )
00112 {
00113 u32 p;
00114 u8* pBuffer;
00115 u8* pPtr;
00116
00117 Seek( m_Header.m_CMFirstEntry, KFS_CURRENT );
00118
00119 pBuffer = new u8[m_Header.m_CMFLength * (m_Header.m_CMEntrySize / 8)];
00120 pPalette = new KRgba[m_Header.m_CMFLength];
00121
00122 Read( pBuffer, m_Header.m_CMFLength * m_Header.m_CMEntrySize );
00123 pPtr = pBuffer;
00124
00125 for( p = 0; p < m_Header.m_CMFLength; p ++ )
00126 {
00127 KRgba* pPix = &pPalette[ p ];
00128
00129 switch( m_Header.m_CMEntrySize )
00130 {
00131 case 8:
00132 {
00133 u8 Color;
00134 Color = *pPtr++;
00135 pPix->r = Color;
00136 pPix->g = Color;
00137 pPix->b = Color;
00138 pPix->a = Color;
00139 break;
00140 }
00141 case 15:
00142 {
00143 u16 Color;
00144 Color = *pPtr++;
00145 pPix->r = ((Color & 0x0000001F)) * 8;
00146 pPix->g = ((Color & 0x000003E0) >> 5) * 8;
00147 pPix->b = ((Color & 0x00007C00) >> 10) * 8;
00148 pPix->a = 255;
00149 break;
00150 }
00151 case 16:
00152 {
00153 u16 Color;
00154 Color = *pPtr++;
00155 pPix->r = ((Color & 0x0000001F)) * 8;
00156 pPix->g = ((Color & 0x000003E0) >> 5) * 8;
00157 pPix->b = ((Color & 0x00007C00) >> 10) * 8;
00158 pPix->a = ((Color & 0x00008000) >> 15) * 255;
00159 break;
00160 }
00161 case 24:
00162 {
00163 pPix->r = *pPtr++;
00164 pPix->g = *pPtr++;
00165 pPix->b = *pPtr++;
00166 pPix->a = 255;
00167 break;
00168 }
00169 case 32:
00170 {
00171 pPix->r = *pPtr++;
00172 pPix->g = *pPtr++;
00173 pPix->b = *pPtr++;
00174 pPix->a = *pPtr++;
00175 break;
00176 }
00177 default:
00178 KError::FatalError( NULL, "KTga::LoadTGA(...) : Unsupported Bpp : %i", m_Header.m_ISBpp );
00179 return false;
00180 }
00181 }
00182
00183 Deletev( pBuffer );
00184 }
00185
00186
00187 u32 x, y;
00188 u32 rx, ry;
00189 u8* pBuffer;
00190 u8* pPtr;
00191 u32 RLESize = 0;
00192 u8 RLEPacket;
00193 int bRLELength = false;
00194
00195 ry = m_OriginTop ? 0 : (m_Height - 1);
00196
00197 m_pBitmap = new KRgba[ m_Width * m_Height ];
00198 pBuffer = new u8[m_Header.m_ISWidth * m_Header.m_ISHeight * (m_Header.m_ISBpp / 8)];
00199 Read( pBuffer, m_Header.m_ISWidth * m_Header.m_ISHeight * (m_Header.m_ISBpp / 8) );
00200 pPtr = pBuffer;
00201
00202 for( y = 0; y < m_Height; y ++ )
00203 {
00204 rx = m_OriginRight ? (m_Width - 1) : 0;
00205
00206 for( x = 0; x < m_Width; x ++ )
00207 {
00208 KASSERT( ry * m_Width + rx < m_Width * m_Height );
00209 KRgba* pPix = &m_pBitmap[ ry * m_Width + rx ];
00210
00211 if( bCompressed && !RLESize )
00212 {
00213 RLEPacket = *pPtr++;
00214 RLESize = (RLEPacket & 0x7F) + 1;
00215 bRLELength = RLEPacket & 0x80;
00216 }
00217
00218 if( bIsColorMapped )
00219 {
00220 u8 Index;
00221 Index = *pPtr++;
00222 KASSERT( Index < m_Header.m_CMFLength );
00223 *pPix = pPalette[Index];
00224 }
00225 else
00226 switch( m_Header.m_ISBpp )
00227 {
00228 case 8:
00229 {
00230 u8 Color;
00231 Color = *pPtr; if( !bCompressed || bRLELength ) pPtr++;
00232 pPix->r = Color;
00233 pPix->g = Color;
00234 pPix->b = Color;
00235 pPix->a = Color;
00236 break;
00237 }
00238 case 15:
00239 {
00240 u16 Color;
00241 Color = *pPtr; if( !bCompressed || bRLELength ) pPtr++;
00242 pPix->r = ((Color & 0x0000001F)) * 8;
00243 pPix->g = ((Color & 0x000003E0) >> 5) * 8;
00244 pPix->b = ((Color & 0x00007C00) >> 10) * 8;
00245 pPix->a = 255;
00246 break;
00247 }
00248 case 16:
00249 {
00250 u16 Color;
00251 Color = *pPtr; if( !bCompressed || bRLELength ) pPtr++;
00252 pPix->r = ((Color & 0x0000001F)) * 8;
00253 pPix->g = ((Color & 0x000003E0) >> 5) * 8;
00254 pPix->b = ((Color & 0x00007C00) >> 10) * 8;
00255 pPix->a = ((Color & 0x00008000) >> 15) * 255;
00256 break;
00257 }
00258 case 24:
00259 {
00260 if( bCompressed )
00261 {
00262 pPix->r = *pPtr++;
00263 pPix->g = *pPtr++;
00264 pPix->b = *pPtr++;
00265 pPix->a = 255;
00266
00267 if( RLESize > 0 )
00268 RLESize --;
00269
00270 if( ( RLESize > 0 ) && bRLELength )
00271 pPtr -= 3;
00272 }
00273 else
00274 {
00275 pPix->r = *pPtr++;
00276 pPix->g = *pPtr++;
00277 pPix->b = *pPtr++;
00278 pPix->a = 255;
00279 }
00280 break;
00281 }
00282 case 32:
00283 {
00284 if( bCompressed )
00285 {
00286 pPix->r = *pPtr++;
00287 pPix->g = *pPtr++;
00288 pPix->b = *pPtr++;
00289 pPix->a = *pPtr++;
00290
00291 if( RLESize > 0 )
00292 RLESize --;
00293
00294 if( ( RLESize > 0 ) && bRLELength )
00295 pPtr -= 4;
00296 }
00297 else
00298 {
00299 pPix->r = *pPtr++;
00300 pPix->g = *pPtr++;
00301 pPix->b = *pPtr++;
00302 pPix->a = *pPtr++;
00303 }
00304 break;
00305 }
00306 default:
00307 KError::FatalError( NULL, "KTga::LoadTGA(...) : Unsupported Bpp : %i", m_Header.m_ISBpp );
00308 return false;
00309 }
00310
00311
00312 rx += m_OriginRight ? -1 : 1;
00313 }
00314 ry += m_OriginTop ? 1 : -1;
00315 }
00316
00317 Deletev( pBuffer );
00318
00319
00320 Close();
00321
00322 if( pPalette )
00323 Deletev( pPalette );
00324
00325 return true;
00326 }