home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 309.lha / PBM_PLUS / pbm / pcxtopbm.c < prev    next >
C/C++ Source or Header  |  1980-12-04  |  4KB  |  157 lines

  1. /* pcxtopbm.c - convert PC paintbrush (.pcx) files to portable bitmaps
  2. **
  3. ** Copyright (C) 1988 by Jef Poskanzer.
  4. **
  5. ** Permission to use, copy, modify, and distribute this software and its
  6. ** documentation for any purpose and without fee is hereby granted, provided
  7. ** that the above copyright notice appear in all copies and that both that
  8. ** copyright notice and this permission notice appear in supporting
  9. ** documentation.  This software is provided "as is" without express or
  10. ** implied warranty.
  11. **
  12. ** This program is based on the pcx2rf program by:
  13. **   Mike Macgirvin
  14. **   Stanford Relativity Gyro Program GP-B
  15. **   Stanford, Calif. 94503
  16. **   ARPA: mike@relgyro.stanford.edu
  17. */
  18.  
  19. #include <stdio.h>
  20. #include "pbm.h"
  21.  
  22. void read_pcx(), spread_byte();
  23.  
  24. main( argc, argv)
  25. int argc;
  26. char *argv[];
  27.     {
  28.     FILE *ifd;
  29.     unsigned char pcxhd[128];
  30.     int cnt, b;
  31.     int xmin;
  32.     int xmax;
  33.     int ymin;
  34.     int ymax;
  35.     int bytes_per_row;
  36.     register bit **bits;
  37.  
  38.     pm_progname = argv[0];
  39.  
  40.     if ( argc > 2 )
  41.     pm_usage( "[pcxfile]" );
  42.  
  43.     /* Open input file. */
  44.     if ( argc == 2 )
  45.     ifd = pm_openr( argv[1] );
  46.     else
  47.     ifd = stdin;
  48.  
  49.     /* Read .pcx header. */
  50.     for ( cnt = 0; cnt < 128; cnt++ )
  51.     {
  52.     b = getc( ifd );
  53.     if ( b == EOF )
  54.         pm_error( "incomplete .pcx header", 0,0,0,0,0 );
  55.     pcxhd[cnt] = b;
  56.     }
  57.  
  58.     /* Calculate raster header and swap bytes. */
  59.     xmin = pcxhd[4] + ( 256 * pcxhd[5] );
  60.     ymin = pcxhd[6] + ( 256 * pcxhd[7] );
  61.     xmax = pcxhd[8] + ( 256 * pcxhd[9] );
  62.     ymax = pcxhd[10] + ( 256 * pcxhd[11] );
  63.     xmax = xmax - xmin + 1;
  64.     ymax = ymax - ymin + 1;
  65.     bytes_per_row = pcxhd[66] + ( 256 * pcxhd[67] );
  66.  
  67.     /* Allocate pbm array. */
  68.     bits = pbm_allocarray( xmax + 8, ymax );
  69.     /* + 8 allows for slop turning bytes to bits; it's easier than checking. */
  70.  
  71.     /* Read compressed bitmap. */
  72.     read_pcx( ifd, bytes_per_row, bits, ymax );
  73.     pm_close( ifd );
  74.  
  75.     /* Write pbm. */
  76.     pbm_writepbm( stdout, bits, xmax, ymax );
  77.  
  78.     /* All done. */
  79.     exit( 0 );
  80.     }
  81.  
  82.  
  83. void
  84. read_pcx( ifd, bytes_per_row, bits, rows )
  85. FILE *ifd;
  86. int bytes_per_row;
  87. bit **bits;
  88. int rows;
  89.     {
  90.     /* Goes like this:  Read a byte.  If the two high bits are set, then the
  91.     ** low 6 bits contain a repeat count, and the byte to repeat is the next
  92.     ** byte in the file.  If the two high bits are not set, then this is the
  93.     ** byte to write.  
  94.     */
  95.     int row = 0;
  96.     int col = 0;
  97.     int bytes_this_row = 0;
  98.     int b, i, cnt;
  99.  
  100.     while ( (b = fgetc( ifd )) != EOF )
  101.     {
  102.     if ( b & 0xC0 == 0xC0 )
  103.         {
  104.         cnt = b & 0x3F;
  105.         b = fgetc( ifd );
  106.         if ( b == EOF )
  107.         pm_error( "unexpected end of file on input", 0,0,0,0,0 );
  108.         for ( i = 0; i < cnt; i++ )
  109.         {
  110.         if ( row >= rows )
  111.             {
  112.             fprintf( stderr, "junk in file after bitmap - ignoring\n" );
  113.             return;
  114.             }
  115.         spread_byte( 255 - b, &(bits[row][col]) );
  116.         col += 8;
  117.         bytes_this_row++;
  118.         if ( bytes_this_row == bytes_per_row )
  119.             {
  120.             row++;
  121.             col = 0;
  122.             bytes_this_row = 0;
  123.             }
  124.         }
  125.         }
  126.     else
  127.         {
  128.         if ( row >= rows )
  129.         {
  130.         fprintf( stderr, "junk in file after bitmap - ignoring\n" );
  131.         return;
  132.         }
  133.         spread_byte( 255 - b, &(bits[row][col]) );
  134.         col += 8;
  135.         bytes_this_row++;
  136.         if ( bytes_this_row == bytes_per_row )
  137.         {
  138.         row++;
  139.         col = 0;
  140.         bytes_this_row = 0;
  141.         }
  142.         }
  143.     }
  144.     }
  145.  
  146.  
  147. void
  148. spread_byte( b, bits )
  149. int b;
  150. bit *bits;
  151.     {
  152.     int i, j;
  153.  
  154.     for ( i = 0, j = 7; i < 8; i++, j-- )
  155.     bits[j] = ( b & ( 1 << i ) ) ? PBM_BLACK : PBM_WHITE;
  156.     }
  157.