Merge commit '48410b113dd2036e69dbf723a39ec9af02fc9b12'
[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 {
45   int   r,g,b;
46   int   i;
47   int   inf;
48   byte  gammatable[256];
49   double gamma;
50
51   gamma = 1.0;//g_qeglobals.d_savedinfo.fGamma;
52
53   if (gamma == 1.0)
54   {
55     for (i=0 ; i<256 ; i++)
56       gammatable[i] = i;
57   } else
58   {
59     for (i=0 ; i<256 ; i++)
60     {
61       inf = (int)(255 * pow ( (i+0.5)/255.5 , gamma ) + 0.5);
62       if (inf < 0)
63         inf = 0;
64       if (inf > 255)
65         inf = 255;
66       gammatable[i] = inf;
67     }
68   }
69
70   for (i=0 ; i<256 ; i++)
71   {
72     r = gammatable[pal[0]];
73     g = gammatable[pal[1]];
74     b = gammatable[pal[2]];
75     pal += 3;
76
77     //v = (r<<24) + (g<<16) + (b<<8) + 255;
78     //v = BigLong (v);
79
80     //mdl_palette[i] = v;
81     mdl_palette[i*3+0] = r;
82     mdl_palette[i*3+1] = g;
83     mdl_palette[i*3+2] = b;
84   }
85 }
86
87 bool LoadPalette()
88 {
89   unsigned char* buffer;
90   //int len =
91   vfsLoadFile ("gfx/palette.lmp", (void **) &buffer);
92   if (buffer == 0)
93     return false;
94
95   Texture_InitPalette(buffer);
96
97   vfsFreeFile(buffer);
98
99   return true;
100 }
101
102 Image* LoadMDLImageBuff(byte* buffer)
103 {
104   if(!LoadPalette())
105   {
106     return 0;
107   }
108
109   if(!ident_equal(buffer, MDL_IDENT))
110   {
111           globalErrorStream() << "LoadMDLImage: data has wrong ident\n";
112     return 0;
113   }
114
115   PointerInputStream inputStream(buffer);
116   inputStream.seek(4 + 4 + 12 + 12 + 4 + 12);
117   //int numskins =
118   istream_read_int32_le(inputStream);
119   int skinwidth = istream_read_int32_le(inputStream);
120   int skinheight = istream_read_int32_le(inputStream);
121   inputStream.seek(4 + 4 + 4 + 4 + 4 + 4);
122
123   switch(istream_read_int32_le(inputStream))
124   {
125   case MDL_SKIN_SINGLE:
126     break;
127   case MDL_SKIN_GROUP:
128     int numskins = istream_read_int32_le(inputStream);
129     inputStream.seek(numskins * 4);
130     break;
131   }
132
133   RGBAImage* image = new RGBAImage(skinwidth, skinheight);
134   unsigned char* pRGBA = image->getRGBAPixels();
135
136   for(int i=0; i<(skinheight); i++)
137   {
138     for(int j=0; j<(skinwidth); j++)
139     {
140       byte index = istream_read_byte(inputStream);
141       *pRGBA++ = mdl_palette[index * 3 + 0];
142       *pRGBA++ = mdl_palette[index * 3 + 1];
143       *pRGBA++ = mdl_palette[index * 3 + 2];
144       *pRGBA++ = 255;
145     }
146   }
147
148   return image;
149 }
150
151 Image* LoadMDLImage(ArchiveFile& file)
152 {
153   ScopedArchiveBuffer buffer(file);
154   return LoadMDLImageBuff( buffer.buffer );
155 }
156
157 void MDLImage_Destroy(byte* pic)
158 {
159   free(pic);
160 }