home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / NETWORK / netpbm_src.lzh / NETPBM / PNM / pnmtorast.c < prev    next >
C/C++ Source or Header  |  1996-11-18  |  8KB  |  313 lines

  1. /* pnmtorast.c - read a portable anymap and produce a Sun rasterfile
  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. #include "ppmcmap.h"
  17. #define MAXCOLORS 256
  18. static colormap_t* make_pr_colormap ARGS(( colorhist_vector chv, int colors ));
  19. static colormap_t* make_gray_pr_colormap ARGS(( void ));
  20. static colormap_t* alloc_pr_colormap ARGS(( void ));
  21.  
  22. int
  23. main( argc, argv )
  24.     int argc;
  25.     char* argv[];
  26.     {
  27.     FILE* ifp;
  28.     xel** xels;
  29.     xel* xelrow;
  30.     xel p;
  31.     register xel* xP;
  32.     colorhist_vector chv;
  33.     colorhash_table cht;
  34.     colormap_t* pr_colormapP;
  35.     int argn, pr_type, rows, cols, format, i;
  36.     int depth, colors, linesize, row;
  37.     register int col, bitcount;
  38.     xelval maxval;
  39.     struct pixrect* pr;
  40.     unsigned char* data;
  41.     register unsigned char* byteP;
  42.     char* usage = "[-standard|-rle] [pnmfile]";
  43.  
  44.     pnm_init( &argc, argv );
  45.  
  46.     argn = 1;
  47.     pr_type = RT_BYTE_ENCODED;
  48.  
  49.     while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
  50.     {
  51.     if ( pm_keymatch( argv[argn], "-standard", 2 ) )
  52.         pr_type = RT_STANDARD;
  53.     else if ( pm_keymatch( argv[argn], "-rle", 2 ) )
  54.         pr_type = RT_BYTE_ENCODED;
  55.     else
  56.         pm_usage( usage );
  57.     ++argn;
  58.     }
  59.  
  60.     if ( argn != argc )
  61.     {
  62.     ifp = pm_openr( argv[argn] );
  63.     ++argn;
  64.     }
  65.     else
  66.     ifp = stdin;
  67.  
  68.     if ( argn != argc )
  69.     pm_usage( usage );
  70.  
  71.     xels = pnm_readpnm( ifp, &cols, &rows, &maxval, &format );
  72.  
  73.     pm_close( ifp );
  74.  
  75.     /* Figure out the proper depth and colormap. */
  76.     switch ( PNM_FORMAT_TYPE(format) )
  77.     {
  78.     case PPM_TYPE:
  79.     pm_message( "computing colormap..." );
  80.     chv = ppm_computecolorhist( xels, cols, rows, MAXCOLORS, &colors );
  81.     if ( chv == (colorhist_vector) 0 )
  82.         {
  83.         pm_message(
  84.         "Too many colors - proceeding to write a 24-bit non-mapped" );
  85.         pm_message(
  86.         "rasterfile.  If you want 8 bits, try doing a 'ppmquant %d'.",
  87.         MAXCOLORS );
  88.         depth = 24;
  89.         pr_type = RT_STANDARD;
  90.         pr_colormapP = (colormap_t*) 0;
  91.         }
  92.     else
  93.         {
  94.         pm_message( "%d colors found", colors );
  95.  
  96.         if ( maxval != 255 )
  97.         for ( i = 0; i < colors; ++i )
  98.             PPM_DEPTH( chv[i].color, chv[i].color, maxval, 255 );
  99.  
  100.         /* Force white to slot 0 and black to slot 1, if possible. */
  101.         PPM_ASSIGN( p, 255, 255, 255 );
  102.         ppm_addtocolorhist( chv, &colors, MAXCOLORS, &p, 0, 0 );
  103.         PPM_ASSIGN( p, 0, 0, 0 );
  104.         ppm_addtocolorhist( chv, &colors, MAXCOLORS, &p, 0, 1 );
  105.  
  106.         if ( colors == 2 )
  107.         {
  108.         /* Monochrome. */
  109.         depth = 1;
  110.         pr_colormapP = (colormap_t*) 0;
  111.         }
  112.         else
  113.         {
  114.         /* Turn the ppm colormap into the appropriate Sun colormap. */
  115.         depth = 8;
  116.         pr_colormapP = make_pr_colormap( chv, colors );
  117.         }
  118.         cht = ppm_colorhisttocolorhash( chv, colors );
  119.         ppm_freecolorhist( chv );
  120.         }
  121.  
  122.     break;
  123.  
  124.     case PGM_TYPE:
  125.     depth = 8;
  126.     pr_colormapP = make_gray_pr_colormap( );
  127.     break;
  128.  
  129.     default:
  130.     depth = 1;
  131.     pr_colormapP = (colormap_t*) 0;
  132.     break;
  133.     }
  134.  
  135.     if ( maxval > 255 && depth != 1 )
  136.     pm_message(
  137.         "maxval is not 255 - automatically rescaling colors" );
  138.     
  139.     /* Allocate space for the Sun-format image. */
  140.     if ( (pr = mem_create(cols, rows, depth)) == (struct pixrect*) 0 )
  141.     pm_error( "unable to create new pixrect" );
  142.     data = ( (struct mpr_data*) pr->pr_data )->md_image;
  143.     linesize = ( (struct mpr_data*) pr->pr_data )->md_linebytes;
  144.  
  145.     /* And compute the Sun image.  The variables at this point are:
  146.     **   cht is null or not
  147.     **   depth is 1, 8, or 24
  148.     */
  149.     for ( row = 0; row < rows; ++row )
  150.     {
  151.     xelrow = xels[row];
  152.     byteP = data;
  153.     switch ( depth )
  154.         {
  155.         case 1:
  156.         *byteP = 0;
  157.         bitcount = 7;
  158.         for ( col = 0, xP = xelrow; col < cols; ++col, ++xP )
  159.         {
  160.         register int color;
  161.  
  162.                 switch ( PNM_FORMAT_TYPE(format) )
  163.                     {
  164.                     case PPM_TYPE:
  165.             if ( maxval != 255 )
  166.             PPM_DEPTH( *xP, *xP, maxval, 255 );
  167.             color = ppm_lookupcolor( cht, xP );
  168.             if ( color == -1 )
  169.             pm_error(
  170.                 "color not found?!?  row=%d col=%d  r=%d g=%d b=%d",
  171.                 row, col, PPM_GETR(*xP), PPM_GETG(*xP),
  172.                 PPM_GETB(*xP) );
  173.             if ( color )
  174.             *byteP |= 1 << bitcount;
  175.                     break;
  176.  
  177.             default:
  178.             color = PNM_GET1( *xP );
  179.             if ( ! color )
  180.             *byteP |= 1 << bitcount;
  181.                     break;
  182.                     }
  183.         --bitcount;
  184.         if ( bitcount < 0 )
  185.             {
  186.             ++byteP;
  187.             *byteP = 0;
  188.             bitcount = 7;
  189.             }
  190.         }
  191.         break;
  192.  
  193.         case 8:
  194.         for ( col = 0, xP = xelrow; col < cols; ++col, ++xP )
  195.         {
  196.         register int color;
  197.  
  198.                 switch ( PNM_FORMAT_TYPE(format) )
  199.                     {
  200.                     case PPM_TYPE:
  201.             if ( maxval != 255 )
  202.             PPM_DEPTH( *xP, *xP, maxval, 255 );
  203.             color = ppm_lookupcolor( cht, xP );
  204.             if ( color == -1 )
  205.             pm_error(
  206.                 "color not found?!?  row=%d col=%d  r=%d g=%d b=%d",
  207.                 row, col, PPM_GETR(*xP), PPM_GETG(*xP),
  208.                 PPM_GETB(*xP) );
  209.                     break;
  210.  
  211.                     case PGM_TYPE:
  212.             color = PNM_GET1( *xP );
  213.             if ( maxval != 255 )
  214.             color = color * 255 / maxval;
  215.                     break;
  216.  
  217.             default:
  218.             color = PNM_GET1( *xP );
  219.                     }
  220.         *byteP++ = color;
  221.         }
  222.         break;
  223.  
  224.         case 24:
  225.         /* If depth is 24, we do NOT have a valid cht. */
  226.         for ( col = 0, xP = xelrow; col < cols; ++col, ++xP )
  227.         {
  228.         if ( maxval != 255 )
  229.             PPM_DEPTH( *xP, *xP, maxval, 255 );
  230.         *byteP++ = PPM_GETB( *xP );
  231.         *byteP++ = PPM_GETG( *xP );
  232.         *byteP++ = PPM_GETR( *xP );
  233.         }
  234.         break;
  235.  
  236.         default:
  237.         pm_error( "can't happen" );
  238.         }
  239.     data += linesize;
  240.     }
  241.     pnm_freearray( xels, rows );
  242.  
  243.     /* Finally, write the sucker out. */
  244.     if ( pr_dump( pr, stdout, pr_colormapP, pr_type, 0 ) == PIX_ERR )
  245.     pm_error( "error writing rasterfile" );
  246.  
  247.     exit( 0 );
  248.     }
  249.  
  250. static colormap_t*
  251. make_pr_colormap( chv, colors )
  252.     colorhist_vector chv;
  253.     int colors;
  254.     {
  255.     colormap_t* pr_colormapP;
  256.     int i;
  257.  
  258.     pr_colormapP = alloc_pr_colormap( );
  259.  
  260.     for ( i = 0; i < colors; ++i )
  261.     {
  262.     pr_colormapP->map[0][i] = PPM_GETR( chv[i].color );
  263.     pr_colormapP->map[1][i] = PPM_GETG( chv[i].color );
  264.     pr_colormapP->map[2][i] = PPM_GETB( chv[i].color );
  265.     }
  266.     for ( ; i < MAXCOLORS; ++i )
  267.     pr_colormapP->map[0][i] = pr_colormapP->map[1][i] =
  268.         pr_colormapP->map[2][i] = 0;
  269.  
  270.     return pr_colormapP;
  271.     }
  272.  
  273. static colormap_t*
  274. make_gray_pr_colormap( )
  275.     {
  276.     colormap_t* pr_colormapP;
  277.     int i;
  278.  
  279.     pr_colormapP = alloc_pr_colormap( );
  280.  
  281.     for ( i = 0; i < MAXCOLORS; ++i )
  282.     {
  283.     pr_colormapP->map[0][i] = i;
  284.     pr_colormapP->map[1][i] = i;
  285.     pr_colormapP->map[2][i] = i;
  286.     }
  287.  
  288.     return pr_colormapP;
  289.     }
  290.  
  291. static colormap_t*
  292. alloc_pr_colormap( )
  293.     {
  294.     colormap_t* pr_colormapP;
  295.  
  296.     pr_colormapP = (colormap_t*) malloc( sizeof(colormap_t) );
  297.     if ( pr_colormapP == (colormap_t*) 0 )
  298.     pm_error( "out of memory" );
  299.     pr_colormapP->type = RMT_EQUAL_RGB;
  300.     pr_colormapP->length = MAXCOLORS;
  301.     pr_colormapP->map[0] =
  302.     (unsigned char*) malloc( MAXCOLORS * sizeof(unsigned char) );
  303.     pr_colormapP->map[1] =
  304.     (unsigned char*) malloc( MAXCOLORS * sizeof(unsigned char) );
  305.     pr_colormapP->map[2] =
  306.     (unsigned char*) malloc( MAXCOLORS * sizeof(unsigned char) );
  307.     if ( pr_colormapP->map[0] == 0 || pr_colormapP->map[1] == 0 ||
  308.      pr_colormapP->map[2] == 0 )
  309.     pm_error( "out of memory" );
  310.  
  311.     return pr_colormapP;
  312.     }
  313.