00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pent_include.h"
00020 #include "TextureTarga.h"
00021 #include "IDataSource.h"
00022
00023 struct TGA
00024 {
00025 uint32 Height;
00026 uint32 Width;
00027 uint32 Bpp;
00028 uint32 bytesPerPixel;
00029 uint32 Flags;
00030 bool Flipped;
00031 bool Compressed;
00032
00033 void Read(IDataSource *ds)
00034 {
00035 Width = ds->read2();
00036 Height = ds->read2();
00037 Bpp = ds->read1();
00038 Flags = ds->read1();
00039
00040 Flipped = (Flags&(1<<5))?false:true;
00041 bytesPerPixel = Bpp / 8;
00042 }
00043 };
00044
00045 static const uint8 uTGAcompare[12] = {0,0,2, 0,0,0,0,0,0,0,0,0};
00046 static const uint8 cTGAcompare[12] = {0,0,10,0,0,0,0,0,0,0,0,0};
00047
00048 bool TextureTarga::Read(IDataSource *ds)
00049 {
00050
00051 uint8 header[12];
00052
00053
00054 TGA tga;
00055
00056
00057 ds->seek(0);
00058
00059
00060 ds->read(static_cast<uint8 *>(header), 12);
00061
00062
00063
00065
00067
00068
00069
00070 if (header[1] != 0) return false;
00071
00072
00073 if (header[2] == 2) tga.Compressed = false;
00074 else if (header[2] == 10) tga.Compressed = true;
00075 else return false;
00076
00077
00078
00079
00080 tga.Read(ds);
00081
00082 ds->skip(header[0]);
00083
00084
00085 width = tga.Width;
00086 height = tga.Height;
00087 format = TEX_FMT_STANDARD;
00088
00089
00090 if(width <= 0 || height <= 0 || (tga.Bpp != 24 && tga.Bpp !=32))
00091 return false;
00092
00093
00094 uint8 *temp_buffer = new uint8[width * height * tga.bytesPerPixel];
00095
00096
00097 if (!temp_buffer) return false;
00098
00099
00100 if (tga.Compressed)
00101 {
00102
00103 uint8 *image = temp_buffer;
00104 uint8 *end = temp_buffer + tga.bytesPerPixel * width * height;
00105
00106 while(image < end)
00107 {
00108 uint32 chunkheader = ds->read1();
00109
00110
00111 if(chunkheader < 128)
00112 {
00113 chunkheader = (chunkheader+1)*tga.bytesPerPixel;
00114
00115
00116 ds->read(static_cast<uint8 *>(image), chunkheader);
00117
00118 image += chunkheader;
00119 }
00120
00121 else
00122 {
00123 chunkheader = (chunkheader-127)*tga.bytesPerPixel;
00124
00125
00126 static uint8 colorbuffer[4];
00127 ds->read(static_cast<uint8 *>(colorbuffer), tga.bytesPerPixel);
00128
00129 uint8 *end_run = image + chunkheader;
00130
00131 if(tga.bytesPerPixel == 4) {
00132 while (image < end_run) {
00133 *image++ = colorbuffer[0];
00134 *image++ = colorbuffer[1];
00135 *image++ = colorbuffer[2];
00136 *image++ = colorbuffer[3];
00137 }
00138 }
00139 else {
00140 while (image < end_run) {
00141 *image++ = colorbuffer[0];
00142 *image++ = colorbuffer[1];
00143 *image++ = colorbuffer[2];
00144 }
00145 }
00146 }
00147 }
00148 }
00149 else
00150 {
00151
00152 ds->read(static_cast<uint8 *>(temp_buffer), width * height * tga.bytesPerPixel);
00153 }
00154
00155
00156 buffer = new uint32[width * height];
00157
00158
00159 if (!buffer)
00160 {
00161 delete [] temp_buffer;
00162 return false;
00163 }
00164
00165
00166 ConvertFormat(temp_buffer, tga);
00167
00168
00169 CalcLOG2s();
00170
00171
00172 delete [] temp_buffer;
00173 return true;
00174 }
00175
00176
00177
00178
00179 void TextureTarga::ConvertFormat(uint8 *src, TGA &tga)
00180 {
00181
00182 uint32 *dst = buffer;
00183 uint32 *end = buffer + width * height;
00184 uint32 line_size = width;
00185
00186 uint32 src_line_inc = 0;
00187
00188 if (tga.Flipped) {
00189 src_line_inc = width * tga.bytesPerPixel * 2;
00190 src = src + (height-1) * width * tga.bytesPerPixel;
00191 }
00192
00193 while (dst < end) {
00194
00195 uint32 *line_end = dst + line_size;
00196
00197 if (tga.Bpp == 32) while (dst < line_end) {
00198
00199
00200 *dst++ = (src[0] << TEX32_B_SHIFT)
00201 | (src[1] << TEX32_G_SHIFT)
00202 | (src[2] << TEX32_R_SHIFT)
00203 | (src[3] << TEX32_A_SHIFT);
00204
00205 src += 4;
00206 }
00207 else if (tga.Bpp == 24) while (dst < line_end) {
00208
00209
00210 *dst++ = (src[0] << TEX32_B_SHIFT)
00211 | (src[1] << TEX32_G_SHIFT)
00212 | (src[2] << TEX32_R_SHIFT)
00213 | (255 << TEX32_A_SHIFT);
00214
00215 src += 3;
00216 }
00217
00218 src -= src_line_inc;
00219 }
00220 }