source: golgotha/src/i4/loaders/tga_load.cc @ 608

Last change on this file since 608 was 80, checked in by Sam Hocevar, 15 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
File size: 4.9 KB
Line 
1/********************************************************************** <BR>
2  This file is part of Crack dot Com's free source code release of
3  Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
4  information about compiling & licensing issues visit this URL</a>
5  <PRE> If that doesn't help, contact Jonathan Clark at
6  golgotha_source@usa.net (Subject should have "GOLG" in it)
7***********************************************************************/
8
9#include "loaders/load.hh"
10#include "image/image.hh"
11#include "status/status.hh"
12#include "file/file.hh"
13#include "memory/malloc.hh"
14#include "error/error.hh"
15#include "palette/pal.hh"
16
17static inline w32 read_color(i4_file_class *fp, w8 bpp)
18{
19  w8 buf[4];
20
21  if (bpp==32)
22  {
23    fp->read(buf,4);
24    return (((w32)buf[3]<<24) |
25            ((w32)buf[2]<<16) |
26            ((w32)buf[1]<<8)  |
27            ((w32)buf[0]));
28
29  } else
30  {
31    fp->read(buf,3);
32    return (((w32)buf[2]<<16) |
33            ((w32)buf[1]<<8)  |
34            ((w32)buf[0]));
35  }
36}
37
38class i4_tga_loader_class : public i4_image_loader_class
39{
40  public :
41  // returns the maximum size you need to identify your file format
42  virtual w16 max_header_size() { return 17; }
43  virtual i4_bool recognize_header(w8 *buf)
44  {
45    if (buf[1]==0 &&                // no colormap
46        buf[2]==2 || buf[2]==10 &&  // true color compressed or raw
47        buf[16]==32 || buf[16]==24)  // 32 or 24 bpp
48      return i4_T;
49    else
50      return i4_F;
51  }
52
53
54  // assume fp is at the start of the file
55  virtual i4_image_class *load(i4_file_class *fp,
56                               i4_status_class *status)
57  {
58    unsigned char color_map,im_type;
59
60    /*
61    w32 fsize = bs_fp->size();
62 
63    w8 *file_buffer = (w8 *)i4_malloc(bs_fp->size(),"tga ram file buffer");
64
65    bs_fp->read(file_buffer,fsize);
66
67    i4_ram_file_class *fp = new i4_ram_file_class(file_buffer,fsize);
68    */
69    w8 id_length=fp->read_8();
70    color_map=fp->read_8();
71    im_type=fp->read_8();
72
73    if (color_map!=0)
74    {
75      return 0;
76    }
77
78    if (!(im_type==2 || im_type==10))
79    {
80      return 0;
81    }
82
83    fp->read_16();  // skip color map info
84    fp->read_16();
85    fp->read_8();
86
87    fp->read_16();  // skip origin x & y
88    fp->read_16();
89
90
91    w16 w=fp->read_16();   // image width & height
92    w16 h=fp->read_16();
93
94    w8  bpp=fp->read_8();
95    w8  bits=fp->read_8();
96
97    if (bpp!=32 && bpp!=24)
98    {
99      return 0;
100    }
101
102    fp->seek(fp->tell() + id_length);
103
104    w32 *data=(w32 *)i4_malloc(w*h*4,"targa image");
105
106
107    int x,y;
108    unsigned char ctrl;
109
110    w32 c,*sl;
111
112    if (im_type==10)     // type 10 is compressed
113    {   
114      i4_error("Cannot read compressed targa files");
115
116      for (y=0;y<h;y++)
117      {
118        if (status)
119          status->update(y/(float)h);
120
121        sl=data+(h-y-1)*w;   // get address of scan line
122
123        for (x=0;x<w;)
124        {
125          ctrl=fp->read_8();  // control byte
126          int npixels=(ctrl&(~0x80))+1;
127
128          if (ctrl&0x80)         // run or raw?
129          {
130            c=read_color(fp,bpp);
131            while (npixels--)
132            {
133              *sl=c;
134              sl++;
135              x++;
136            }
137          } else
138          {
139            while (npixels--)
140            {
141              c=read_color(fp,bpp);
142              *sl=c;
143              sl++;
144              x++;
145            }
146          }
147        }
148      }   
149    } else
150    {
151      for (y=0;y<h;y++)
152      {
153        if (status)
154          status->update(y/(float)h);
155
156        sl=data+(h-y-1)*w;   // get address of scan line
157
158        for (x=0;x<w;x++)
159        {
160          *sl=read_color(fp,bpp);
161          sl++;         
162        }
163      }
164
165    }
166
167    enum { REVERSE_HORZ=0x10,
168           REVERSE_VERT=0x20 };
169
170    if (bits & REVERSE_VERT)
171    {
172      w32 *s1=data, *s2=data+(h-1)*w;
173      for (y=0; y<h/2; y++)
174      {
175        for (x=0; x<w; x++)
176        {
177          w32 c=s1[x];
178          s1[x]=s2[x];
179          s2[x]=c;
180        }
181        s2-=w;
182        s1+=w;
183      }
184    }
185
186    if (bits & REVERSE_HORZ)
187    {
188      w32 *s1=data, *s2=data+w-1;
189      for (y=0; y<h; y++)
190      {
191        for (x=0; x<w; x++)
192        {
193          w32 c=*s1;
194          *s1=*s2;
195          *s2=c;
196          s1++;
197          s2--;
198        }
199        s2+=w;
200      }
201    }
202   
203    i4_pixel_format fmt;
204    fmt.default_format();
205
206    if (bpp==24)             // no alpha info in these images
207    {
208      fmt.alpha_mask=0;
209      fmt.calc_shift();
210    }
211   
212    i4_pal *pal=i4_pal_man.register_pal(&fmt);
213
214    i4_image_class *im=i4_create_image(w,h,  // width & height
215        pal,                            // palette (should be 32 bit by default)
216        data,
217        w*4);                            // bytes per line
218   
219    im->dont_free_data=i4_F;
220
221    return im;
222  }
223
224} i4_tga_loader_instance;
Note: See TracBrowser for help on using the repository browser.