]> git.jsancho.org Git - lugaru.git/blob - Source/TGALoader.cpp
b9c1b91bd69f1cb401c50ef702fcb47b70c2c186
[lugaru.git] / Source / TGALoader.cpp
1 /**> HEADER FILES <**/
2 #include "TGALoader.h"
3 #include "Game.h"
4
5 extern float texdetail;
6 extern TGAImageRec texture;
7 extern short vRefNum;
8 extern long dirID;
9 extern bool visibleloading;
10 extern Game * pgame;
11 extern int loadscreencolor;
12
13 extern bool LoadImage(const char * fname, TGAImageRec & tex);
14 /********************> LoadTGA() <*****/
15 bool upload_image(const unsigned char* filePath, bool hasalpha)
16 {
17         if(visibleloading){
18                 loadscreencolor=1;
19                 pgame->LoadingScreen();
20         }
21
22 #if !PLATFORM_MACOSX
23
24         // for Windows, just use TGA loader for now
25         char fileName[ 256];
26         CopyPascalStringToC( filePath, fileName);
27 /*
28         // change extension to .TGA
29         int len = strlen( fileName);
30         if (len > 3)
31         {
32                 fileName[ len - 3] = 't';
33                 fileName[ len - 2] = 'g';
34                 fileName[ len - 1] = 'a';
35         }
36 */
37 //      return (LoadTGA( fileName) != NULL);
38         return (LoadImage(fileName, texture));
39
40 #else
41
42         OSStatus err;
43         ComponentResult cr;
44
45         /*FSRef fsref;
46         Boolean isdir;
47         err = FSPathMakeRef((const UInt8*)filePath, &fsref, &isdir);
48         if(err)return;
49
50         FSSpec fsspec;
51         err = FSGetCatalogInfo(&fsref, kFSCatInfoNone, NULL, NULL, &fsspec, NULL);
52         if(err)return;
53         */
54
55         //Boolean isdir;
56         FSSpec fsspec;
57         //err = FSMakeFSSpec (0, 0, (const unsigned char*)filePath, &fsspec);
58         err = FSMakeFSSpec (0, 0, filePath, &fsspec);
59         //err=FSPathMakeFSSpec((const UInt8*)filePath,&fsspec,&isdir);*/
60         if(err)return;
61
62         GraphicsImportComponent gi;
63         err = GetGraphicsImporterForFile(&fsspec, &gi);
64         if(err)return;
65
66         Rect natbounds;
67         cr = GraphicsImportGetNaturalBounds(gi, &natbounds);
68
69         size_t buffersize = 4 * natbounds.bottom * natbounds.right;
70         //void* buf = malloc(buffersize);
71         texture.sizeX=natbounds.right;
72         texture.sizeY=natbounds.bottom;
73         /*if(hasalpha)*/texture.bpp = 32;
74         //if(!hasalpha)texture.bpp = 24;
75
76         GWorldPtr gw;
77         err = QTNewGWorldFromPtr(&gw, k32ARGBPixelFormat, &natbounds, NULL, NULL,
78                 0, texture.data, 4 * natbounds.right);
79         if(err)return;
80
81         cr = GraphicsImportSetGWorld(gi, gw, NULL);
82
83         natbounds.top = natbounds.bottom;
84         natbounds.bottom = 0;
85
86         cr = GraphicsImportSetBoundsRect(gi, &natbounds);
87
88         cr = GraphicsImportDraw(gi);
89
90         err = CloseComponent(gi);
91         if(err)return;
92
93         /*glTexImage2D(textureTarget, 0, GL_RGBA, natbounds.right, natbounds.top, 0,
94         GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, buf);
95         */
96
97         //free(buf);
98         DisposeGWorld(gw);
99
100         // Loop Through The Image Data
101         GLuint                  imageSize;                                                                      // Used To Store The Image Size When Setting Aside Ram
102         GLuint                  temp;                                                                           // Temporary Variable
103         GLuint                  bytesPerPixel;                                                                          // Temporary Variable
104         bytesPerPixel=texture.bpp/8;
105         imageSize = texture.sizeX * texture.sizeY * bytesPerPixel;
106         int alltrans=10;
107
108         for( GLuint i = 0; i < int( imageSize ); i += 4 )
109         {
110                 // Swaps The 1st And 3rd Bytes ('R'ed and 'B'lue)
111                 temp = texture.data[i];                                 // Temporarily Store The Value At Image Data 'i'
112                 texture.data[i] = texture.data[i + 1];  // Set The 1st Byte To The Value Of The 3rd Byte
113                 texture.data[i + 1] = texture.data[i + 2];                              // Set The 3rd Byte To The Value In 'temp' (1st Byte Value)
114                 texture.data[i + 2] = texture.data[i + 3];
115                 texture.data[i + 3] = temp;
116         }
117
118         int tempplace;
119         tempplace=0;
120         if(!hasalpha){
121                 for( GLuint i = 0; i < int( imageSize ); i += 4 )
122                 {
123                         texture.data[i + 3] = 255;
124                         /*texture.data[tempplace] = texture.data[i];    // Set The 1st Byte To The Value Of The 3rd Byte
125                         texture.data[tempplace + 1] = texture.data[i + 1];                              // Set The 3rd Byte To The Value In 'temp' (1st Byte Value)
126                         texture.data[tempplace + 2] = texture.data[i + 2];
127                         tempplace+=3;*/
128                 }
129         }
130
131         if(texdetail>1){
132                 int which=0;
133                 float temp;
134                 float howmany;
135                 for( GLuint k = 0; k < int( imageSize); k += bytesPerPixel*texture.sizeX*texdetail )
136                 {
137                         for( GLuint i = 0; i < int( imageSize/texture.sizeY ); i += bytesPerPixel*texdetail )
138                         {
139                                 for( GLuint b = 0; b < bytesPerPixel ; b ++ ){  
140                                         temp=0;
141                                         howmany=0;
142                                         for( GLuint l = 0; l < texdetail*texture.sizeX ; l +=texture.sizeX ){
143                                                 for( GLuint j = 0; j < texdetail ; j ++ )
144                                                 {
145                                                         temp += (int)texture.data[k+i+j*bytesPerPixel+l*bytesPerPixel+b];       // Set The 1st Byte To The Value Of The 3rd Byte
146                                                         howmany++;
147                                                 }
148                                         }
149                                         texture.data[which+b]=GLubyte(temp/howmany);
150                                 }
151                                 which+=bytesPerPixel;
152                         }
153                 }
154                 texture.sizeX/=texdetail;
155                 texture.sizeY/=texdetail;
156         }
157
158         return true;
159
160 #endif
161 }
162
163
164 TGAImageRec*    LoadTGA( char *filename )
165 {    
166         GLubyte                 TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0};        // Uncompressed TGA Header
167         GLubyte                 TGAcompare[12];                                                         // Used To Compare TGA Header
168         GLubyte                 header[6];                                                                      // First 6 Useful Bytes From The Header
169         GLuint                  bytesPerPixel;                                                          // Holds Number Of Bytes Per Pixel Used In The TGA File
170         GLuint                  imageSize;                                                                      // Used To Store The Image Size When Setting Aside Ram
171         GLuint                  temp;                                                                           // Temporary Variable
172         GLuint                  type = GL_RGBA;                                                         // Set The Default GL Mode To RBGA (32 BPP)
173         //TGAImageRec           *texture;
174         FILE                    *file;
175
176         // Open The TGA File
177         file = fopen( filename, "rb" );
178
179         if( ( file == NULL ) || // Does File Even Exist?
180                 ( fread( TGAcompare, 1, sizeof( TGAcompare ), file ) != sizeof( TGAcompare ) ) ||       // Are There 12 Bytes To Read?
181                 ( memcmp( TGAheader, TGAcompare, sizeof( TGAheader ) ) != 0 ) ||        // Does The Header Match What We Want?
182                 ( fread( header, 1, sizeof( header ), file ) != sizeof( header ) ) )// If So Read Next 6 Header Bytes
183         {
184                 // If anything failed then close the file and return false
185                 if (file) fclose( file );
186                 return NULL;
187         }
188
189         // Create a new RGBAImageRec
190         //texture = ( TGAImageRec* )malloc( sizeof( TGAImageRec ) );
191
192         // Determine the TGA width (highbyte*256+lowbyte) and height (highbyte*256+lowbyte)
193         texture.sizeX  = (header[1] * 256 + header[0]);
194         texture.sizeY = (header[3] * 256 + header[2]);
195
196         // Make sure the height, width, and bit depth are valid
197         if(     ( texture.sizeX <= 0 ) || ( texture.sizeY <= 0 ) || ( ( header[4] != 24 ) && ( header[4] != 32 ) ) )
198         {
199                 // If anything failed then close the file, free up memory for the image, and return NULL
200                 fclose( file );
201                 //free( texture );
202                 return NULL;
203         }
204
205         // Grab The TGA's Bits Per Pixel (24 or 32)
206         texture.bpp = header[4];                                                        
207         bytesPerPixel = texture.bpp/8;  // Divide By 8 To Get The Bytes Per Pixel
208
209         // Calculate The Memory Required For The TGA Data
210         imageSize = texture.sizeX * texture.sizeY * bytesPerPixel;
211
212         // Reserve Memory To Hold The TGA Data
213         //texture.data = ( GLubyte* )malloc( imageSize );               
214
215         // Make sure the right amount of memory was allocated
216         if(     ( texture.data == NULL ) || ( fread( texture.data, 1, imageSize, file ) != imageSize ) )
217         {
218                 // Free up the image data if there was any
219                 //              if( texture.data != NULL )
220                 //                      free( texture.data );
221
222                 // If anything failed then close the file, free up memory for the image, and return NULL
223                 fclose( file );
224                 //              free( texture );
225                 return NULL;
226         }
227
228         // Loop Through The Image Data
229         for( GLuint i = 0; i < int( imageSize ); i += bytesPerPixel )
230         {
231                 // Swaps The 1st And 3rd Bytes ('R'ed and 'B'lue)
232                 temp = texture.data[i];                                 // Temporarily Store The Value At Image Data 'i'
233                 texture.data[i] = texture.data[i + 2];  // Set The 1st Byte To The Value Of The 3rd Byte
234                 texture.data[i + 2] = temp;                             // Set The 3rd Byte To The Value In 'temp' (1st Byte Value)
235         }
236
237         if(texdetail>1){
238                 int which=0;
239                 float temp;
240                 float howmany;
241                 for( GLuint k = 0; k < int( imageSize); k += bytesPerPixel*texture.sizeX*texdetail )
242                 {
243                         for( GLuint i = 0; i < int( imageSize/texture.sizeY ); i += bytesPerPixel*texdetail )
244                         {
245                                 for( GLuint b = 0; b < bytesPerPixel ; b ++ ){  
246                                         temp=0;
247                                         howmany=0;
248                                         for( GLuint l = 0; l < texdetail*texture.sizeX ; l +=texture.sizeX ){
249                                                 for( GLuint j = 0; j < texdetail ; j ++ )
250                                                 {
251                                                         temp += (int)texture.data[k+i+j*bytesPerPixel+l*bytesPerPixel+b];       // Set The 1st Byte To The Value Of The 3rd Byte
252                                                         howmany++;
253                                                 }
254                                         }
255                                         texture.data[which+b]=GLubyte(temp/howmany);
256                                 }
257                                 which+=bytesPerPixel;
258                         }
259                 }
260                 texture.sizeX/=texdetail;
261                 texture.sizeY/=texdetail;
262         }
263
264         // Close The File
265         fclose( file );
266         return &texture;
267 }