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 =================================================================
42 unsigned char manufacturer;
43 unsigned char version;
44 unsigned char encoding;
45 unsigned char bits_per_pixel;
46 unsigned short xmin, ymin, xmax, ymax;
47 unsigned short hres, vres;
48 unsigned char palette[48];
49 unsigned char reserved;
50 unsigned char color_planes;
51 unsigned short bytes_per_line;
52 unsigned short palette_type;
53 unsigned char filler[58];
54 unsigned char data; // unbounded
68 inline void ByteStream_readPCXRLEPacket(PointerInputStream &inputStream, PCXRLEPacket &packet)
71 inputStream.read(&d, 1);
72 if ((d & 0xC0) == 0xC0) {
73 packet.length = d & 0x3F;
74 inputStream.read(&packet.data, 1);
81 void LoadPCXBuff(byte *buffer, std::size_t len, byte **pic, byte **palette, int *width, int *height)
89 /* parse the PCX file */
91 PointerInputStream inputStream(buffer);
93 pcx.manufacturer = istream_read_byte(inputStream);
94 pcx.version = istream_read_byte(inputStream);
95 pcx.encoding = istream_read_byte(inputStream);
96 pcx.bits_per_pixel = istream_read_byte(inputStream);
97 pcx.xmin = istream_read_int16_le(inputStream);
98 pcx.ymin = istream_read_int16_le(inputStream);
99 pcx.xmax = istream_read_int16_le(inputStream);
100 pcx.ymax = istream_read_int16_le(inputStream);
101 pcx.hres = istream_read_int16_le(inputStream);
102 pcx.vres = istream_read_int16_le(inputStream);
103 inputStream.read(pcx.palette, 48);
104 pcx.reserved = istream_read_byte(inputStream);
105 pcx.color_planes = istream_read_byte(inputStream);
106 pcx.bytes_per_line = istream_read_int16_le(inputStream);
107 pcx.palette_type = istream_read_int16_le(inputStream);
108 inputStream.read(pcx.filler, 58);
111 if (pcx.manufacturer != 0x0a
114 || pcx.bits_per_pixel != 8) {
119 *width = pcx.xmax + 1;
122 *height = pcx.ymax + 1;
129 out = (byte *) malloc((pcx.ymax + 1) * (pcx.xmax + 1));
134 /* RR2DO2: pcx fix */
135 lsize = pcx.color_planes * pcx.bytes_per_line;
137 /* go scanline by scanline */
138 for (y = 0; y <= pcx.ymax; y++, pix += pcx.xmax + 1) {
140 for (x = 0; x <= pcx.xmax;) {
143 ByteStream_readPCXRLEPacket(inputStream, packet);
145 while (packet.length-- > 0) {
146 pix[x++] = packet.data;
150 /* RR2DO2: discard any other data */
153 ByteStream_readPCXRLEPacket(inputStream, packet);
156 while (packet.length-- > 0) {
162 if (std::size_t(inputStream.get() - buffer) > len) {
167 *palette = (byte *) malloc(768);
168 memcpy(*palette, buffer + len - 768, 768);
177 Image *LoadPCX32Buff(byte *buffer, std::size_t length)
181 int i, c, p, width, height;
184 LoadPCXBuff(buffer, length, &pic8, &palette, &width, &height);
189 RGBAImage *image = new RGBAImage(width, height);
190 c = (width) * (height);
191 pic32 = image->getRGBAPixels();
192 for (i = 0; i < c; i++) {
194 pic32[0] = palette[p * 3];
195 pic32[1] = palette[p * 3 + 1];
196 pic32[2] = palette[p * 3 + 2];
207 Image *LoadPCX32(ArchiveFile &file)
209 ScopedArchiveBuffer buffer(file);
210 return LoadPCX32Buff(buffer.buffer, buffer.length);