2 Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
5 This file is part of GtkRadiant.
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.
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.
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
24 #include "ifilesystem.h"
26 typedef unsigned char byte;
31 #include "bytestreamutils.h"
34 =================================================================
38 =================================================================
43 unsigned char manufacturer;
44 unsigned char version;
45 unsigned char encoding;
46 unsigned char bits_per_pixel;
47 unsigned short xmin, ymin, xmax, ymax;
48 unsigned short hres, vres;
49 unsigned char palette[48];
50 unsigned char reserved;
51 unsigned char color_planes;
52 unsigned short bytes_per_line;
53 unsigned short palette_type;
54 unsigned char filler[58];
55 unsigned char data; // unbounded
70 inline void ByteStream_readPCXRLEPacket(PointerInputStream& inputStream, PCXRLEPacket& packet)
73 inputStream.read(&d, 1);
74 if((d & 0xC0) == 0xC0)
76 packet.length = d & 0x3F;
77 inputStream.read(&packet.data, 1);
86 void LoadPCXBuff(byte* buffer, std::size_t len, byte **pic, byte **palette, int *width, int *height )
94 /* parse the PCX file */
96 PointerInputStream inputStream(buffer);
98 pcx.manufacturer = istream_read_byte(inputStream);
99 pcx.version = istream_read_byte(inputStream);
100 pcx.encoding = istream_read_byte(inputStream);
101 pcx.bits_per_pixel = istream_read_byte(inputStream);
102 pcx.xmin = istream_read_int16_le(inputStream);
103 pcx.ymin = istream_read_int16_le(inputStream);
104 pcx.xmax = istream_read_int16_le(inputStream);
105 pcx.ymax = istream_read_int16_le(inputStream);
106 pcx.hres = istream_read_int16_le(inputStream);
107 pcx.vres = istream_read_int16_le(inputStream);
108 inputStream.read(pcx.palette, 48);
109 pcx.reserved = istream_read_byte(inputStream);
110 pcx.color_planes = istream_read_byte(inputStream);
111 pcx.bytes_per_line = istream_read_int16_le(inputStream);
112 pcx.palette_type = istream_read_int16_le(inputStream);
113 inputStream.read(pcx.filler, 58);
116 if (pcx.manufacturer != 0x0a
119 || pcx.bits_per_pixel != 8)
125 *height = pcx.ymax+1;
130 out = (byte *)malloc ( (pcx.ymax+1) * (pcx.xmax+1) );
135 /* RR2DO2: pcx fix */
136 lsize = pcx.color_planes * pcx.bytes_per_line;
138 /* go scanline by scanline */
139 for( y = 0; y <= pcx.ymax; y++, pix += pcx.xmax + 1 )
142 for( x=0; x <= pcx.xmax; )
146 ByteStream_readPCXRLEPacket(inputStream, packet);
148 while(packet.length-- > 0)
150 pix[ x++ ] = packet.data;
154 /* RR2DO2: discard any other data */
158 ByteStream_readPCXRLEPacket(inputStream, packet);
161 while( packet.length-- > 0 )
168 if( std::size_t(inputStream.get() - buffer) > len)
175 *palette = (byte *)malloc(768);
176 memcpy (*palette, buffer + len - 768, 768);
185 Image* LoadPCX32Buff(byte* buffer, std::size_t length)
189 int i, c, p, width, height;
192 LoadPCXBuff(buffer, length, &pic8, &palette, &width, &height);
198 RGBAImage* image = new RGBAImage(width, height);
199 c = (width) * (height);
200 pic32 = image->getRGBAPixels();
201 for (i = 0; i < c; i++)
204 pic32[0] = palette[p * 3];
205 pic32[1] = palette[p * 3 + 1];
206 pic32[2] = palette[p * 3 + 2];
217 Image* LoadPCX32(ArchiveFile& file)
219 ScopedArchiveBuffer buffer(file);
220 return LoadPCX32Buff(buffer.buffer, buffer.length);