2 * upkg: a tool for manipulating Unreal Tournament packages.
3 * Very simple PCX writer for saving extracted textures.
5 * Copyright © 2012 Nick Bowler
7 * This program 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 3 of the License, or
10 * (at your option) any later version.
12 * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
26 #include <engine/palette.h>
31 int pcx_init_header(struct pcx_head *head)
33 unsigned short stride;
35 if (head->width == 0 || head->width > 0xffff)
37 if (head->height == 0 || head->height > 0xffff)
40 stride = head->width + (head->width & 1);
41 if (stride == 0 || stride > 0xffff)
44 memset(head->encoded, 0, sizeof head->encoded);
46 head->encoded[0] = 10; /* PCX Magic */
47 head->encoded[1] = 5; /* Version 3. */
48 head->encoded[2] = 1; /* Run-length encoding. */
49 head->encoded[3] = 8; /* Bits per pixel. */
51 pack_16_le(head->encoded+8, head->width-1);
52 pack_16_le(head->encoded+10, head->height-1);
54 head->encoded[65] = 1; /* One plane (indexed colour). */
55 pack_16_le(head->encoded+66, stride);
57 head->encoded[68] = 1; /* Colour palette. */
62 int pcx_write_scanline(const struct pcx_head *head, const unsigned char *src,
65 size_t len = head->width, offset = 0;
66 unsigned char buf[head->width*2ul];
68 for (size_t i = 0; i < len;) {
71 while (i+run < len && src[i] == src[i+run] && run < 0x3f)
74 if (run > 1 || src[i] > 0xbf)
75 buf[offset++] = 0xc0 | run;
76 buf[offset++] = src[i];
80 if (fwrite(buf, offset, 1, f) != 1)
85 int pcx_write_palette(EnginePalette *palette, FILE *f)
87 unsigned char buf[769] = {12};
89 for (unsigned i = 0; i < palette->entries; i++) {
90 buf[3*i+1] = palette->rgba[i][0];
91 buf[3*i+2] = palette->rgba[i][1];
92 buf[3*i+3] = palette->rgba[i][2];
95 if (fwrite(buf, sizeof buf, 1, f) != 1)