ack3d/ack_lib/ACKPCX.C
Gered 83aaf0d5b9 update acklib to build under watcom
borland conditionals have been removed. asm sources converted fully
to tasm ideal mode. keyboard and timer interrupt handlers moved to c
code copied from fdemo watcom sources
2019-11-02 13:56:52 -04:00

161 lines
5.2 KiB
C

// This source file contains the functions needed to read in PCX files.
// (c) 1995 ACK Software (Lary Myers)
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
//typedef unsigned short USHORT;
#include "ack3d.h" // Main ACK-3D internal and interface data structures
#include "ackeng.h" // Internal data structures and constants
#include "ackext.h" // Defines external (global) variables
typedef struct
{
char manufacturer; // Always set to 0
char version; // Always 5 for 256-color files
char encoding; // Always set to 1
char bits_per_pixel; // Should be 8 for 256-color files
short xmin,ymin; // Coordinates for top left corner
short xmax,ymax; // Width and height of image
short hres; // Horizontal resolution of image
short vres; // Vertical resolution of image
char palette16[48]; // EGA palette; not used for 256-color files
char reserved; // Reserved for future use
char color_planes; // Color planes
short bytes_per_line; // Number of bytes in 1 line of pixels
short palette_type; // Should be 2 for color palette
char filler[58]; // Reserved
} PcxHeader;
typedef struct
{
PcxHeader hdr; // Header information
UCHAR *bitmap; // The bitmap data
UCHAR pal[768]; // Color palette for the bitmap data
unsigned short imagebytes,width,height; // Size of the bitmap
} PcxFile;
#define PCX_MAX_SIZE 64000L
enum {PCX_OK,PCX_NOMEM,PCX_TOOBIG,PCX_NOFILE};
enum {NORMAL,RLE};
//enum {FALSE,TRUE};
PcxFile pcxGlobal; // data structure for reading PCX files
extern unsigned char colordat[];
//=============================================================================
// This routine loads a 256 color PCX file. The file can be a standalone
// PCX file or it can be combined with a resource. If the data is part
// of a resource, the rshandle flag will be set. The bitmap data is read
// into a buffer that is the size of the bitmap + 4 bytes. The first 4
// bytes in the buffer contain the width and height of the bitmap.
//=============================================================================
unsigned char *AckReadPCX(char *filename)
{
long i;
int mode=NORMAL,nbytes;
char abyte,*p;
int handle;
PcxFile *pcx;
pcx = &pcxGlobal;
// Open the file since no resource is open.
if (!rsHandle)
{
handle = open(filename,O_RDONLY|O_BINARY); // Open the file for reading
if (handle < 1) // Make sure file is opened
{
ErrorCode = ERR_BADFILE;
return NULL;
}
}
else // Use the resource instead
{
handle = rsHandle; // Use the handle to the resource file
// Move to the location in the resource where the data is stored
lseek(handle,rbaTable[(ULONG)filename],SEEK_SET);
}
read(handle,&pcx->hdr,sizeof(PcxHeader)); // Read in the header data
pcx->width=1+pcx->hdr.xmax-pcx->hdr.xmin; // Store width and height
pcx->height=1+pcx->hdr.ymax-pcx->hdr.ymin;
// Store number of bytes used for image
pcx->imagebytes=(unsigned int)(pcx->width*pcx->height);
// Make sure bitmap is correct size
if (pcx->imagebytes > PCX_MAX_SIZE)
{
if (!rsHandle)
close(handle);
ErrorCode = ERR_INVALIDFORM;
return(NULL);
}
// Allocate size for bitmap. 4 extra bytes are included to give
// room to store bitmap width and height info.
pcx->bitmap=(char*)AckMalloc(pcx->imagebytes+4);
if (pcx->bitmap == NULL) // Make sure memory is allocated
{
if (!rsHandle)
close(handle);
ErrorCode = ERR_NOMEMORY;
return(NULL);
}
p=&pcx->bitmap[4]; // Get address of data area
// Loop and read in pixel data for bitmap
// Uses RLE decompression
for (i=0;i<pcx->imagebytes;i++)
{
if (mode == NORMAL) // Normal color read mode
{
read(handle,&abyte,1); // Read in pixel value from file
if ((unsigned char)abyte > 0xbf) // Value read > 191
{
nbytes=abyte & 0x3f; // Get the RLE counter
read(handle,&abyte,1);
if (--nbytes > 0) // Is counter greater than 1?
mode=RLE; // Yes, we're in RLE mode
}
}
else if (--nbytes == 0) // When counter down to 0
mode=NORMAL; // return to color read mode
*p++=abyte; // Store pixel value
}
// Get palette from PCX file, 256 color palette store 768 bytes from
// end of file. For a resource file we need to find the position where
// the next file starts and then backup 768 bytes
if (rsHandle)
lseek(handle,rbaTable[(ULONG)(filename + 1)]-768L,SEEK_CUR);
else
lseek(handle,-768L,SEEK_END);
// Store the palette data in our global colordat array
read(handle,colordat,768);
p=colordat;
for (i=0;i<768;i++) // bit shift palette
*p++ = *p >> 2;
if (!rsHandle) // Close pcx file if not using a resource
close(handle);
// Add in bitmap width and height to first 4 bytes of buffer
p = pcx->bitmap;
(*(short *)p) = pcx->width;
p += sizeof(short);
(*(short *)p) = pcx->height;
return(pcx->bitmap); // return bitmap buffer
}
// **** End of Source ****