home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume2 / pbm / Part2 / xwdtopbm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-07  |  7.6 KB  |  296 lines

  1. /* xwdtopbm.c - read an X11 window dump file and write a portable bitmap
  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.  
  13. #include <stdio.h>
  14. #include "pbm.h"
  15.  
  16. main( argc, argv )
  17. int argc;
  18. char *argv[];
  19.     {
  20.     FILE *ifd;
  21.     bit **bits, getbit();
  22.     int rows, cols, padR, row, col;
  23.  
  24.     if ( argc > 2 )
  25.     {
  26.     fprintf( stderr, "usage:  %s [xwdfile]\n", argv[0] );
  27.     exit( 1 );
  28.     }
  29.  
  30.     if ( argc == 2 )
  31.     {
  32.         ifd = fopen( argv[1], "r" );
  33.         if ( ifd == NULL )
  34.         {
  35.         fprintf( stderr, "%s: can't open.\n", argv[1] );
  36.         exit( 1 );
  37.         }
  38.     }
  39.     else
  40.     ifd = stdin;
  41.  
  42.     getinit( ifd, &cols, &rows, &padR );
  43.  
  44.     bits = pbm_allocarray( cols, rows );
  45.  
  46.     for ( row = 0; row < rows; row++ )
  47.     {
  48.         for ( col = 0; col < cols; col++ )
  49.         bits[row][col] = getbit( ifd );
  50.         for ( col = 0; col < padR; col++ )
  51.         (void) getbit( ifd );
  52.     }
  53.  
  54.     if ( ifd != stdin )
  55.     fclose( ifd );
  56.     
  57.     pbm_writepbm( stdout, bits, cols, rows );
  58.  
  59.     exit( 0 );
  60.     }
  61.  
  62.  
  63. unsigned char bitem;
  64. short sitem;
  65. int bits_per_item, bits_used, bit_shift, bit_order, bit_invert;
  66.  
  67. /* The following defs are taken from various X10 header files. */
  68. #define X10WD_FILE_VERSION 6
  69. typedef struct {
  70.     int header_size;        /* Size of the entire file header (bytes). */
  71.     int file_version;        /* X10WD_FILE_VERSION */
  72.     int display_type;        /* Display type. */
  73.     int display_planes;        /* Number of display planes. */
  74.     int pixmap_format;        /* Pixmap format. */
  75.     int pixmap_width;        /* Pixmap width. */
  76.     int pixmap_height;        /* Pixmap height. */
  77.     short window_width;        /* Window width. */
  78.     short window_height;    /* Window height. */
  79.     short window_x;        /* Window upper left X coordinate. */
  80.     short window_y;        /* Window upper left Y coordinate. */
  81.     short window_bdrwidth;    /* Window border width. */
  82.     short window_ncolors;    /* number of Color entries in this window */
  83.     } X10WDFileHeader;
  84.  
  85. typedef struct {
  86.     int pixel;
  87.     unsigned short red, green, blue;
  88.     } X10Color;
  89.  
  90.  
  91. /* The following defs are taken from various X11 header files. */
  92. typedef unsigned long xwdval;
  93. #define X11WD_FILE_VERSION 7
  94. typedef struct {
  95.     xwdval header_size;        /* Size of the entire file header (bytes). */
  96.     xwdval file_version;    /* X11WD_FILE_VERSION */
  97.     xwdval pixmap_format;    /* Pixmap format */
  98.     xwdval pixmap_depth;    /* Pixmap depth */
  99.     xwdval pixmap_width;    /* Pixmap width */
  100.     xwdval pixmap_height;    /* Pixmap height */
  101.     xwdval xoffset;        /* Bitmap x offset */
  102.     xwdval byte_order;        /* MSBFirst, LSBFirst */
  103.     xwdval bitmap_unit;        /* Bitmap unit */
  104.     xwdval bitmap_bit_order;    /* MSBFirst, LSBFirst */
  105.     xwdval bitmap_pad;        /* Bitmap scanline pad */
  106.     xwdval bits_per_pixel;    /* Bits per pixel */
  107.     xwdval bytes_per_line;    /* Bytes per scanline */
  108.     xwdval visual_class;    /* Class of colormap */
  109.     xwdval red_mask;        /* Z red mask */
  110.     xwdval green_mask;        /* Z green mask */
  111.     xwdval blue_mask;        /* Z blue mask */
  112.     xwdval bits_per_rgb;    /* Log base 2 of distinct color values */
  113.     xwdval colormap_entries;    /* Number of entries in colormap */
  114.     xwdval ncolors;        /* Number of Color structures */
  115.     xwdval window_width;    /* Window width */
  116.     xwdval window_height;    /* Window height */
  117.     long window_x;        /* Window upper left X coordinate */
  118.     long window_y;        /* Window upper left Y coordinate */
  119.     xwdval window_bdrwidth;    /* Window border width */
  120.     } X11WDFileHeader;
  121.  
  122. typedef struct {
  123.     unsigned long pixel;
  124.     unsigned short red, green, blue;
  125.     char flags;            /* do_red, do_green, do_blue */
  126.     char pad;
  127.     } X11XColor;
  128.  
  129.  
  130. getinit( file, colP, rowP, padRP )
  131. FILE *file;
  132. int *colP, *rowP, *padRP;
  133.     {
  134.     int header_size;
  135.     int file_version;
  136.     X10WDFileHeader h10;
  137.     X11WDFileHeader h11;
  138.     char junk[10000];
  139.  
  140.     if ( fread( &header_size, sizeof( header_size ), 1, file ) != 1 )
  141.     {
  142.     fprintf( stderr, "Couldn't read XWD header size.\n" );
  143.     exit( 1 );
  144.     }
  145.     if ( fread( &file_version, sizeof( file_version ), 1, file ) != 1 )
  146.     {
  147.     fprintf( stderr, "Couldn't read XWD file version.\n" );
  148.     exit( 1 );
  149.     }
  150.     if ( file_version == X10WD_FILE_VERSION )
  151.     {
  152.     if ( fread( &h10.display_type, sizeof( h10 ) - 2 * sizeof( int ), 1,
  153.                     file ) != 1 )
  154.         {
  155.         fprintf( stderr, "Couldn't read X10 XWD file header.\n" );
  156.         exit( 1 );
  157.         }
  158.     if ( fread( junk, header_size - sizeof( h10 ), 1, file ) != 1 )
  159.         {
  160.         fprintf( stderr, "Couldn't read rest of X10 XWD file header.\n" );
  161.         exit( 1 );
  162.         }
  163.     if ( fread( junk, sizeof(X10Color), h10.window_ncolors, file ) !=
  164.          h10.window_ncolors )
  165.         {
  166.         fprintf( stderr, "Couldn't read X10 XWD colormap.\n" );
  167.         exit( 1 );
  168.         }
  169.  
  170.     /* Check whether we can handle this dump. */
  171.     if ( h10.window_ncolors != 0 )
  172.         {
  173.         fprintf( stderr, "Can't handle X10 window_ncolors != 0.\n" );
  174.         exit( 1 );
  175.         }
  176.     if ( h10.pixmap_format != 0 )
  177.         {
  178.         fprintf( stderr, "Can't handle X10 pixmap_format %d.\n",
  179.              h10.pixmap_format );
  180.         exit( 1 );
  181.         }
  182.  
  183.     *colP = h10.pixmap_width;
  184.     *rowP = h10.pixmap_height;
  185.     *padRP = ( h10.pixmap_width + 15 ) / 16 * 16 - h10.pixmap_width;
  186.     bits_per_item = 16;
  187.     bit_order = 0;
  188.     bit_invert = 1;
  189.     bits_used = 16;
  190.     }
  191.     else if ( file_version == X11WD_FILE_VERSION )
  192.     {
  193.     if ( fread( &h11.pixmap_format, sizeof( h11 ) - 2 * sizeof( xwdval ),
  194.             1, file ) != 1 )
  195.         {
  196.         fprintf( stderr, "Couldn't read X11 XWD file header.\n" );
  197.         exit( 1 );
  198.         }
  199.     if ( fread( junk, header_size - sizeof( h11 ), 1, file ) != 1 )
  200.         {
  201.         fprintf( stderr, "Couldn't read rest of X11 XWD file header.\n" );
  202.         exit( 1 );
  203.         }
  204.     if ( fread( junk, sizeof( X11XColor ), h11.ncolors, file ) !=
  205.          h11.ncolors )
  206.         {
  207.         fprintf( stderr, "Couldn't read X11 XWD colormap.\n" );
  208.         exit( 1 );
  209.         }
  210.  
  211.     /* Check whether we can handle this dump. */
  212.     if ( h11.pixmap_depth != 1 )
  213.         {
  214.         fprintf( stderr, "Can't handle X11 pixmap_depth > 1.\n" );
  215.         exit( 1 );
  216.         }
  217.     if ( h11.colormap_entries != 2 )
  218.         {
  219.         fprintf( stderr, "Can't handle X11 colormap_entries != 2.\n" );
  220.         exit( 1 );
  221.         }
  222.     if ( h11.ncolors != 2 )
  223.         {
  224.         fprintf( stderr, "Can't handle X11 ncolors != 2.\n" );
  225.         exit( 1 );
  226.         }
  227.     if ( h11.pixmap_format != 2 )
  228.         {
  229.         fprintf( stderr, "Can't handle X11 pixmap_format %d.\n",
  230.              h11.pixmap_format );
  231.         exit( 1 );
  232.         }
  233.  
  234.     *colP = h11.pixmap_width;
  235.     *rowP = h11.pixmap_height;
  236.     *padRP = h11.bytes_per_line * 8 - h11.pixmap_width;
  237.     bits_per_item = 8;
  238.     bit_order = h11.bitmap_bit_order;
  239.     bit_invert = 0;
  240.     bits_used = 8;
  241.     }
  242.     else
  243.     {
  244.     fprintf( stderr, "Unknown XWD file version: %d.\n", file_version );
  245.     exit( 1 );
  246.     }
  247.     }
  248.  
  249. bit
  250. getbit( file )
  251. FILE *file;
  252.     {
  253.     bit b;
  254.  
  255.     if ( bits_used == bits_per_item )
  256.     {
  257.     if ( bits_per_item == 16 )
  258.         {
  259.         if ( fread( &sitem, 2, 1, file ) != 1 )
  260.         {
  261.         fprintf( stderr, "Couldn't read short bits.\n" );
  262.         exit( 1 );
  263.         }
  264.         }
  265.     else
  266.         {
  267.         if ( fread( &bitem, 1, 1, file ) != 1 )
  268.         {
  269.         fprintf( stderr, "Couldn't read byte bits.\n" );
  270.         exit( 1 );
  271.         }
  272.         }
  273.     bits_used = 0;
  274.  
  275.     if ( bit_order == 1 )
  276.         bit_shift = bits_per_item - 1;
  277.     else
  278.         bit_shift = 0;
  279.     }
  280.  
  281.     bits_used++;
  282.     if ( bits_per_item == 16 )
  283.     b = ( sitem >> bit_shift) & 1;
  284.     else
  285.     b = ( bitem >> bit_shift) & 1;
  286.     if ( bit_invert )
  287.     b = 1 - b;
  288.  
  289.     if ( bit_order == 1 )
  290.     bit_shift--;
  291.     else
  292.     bit_shift++;
  293.  
  294.     return ( b );
  295.     }
  296.