00001 #include "ImageLoaders.h" 00002 #include "MercuryTextureManager.h" 00003 #include "MercuryFiles.h" 00004 #include "MercuryLog.h" 00005 00006 struct TGAHeader { 00007 char IDLen; //String <<after>> header 00008 char ColorMapType; //Should be zero 00009 char DataType; //Describes pixel type 00010 short ColorMapOrgin; //Ignore 00011 short ColorMapLength; //Ignore 00012 //char ColorMapDepth; //Ignore 00013 short x_origin; //Should be zero, ignore if not. 00014 short y_origin; //Should be zero, ignore if not. 00015 short width; //Important 00016 short height; //Important 00017 char bitsperpixel; //Bits per pixel 00018 char imagedescriptor; // 00019 }; 00020 00021 RawImageData* LoadTGA( MercuryFile * fp ) 00022 { 00023 TGAHeader MyHeader; 00024 char tc; 00025 int x; 00026 fp->Read( &MyHeader, sizeof( TGAHeader ) ); 00027 00028 if( MyHeader.ColorMapLength != 0 ) 00029 { 00030 LOG.Warn( "TGA Loading failed on file:" + fp->GetName() + " Colormaps not supported." ); 00031 return 0; 00032 } 00033 00034 RawImageData * tmp = new RawImageData; 00035 00036 switch( MyHeader.DataType ) 00037 { 00038 case 2: 00039 switch( MyHeader.bitsperpixel ) 00040 { 00041 case 24: 00042 tmp->attrs.m_ColorByteType = RGB; 00043 break; 00044 case 32: 00045 tmp->attrs.m_ColorByteType = RGBA; 00046 break; 00047 default: 00048 LOG.Warn( "TGA Loading failed on file:" + fp->GetName() + " invalid bpp on a RGB image (must be 24 or 32)." ); 00049 delete tmp; 00050 return 0; 00051 } 00052 break; 00053 case 3: 00054 tmp->attrs.m_ColorByteType = LUMINANCE_ALPHA; 00055 if( MyHeader.bitsperpixel != 8 ) 00056 { 00057 LOG.Warn( "TGA Loading failed on file:" + fp->GetName() + " invalid bpp on a grayscale image (must be 8)." ); 00058 delete tmp; 00059 return 0; 00060 } 00061 break; 00062 default: 00063 LOG.Warn( "TGA Loading failed on file:" + fp->GetName() + " invalid data type." ); 00064 delete tmp; 00065 return 0; 00066 } 00067 00068 tmp->attrs.m_dpi_x = tmp->attrs.m_dpi_y = 0; 00069 00070 tmp->attrs.m_height = MyHeader.height; 00071 tmp->attrs.m_width = MyHeader.width; 00072 00073 //Read comment 00074 char * comment = new char[MyHeader.IDLen + 1]; 00075 fp->Read( comment, MyHeader.IDLen ); 00076 comment[MyHeader.IDLen] = 0; 00077 if( MyHeader.IDLen ) 00078 LOG.Log( "Tag on TGA file: " + MString( comment ) ); 00079 delete comment; 00080 00081 //There will be no color table. 00082 00083 int iImageSize = MyHeader.width * MyHeader.height * MyHeader.bitsperpixel / 8; 00084 if( tmp->attrs.m_ColorByteType == LUMINANCE_ALPHA ) 00085 tmp->data = new unsigned char[iImageSize*2]; 00086 else 00087 tmp->data = new unsigned char[iImageSize]; 00088 fp->Read( tmp->data, iImageSize ); 00089 00090 //Swap red with blue 00091 if( tmp->attrs.m_ColorByteType == RGB ) 00092 for( x = 0; x < iImageSize; x+=3 ) 00093 { 00094 tc = tmp->data[x]; 00095 tmp->data[x] = tmp->data[x+2]; 00096 tmp->data[x+2] = tc; 00097 } 00098 else if( tmp->attrs.m_ColorByteType == RGBA ) 00099 for( x = 0; x < iImageSize; x+=4 ) 00100 { 00101 tc = tmp->data[x]; 00102 tmp->data[x] = tmp->data[x+2]; 00103 tmp->data[x+2] = tc; 00104 tmp->data[x+3] = tmp->data[x+3]; //huh? This is zero on virtually all images. 00105 } 00106 else if( tmp->attrs.m_ColorByteType == LUMINANCE_ALPHA ) 00107 for( x = (iImageSize*2)-1; x > 0; x-=2 ) 00108 { 00109 tmp->data[x] = tmp->data[x/2]; 00110 tmp->data[x-1] = 255; 00111 } 00112 00113 return tmp; 00114 } 00115 00116 RUN_STATEMENT_AT_BOOT( include_tga1, IMAGEREADERREGISTER.AddDecoder( LoadTGA, "\0\0\2" ); ) //RGB uncompressed 00117 RUN_STATEMENT_AT_BOOT( include_tga2, IMAGEREADERREGISTER.AddDecoder( LoadTGA, "\0\0\3" ); ) //grayscale uncompressed 00118 00119 00120 /* 00121 * Copyright (c) 2006 Charles Lohr 00122 * All rights reserved. 00123 * 00124 * Redistribution and use in source and binary forms, with or 00125 * without modification, are permitted provided that the following 00126 * conditions are met: 00127 * - Redistributions of source code must retain the above 00128 * copyright notice, this list of conditions and the following disclaimer. 00129 * - Redistributions in binary form must reproduce the above copyright 00130 * notice, this list of conditions and the following disclaimer in 00131 * the documentation and/or other materials provided with the distribution. 00132 * - Neither the name of the Mercury Engine nor the names of its 00133 * contributors may be used to endorse or promote products derived from 00134 * this software without specific prior written permission. 00135 * 00136 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00137 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00138 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00139 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 00140 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00141 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00142 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00143 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00144 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 00145 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00146 */