1 /*
2 PLIB - A Suite of Portable Game Libraries
3 Copyright (C) 2001 Steve Baker
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 For further information visit http://plib.sourceforge.net
20
21 $Id: ssgLoadPCX.cxx 1963 2004-09-26 09:27:28Z bram $
22 */
23
24 //===========================================================================
25 //
26 // File: ssgLoadPCX.cxx
27 //
28 // Created: 12.12.2003
29 //
30 // Author: Wolfram Kuss
31 //
32 // Revision: $Id: ssgLoadPCX.cxx 1963 2004-09-26 09:27:28Z bram $
33 //
34 // Description: Loads PCX texture files. Only 8 bit indexed for now.
35 //
36 //
37 //===========================================================================
38
39 #include "ssgLocal.h"
40 typedef unsigned char UByte,*UByteP;
41 #include "pcx.h"
42
43
44 #ifdef SSG_LOAD_PCX_SUPPORTED
45
ReadFileIntoBuffer(const char * fname,UByte * & buffer,UByte * & bufferorig,unsigned long & file_length)46 int ReadFileIntoBuffer(const char *fname, UByte *&buffer, UByte *&bufferorig, unsigned long &file_length)
47 // Opens the file, allocates buffer of correct size to hold the file, reads it, closes it
48 {
49 // **** open file ****
50 FILE *tfile;
51 if ( (tfile = fopen(fname, "rb")) == NULL) {
52 ulSetError( UL_WARNING, "ssgLoadTexture: Failed to open file '%s' for reading.", fname );
53 return false ;
54 }
55
56 // **** allocate buffer, read file into it and close file ****
57 fseek(tfile, 0, SEEK_END);
58 file_length = ftell(tfile);
59 fseek(tfile, 0, SEEK_SET);
60
61 buffer = new UByte[file_length];
62 bufferorig = buffer;
63
64 fread(buffer, file_length, 1, tfile);
65 fclose(tfile);
66 return true;
67 }
68
ssgLoadPCX(const char * fname,ssgTextureInfo * info)69 bool ssgLoadPCX ( const char *fname, ssgTextureInfo* info )
70 {
71 UByte *buffer, *bufferorig;
72 unsigned long file_length;
73 if(!ReadFileIntoBuffer(fname, buffer, bufferorig, file_length))
74 return false ;
75 // **** "read" header and "analyse" it ****
76 pcxHeaderType *ppcxHeader = (pcxHeaderType *) buffer;
77 buffer += sizeof(pcxHeaderType);
78
79 short width = ppcxHeader->xmax-ppcxHeader->x+1;
80 short height = ppcxHeader->ymax-ppcxHeader->y+1;
81 //p->isMasked = ((p->resOfRowanTexture & 0x200) != 0) ? 1 : 0;
82
83 if ( info != NULL )
84 {
85 info -> width = width ;
86 info -> height = height ;
87 info -> depth = 4 ;
88 info -> alpha = TRUE ; //I think we have to set it to true always, since we always generate 4 bytes per pixel
89 }
90
91 // **** read body�; Do error checking ****
92 long size = ((long)width)*height;
93 UByte *pAlfa = NULL, * pBody = new UByte [size]; // 1 byte per texel
94 UByte * pBodyorig = pBody;
95
96 if(!ReadPCXBody(buffer, ppcxHeader, pBody))
97 // writes to pBody, which must have been allocated
98 {
99 delete [] buffer;
100 delete [] pBody;
101 ulSetError ( UL_WARNING,
102 "ssgLoadTexture: '%s' - unsupported or broken PCX texture file", fname ) ;
103 return false ;
104 }
105 if(*buffer++ != 12)
106 { ulSetError ( UL_WARNING, "ssgLoadTexture: '%s' - PCX files needs a '12' byte", fname ) ;
107 return false ;
108 }
109 assert(bufferorig + file_length - 768 == buffer);
110 // starting at "buffer", you can find the palette, 256 entrys with 3 bytes each
111 // only true for version 5 (and possible later versions)=
112
113 // start alfa handling
114 // PCX does not allow alfa, so to enable alfa, you need two files :-(,
115 // one for the body, for example abc.pcx and one for the alfa component, for example abc_trans.pcx
116 if(fname[strlen(fname)-4]=='.')
117 {
118 char *t, *s = new char[strlen(fname)+15];
119 strcpy(s, fname);
120 t=&(s[strlen(s)-4]);
121 strcpy(t, "_trans.pcx");
122 if(ulFileExists(s))
123 {
124 UByte *alfaBuffer, *alfaBufferorig;
125 if(!ReadFileIntoBuffer(s, alfaBuffer, alfaBufferorig, file_length))
126 return false ;
127 // **** "read" header and "analyse" it ****
128 ppcxHeader = (pcxHeaderType *) alfaBuffer;
129 alfaBuffer += sizeof(pcxHeaderType);
130
131 if(width != ppcxHeader->xmax-ppcxHeader->x+1)
132 ulSetError ( UL_WARNING, "ssgLoadTexture: '%s' - Width does not agree to 'body' width, so alfa is ignored", s ) ;
133 else
134 {
135
136 if (height != ppcxHeader->ymax-ppcxHeader->y+1)
137 ulSetError ( UL_WARNING, "ssgLoadTexture: '%s' - Height does not agree to 'body' height, so alfa is ignored", s ) ;
138 else
139 {
140 // **** read body�; Do error checking ****
141 pAlfa = new UByte [size]; // 1 byte per texel
142
143 if(!ReadPCXBody(alfaBuffer, ppcxHeader, pAlfa))
144 // writes to pBody, which must have been allocated
145 {
146 delete [] buffer;
147 delete [] pAlfa;
148 ulSetError ( UL_WARNING,
149 "ssgLoadTexture: '%s' - unsupported or broken PCX texture file", fname ) ;
150 return false ;
151 }
152 }
153 }
154 }
155 }
156 // end alfa handling
157
158 UByte *texels = new UByte [size * 4]; // 4 bytes per texel
159 int c = 0;
160 int iRunningIndex = 0;
161 for (int y = 0; y < height; y++) {
162 for (int x = 0; x < width; x++) {
163 UByte a = pAlfa?pAlfa[iRunningIndex]:255;
164 UByte b = pBody[iRunningIndex++];
165 texels[c++] = buffer[b*3 ];
166 texels[c++] = buffer[b*3 + 1];
167 texels[c++] = buffer[b*3 + 2];
168 texels[c++] = a;
169 }
170 }
171
172 delete [] pBodyorig;
173 delete [] bufferorig;
174 if (pAlfa)
175 delete [] pAlfa;
176 return ssgMakeMipMaps ( texels, width, height, 4 ) ;
177 }
178 #else
179
ssgLoadPCX(const char * fname,ssgTextureInfo * info)180 bool ssgLoadPCX ( const char *fname, ssgTextureInfo* info )
181 {
182 ulSetError ( UL_WARNING,
183 "ssgLoadTexture: '%s' - PCX texture support not configured", fname ) ;
184 return false ;
185 }
186
187 #endif
188
189