www.pudn.com > pcx_c.zip > PCXFILE.C


/*	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; ihdr), 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; 
}