This repository has been archived on 2025-02-27. You can view files and clone it, but cannot push or open issues or pull requests.
CnC_Renegade/Code/wwlib/pcx.cpp

168 lines
6.5 KiB
C++

/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** 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 3 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, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Command & Conquer *
* *
* $Archive:: /Commando/Code/Library/PCX.cpp $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 9/28/98 12:06p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "always.h"
#include "pcx.h"
#include <stdlib.h>
/***************************************************************************
* READ_PCX_FILE -- read a pcx file into a Graphic Buffer *
* *
* GraphicBufferClass* Read_PCX_File (char* name, char* palette,void *Buff, long size ); *
* *
* *
* INPUT: name is a NULL terminated string of the format [xxxx.pcx] *
* palette is optional, if palette != NULL the the color palette of *
* the pcx file will be place in the memory block pointed *
* by palette. *
* Buff is optional, if Buff == NULL a new memory Buffer *
* will be allocated, otherwise the file will be placed *
* at location pointed by Buffer; *
* Size is the size in bytes of the memory block pointed by Buff *
* is also optional; * *
* OUTPUT: on success a pointer to a GraphicBufferClass containing the *
* pcx file, NULL otherwise. *
* *
* WARNINGS: *
* Appears to be a comment-free zone *
* *
* HISTORY: *
* 05/03/1995 JRJ : Created. *
* 04/30/1996 ST : Tidied up and modified to use CCFileClass *
*=========================================================================*/
#define POOL_SIZE 2048
#define READ_CHAR() *file_ptr++ ; \
if ( file_ptr >= & pool [ POOL_SIZE ] ) { \
file_handle.Read (pool, POOL_SIZE ); \
file_ptr = pool ; \
}
#define READ_CHARx() *file_ptr++ ; \
if ( file_ptr >= & pool [ POOL_SIZE ] ) { \
file_handle.Read (pool, POOL_SIZE ); \
}
Surface * Read_PCX_File(FileClass & file_handle, PaletteClass * palette, void * Buff, long Size)
{
unsigned i, j;
unsigned rle;
unsigned color;
unsigned scan_pos;
char *file_ptr;
unsigned width;
unsigned height;
char *buffer;
PCX_HEADER header;
char pool [POOL_SIZE];
BSurface * pic;
if (!file_handle.Is_Available()) return (NULL);
file_handle.Open(FileClass::READ);
file_handle.Read (&header, sizeof (PCX_HEADER));
if (header.id != 10 && header.version != 5 && header.pixelsize != 8 ) return NULL ;
width = header.width - header.x + 1;
height = header.height - header.y + 1;
if (Buff != NULL) {
i = Size / width;
height = MIN ((int)(i - 1), (int)height);
Buffer b(Buff, Size);
pic = new BSurface(width, height, 1, &b);
if (pic == NULL) return NULL ;
} else {
pic = new BSurface(width, height, 1);
if (pic == NULL) return NULL ;
}
buffer = (char *)pic->Lock();
if (buffer != NULL) {
file_ptr = pool ;
file_handle.Read (pool, POOL_SIZE);
if ( header.byte_per_line != width ) {
i = 0;
rle = 0;
for ( scan_pos = j = 0 ; j < height ; j ++, scan_pos += width ) {
for ( i = 0 ; i < width ; ) {
rle = READ_CHAR ();
if ( rle > 192 ) {
rle -= 192 ;
color = READ_CHAR (); ;
memset ( buffer + scan_pos + i, color, rle );
i += rle;
} else {
*(buffer+scan_pos + i++ ) = (char)rle;
}
}
}
if ( i == width ) rle = READ_CHAR ();
if ( rle > 192 ) READ_CHARx();
} else {
for ( i = 0 ; i < width * height ; ) {
rle = READ_CHAR ();
rle &= 0xff;
if ( rle > 192 ) {
rle -= 192 ;
color = READ_CHAR ();
memset ( buffer + i, color, rle );
i += rle ;
} else {
*(buffer + i++) = (char)rle;
}
}
}
pic->Unlock();
}
if ( palette ) {
file_handle.Seek (- (256 * (int)sizeof(RGB)), SEEK_END );
file_handle.Read (palette, 256L * sizeof ( RGB ));
}
file_handle.Close();
return pic;
}