/* * Copyright(c) 1997-2001 Id Software, Inc. * Copyright(c) 2002 The Quakeforge Project. * Copyright(c) 2006 Quetoo. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or(at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "pcx.h" #include "video.h" /* LoadPCX */ void LoadPCX(char *name, byte **pic, byte **palette, int *width, int *height){ byte *buffer; pcx_t *pcx; int x, y, length; int data, run_length; byte *out, *pixbuf; *pic = NULL; *palette = NULL; length = FS_LoadFile(name, (void **)(char *)&buffer); if(!buffer){ // unable to open file return; } pcx = (pcx_t *)buffer; pcx->xmin = LittleShort(pcx->xmin); pcx->ymin = LittleShort(pcx->ymin); pcx->xmax = LittleShort(pcx->xmax); pcx->ymax = LittleShort(pcx->ymax); pcx->hres = LittleShort(pcx->hres); pcx->vres = LittleShort(pcx->vres); pcx->bytes_per_line = LittleShort(pcx->bytes_per_line); pcx->palette_type = LittleShort(pcx->palette_type); buffer = &pcx->data; if(pcx->manufacturer != 0x0a || pcx->version != 5 || pcx->encoding != 1 || pcx->bits_per_pixel != 8 || pcx->xmax >= 640 || pcx->ymax >= 480){ return; } out = malloc((pcx->ymax + 1) *(pcx->xmax + 1)); *pic = out; pixbuf = out; if(palette){ *palette = malloc(768); memcpy(*palette,(byte *)pcx + length - 768, 768); } if(width) *width = pcx->xmax + 1; if(height) *height = pcx->ymax + 1; for(y = 0; y <= pcx->ymax; y++, pixbuf += pcx->xmax + 1){ for(x = 0; x <= pcx->xmax;){ data = *buffer++; if((data & 0xC0) == 0xC0){ run_length = data & 0x3F; data = *buffer++; } else run_length = 1; while(run_length-- > 0) pixbuf[x++] = data; } } if(buffer - (byte *)pcx > length){ free(*pic); *pic = NULL; } FS_FreeFile(pcx); } /* WritePCX */ void WritePCX(char *name, byte *data, int width, int height, int rowbytes, byte *palette){ int i, j, length; pcx_t *pcx; byte *pack; FILE *f; pcx = (pcx_t *)malloc(width * height * 2 + 1000); if(!pcx) return; pcx->manufacturer = 0x0a; // PCX id pcx->version = 5; // 256 color pcx->encoding = 1; // uncompressed pcx->bits_per_pixel = 8; // 256 color pcx->xmin = 0; pcx->ymin = 0; pcx->xmax = LittleShort((short)(width - 1)); pcx->ymax = LittleShort((short)(height - 1)); pcx->hres = LittleShort((short)width); pcx->vres = LittleShort((short)height); memset(pcx->palette, 0, sizeof(pcx->palette)); pcx->color_planes = 1; // chunky image pcx->bytes_per_line = LittleShort((short)width); pcx->palette_type = LittleShort(2); // not a grey scale memset(pcx->filler, 0, sizeof(pcx->filler)); // pack the image pack = &pcx->data; for(i = 0; i < height; i++){ for(j = 0; j < width; j++){ if((*data & 0xc0) != 0xc0) *pack++ = *data++; else { *pack++ = 0xc1; *pack++ = *data++; } } data += rowbytes - width; } // write the palette *pack++ = 0x0c; // palette ID byte for(i = 0; i < 768; i++) *pack++ = *palette++; // write output file length = pack - (byte *)pcx; f = fopen(name, "wb"); if(!f) Com_Printf( "Failed to open to %s\n", name); else { fwrite((void *)pcx, 1, length, f); fclose(f); } free(pcx); }