home *** CD-ROM | disk | FTP | other *** search
/ Power Programming / powerprogramming1994.iso / progtool / microcrn / issue_42.arc / $$$PCX.ARC / PCXFILE.C < prev    next >
C/C++ Source or Header  |  1988-04-17  |  4KB  |  196 lines

  1. /*    PCXFILE.c -  Routines to generate PCX files
  2. */
  3.  
  4.  
  5. #include <stdio.h>
  6. #include "lib.h"
  7. #include "pcx.h"
  8.  
  9.  
  10. /*    PCX_GETC
  11.  
  12.     Read the next "token" in the picture file. If the high order
  13.     two bits are not 11, then it's a single byte. If they are,
  14.     it's a repeat count, and the next byte is the value to repeat.
  15. */
  16.  
  17. int pcx_getc( c, n, fp, maxn )
  18. FILE *fp;
  19. uint *c, *n, maxn;
  20. {
  21.     static int csave=-1, nsave=-1;
  22.     unsigned int i;
  23.  
  24.     if ( !fp )
  25.        return nsave = csave = -1;
  26.  
  27.     if ( nsave == -1 )
  28.     {  *n = 1;
  29.  
  30.        if ( (i=getc(fp)) == EOF )
  31.           return ERROR;
  32.  
  33.        if ( (i & 0xc0) == 0xc0 )
  34.        {  *n = i & 0x3f;
  35.           if ( (i=getc(fp)) == EOF )
  36.              return ERROR;
  37.        };
  38.  
  39.        *c = i;
  40.     } else
  41.     {  *n = nsave;
  42.        *c = csave;
  43.        nsave = csave = -1;
  44.     };
  45.  
  46.     if ( *n > maxn )
  47.     {  nsave = *n - maxn;
  48.        csave = *c;
  49.        *n = maxn;
  50.     };
  51.     return OK;
  52. }
  53.  
  54.  
  55. /*    PCX_PUTC
  56.  
  57.     Write a "token" to the picture file. If the repeat count is
  58.     not 1, then write the repeat count | 0xc0 as the first byte,
  59.     then the character as the next. If the character has its two
  60.     high order bits set, then first write out a repeat count of
  61.     1, then the character.
  62.  
  63.     pcx_xputc() counts the number of times that it receives a
  64.     character, then passes that information on to pcx_putc().
  65. */
  66.  
  67. int pcx_xputc( c, fp )
  68. FILE *fp;
  69. int c;
  70. {
  71.     int i;
  72.     static int csave = -1, n = -1;
  73.  
  74.     if ( c == -1 )
  75.     {  if ( csave != -1 )
  76.           if ( pcx_putc( csave, n, fp ) )
  77.              return ERROR;      
  78.        csave = n = -1;
  79.        return OK;
  80.     };
  81.  
  82.     if ( c == csave )
  83.     {  n++;
  84.        return OK;
  85.     };
  86.  
  87.     if ( csave != -1 )
  88.     {  if ( i = pcx_putc( csave, n, fp ) )
  89.           return i;
  90.        csave = n = -1;
  91.     };
  92.  
  93.     csave = c;
  94.     n = 1;
  95.     return OK;
  96. }
  97.  
  98.  
  99. int pcx_putc( c, n, fp )
  100. FILE *fp;
  101. unsigned int c, n;
  102. {
  103.     if ( (n > 1) || ( (c & 0xc0) == 0xc0 ) )
  104.     {  while ( n > 0x3f )
  105.           if ( pcx_putc( c, 0x3f, fp ) )
  106.              return ERROR;
  107.           else n -= 0x3f;
  108.  
  109.        if ( !n )
  110.           return OK;
  111.  
  112.        if ( fputc( 0xc0 | n, fp ) == EOF )
  113.           return ERROR;
  114.     };
  115.  
  116.     if ( fputc( c, fp ) == EOF )
  117.        return ERROR;
  118.  
  119.     return OK;
  120. }
  121.  
  122.  
  123. int pcx_read_pic( pic, fp )
  124. FILE *fp;
  125. PCXPIC *pic;
  126. {
  127.     /* A picture consists of a number of lines, each line having
  128.        a number of planes. Each plane is a bit map.
  129.     */
  130.     uchar *calloc(), *allocz(), *p;
  131.     int i, j, c, n, row, plane, bytes, nrows, nplan;
  132.     PCXHDR *ph;
  133.     
  134.     ph = & pic->hdr;
  135.  
  136.     fseek( fp, 0l, 0 );
  137.     if ( fread( (char *)ph, sizeof(*ph), 1, fp ) != sizeof(*ph) )
  138.        return ERROR;
  139.  
  140.     pcx_getc( (uint *)0, (uint *)0, (FILE *)0, 0 );
  141.  
  142.     bytes = ph->bpl;
  143.     nrows = ph->y2 - ph->y1 +1;
  144.     nplan = ph->nplanes;
  145.  
  146.     for ( plane = 0; plane < nplan; plane++ )
  147.        if ( ! pic->rows[plane] )
  148.           if ( ! (pic->rows[plane] = 
  149.                 (uchar **)calloc(1,sizeof(char *) * nrows)) )
  150.              return 1;
  151.  
  152.     for ( row = 0; row < nrows; row++ )
  153.        for ( plane = 0; plane < nplan; plane++ )
  154.        {  if ( !(p = pic->rows[plane][row]) )
  155.              if ( !(p = pic->rows[plane][row] = calloc(1,bytes +1)) )
  156.                 return 1;
  157.  
  158.           for ( n=i=0; i<bytes; i += n )
  159.           {  if ( pcx_getc( (uint *)&c, (uint *)&n, (FILE *)fp, bytes - i ) )
  160.                 return ERROR;
  161.              for ( j=0; j < n; j++ )
  162.                 *p++ = c;
  163.           };
  164.        };
  165.  
  166.     return OK;
  167. }
  168.  
  169.  
  170. int pcx_write_pic( pic, fp )
  171. PCXPIC *pic;
  172. FILE *fp;
  173. {
  174.     unsigned char *p;
  175.     int i, row, plane, bytes, nrows, nplan;
  176.     
  177.     fseek( fp, 0l, 0 );
  178.     if ( fwrite( (char *)&(pic->hdr), sizeof(pic->hdr), 1, fp ) != 1 )
  179.        return ERROR;
  180.  
  181.     bytes = pic->hdr.bpl;
  182.     nrows = pic->hdr.y2 - pic->hdr.y1 +1;
  183.     nplan = pic->hdr.nplanes;
  184.  
  185.     for ( row = 0; row < nrows; row++ )
  186.        for ( plane = 0; plane < nplan; plane++, pcx_xputc(-1,fp) )
  187.           for ( p = pic->rows[plane][row], i=bytes; i--; )
  188.              if ( pcx_xputc( *p++, fp ) )
  189.                 return ERROR;
  190.  
  191.     pcx_xputc( -1, fp );
  192.     return OK;
  193. }
  194.  
  195.  
  196.