home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / netpbma.zip / pnm / rasttopnm.c < prev    next >
C/C++ Source or Header  |  1993-10-04  |  6KB  |  261 lines

  1. /* rasttopnm.c - read a Sun rasterfile and produce a portable anymap
  2. **
  3. ** Copyright (C) 1989, 1991 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.  
  13. #include "pnm.h"
  14. #include "rast.h"
  15.  
  16. int
  17. main( argc, argv )
  18.     int argc;
  19.     char* argv[];
  20.     {
  21.     FILE* ifp;
  22.     struct rasterfile header;
  23.     colormap_t pr_colormap;
  24.     int grayscale;
  25.     struct pixrect* pr;
  26.     xel* xelrow;
  27.     register xel* xP;
  28.     int argn, rows, cols, format, depth, i, row, mask;
  29.     register int col;
  30.     xelval maxval;
  31.     xel zero, one;
  32.     int linesize;
  33.     unsigned char* data;
  34.     unsigned char* byteP;
  35.  
  36.     pnm_init( &argc, argv );
  37.  
  38.     argn = 1;
  39.  
  40.     if ( argn != argc )
  41.     {
  42.     ifp = pm_openr( argv[argn] );
  43.     ++argn;
  44.     }
  45.     else
  46.     ifp = stdin;
  47.  
  48.     if ( argn != argc )
  49.     pm_usage( "[rastfile]" );
  50.  
  51.     /* Read in the rasterfile.  First the header. */
  52.     if ( pr_load_header( ifp, &header ) != 0 )
  53.     pm_error( "unable to read in rasterfile header" );
  54.  
  55.     cols = header.ras_width;
  56.     rows = header.ras_height;
  57.     depth = header.ras_depth;
  58.  
  59.     if ( cols <= 0 )
  60.     pm_error( "invalid cols: %d", cols );
  61.     if ( rows <= 0 )
  62.     pm_error( "invalid rows: %d", rows );
  63.  
  64.     /* If there is a color map, read it. */
  65.     grayscale = 1;
  66.     if ( header.ras_maplength != 0 )
  67.     {
  68.     if ( pr_load_colormap( ifp, &header, &pr_colormap ) != 0 )
  69.         pm_error( "unable to skip colormap data" );
  70.     for ( i = 0; i < header.ras_maplength / 3; ++i )
  71.         if ( pr_colormap.map[0][i] != pr_colormap.map[1][i] ||
  72.          pr_colormap.map[1][i] != pr_colormap.map[2][i] )
  73.         {
  74.         grayscale = 0;
  75.         break;
  76.         }
  77.     }
  78.  
  79.     /* Check the depth and color map. */
  80.     switch ( depth )
  81.     {
  82.     case 1:
  83.     if ( header.ras_maptype == RMT_NONE && header.ras_maplength == 0 )
  84.         {
  85.         maxval = pnm_pbmmaxval;
  86.         format = PBM_TYPE;
  87.         PNM_ASSIGN1( zero, maxval );
  88.         PNM_ASSIGN1( one, 0 );
  89.         }
  90.     else if ( header.ras_maptype == RMT_EQUAL_RGB &&
  91.           header.ras_maplength == 6 )
  92.         {
  93.         if ( grayscale )
  94.         {
  95.         maxval = 255;
  96.         format = PGM_TYPE;
  97.         PNM_ASSIGN1( zero, pr_colormap.map[0][0] );
  98.         PNM_ASSIGN1( one, pr_colormap.map[0][1] );
  99.         }
  100.         else
  101.         {
  102.         maxval = 255;
  103.         format = PPM_TYPE;
  104.         PPM_ASSIGN(
  105.             zero, pr_colormap.map[0][0], pr_colormap.map[1][0],
  106.             pr_colormap.map[2][0] );
  107.         PPM_ASSIGN(
  108.             one, pr_colormap.map[0][1], pr_colormap.map[1][1],
  109.             pr_colormap.map[2][1] );
  110.         }
  111.         }
  112.     else
  113.         pm_error(
  114.       "this depth-1 rasterfile has a non-standard colormap - type %d length %d",
  115.         header.ras_maptype, header.ras_maplength );
  116.     break;
  117.  
  118.     case 8:
  119.     if ( grayscale )
  120.         {
  121.         maxval = 255;
  122.         format = PGM_TYPE;
  123.         }
  124.     else if ( header.ras_maptype == RMT_EQUAL_RGB )
  125.         {
  126.         maxval = 255;
  127.         format = PPM_TYPE;
  128.         }
  129.     else
  130.         pm_error(
  131.       "this depth-8 rasterfile has a non-standard colormap - type %d length %d",
  132.         header.ras_maptype, header.ras_maplength );
  133.     break;
  134.  
  135.     case 24:
  136.     case 32:
  137.     if ( header.ras_maptype == RMT_NONE && header.ras_maplength == 0 )
  138.         ;
  139.     else if ( header.ras_maptype == RMT_RAW || header.ras_maplength == 768 )
  140.         ;
  141.     else
  142.         pm_error(
  143.      "this depth-%d rasterfile has a non-standard colormap - type %d length %d",
  144.         depth, header.ras_maptype, header.ras_maplength );
  145.     maxval = 255;
  146.     format = PPM_TYPE;
  147.     break;
  148.  
  149.     default:
  150.     pm_error(
  151.         "invalid depth: %d.  Can only handle depth 1, 8, 24, or 32.",
  152.         depth );
  153.     }
  154.  
  155.     /* Now load the data.  The pixrect returned is a memory pixrect. */
  156.     if ( ( pr = pr_load_image( ifp, &header, NULL ) ) == NULL )
  157.     pm_error(
  158.         "unable to read in the image from the rasterfile" );
  159.  
  160.     linesize = ( (struct mpr_data*) pr->pr_data )->md_linebytes;
  161.     data = ( (struct mpr_data*) pr->pr_data )->md_image;
  162.  
  163.     pm_close( ifp );
  164.  
  165.     /* Now write out the anymap. */
  166.     pnm_writepnminit( stdout, cols, rows, maxval, format, 0 );
  167.     xelrow = pnm_allocrow( cols );
  168.     switch ( PNM_FORMAT_TYPE(format) )
  169.         {
  170.         case PBM_TYPE:
  171.         pm_message( "writing PBM file" );
  172.         break;
  173.  
  174.         case PGM_TYPE:
  175.         pm_message( "writing PGM file" );
  176.         break;
  177.  
  178.         case PPM_TYPE:
  179.         pm_message( "writing PPM file" );
  180.         break;
  181.  
  182.         default:
  183.         pm_error( "shouldn't happen" );
  184.         }
  185.  
  186.     for ( row = 0; row < rows; ++row )
  187.     {
  188.     byteP = data;
  189.     switch ( depth )
  190.         {
  191.         case 1:
  192.         mask = 0x80;
  193.         for ( col = 0, xP = xelrow; col < cols; ++col, ++xP )
  194.         {
  195.         if ( mask == 0 )
  196.             {
  197.             ++byteP;
  198.             mask = 0x80;
  199.             }
  200.         *xP = ( *byteP & mask ) ? one : zero;
  201.         mask = mask >> 1;
  202.         }
  203.         break;
  204.  
  205.         case 8:
  206.         for ( col = 0, xP = xelrow; col < cols; ++col, ++xP )
  207.         {
  208.         if ( header.ras_maplength == 0 )
  209.             PNM_ASSIGN1( *xP, *byteP );
  210.         else if ( grayscale )
  211.             PNM_ASSIGN1( *xP, pr_colormap.map[0][*byteP] );
  212.         else
  213.             PPM_ASSIGN(
  214.             *xP, pr_colormap.map[0][*byteP],
  215.             pr_colormap.map[1][*byteP],
  216.             pr_colormap.map[2][*byteP] );
  217.         ++byteP;
  218.         }
  219.         break;
  220.  
  221.         case 24:
  222.         case 32:
  223.         for ( col = 0, xP = xelrow; col < cols; ++col, ++xP )
  224.         {
  225.         register xelval r, g, b;
  226.  
  227.         if ( depth == 32 )
  228.             ++byteP;
  229.         if ( header.ras_type == RT_FORMAT_RGB )
  230.             {
  231.             r = *byteP++;
  232.             g = *byteP++;
  233.             b = *byteP++;
  234.             }
  235.         else
  236.             {
  237.             b = *byteP++;
  238.             g = *byteP++;
  239.             r = *byteP++;
  240.             }
  241.         if ( header.ras_maplength == 0 )
  242.             PPM_ASSIGN( *xP, r, g, b );
  243.         else
  244.             PPM_ASSIGN(
  245.             *xP, pr_colormap.map[0][r], pr_colormap.map[1][g],
  246.             pr_colormap.map[2][b] );
  247.         }
  248.         break;
  249.  
  250.         default:
  251.         pm_error( "can't happen" );
  252.         }
  253.     data += linesize;
  254.     pnm_writepnmrow( stdout, xelrow, cols, maxval, format, 0 );
  255.     }
  256.  
  257.     pm_close( stdout );
  258.  
  259.     exit( 0 );
  260.     }
  261.