more eol-style
[xonotic/netradiant.git] / plugins / imagehl / lbmlib.cpp
1 /*
2 Copyright (C) 1999-2007 id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
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 // lbmlib.c
23
24 // by Hydra - hydra@hydras-world.com
25 //
26 // This module is based on the image module, but just more stripped down.
27 // it still currently supports TGA file loading, even though this is not
28 // required for HalfLife support (unless MD2 files use TGA's)
29 //
30 // use the #defines in imagehl.h to enable/disable the various formats.
31 //
32 // HLW = Half-Life-WAD, I don't know if the actual in data in the WAD files
33 // has it's own name, so I'm just calling the individal textures .HLW files :)
34 //
35 // Thanks to the guys that made Wally for releasing an example WAD loader.
36 // without it this would not have been possible.
37
38 #include <stdlib.h>
39 #include <string.h>
40 #include <glib.h>
41 #include "imagehl.h"
42 #include "lbmlib.h"
43
44 #include <stdio.h>
45
46 #define Sys_Printf g_FuncTable.m_pfnSysPrintf
47 #define Sys_FPrintf g_FuncTable.m_pfnSysFPrintf
48
49
50 #ifdef USE_IDSP
51 /*
52 ============================================================================
53
54 IDSP IMAGE (.spr files)
55
56 Some code copied straight from the Q1 source, also used the HalfLife SDK as
57 a reference.
58
59 ============================================================================
60 */
61
62 typedef enum {ST_SYNC=0, ST_RAND } synctype_t;
63 typedef enum { SPR_SINGLE=0, SPR_GROUP } spriteframetype_t;
64
65 typedef struct dspriteheader_s {
66         int                     ident;
67         int                     version;
68 } dspriteheader_t;
69
70 // Quake1
71 typedef struct {
72         int                     type;
73         float           boundingradius;
74         int                     width;
75         int                     height;
76         int                     numframes;
77         float           beamlength;
78         synctype_t      synctype;
79 } dspritev1_t;
80
81 // Halflife
82 typedef struct {
83         int                     type;
84         int                     texFormat;
85         float           boundingradius;
86         int                     width;
87         int                     height;
88         int                     numframes;
89         float           beamlength;
90         synctype_t   synctype;
91 } dspritev2_t;
92
93 typedef struct {
94         int                     origin[2];
95         int                     width;
96         int                     height;
97 } dspriteframe_t;
98
99 typedef struct {
100         short   type;
101 } dspriteframetype_t;
102
103 /*
104 typedef struct {
105   byte rgb[256][3];
106 } dpalette_t;
107 */
108
109 #define IDSPRITEHEADER  (('P'<<24)+('S'<<16)+('D'<<8)+'I')
110                                                                                                                 // little-endian "IDSP"
111
112 /*
113 =============
114 LoadIDSP
115 =============
116 */
117
118 static void LoadIDSP (const char *name, byte ** pic, int *width, int *height)
119 {
120   byte *buffer;
121   byte *buf_p;
122   unsigned int length;
123   int columns, rows, numPixels;
124   byte *pixbuf;
125
126   int row, column;
127   byte *bmpRGBA;
128   byte *palette;
129         unsigned char red, green, blue, alphabyte;
130
131   dspriteheader_t *header;
132         dspritev1_t                     *pinv1;
133         dspritev2_t                     *pinv2;
134         dspriteframetype_t      *pframetype;
135         int                                     version;
136         int                                     numframes;
137         int                                     size;
138   spriteframetype_t     frametype;
139   dspriteframe_t *spriteframe;
140
141   *pic = NULL;
142
143   //
144   // load the file
145   //
146   length = vfsLoadFile ((char *) name, (void **) &buffer);
147   if (length == (unsigned int) -1)
148     return;
149
150   header = (dspriteheader_t *)buffer;
151
152   if (header->ident != IDSPRITEHEADER)
153   {
154     Sys_Printf ("WARNING: %s has wrong header\n");
155     vfsFreeFile (buffer);
156     return;
157   }
158
159   version = header->version;
160   if (version != 1 && version != 2 )
161   {
162     Sys_Printf ("WARNING: %s has wrong version number "
163                                  "(%i should be 1 or 2)\n", name, version);
164     vfsFreeFile (buffer);
165     return;
166   }
167
168   // initialise variables depending on the sprite version.
169   switch (version)
170   {
171     case 1:
172             pinv1 = (dspritev1_t *)(header+1);
173       numframes = pinv1->numframes;
174       columns = pinv1->width;
175       rows = pinv1->height;
176         pframetype = (dspriteframetype_t *)(pinv1 + 1);
177       break;
178     case 2:
179             pinv2 = (dspritev2_t *)(header+1);
180       numframes = pinv2->numframes;
181       columns = pinv2->width;
182       rows = pinv2->height;
183       pframetype = (dspriteframetype_t *)(pinv2 + 1);
184       break;
185   }
186   if (numframes > 1)
187     Sys_Printf ("WARNING: %s has multiple frames, only the first frame will be used.\n", name);
188
189   // palette = buffer+mipdatasize+2;
190   // buf_p = buffer+lpMip->offsets[0];
191
192   numPixels = columns * rows;
193
194   if (width)
195     *width = columns;
196   if (height)
197     *height = rows;
198
199   bmpRGBA = reinterpret_cast < unsigned char *>(g_malloc (numPixels * 4));
200   *pic = bmpRGBA;
201
202 #ifdef DEBUG
203         frametype = spriteframetype_t(LittleLong(pframetype->type));
204         if (frametype == SPR_SINGLE)
205   {
206     Sys_Printf("Single Frame\n");
207   }
208   else if (frametype == SPR_GROUP)
209   {
210     Sys_Printf("Group of Frames\n");
211   }
212   else
213   {
214     Sys_Printf("Bleh!\n"); // <-- we always get this, wtf!
215   }
216 #endif
217
218   palette = (byte *)(pframetype+1);
219   spriteframe = (dspriteframe_t *)(palette + (256*3) + 4); // what are those 4 extra bytes ? what's missing ?
220   buf_p = (byte *)(spriteframe + 1);
221
222   int temp;
223
224   temp = buf_p - buffer;
225
226   for (row = 0; row < rows; row++)
227   {
228     pixbuf = bmpRGBA + row * columns * 4;
229
230     for (column = 0; column < columns; column++)
231     {
232       int palIndex;
233
234             palIndex = *buf_p++;
235
236       red = *(palette+(palIndex*3));
237       green = *(palette+(palIndex*3)+1);
238       blue = *(palette+(palIndex*3)+2);
239
240       // HalfLife engine makes pixels that are BLUE transparent. (RGB = 0x0000FF)
241       // So show them that way in the editor.
242       if (blue == 0xff && red == 0x00 && green == 0x00)
243       {
244         alphabyte = 0xff; //FIXME: backwards? (so sprite models to render correctly)
245         blue = 0x00; // don't set the resulting pixel to blue
246       }
247       else
248       {
249         alphabyte = 0x00; //FIXME: backwards? (so sprite models to render correctly)
250       }
251
252             *pixbuf++ = red;
253             *pixbuf++ = green;
254             *pixbuf++ = blue;
255
256             *pixbuf++ = alphabyte;
257     }
258   }
259
260   vfsFreeFile (buffer);
261 }
262 #endif
263
264 #ifdef USE_HLW
265 /*
266 ============================================================================
267
268 HLW IMAGE
269
270   HalfLife WAD files contain files that look like this:
271
272         Mip section
273                 First mip
274                         Mip header
275                         First mip (width * height)
276                         Second mip (width * height / 4)
277                         Third mip (width * height / 16)
278                         Fourth mip (width * height / 64)
279                         Palette size (WORD)
280                         Palette (Palette size * 3)
281                         Padding (WORD)
282
283 ============================================================================
284 */
285
286 #define GET_MIP_DATA_SIZE(WIDTH, HEIGHT) (sizeof(WAD3_MIP) + (WIDTH * HEIGHT) + (WIDTH * HEIGHT / 4) + (WIDTH * HEIGHT / 16) + (WIDTH * HEIGHT / 64))
287
288 typedef struct
289 {
290         char            name[16];
291         DWORD           width, height;
292         DWORD           offsets[4];             // four mip maps stored
293 } WAD3_MIP, *LPWAD3_MIP;
294
295 /*
296 =========================================================
297
298 HLW LOADING
299
300   Hydra: this code isn't bullet proof and probably won't
301   like corrupt WAD files, but it works for now.
302
303   TODO: make it more robust.
304 =========================================================
305 */
306
307 /*
308 =============
309 LoadHLW
310 =============
311 */
312
313 static void LoadHLW (const char *name, byte ** pic, int *width, int *height)
314 {
315   byte *buffer;
316   byte *buf_p;
317   unsigned int length;
318   unsigned long mipdatasize;
319   int columns, rows, numPixels;
320   byte *pixbuf;
321   int row, column;
322   byte *bmpRGBA;
323   byte *palette;
324         LPWAD3_MIP              lpMip;
325         unsigned char red, green, blue, alphabyte;
326
327   *pic = NULL;
328
329   //
330   // load the file
331   //
332   length = vfsLoadFile ((char *) name, (void **) &buffer);
333   if (length == (unsigned int) -1)
334     return;
335
336   lpMip = (LPWAD3_MIP)buffer;
337
338   mipdatasize = GET_MIP_DATA_SIZE(lpMip->width,lpMip->height);
339
340   palette = buffer+mipdatasize+2;
341
342   buf_p = buffer+lpMip->offsets[0];
343
344   columns = lpMip->width;
345   rows = lpMip->height;
346   numPixels = columns * rows;
347
348   if (width)
349     *width = columns;
350   if (height)
351     *height = rows;
352
353   bmpRGBA = reinterpret_cast < unsigned char *>(g_malloc (numPixels * 4));
354   *pic = bmpRGBA;
355
356   for (row = 0; row < rows; row++)
357   {
358     pixbuf = bmpRGBA + row * columns * 4;
359
360     for (column = 0; column < columns; column++)
361     {
362       int palIndex;
363
364             palIndex = *buf_p++;
365
366       red = *(palette+(palIndex*3));
367       green = *(palette+(palIndex*3)+1);
368       blue = *(palette+(palIndex*3)+2);
369
370       // HalfLife engine makes pixels that are BLUE transparent.
371       // So show them that way in the editor.
372       if (blue == 0xff && red == 0x00 && green == 0x00)
373       {
374         alphabyte = 0x00;
375         blue = 0x00; // don't set the resulting pixel to blue
376       }
377       else
378       {
379         alphabyte = 0xff;
380       }
381
382             *pixbuf++ = red;
383             *pixbuf++ = green;
384             *pixbuf++ = blue;
385
386             *pixbuf++ = alphabyte;
387     }
388   }
389
390   vfsFreeFile (buffer);
391 }
392 #endif
393
394 #ifdef USE_MIP
395 /*
396 ============================================================================
397
398 MIP IMAGE
399
400   Quake WAD files contain miptex files that look like this:
401
402         Mip section
403                 First mip
404                         Mip header
405                         First mip (width * height)
406                         Second mip (width * height / 4)
407                         Third mip (width * height / 16)
408                         Fourth mip (width * height / 64)
409
410 ============================================================================
411 */
412
413 /*
414 =========================================================
415
416 MIP LOADING
417
418   LordHavoc: this code is based on the HLW code above.
419 =========================================================
420 */
421
422
423 static const byte quakepalette[768] =
424 {
425   0x00,0x00,0x00, 0x0f,0x0f,0x0f, 0x1f,0x1f,0x1f, 0x2f,0x2f,0x2f,
426   0x3f,0x3f,0x3f, 0x4b,0x4b,0x4b, 0x5b,0x5b,0x5b, 0x6b,0x6b,0x6b,
427   0x7b,0x7b,0x7b, 0x8b,0x8b,0x8b, 0x9b,0x9b,0x9b, 0xab,0xab,0xab,
428   0xbb,0xbb,0xbb, 0xcb,0xcb,0xcb, 0xdb,0xdb,0xdb, 0xeb,0xeb,0xeb,
429   0x0f,0x0b,0x07, 0x17,0x0f,0x0b, 0x1f,0x17,0x0b, 0x27,0x1b,0x0f,
430   0x2f,0x23,0x13, 0x37,0x2b,0x17, 0x3f,0x2f,0x17, 0x4b,0x37,0x1b,
431   0x53,0x3b,0x1b, 0x5b,0x43,0x1f, 0x63,0x4b,0x1f, 0x6b,0x53,0x1f,
432   0x73,0x57,0x1f, 0x7b,0x5f,0x23, 0x83,0x67,0x23, 0x8f,0x6f,0x23,
433   0x0b,0x0b,0x0f, 0x13,0x13,0x1b, 0x1b,0x1b,0x27, 0x27,0x27,0x33,
434   0x2f,0x2f,0x3f, 0x37,0x37,0x4b, 0x3f,0x3f,0x57, 0x47,0x47,0x67,
435   0x4f,0x4f,0x73, 0x5b,0x5b,0x7f, 0x63,0x63,0x8b, 0x6b,0x6b,0x97,
436   0x73,0x73,0xa3, 0x7b,0x7b,0xaf, 0x83,0x83,0xbb, 0x8b,0x8b,0xcb,
437   0x00,0x00,0x00, 0x07,0x07,0x00, 0x0b,0x0b,0x00, 0x13,0x13,0x00,
438   0x1b,0x1b,0x00, 0x23,0x23,0x00, 0x2b,0x2b,0x07, 0x2f,0x2f,0x07,
439   0x37,0x37,0x07, 0x3f,0x3f,0x07, 0x47,0x47,0x07, 0x4b,0x4b,0x0b,
440   0x53,0x53,0x0b, 0x5b,0x5b,0x0b, 0x63,0x63,0x0b, 0x6b,0x6b,0x0f,
441   0x07,0x00,0x00, 0x0f,0x00,0x00, 0x17,0x00,0x00, 0x1f,0x00,0x00,
442   0x27,0x00,0x00, 0x2f,0x00,0x00, 0x37,0x00,0x00, 0x3f,0x00,0x00,
443   0x47,0x00,0x00, 0x4f,0x00,0x00, 0x57,0x00,0x00, 0x5f,0x00,0x00,
444   0x67,0x00,0x00, 0x6f,0x00,0x00, 0x77,0x00,0x00, 0x7f,0x00,0x00,
445   0x13,0x13,0x00, 0x1b,0x1b,0x00, 0x23,0x23,0x00, 0x2f,0x2b,0x00,
446   0x37,0x2f,0x00, 0x43,0x37,0x00, 0x4b,0x3b,0x07, 0x57,0x43,0x07,
447   0x5f,0x47,0x07, 0x6b,0x4b,0x0b, 0x77,0x53,0x0f, 0x83,0x57,0x13,
448   0x8b,0x5b,0x13, 0x97,0x5f,0x1b, 0xa3,0x63,0x1f, 0xaf,0x67,0x23,
449   0x23,0x13,0x07, 0x2f,0x17,0x0b, 0x3b,0x1f,0x0f, 0x4b,0x23,0x13,
450   0x57,0x2b,0x17, 0x63,0x2f,0x1f, 0x73,0x37,0x23, 0x7f,0x3b,0x2b,
451   0x8f,0x43,0x33, 0x9f,0x4f,0x33, 0xaf,0x63,0x2f, 0xbf,0x77,0x2f,
452   0xcf,0x8f,0x2b, 0xdf,0xab,0x27, 0xef,0xcb,0x1f, 0xff,0xf3,0x1b,
453   0x0b,0x07,0x00, 0x1b,0x13,0x00, 0x2b,0x23,0x0f, 0x37,0x2b,0x13,
454   0x47,0x33,0x1b, 0x53,0x37,0x23, 0x63,0x3f,0x2b, 0x6f,0x47,0x33,
455   0x7f,0x53,0x3f, 0x8b,0x5f,0x47, 0x9b,0x6b,0x53, 0xa7,0x7b,0x5f,
456   0xb7,0x87,0x6b, 0xc3,0x93,0x7b, 0xd3,0xa3,0x8b, 0xe3,0xb3,0x97,
457   0xab,0x8b,0xa3, 0x9f,0x7f,0x97, 0x93,0x73,0x87, 0x8b,0x67,0x7b,
458   0x7f,0x5b,0x6f, 0x77,0x53,0x63, 0x6b,0x4b,0x57, 0x5f,0x3f,0x4b,
459   0x57,0x37,0x43, 0x4b,0x2f,0x37, 0x43,0x27,0x2f, 0x37,0x1f,0x23,
460   0x2b,0x17,0x1b, 0x23,0x13,0x13, 0x17,0x0b,0x0b, 0x0f,0x07,0x07,
461   0xbb,0x73,0x9f, 0xaf,0x6b,0x8f, 0xa3,0x5f,0x83, 0x97,0x57,0x77,
462   0x8b,0x4f,0x6b, 0x7f,0x4b,0x5f, 0x73,0x43,0x53, 0x6b,0x3b,0x4b,
463   0x5f,0x33,0x3f, 0x53,0x2b,0x37, 0x47,0x23,0x2b, 0x3b,0x1f,0x23,
464   0x2f,0x17,0x1b, 0x23,0x13,0x13, 0x17,0x0b,0x0b, 0x0f,0x07,0x07,
465   0xdb,0xc3,0xbb, 0xcb,0xb3,0xa7, 0xbf,0xa3,0x9b, 0xaf,0x97,0x8b,
466   0xa3,0x87,0x7b, 0x97,0x7b,0x6f, 0x87,0x6f,0x5f, 0x7b,0x63,0x53,
467   0x6b,0x57,0x47, 0x5f,0x4b,0x3b, 0x53,0x3f,0x33, 0x43,0x33,0x27,
468   0x37,0x2b,0x1f, 0x27,0x1f,0x17, 0x1b,0x13,0x0f, 0x0f,0x0b,0x07,
469   0x6f,0x83,0x7b, 0x67,0x7b,0x6f, 0x5f,0x73,0x67, 0x57,0x6b,0x5f,
470   0x4f,0x63,0x57, 0x47,0x5b,0x4f, 0x3f,0x53,0x47, 0x37,0x4b,0x3f,
471   0x2f,0x43,0x37, 0x2b,0x3b,0x2f, 0x23,0x33,0x27, 0x1f,0x2b,0x1f,
472   0x17,0x23,0x17, 0x0f,0x1b,0x13, 0x0b,0x13,0x0b, 0x07,0x0b,0x07,
473   0xff,0xf3,0x1b, 0xef,0xdf,0x17, 0xdb,0xcb,0x13, 0xcb,0xb7,0x0f,
474   0xbb,0xa7,0x0f, 0xab,0x97,0x0b, 0x9b,0x83,0x07, 0x8b,0x73,0x07,
475   0x7b,0x63,0x07, 0x6b,0x53,0x00, 0x5b,0x47,0x00, 0x4b,0x37,0x00,
476   0x3b,0x2b,0x00, 0x2b,0x1f,0x00, 0x1b,0x0f,0x00, 0x0b,0x07,0x00,
477   0x00,0x00,0xff, 0x0b,0x0b,0xef, 0x13,0x13,0xdf, 0x1b,0x1b,0xcf,
478   0x23,0x23,0xbf, 0x2b,0x2b,0xaf, 0x2f,0x2f,0x9f, 0x2f,0x2f,0x8f,
479   0x2f,0x2f,0x7f, 0x2f,0x2f,0x6f, 0x2f,0x2f,0x5f, 0x2b,0x2b,0x4f,
480   0x23,0x23,0x3f, 0x1b,0x1b,0x2f, 0x13,0x13,0x1f, 0x0b,0x0b,0x0f,
481   0x2b,0x00,0x00, 0x3b,0x00,0x00, 0x4b,0x07,0x00, 0x5f,0x07,0x00,
482   0x6f,0x0f,0x00, 0x7f,0x17,0x07, 0x93,0x1f,0x07, 0xa3,0x27,0x0b,
483   0xb7,0x33,0x0f, 0xc3,0x4b,0x1b, 0xcf,0x63,0x2b, 0xdb,0x7f,0x3b,
484   0xe3,0x97,0x4f, 0xe7,0xab,0x5f, 0xef,0xbf,0x77, 0xf7,0xd3,0x8b,
485   0xa7,0x7b,0x3b, 0xb7,0x9b,0x37, 0xc7,0xc3,0x37, 0xe7,0xe3,0x57,
486   0x7f,0xbf,0xff, 0xab,0xe7,0xff, 0xd7,0xff,0xff, 0x67,0x00,0x00,
487   0x8b,0x00,0x00, 0xb3,0x00,0x00, 0xd7,0x00,0x00, 0xff,0x00,0x00,
488   0xff,0xf3,0x93, 0xff,0xf7,0xc7, 0xff,0xff,0xff, 0x9f,0x5b,0x53
489 };
490
491 /*
492 =============
493 LoadMIP
494 =============
495 */
496
497 static void LoadMIP (const char *name, byte ** pic, int *width, int *height)
498 {
499   byte *buffer;
500   byte *buf_p;
501   unsigned int length, palettelength;
502   unsigned long mipdatasize;
503   int columns, rows, numPixels;
504   byte *pixbuf;
505   int i;
506   byte *bmpRGBA;
507   byte *loadedpalette;
508   const byte *palette;
509   LPWAD3_MIP            lpMip;
510
511   *pic = NULL;
512   loadedpalette = NULL;
513
514   //
515   // load the file
516   //
517   length = vfsLoadFile ((char *) name, (void **) &buffer);
518   if (length == (unsigned int) -1)
519     return;
520
521   lpMip = (LPWAD3_MIP)buffer;
522
523   mipdatasize = GET_MIP_DATA_SIZE(lpMip->width,lpMip->height);
524
525   palettelength = vfsLoadFile ("textures/palette.lmp", (void **) &loadedpalette);
526   if (palettelength == 768)
527     palette = loadedpalette;
528   else
529   {
530     loadedpalette = NULL;
531     palette = quakepalette;
532   }
533
534   buf_p = buffer+lpMip->offsets[0];
535
536   columns = lpMip->width;
537   rows = lpMip->height;
538   numPixels = columns * rows;
539
540   if (width)
541     *width = columns;
542   if (height)
543     *height = rows;
544
545   //Sys_Printf("lpMip->width = %i, lpMip->height = %i, lpMip->offsets[0] = %i, lpMip->offsets[1] = %i, lpMip->offsets[2] = %i, lpMip->offsets[3] = %i, numPixels = %i\n", lpMip->width, lpMip->height, lpMip->offsets[0], lpMip->offsets[1], lpMip->offsets[2], lpMip->offsets[3], numPixels);
546   //for (i = 0; i < sizeof(*lpMip); i++)
547   //  Sys_Printf("%02x", (int) ((unsigned char *)lpMip)[i]);
548
549   bmpRGBA = reinterpret_cast < unsigned char *>(g_malloc (numPixels * 4));
550   *pic = bmpRGBA;
551   pixbuf = bmpRGBA;
552
553   for (i = 0; i < numPixels; i++)
554   {
555     int palIndex = *buf_p++;
556     *pixbuf++ = palette[palIndex*3];
557     *pixbuf++ = palette[palIndex*3+1];
558     *pixbuf++ = palette[palIndex*3+2];
559     *pixbuf++ = 0xff;
560   }
561
562   vfsFreeFile (buffer);
563   if (loadedpalette != NULL)
564     vfsFreeFile (loadedpalette);
565 }
566 #endif
567
568 /*
569 =================
570 LoadImage
571
572 Loads any of the supported image types into a cannonical
573 32 bit format.
574 =================
575 */
576 void LoadImage (const char *name, byte ** pic, int *width, int *height)
577 {
578   int len;
579   *pic = NULL;
580   *width = 0;
581   *height = 0;
582
583   len = strlen (name);
584   if (len < 5)
585   {
586     return;
587   }
588
589 #ifdef USE_HLW
590   if (*pic == NULL && !g_strcasecmp (name + len - 4, ".hlw"))
591   {
592     LoadHLW (name, pic, width, height);
593   }
594 #endif
595
596 #ifdef USE_MIP
597   if (*pic == NULL && !g_strcasecmp (name + len - 4, ".mip"))
598   {
599     LoadMIP (name, pic, width, height);
600   }
601 #endif
602
603 #ifdef USE_IDSP
604   if (*pic == NULL && !g_strcasecmp (name + len - 4, ".spr"))
605   {
606     LoadIDSP (name, pic, width, height);
607   }
608 #endif
609 }