Category : Printer + Display Graphics
Archive   : $$$PCX.ZIP
Filename : PCXFILE.C

 
Output of file : PCXFILE.C contained in archive : $$$PCX.ZIP

/* PCXFILE.c - Routines to generate PCX files
*/


#include
#include "lib.h"
#include "pcx.h"


/* PCX_GETC

Read the next "token" in the picture file. If the high order
two bits are not 11, then it's a single byte. If they are,
it's a repeat count, and the next byte is the value to repeat.
*/

int pcx_getc( c, n, fp, maxn )
FILE *fp;
uint *c, *n, maxn;
{
static int csave=-1, nsave=-1;
unsigned int i;

if ( !fp )
return nsave = csave = -1;

if ( nsave == -1 )
{ *n = 1;

if ( (i=getc(fp)) == EOF )
return ERROR;

if ( (i & 0xc0) == 0xc0 )
{ *n = i & 0x3f;
if ( (i=getc(fp)) == EOF )
return ERROR;
};

*c = i;
} else
{ *n = nsave;
*c = csave;
nsave = csave = -1;
};

if ( *n > maxn )
{ nsave = *n - maxn;
csave = *c;
*n = maxn;
};
return OK;
}


/* PCX_PUTC

Write a "token" to the picture file. If the repeat count is
not 1, then write the repeat count | 0xc0 as the first byte,
then the character as the next. If the character has its two
high order bits set, then first write out a repeat count of
1, then the character.

pcx_xputc() counts the number of times that it receives a
character, then passes that information on to pcx_putc().
*/

int pcx_xputc( c, fp )
FILE *fp;
int c;
{
int i;
static int csave = -1, n = -1;

if ( c == -1 )
{ if ( csave != -1 )
if ( pcx_putc( csave, n, fp ) )
return ERROR;
csave = n = -1;
return OK;
};

if ( c == csave )
{ n++;
return OK;
};

if ( csave != -1 )
{ if ( i = pcx_putc( csave, n, fp ) )
return i;
csave = n = -1;
};

csave = c;
n = 1;
return OK;
}


int pcx_putc( c, n, fp )
FILE *fp;
unsigned int c, n;
{
if ( (n > 1) || ( (c & 0xc0) == 0xc0 ) )
{ while ( n > 0x3f )
if ( pcx_putc( c, 0x3f, fp ) )
return ERROR;
else n -= 0x3f;

if ( !n )
return OK;

if ( fputc( 0xc0 | n, fp ) == EOF )
return ERROR;
};

if ( fputc( c, fp ) == EOF )
return ERROR;

return OK;
}


int pcx_read_pic( pic, fp )
FILE *fp;
PCXPIC *pic;
{
/* A picture consists of a number of lines, each line having
a number of planes. Each plane is a bit map.
*/
uchar *calloc(), *allocz(), *p;
int i, j, c, n, row, plane, bytes, nrows, nplan;
PCXHDR *ph;

ph = & pic->hdr;

fseek( fp, 0l, 0 );
if ( fread( (char *)ph, sizeof(*ph), 1, fp ) != sizeof(*ph) )
return ERROR;

pcx_getc( (uint *)0, (uint *)0, (FILE *)0, 0 );

bytes = ph->bpl;
nrows = ph->y2 - ph->y1 +1;
nplan = ph->nplanes;

for ( plane = 0; plane < nplan; plane++ )
if ( ! pic->rows[plane] )
if ( ! (pic->rows[plane] =
(uchar **)calloc(1,sizeof(char *) * nrows)) )
return 1;

for ( row = 0; row < nrows; row++ )
for ( plane = 0; plane < nplan; plane++ )
{ if ( !(p = pic->rows[plane][row]) )
if ( !(p = pic->rows[plane][row] = calloc(1,bytes +1)) )
return 1;

for ( n=i=0; i { if ( pcx_getc( (uint *)&c, (uint *)&n, (FILE *)fp, bytes - i ) )
return ERROR;
for ( j=0; j < n; j++ )
*p++ = c;
};
};

return OK;
}


int pcx_write_pic( pic, fp )
PCXPIC *pic;
FILE *fp;
{
unsigned char *p;
int i, row, plane, bytes, nrows, nplan;

fseek( fp, 0l, 0 );
if ( fwrite( (char *)&(pic->hdr), sizeof(pic->hdr), 1, fp ) != 1 )
return ERROR;

bytes = pic->hdr.bpl;
nrows = pic->hdr.y2 - pic->hdr.y1 +1;
nplan = pic->hdr.nplanes;

for ( row = 0; row < nrows; row++ )
for ( plane = 0; plane < nplan; plane++, pcx_xputc(-1,fp) )
for ( p = pic->rows[plane][row], i=bytes; i--; )
if ( pcx_xputc( *p++, fp ) )
return ERROR;

pcx_xputc( -1, fp );
return OK;
}