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

  1. /* rasttoppm.c - read a Sun raster file and produce a portable pixmap
  2. **
  3. ** Copyright (C) 1989 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 <stdio.h>
  14. #include "ppm.h"
  15.  
  16. /* This program compiles only on Suns. */
  17. #include <pixrect/pixrect_hs.h>
  18.  
  19. main( argc, argv )
  20. int argc;
  21. char *argv[];
  22.     {
  23.     FILE *ifd;
  24.     struct rasterfile header;
  25.     colormap_t pr_colormap;
  26.     struct pixrect *pr, *pr_load_image( );
  27.     register pixel *pixelrow, *pP;
  28.     int argn, rows, cols, depth, row, col, mask, bytenum;
  29.     pixval maxval, r, g, b;
  30.     pixel zero, one;
  31.     int linesize;
  32.     short *data, *sp;
  33.     unsigned char byte;
  34.  
  35.     pm_progname = argv[0];
  36.  
  37.     argn = 1;
  38.  
  39.     if ( argn != argc )
  40.     {
  41.     ifd = pm_openr( argv[argn] );
  42.     argn++;
  43.     }
  44.     else
  45.     ifd = stdin;
  46.  
  47.     if ( argn != argc )
  48.     pm_usage( "[rastfile]" );
  49.  
  50.     /* Read in the raster file.  First the header. */
  51.     if ( pr_load_header( ifd, &header ) != 0 )
  52.     pm_error( "unable to read in raster file header", 0,0,0,0,0 );
  53.  
  54.     cols = header.ras_width;
  55.     rows = header.ras_height;
  56.     depth = header.ras_depth;
  57.  
  58.     if ( cols <= 0 )
  59.     pm_error( "invalid cols: %d", cols, 0,0,0,0 );
  60.     if ( rows <= 0 )
  61.     pm_error( "invalid rows: %d", rows, 0,0,0,0);
  62.  
  63.     /* If there is a color map, read it. */
  64.     if ( header.ras_maptype != RMT_NONE || header.ras_maplength != 0 )
  65.     {
  66.     if ( pr_load_colormap( ifd, &header, &pr_colormap ) != 0 )
  67.         pm_error( "unable to skip colormap data", 0,0,0,0,0 );
  68.     }
  69.  
  70.     /* Check the depth and color map. */
  71.     switch ( depth )
  72.     {
  73.     case 1:
  74.     if ( header.ras_maptype == RMT_NONE && header.ras_maplength == 0 )
  75.         {
  76.         maxval = 255;
  77.         PPM_ASSIGN( zero, maxval, maxval, maxval );
  78.         PPM_ASSIGN( one, 0, 0, 0 );
  79.         }
  80.     else if ( header.ras_maptype == RMT_EQUAL_RGB &&
  81.           header.ras_maplength == 6 )
  82.         {
  83.         maxval = 255;
  84.         PPM_ASSIGN(
  85.         zero, pr_colormap.map[0][0], pr_colormap.map[1][0],
  86.         pr_colormap.map[2][0] );
  87.         PPM_ASSIGN(
  88.         one, pr_colormap.map[0][1], pr_colormap.map[1][1],
  89.         pr_colormap.map[2][1] );
  90.         }
  91.     else
  92.         pm_error(
  93.         "this depth-1 rasterfile has a non-standard colormap - type %d length %d",
  94.         header.ras_maptype, header.ras_maplength, 0,0,0 );
  95.     break;
  96.  
  97.     case 8:
  98.     if ( header.ras_maptype != RMT_EQUAL_RGB )
  99.         pm_error(
  100.         "this depth-8 rasterfile has a non-standard colormap - type %d length %d",
  101.         header.ras_maptype, header.ras_maplength, 0,0,0 );
  102.     maxval = 255;
  103.     break;
  104.  
  105.     case 24:
  106.     if ( header.ras_maptype != RMT_NONE || header.ras_maplength != 0 )
  107.         pm_error(
  108.         "this depth-24 rasterfile has a colormap - can't handle it",
  109.         0,0,0,0,0 );
  110.     maxval = 255;
  111.     break;
  112.  
  113.     default:
  114.     pm_error(
  115.         "invalid depth: %d.  PPM can only handle depth 1, 8, or 24.",
  116.         depth, 0,0,0,0 );
  117.     }
  118.  
  119.     /* Now load the data.  The pixrect returned is a memory pixrect. */
  120.     if ( ( pr = pr_load_image( ifd, &header, NULL ) ) == NULL )
  121.     pm_error(
  122.         "unable to read in the image from the raster file", 0,0,0,0,0 );
  123.  
  124. #ifdef sun386
  125.     /* Force a flip to 680x0 format. */
  126.     pr_flip( pr );
  127.     ( (struct mpr_data *) pr->pr_data )->md_flags &= ! MP_I386;
  128.     pr_flip( pr );
  129. #endif
  130.  
  131.     linesize = ( (struct mpr_data *) pr->pr_data )->md_linebytes;
  132.     data = ( (struct mpr_data *) pr->pr_data )->md_image;
  133.  
  134.     pm_close( ifd );
  135.  
  136.     /* Now write out the PPM. */
  137.     ppm_writeppminit( stdout, cols, rows, maxval );
  138.     pixelrow = ppm_allocrow( cols );
  139.  
  140.     for ( row = 0; row < rows; row++ )
  141.     {
  142.     sp = data;
  143.     switch ( depth )
  144.         {
  145.         case 1:
  146.         mask = 0x8000;
  147.         for ( col = 0, pP = pixelrow; col < cols; col++, pP++ )
  148.         {
  149.         if ( mask == 0 )
  150.             {
  151.             sp++;
  152.             mask = 0x8000;
  153.             }
  154.         if ( *sp & mask )
  155.             *pP = one;
  156.         else
  157.             *pP = zero;
  158.         mask = mask >> 1;
  159.         }
  160.         break;
  161.  
  162.         case 8:
  163.         bytenum = 0;
  164.         for ( col = 0, pP = pixelrow; col < cols; col++, pP++ )
  165.         {
  166.         if ( bytenum == 2 )
  167.             {
  168.             sp++;
  169.             bytenum = 0;
  170.             }
  171.         if ( bytenum == 0 )
  172.             byte = ( *sp & 0xff00 ) >> 8;
  173.         else
  174.             byte = *sp & 0xff;
  175.         PPM_ASSIGN(
  176.             *pP, pr_colormap.map[0][byte], pr_colormap.map[1][byte],
  177.             pr_colormap.map[2][byte] );
  178.         bytenum++;
  179.         }
  180.         break;
  181.  
  182.         case 24:
  183.         bytenum = 0;
  184.         for ( col = 0, pP = pixelrow; col < cols; col++, pP++ )
  185.         {
  186.         if ( bytenum == 2 )
  187.             {
  188.             sp++;
  189.             bytenum = 0;
  190.             }
  191.         if ( bytenum == 0 )
  192.             r = ( *sp & 0xff00 ) >> 8;
  193.         else
  194.             r = *sp & 0xff;
  195.         bytenum++;
  196.         if ( bytenum == 2 )
  197.             {
  198.             sp++;
  199.             bytenum = 0;
  200.             }
  201.         if ( bytenum == 0 )
  202.             g = ( *sp & 0xff00 ) >> 8;
  203.         else
  204.             g = *sp & 0xff;
  205.         bytenum++;
  206.         if ( bytenum == 2 )
  207.             {
  208.             sp++;
  209.             bytenum = 0;
  210.             }
  211.         if ( bytenum == 0 )
  212.             b = ( *sp & 0xff00 ) >> 8;
  213.         else
  214.             b = *sp & 0xff;
  215.         bytenum++;
  216.         PPM_ASSIGN( *pP, r, g, b );
  217.         }
  218.         break;
  219.  
  220.         default:
  221.         pm_error( "can't happen", 0,0,0,0,0 );
  222.         }
  223.     data += linesize / sizeof(short);
  224.     ppm_writeppmrow( stdout, pixelrow, cols, maxval );
  225.     }
  226.  
  227.     exit( 0 );
  228.     }
  229.