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