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

  1. /* pnmtoxwd.c - read a portable anymap and produce a color X11 window dump
  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 "x11wd.h"
  15.  
  16. #include "ppmcmap.h"
  17.  
  18. int
  19. main( argc, argv )
  20.     int argc;
  21.     char* argv[];
  22.     {
  23.     FILE* ifp;
  24.     xel** xels;
  25.     register xel* xP;
  26.     char* dumpname;
  27.     int argn, rows, cols, format, colors, i, row, col;
  28.     int pseudodepth;
  29.     int forcedirect, direct, grayscale;
  30.     xelval maxval;
  31.     long lmaxval, xmaxval;
  32.     colorhist_vector chv;
  33.     colorhash_table cht;
  34.     X11WDFileHeader h11;
  35.     X11XColor color;
  36.     char* usage = "[-pseudodepth n] [-directcolor] [pnmfile]";
  37.  
  38.     pnm_init( &argc, argv );
  39.  
  40.     argn = 1;
  41.     pseudodepth = 8;
  42.     forcedirect = 0;
  43.  
  44.     while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
  45.     {
  46.     if ( pm_keymatch( argv[argn], "-pseudodepth", 2 ) )
  47.         {
  48.         ++argn;
  49.         if ( argn == argc || sscanf( argv[argn], "%d", &pseudodepth ) != 1 )
  50.         pm_usage( usage );
  51.         if ( pseudodepth < 1 || pseudodepth > 16 )
  52.         pm_usage( usage );
  53.         }
  54.     else if ( pm_keymatch( argv[argn], "-directcolor", 2 ) )
  55.         forcedirect = 1;
  56.     else
  57.         pm_usage( usage );
  58.     ++argn;
  59.     }
  60.  
  61.     if ( argn != argc )
  62.     {
  63.     dumpname = argv[1];
  64.     ifp = pm_openr( argv[1] );
  65.     ++argn;
  66.     }
  67.     else
  68.     {
  69.     dumpname = "stdin";
  70.     ifp = stdin;
  71.     }
  72.     
  73.     if ( argn != argc )
  74.     pm_usage( usage );
  75.  
  76.     xels = pnm_readpnm( ifp, &cols, &rows, &maxval, &format );
  77.     lmaxval = (long) maxval;
  78.     xmaxval = ( 1 << pseudodepth ) - 1;
  79.     pm_close( ifp );
  80.     
  81.     if ( forcedirect )
  82.     direct = 1;
  83.     else
  84.     {
  85.     /* Figure out the colormap. */
  86.     switch ( PNM_FORMAT_TYPE(format) )
  87.         {
  88.         case PPM_TYPE:
  89.         direct = 0;
  90.         pm_message( "computing colormap..." );
  91.         chv = ppm_computecolorhist( xels, cols, rows, xmaxval+1, &colors );
  92.         if ( chv == (colorhist_vector) 0 )
  93.         {
  94.         pm_message(
  95.          "Too many colors - proceeding to write a 24-bit DirectColor" );
  96.         pm_message(
  97.           "dump file.  If you want PseudoColor, try doing a 'ppmquant %d'.",
  98.             xmaxval );
  99.         direct = 1;
  100.         }
  101.         else
  102.         {
  103.         pm_message( "%d colors found", colors );
  104.         grayscale = 0;
  105.         direct = 0;
  106.         /* Make a hash table for fast color lookup. */
  107.         cht = ppm_colorhisttocolorhash( chv, colors );
  108.         }
  109.         break;
  110.  
  111.         default:
  112.         direct = 0;
  113.         grayscale = 1;
  114.         break;
  115.         }
  116.  
  117.     }
  118.  
  119.     /* Set up the header. */
  120.     h11.header_size = sizeof(h11) + strlen( dumpname ) + 1;
  121.     h11.file_version = X11WD_FILE_VERSION;
  122.     h11.pixmap_format = ZPixmap;
  123.     h11.pixmap_width = cols;
  124.     h11.pixmap_height = rows;
  125.     h11.xoffset = 0;
  126.     h11.byte_order = MSBFirst;
  127.     h11.bitmap_bit_order = MSBFirst;
  128.     h11.window_width = cols;
  129.     h11.window_height = rows;
  130.     h11.window_x = 0;
  131.     h11.window_y = 0;
  132.     h11.window_bdrwidth = 0;
  133.  
  134.     if ( direct )
  135.     {
  136.     h11.pixmap_depth = 24;
  137.     h11.bitmap_unit = 32;
  138.     h11.bitmap_pad = 32;
  139.     h11.bits_per_pixel = 32;
  140.     h11.visual_class = DirectColor;
  141.     h11.colormap_entries = 256;
  142.     h11.ncolors = 0;
  143.     h11.red_mask = 0xff0000;
  144.     h11.green_mask = 0xff00;
  145.     h11.blue_mask = 0xff;
  146.     h11.bytes_per_line = cols * 4;
  147.     }
  148.     else if ( grayscale )
  149.     {
  150.     if ( PNM_FORMAT_TYPE(format) == PBM_TYPE )
  151.         {
  152.         h11.pixmap_depth = 1;
  153.         h11.bits_per_pixel = 1;
  154.         colors = 2;
  155.         h11.colormap_entries = colors;
  156.         h11.ncolors = colors;
  157.         h11.bytes_per_line = ( cols + 7 ) / 8;
  158.         }
  159.     else
  160.         {
  161.         h11.pixmap_depth = pseudodepth;
  162.         h11.bits_per_pixel = pseudodepth;
  163.         colors = xmaxval + 1;
  164.         h11.colormap_entries = colors;
  165.         h11.ncolors = colors;
  166.         h11.bytes_per_line = cols;
  167.         }
  168.     h11.bitmap_unit = 8;
  169.     h11.bitmap_pad = 8;
  170.     h11.visual_class = StaticGray;
  171.     h11.red_mask = 0;
  172.     h11.green_mask = 0;
  173.     h11.blue_mask = 0;
  174.     }
  175.     else
  176.     {
  177.     h11.pixmap_depth = pseudodepth;
  178.     h11.bits_per_pixel = pseudodepth;
  179.     h11.visual_class = PseudoColor;
  180.     h11.colormap_entries = xmaxval + 1;
  181.     h11.ncolors = colors;
  182.     h11.red_mask = 0;
  183.     h11.green_mask = 0;
  184.     h11.blue_mask = 0;
  185.     h11.bytes_per_line = cols;
  186.     h11.bitmap_unit = 8;
  187.     h11.bitmap_pad = 8;
  188.     }
  189.     h11.bits_per_rgb = h11.pixmap_depth;
  190.  
  191.     /* Write out the header in big-endian order. */
  192.     pm_writebiglong( stdout, h11.header_size );
  193.     pm_writebiglong( stdout, h11.file_version );
  194.     pm_writebiglong( stdout, h11.pixmap_format );
  195.     pm_writebiglong( stdout, h11.pixmap_depth );
  196.     pm_writebiglong( stdout, h11.pixmap_width );
  197.     pm_writebiglong( stdout, h11.pixmap_height );
  198.     pm_writebiglong( stdout, h11.xoffset );
  199.     pm_writebiglong( stdout, h11.byte_order );
  200.     pm_writebiglong( stdout, h11.bitmap_unit );
  201.     pm_writebiglong( stdout, h11.bitmap_bit_order );
  202.     pm_writebiglong( stdout, h11.bitmap_pad );
  203.     pm_writebiglong( stdout, h11.bits_per_pixel );
  204.     pm_writebiglong( stdout, h11.bytes_per_line );
  205.     pm_writebiglong( stdout, h11.visual_class );
  206.     pm_writebiglong( stdout, h11.red_mask );
  207.     pm_writebiglong( stdout, h11.green_mask );
  208.     pm_writebiglong( stdout, h11.blue_mask );
  209.     pm_writebiglong( stdout, h11.bits_per_rgb );
  210.     pm_writebiglong( stdout, h11.colormap_entries );
  211.     pm_writebiglong( stdout, h11.ncolors );
  212.     pm_writebiglong( stdout, h11.window_width );
  213.     pm_writebiglong( stdout, h11.window_height );
  214.     pm_writebiglong( stdout, h11.window_x );
  215.     pm_writebiglong( stdout, h11.window_y );
  216.     pm_writebiglong( stdout, h11.window_bdrwidth );
  217.  
  218.     /* Write out the dump name. */
  219.     fwrite( dumpname, 1, strlen( dumpname ) + 1, stdout );
  220.  
  221.     if ( ! direct )
  222.     {
  223.     /* Write out the colormap, big-endian order. */
  224.     color.flags = 7;
  225.     color.pad = 0;
  226.     for ( i = 0; i < colors; ++i )
  227.         {
  228.         color.num = i;
  229.         if ( grayscale )
  230.         {
  231.  
  232.         /* Stupid hack because xloadimage and xwud disagree on
  233.         ** how to interpret bitmaps. */
  234.         if ( PNM_FORMAT_TYPE(format) == PBM_TYPE )
  235.             color.red = (long) ( colors-1-i ) * 65535L / ( colors - 1 );
  236.         else
  237.             color.red = (long) i * 65535L / ( colors - 1 );
  238.  
  239.         color.green = color.red;
  240.         color.blue = color.red;
  241.         }
  242.         else
  243.         {
  244.         color.red = PPM_GETR( chv[i].color );
  245.         color.green = PPM_GETG( chv[i].color );
  246.         color.blue = PPM_GETB( chv[i].color );
  247.         if ( lmaxval != 65535L )
  248.             {
  249.             color.red = (long) color.red * 65535L / lmaxval;
  250.             color.green = (long) color.green * 65535L / lmaxval;
  251.             color.blue = (long) color.blue * 65535L / lmaxval;
  252.             }
  253.         }
  254.         pm_writebiglong( stdout, color.num );
  255.         pm_writebigshort( stdout, color.red );
  256.         pm_writebigshort( stdout, color.green );
  257.         pm_writebigshort( stdout, color.blue );
  258.         (void) putc( color.flags, stdout );
  259.         (void) putc( color.pad, stdout );
  260.         }
  261.     }
  262.  
  263.     /* Finally, write out the data. */
  264.     for ( row = 0; row < rows; ++row )
  265.     if ( direct )
  266.         {
  267.         switch ( PNM_FORMAT_TYPE(format) )
  268.         {
  269.         case PPM_TYPE:
  270.         for ( col = 0, xP = xels[row]; col < cols; ++col, ++xP )
  271.             {
  272.             unsigned long ul;
  273.  
  274.             ul = ( ( PPM_GETR( *xP ) * xmaxval / lmaxval ) << 16 ) |
  275.              ( ( PPM_GETG( *xP ) * xmaxval / lmaxval ) << 8 ) |
  276.              ( PPM_GETB( *xP ) * xmaxval / lmaxval );
  277.             fwrite( &ul, sizeof(ul), 1, stdout );
  278.             }
  279.         break;
  280.  
  281.         default:
  282.         for ( col = 0, xP = xels[row]; col < cols; ++col, ++xP )
  283.             {
  284.             unsigned long ul;
  285.             register unsigned long val;
  286.  
  287.             val = PNM_GET1( *xP );
  288.             ul = ( ( val * xmaxval / lmaxval ) << 16 ) |
  289.              ( ( val * xmaxval / lmaxval ) << 8 ) |
  290.              ( val * xmaxval / lmaxval );
  291.             fwrite( &ul, sizeof(ul), 1, stdout );
  292.             }
  293.         break;
  294.         }
  295.         }
  296.     else if ( grayscale )
  297.         {
  298.         register xelval bigger_maxval;
  299.         register int bitshift;
  300.         unsigned char byte;
  301.         register xelval s;
  302.  
  303.         bigger_maxval = pm_bitstomaxval( h11.bits_per_pixel );
  304.         bitshift = 8 - h11.bits_per_pixel;
  305.         byte = 0;
  306.         for ( col = 0, xP = xels[row]; col < cols; ++col, ++xP )
  307.         {
  308.         s = PNM_GET1( *xP );
  309.  
  310.         /* More stupid hack. */
  311.         if ( PNM_FORMAT_TYPE(format) == PBM_TYPE )
  312.             s = 1 - s;
  313.  
  314.         if ( maxval != bigger_maxval )
  315.             s = (long) s * bigger_maxval / maxval;
  316.         byte |= s << bitshift;
  317.         bitshift -= h11.bits_per_pixel;
  318.         if ( bitshift < 0 )
  319.             {
  320.             putchar( byte );
  321.             bitshift = 8 - h11.bits_per_pixel;
  322.             byte = 0;
  323.             }
  324.         }
  325.         if ( bitshift < 8 - h11.bits_per_pixel )
  326.         putchar( byte );
  327.         }
  328.     else
  329.         {
  330.         for ( col = 0, xP = xels[row]; col < cols; ++col, ++xP )
  331.         putchar( ppm_lookupcolor( cht, xP ) );
  332.         }
  333.  
  334.     exit( 0 );
  335.     }
  336.