home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Education Master 1994 (4th Edition)
/
EDUCATIONS_MASTER_4TH_EDITION.bin
/
files
/
progng_c
/
pcxc
/
pcxfile.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-04-17
|
4KB
|
196 lines
/* PCXFILE.c - Routines to generate PCX files
*/
#include <stdio.h>
#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<bytes; i += n )
{ 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;
}