home *** CD-ROM | disk | FTP | other *** search
- //---------------------------------------------------------------------------
- //
- // File: PCX256.CPP
- // Path: ...\REHACK\graphics
- // Version: 2.0
- // Author: Dave Boynton
- // CIS Id: 71043,317
- // Created On: January 1992
- // Modified On: 7/25/93
- // Description: reads/writes 256 color pcx files, including files
- // embedded in "resource" files.
- // Tabs: 4
- //
- //---------------------------------------------------------------------------
- // extracted/modified from pcxlib 2.0 (c) 1992,1993 David Boynton
- // All rights reserved.
- //-----------------------------------------------------------------------//
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "..\general\types.hpp"
- #include "..\graphics\pcx.hpp"
-
- PcxFile256::PcxFile256(char *filename) : PcxFile(filename)
- {
- if ( validFlag == false )
- return;
- // else fp is valid and the header's already read in
-
- if ( (header->version != 5) ||
- (header->bitsPixel != 8) ||
- (header->planes != 1) )// planes == 3 indicates 24bit file
- validFlag=false;
-
- if ( validFlag )
- {
- lineBuffer=new byte[bytesPerLine];
- //palette=new struct PCXRGB[256];
- palette=new Palette;
- if ( readPalette() == false )
- delete palette;
- }
- }
-
- PcxFile256::PcxFile256(FILE *fp) : PcxFile(fp)
- {
- if ( (validFlag == false) ||
- (header->version != 5) ||
- (header->bitsPixel != 8) ||
- (header->planes != 1) )// planes == 3 indicates 24bit file
- validFlag=false;
-
- if ( validFlag )
- {
- lineBuffer=new byte[bytesPerLine];
- palette=new Palette;
- if ( readPalette() == false )
- delete palette;
- seekLine(0);
- }
- }
-
- // open an output file
- // example: PcxFile256 *pcx=new PcxFile256("name.pcx", 320, 200);
- // pcx.writeHeader();
- // <write lines of data>
- // pcx.writePalette();
- // delete pcx;
- PcxFile256::PcxFile256(char *filename, word xSize, word ySize)
- : PcxFile(filename, xSize, ySize)
- {
- if ( validFlag )
- {
- header->version=5;
- header->bitsPixel=8;
- header->planes=1;
- palette=new Palette;
- writeHeader();
- }
- }
-
- PcxFile256::~PcxFile256()
- {
- if ( palette )
- delete palette;
- // ~PcxFile() will take care of lineBuffer, header, and fp
- }
-
- // seek to the begining of line, (0-based)
- bool PcxFile256::seekLine(word line)
- {
- if ( !validFlag )
- return false;
- if ( line >= vPixels )
- return false;
- fseek(fp, sizeof(PCXH)+filestart, SEEK_SET);
-
- int i;
- for (i=0; i<line; i++)
- {
- if ( !skipLine() )
- return false; // read-error
- }
- return true;
- }
-
- bool PcxFile256::skipLine(void)
- {
- return readLine(NULL,1,0);
- }
-
- // x0 is first, x1 is the last ...
- bool PcxFile256::readLine(byte * destBuffer, word x0, word x1)
- {
- if ( destBuffer == NULL )
- return false;
-
- word destIndex; // next char to read into
- word fileIndex; // next logical character to read from file
- word charCount=0;
-
- static word runLength=0;
- static int data;
-
- destIndex=fileIndex=0;
- if ( x1 > bytesPerLine-1 )
- x1=bytesPerLine-1;
-
- // handle left-overs ...
- while( (runLength) &&
- (fileIndex < bytesPerLine) )
- {
- if ( (fileIndex >= x0) && (fileIndex <= x1) )
- {
- destBuffer[destIndex++]=(char)data;
- charCount++;
- }
- fileIndex++;
- runLength--;
- }
-
- // done with left-overs, now the rest of the line.
- while( fileIndex < bytesPerLine )
- {
- if ( (data=fgetc(fp)) == EOF)
- {
- return false;
- }
-
- // If the two high bits are both set it's a run.
- if ( (word)data >= 0x00c0)
- {
- runLength = data & 0x003f; // get duplication count
- if ( (data=fgetc(fp)) == EOF)
- {
- return false;
- }
- while( (runLength) &&
- (fileIndex < bytesPerLine) )
- {
- if ( (fileIndex >= x0) &&
- (fileIndex <= x1) )
- {
- destBuffer[destIndex++]=(char)data;
- charCount++;
- }
- fileIndex++;
- runLength--;
- } // end while
- } else { // non-run, single byte of data
- if ( (fileIndex >= x0) &&
- (fileIndex <= x1) )
- {
- destBuffer[destIndex++]=(char)data;
- charCount++;
- }
- fileIndex++;
- } // end if ( (word)data >= 0x00c0) {} else
-
- } // end while( fileIndex < bytesPerLine )
-
- return true;
- }
-
- // x0 is first column, x1 is last column
- // fixes needed: fputc's should be checked for errors
- bool PcxFile256::writeLine(byte * srcBuffer, word x0, word x1, byte fill)
- {
- word srcIndex=0, fileIndex=0; // next bytes to read/write
- word runLength;
- int last; // allow -1 for begining flag
- byte data;
- if ( x1 > hPixels-1)
- x1=hPixels-1;
-
- /* pre- fill */
- while (fileIndex < x0 )
- {
- runLength=(x0-fileIndex);
- if ( runLength > 63 )
- runLength=63;
-
- if ( (runLength != 1) || (fill > 191) )
- {
- fputc( ( runLength | 0xc0 ),fp);
- }
- fputc(fill,fp);
- fileIndex+=runLength;
- } // end fill to first column
-
- /* passed data */
- last=-1;
-
- for (runLength=srcIndex=fileIndex=0; srcIndex <= x1; srcIndex++)
- {
- if ( (data=*(srcBuffer+srcIndex)) == last)
- {
- if ( runLength < 63 )
- {
- runLength++;
- continue;
- }
- }
- // handle previous run if necessary
- if ( last != -1 )
- {
- if ( (runLength != 1) || (last > 0xbf) )
- {
- fputc( (runLength | 0xc0),fp);
- }
- fputc(last,fp);
- fileIndex+=runLength;
- } // end if ( last != -1 )
- last=data;
- runLength=1;
- } // end for(...; srcIndex <= x1; srcIndex++)
-
- // left-overs (ie., for() done, but we still have some runLength...)
- if (runLength)
- {
- if ( (runLength != 1) || (last > 0xbfU) )
- {
- fputc( (runLength | 0xc0U),fp);
- }
- fputc(last,fp);
- fileIndex+=runLength;
- runLength=0;
- } // end if (left-overs)
-
- // fill to the end of line
- while (fileIndex < hPixels )
- {
- runLength=(hPixels - fileIndex + 1);
- if ( runLength > 63 )
- runLength=63;
-
- if ( (runLength != 1) || (fill > 191) )
- {
- fputc( ( runLength | 0xc0 ),fp);
- }
- fputc(fill,fp);
- fileIndex+=runLength;
- } // end fill to end-of-line
-
- return true;
- }
-
- bool PcxFile256::readPalette(void)
- {
- char Id256Pal;
- if ( ( filestart != 0L ) || // don't bother with a resource file
- ( fseek(fp, -769, SEEK_END) == -1) ||
- ( fread(&Id256Pal,1,1,fp) != 1) ||
- ( Id256Pal != 0x0cU ) ||
- ( fread(palette, 768, 1, fp) != 1) )
- {
- return false;
- } else {
- return true;
- }
- }
-
- // assumes we're already in position.
- bool PcxFile256::writePalette(void)
- {
- if ( (fputc(0x0cU, fp) == EOF) ||
- (fwrite(palette, 768, 1, fp) != 1 ) )
- return false;
- else
- return true;
- }
-
- void PcxFile256::shiftPaletteDown(void)
- {
- int i;
- for (i=0; i<256; i++)
- {
- palette[i].r >>= 2;
- palette[i].g >>= 2;
- palette[i].b >>= 2;
- }
- }
-
- void PcxFile256::shiftPaletteUp(void)
- {
- int i;
- for (i=0; i<256; i++)
- {
- palette[i].r <<= 2;
- palette[i].g <<= 2;
- palette[i].b <<= 2;
- }
- }
-
-
-
-
-