ImageFormat_TGA.cpp
Go to the documentation of this file.00001 //*** ImageFormat_TGA.cpp *** 00002 00003 #include "ImageFormat_TGA.h" 00004 #include "Debug.h" 00005 #include "Asset.h" 00006 #include "StandardLibrary.h" 00007 #include "Filename.h" 00008 00009 #define WIN32_LEAN_AND_MEAN 00010 #define VC_EXTRALEAN 00011 #include <stdio.h> 00012 #include "targa/targa.h" 00013 00014 //*** Register *** 00015 00016 void ImageFormat_TGA::Register() 00017 { 00018 ImageFormat::RegisterImageFormat(TestAsset,Create); 00019 } 00020 00021 00022 //*** Create *** 00023 00024 ImageFormat* ImageFormat_TGA::Create(const Asset& asset) 00025 { 00026 return new ImageFormat_TGA(asset); 00027 } 00028 00029 00030 //*** TestAsset *** 00031 00032 bool ImageFormat_TGA::TestAsset(const Asset& asset) 00033 { 00034 // Check if the footer says that this is a TGA file 00035 if (asset.Open()) 00036 { 00037 asset.Seek(-18,Asset::SEEK_FROM_END); 00038 char buffer[16]; 00039 asset.Read(buffer,16); 00040 asset.Close(); 00041 if (StrNCmp(buffer,"TRUEVISION-XFILE",16)==0) 00042 { 00043 return true; 00044 } 00045 } 00046 00047 // If the footer doesn't match, this might still be a tga file (version < 2) 00048 // so try and load it as a tga and see if it works... 00049 int size=asset.GetSize(); 00050 char* buffer=new char[size]; 00051 asset.Open(); 00052 asset.Read(buffer,size); 00053 asset.Close(); 00054 00055 tga_image image; 00056 tga_read_from_Buffer(&image,buffer); 00057 00058 delete[] buffer; 00059 00060 // Check to see if the header data makes sense... 00061 if (image.width<32767 && image.height<32767 && image.image_data && (image.pixel_depth==8 || image.pixel_depth==24 || image.pixel_depth==16 || image.pixel_depth==32)) 00062 { 00063 // Yeah, sure, this looks like proper data, so give thumbs up and hope for the best 00064 return true; 00065 } 00066 00067 tga_free_buffers(&image); 00068 00069 // Nope, not likely to be a TGA 00070 return false; 00071 } 00072 00073 00074 //*** Constructor *** 00075 00076 ImageFormat_TGA::ImageFormat_TGA(const Asset& asset): 00077 image_(0) 00078 { 00079 int size=asset.GetSize(); 00080 char* buffer=new char[size]; 00081 asset.Open(); 00082 asset.Read(buffer,size); 00083 asset.Close(); 00084 00085 image_=new tga_image; 00086 tga_read_from_Buffer(static_cast<tga_image*>(image_),buffer); 00087 00088 delete[] buffer; 00089 } 00090 00091 00092 //*** Destructor *** 00093 00094 ImageFormat_TGA::~ImageFormat_TGA() 00095 { 00096 tga_free_buffers(static_cast<tga_image*>(image_)); 00097 delete static_cast<tga_image*>(image_); 00098 } 00099 00100 00101 //*** GetWidth *** 00102 00103 int ImageFormat_TGA::GetWidth() 00104 { 00105 return static_cast<tga_image*>(image_)->width; 00106 } 00107 00108 00109 //*** GetHeight *** 00110 00111 int ImageFormat_TGA::GetHeight() 00112 { 00113 return static_cast<tga_image*>(image_)->height; 00114 } 00115 00116 00117 //*** GetCelCount *** 00118 00119 int ImageFormat_TGA::GetCelCount() 00120 { 00121 return 1; 00122 } 00123 00124 00125 //*** GetCelDelay *** 00126 00127 float ImageFormat_TGA::GetCelDelay(int celIndex) 00128 { 00129 return 0; 00130 } 00131 00132 00133 //*** CopyPixels *** 00134 00135 void ImageFormat_TGA::CopyPixels(unsigned int* destination) 00136 { 00137 tga_image* image=static_cast<tga_image*>(image_); 00138 bool upsidedown=!tga_is_top_to_bottom(image); 00139 int width=image->width; 00140 int height=image->height; 00141 unsigned char* data=image->image_data; 00142 00143 if (image->pixel_depth==24) 00144 { 00145 for (int y=0; y<height; y++) 00146 { 00147 for (int x=0; x<width; x++) 00148 { 00149 unsigned int c=0xff000000; 00150 c|=data[2]<<16; 00151 c|=data[1]<<8; 00152 c|=data[0]; 00153 int yp=y; 00154 if (upsidedown) 00155 { 00156 yp=height-y-1; 00157 } 00158 destination[x+yp*width]=c; 00159 data+=3; 00160 } 00161 } 00162 return; 00163 } 00164 00165 if (image->pixel_depth==32) 00166 { 00167 for (int y=0; y<height; y++) 00168 { 00169 for (int x=0; x<width; x++) 00170 { 00171 unsigned int c=0x00000000; 00172 c|=data[3]<<24; 00173 c|=data[2]<<16; 00174 c|=data[1]<<8; 00175 c|=data[0]; 00176 int yp=y; 00177 if (upsidedown) 00178 { 00179 yp=height-y-1; 00180 } 00181 destination[x+yp*width]=c; 00182 data+=4; 00183 } 00184 } 00185 return; 00186 } 00187 00188 if (image->pixel_depth==16) 00189 { 00190 for (int y=0; y<height; y++) 00191 { 00192 for (int x=0; x<width; x++) 00193 { 00194 unsigned int s=data[1]<<8 | data[0]; 00195 unsigned int c=0xff000000; 00196 unsigned int b=((s&0x1f)); 00197 unsigned int g=(((s>>5)&0x1f)); 00198 unsigned int r=(((s>>10)&0x1f)); 00199 float fr=((float)r)/31.0f; 00200 float fg=((float)g)/31.0f; 00201 float fb=((float)b)/31.0f; 00202 00203 r=(unsigned int)(255.0f*fr); 00204 g=(unsigned int)(255.0f*fg); 00205 b=(unsigned int)(255.0f*fb); 00206 c|=r<<16; 00207 c|=g<<8; 00208 c|=b; 00209 int yp=y; 00210 if (upsidedown) 00211 { 00212 yp=height-y-1; 00213 } 00214 destination[x+yp*width]=c; 00215 data+=2; 00216 } 00217 } 00218 return; 00219 } 00220 00221 00222 Assert(false,"Unsupported TGA file"); 00223 } 00224 00225 00226 //*** Save *** 00227 00228 void ImageFormat_TGA::Save(const Filename& filename, int width, int height, void* data) 00229 { 00230 tga_image tga; 00231 MemSet(&tga,0,sizeof(tga)); 00232 tga.image_id_length=0; 00233 tga.color_map_type=0; 00234 tga.image_type=TGA_IMAGE_TYPE_BGR; 00235 tga.color_map_origin=0; 00236 tga.color_map_length=0; 00237 tga.color_map_depth=0; 00238 tga.origin_x=0; 00239 tga.origin_y=0; 00240 tga.width=(unsigned short)width; 00241 tga.height=(unsigned short)height; 00242 tga.pixel_depth=32; 00243 tga.image_descriptor=TGA_T_TO_B_BIT; 00244 tga.image_id=0; 00245 tga.color_map_data=0; 00246 tga.image_data=static_cast<unsigned char*>(data); 00247 00248 tga_write(filename.GetString(),&tga); 00249 }
Reproduction/republishing of any material on this site without permission is strictly prohibited.
