fix include
[xonotic/netradiant.git] / plugins / md3model / mdlimage.cpp
1 /*
2    Copyright (C) 2001-2006, William Joseph.
3    All Rights Reserved.
4
5    This file is part of GtkRadiant.
6
7    GtkRadiant is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    GtkRadiant is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with GtkRadiant; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21
22 #include "mdlimage.h"
23
24 #include <math.h>
25 #include <stdlib.h>
26
27 #include "ifilesystem.h"
28 #include "bytestreamutils.h"
29
30 #include "stream/textstream.h"
31 #include "imagelib.h"
32
33 #include "mdlformat.h"
34 #include "ident.h"
35
36
37 unsigned char mdl_palette[768];
38 /*
39    ==============
40    Texture_InitPalette
41    ==============
42  */
43 void Texture_InitPalette( byte *pal ){
44         int r,g,b;
45         int i;
46         int inf;
47         byte gammatable[256];
48         double gamma;
49
50         gamma = 1.0; //g_qeglobals.d_savedinfo.fGamma;
51
52         if ( gamma == 1.0 ) {
53                 for ( i = 0 ; i < 256 ; i++ )
54                         gammatable[i] = i;
55         }
56         else
57         {
58                 for ( i = 0 ; i < 256 ; i++ )
59                 {
60                         inf = (int)( 255 * pow( ( i + 0.5 ) / 255.5, gamma ) + 0.5 );
61                         if ( inf < 0 ) {
62                                 inf = 0;
63                         }
64                         if ( inf > 255 ) {
65                                 inf = 255;
66                         }
67                         gammatable[i] = inf;
68                 }
69         }
70
71         for ( i = 0 ; i < 256 ; i++ )
72         {
73                 r = gammatable[pal[0]];
74                 g = gammatable[pal[1]];
75                 b = gammatable[pal[2]];
76                 pal += 3;
77
78                 //v = (r<<24) + (g<<16) + (b<<8) + 255;
79                 //v = BigLong (v);
80
81                 //mdl_palette[i] = v;
82                 mdl_palette[i * 3 + 0] = r;
83                 mdl_palette[i * 3 + 1] = g;
84                 mdl_palette[i * 3 + 2] = b;
85         }
86 }
87
88 bool LoadPalette(){
89         unsigned char* buffer;
90         //int len =
91         vfsLoadFile( "gfx/palette.lmp", (void **) &buffer );
92         if ( buffer == 0 ) {
93                 return false;
94         }
95
96         Texture_InitPalette( buffer );
97
98         vfsFreeFile( buffer );
99
100         return true;
101 }
102
103 Image* LoadMDLImageBuff( byte* buffer ){
104         if ( !LoadPalette() ) {
105                 return 0;
106         }
107
108         if ( !ident_equal( buffer, MDL_IDENT ) ) {
109                 globalErrorStream() << "LoadMDLImage: data has wrong ident\n";
110                 return 0;
111         }
112
113         PointerInputStream inputStream( buffer );
114         inputStream.seek( 4 + 4 + 12 + 12 + 4 + 12 );
115         //int numskins =
116         istream_read_int32_le( inputStream );
117         int skinwidth = istream_read_int32_le( inputStream );
118         int skinheight = istream_read_int32_le( inputStream );
119         inputStream.seek( 4 + 4 + 4 + 4 + 4 + 4 );
120
121         switch ( istream_read_int32_le( inputStream ) )
122         {
123         case MDL_SKIN_SINGLE:
124                 break;
125         case MDL_SKIN_GROUP:
126                 int numskins = istream_read_int32_le( inputStream );
127                 inputStream.seek( numskins * 4 );
128                 break;
129         }
130
131         RGBAImage* image = new RGBAImage( skinwidth, skinheight );
132         unsigned char* pRGBA = image->getRGBAPixels();
133
134         for ( int i = 0; i < ( skinheight ); i++ )
135         {
136                 for ( int j = 0; j < ( skinwidth ); j++ )
137                 {
138                         byte index = istream_read_byte( inputStream );
139                         *pRGBA++ = mdl_palette[index * 3 + 0];
140                         *pRGBA++ = mdl_palette[index * 3 + 1];
141                         *pRGBA++ = mdl_palette[index * 3 + 2];
142                         *pRGBA++ = 255;
143                 }
144         }
145
146         return image;
147 }
148
149 Image* LoadMDLImage( ArchiveFile& file ){
150         ScopedArchiveBuffer buffer( file );
151         return LoadMDLImageBuff( buffer.buffer );
152 }
153
154 void MDLImage_Destroy( byte* pic ){
155         free( pic );
156 }