home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 309.lha / PBM_PLUS / pbm / xwdtopbm.c < prev   
C/C++ Source or Header  |  1980-12-04  |  9KB  |  331 lines

  1. /* xwdtopbm.c - read an X11 or X10 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. #include "x10wd.h"
  16. #include "x11wd.h"
  17.  
  18. main( argc, argv )
  19. int argc;
  20. char *argv[];
  21.     {
  22.     FILE *ifd;
  23.     register bit *bitrow, *bP;
  24.     bit getbit();
  25.     int rows, cols, padright, row, col;
  26.  
  27.     pm_progname = argv[0];
  28.  
  29.     if ( argc > 2 )
  30.     pm_usage( "[xwdfile]" );
  31.  
  32.     if ( argc == 2 )
  33.     ifd = pm_openr( argv[1] );
  34.     else
  35.     ifd = stdin;
  36.  
  37.     getinit( ifd, &cols, &rows, &padright );
  38.  
  39.     pbm_writepbminit( stdout, cols, rows );
  40.     bitrow = pbm_allocrow( cols );
  41.  
  42.     for ( row = 0; row < rows; row++ )
  43.     {
  44.         for ( col = 0, bP = bitrow; col < cols; col++, bP++ )
  45.         *bP = getbit( ifd );
  46.         for ( col = 0; col < padright; col++ )
  47.         (void) getbit( ifd );
  48.     pbm_writepbmrow( stdout, bitrow, cols );
  49.     }
  50.  
  51.     pm_close( ifd );
  52.  
  53.     exit( 0 );
  54.     }
  55.  
  56.  
  57. char buf[4];
  58. char *byteP;
  59. short *shortP;
  60. long *longP;
  61. int bits_per_item, bits_used, bit_shift, bits_per_pixel, bit_order, bit_invert, byte_swap;
  62.  
  63. short bs_short();
  64. int bs_int();
  65. long bs_long();
  66.  
  67.  
  68. getinit( file, colP, rowP, padrightP )
  69. FILE *file;
  70. int *colP, *rowP, *padrightP;
  71.     {
  72.     /* Assume X11 headers are larger than X10 ones. */
  73.     unsigned char header[sizeof(X11WDFileHeader)];
  74.     X10WDFileHeader *h10P;
  75.     X11WDFileHeader *h11P;
  76.     char junk[10000];
  77.  
  78.     h10P = (X10WDFileHeader *) header;
  79.     h11P = (X11WDFileHeader *) header;
  80.  
  81.     if ( sizeof(*h10P) > sizeof(*h11P) )
  82.     {
  83.     pm_message(
  84.         "ARGH!  On this machine, X10 headers are larger than X11 headers!",
  85.         0,0,0,0,0 );
  86.     pm_error(
  87.         "You will have to re-write xwdtopbm.", 0,0,0,0,0 );
  88.     }
  89.  
  90.     /* Read an X10 header. */
  91.     if ( fread( &header[0], sizeof(*h10P), 1, file ) != 1 )
  92.     pm_error( "couldn't read XWD file header", 0,0,0,0,0 );
  93.  
  94.     if ( h10P->file_version == X10WD_FILE_VERSION ||
  95.      bs_int( h10P->file_version ) == X10WD_FILE_VERSION )
  96.     {
  97.     if ( h10P->file_version != X10WD_FILE_VERSION )
  98.         {
  99.         byte_swap = 1;
  100.         h10P->header_size = bs_int( h10P->header_size );
  101.         h10P->file_version = bs_int( h10P->file_version );
  102.         h10P->display_type = bs_int( h10P->display_type );
  103.         h10P->display_planes = bs_int( h10P->display_planes );
  104.         h10P->pixmap_format = bs_int( h10P->pixmap_format );
  105.         h10P->pixmap_width = bs_int( h10P->pixmap_width );
  106.         h10P->pixmap_height = bs_int( h10P->pixmap_height );
  107.         h10P->window_width = bs_short( h10P->window_width );
  108.         h10P->window_height = bs_short( h10P->window_height );
  109.         h10P->window_x = bs_short( h10P->window_x );
  110.         h10P->window_y = bs_short( h10P->window_y );
  111.         h10P->window_bdrwidth = bs_short( h10P->window_bdrwidth );
  112.         h10P->window_ncolors = bs_short( h10P->window_ncolors );
  113.         }
  114.     if ( fread( junk, 1, h10P->header_size - sizeof(*h10P), file ) != h10P->header_size - sizeof(*h10P) )
  115.         pm_error( "couldn't read rest of X10 XWD file header", 0,0,0,0,0 );
  116.     if ( fread( junk, sizeof(X10Color), h10P->window_ncolors, file ) !=
  117.          h10P->window_ncolors )
  118.         pm_error( "couldn't read X10 XWD colormap", 0,0,0,0,0 );
  119.  
  120.     /* Check whether we can handle this dump. */
  121.     if ( h10P->window_ncolors != 0 )
  122.         pm_error( "can't handle X10 color dump - try xwdtoppm", 0,0,0,0,0 );
  123.     if ( h10P->pixmap_format != XYFormat )
  124.         pm_error(
  125.         "can't handle X10 pixmap_format %d", h10P->pixmap_format,
  126.         0,0,0,0 );
  127.  
  128.     *colP = h10P->pixmap_width;
  129.     *rowP = h10P->pixmap_height;
  130.     *padrightP =
  131.         ( ( h10P->pixmap_width + 15 ) / 16 ) * 16 - h10P->pixmap_width;
  132.     bits_per_item = 16;
  133.     bits_used = bits_per_item;
  134.     bits_per_pixel = 1;
  135.     bit_order = LSBFirst;
  136.     bit_invert = 1;
  137.     }
  138.     else if ( h11P->file_version == X11WD_FILE_VERSION ||
  139.          bs_long( h11P->file_version ) == X11WD_FILE_VERSION )
  140.     {
  141.     if ( fread( &header[sizeof(*h10P)], sizeof(*h11P) - sizeof(*h10P), 1, file ) != 1 )
  142.         pm_error( "couldn't read X11 XWD file header", 0,0,0,0,0 );
  143.     if ( h11P->file_version != X11WD_FILE_VERSION )
  144.         {
  145.         byte_swap = 1;
  146.         h11P->header_size = bs_long( h11P->header_size );
  147.         h11P->file_version = bs_long( h11P->file_version );
  148.         h11P->pixmap_format = bs_long( h11P->pixmap_format );
  149.         h11P->pixmap_depth = bs_long( h11P->pixmap_depth );
  150.         h11P->pixmap_width = bs_long( h11P->pixmap_width );
  151.         h11P->pixmap_height = bs_long( h11P->pixmap_height );
  152.         h11P->xoffset = bs_long( h11P->xoffset );
  153.         h11P->byte_order = bs_long( h11P->byte_order );
  154.         h11P->bitmap_unit = bs_long( h11P->bitmap_unit );
  155.         h11P->bitmap_bit_order = bs_long( h11P->bitmap_bit_order );
  156.         h11P->bitmap_pad = bs_long( h11P->bitmap_pad );
  157.         h11P->bits_per_pixel = bs_long( h11P->bits_per_pixel );
  158.         h11P->bytes_per_line = bs_long( h11P->bytes_per_line );
  159.         h11P->visual_class = bs_long( h11P->visual_class );
  160.         h11P->red_mask = bs_long( h11P->red_mask );
  161.         h11P->green_mask = bs_long( h11P->green_mask );
  162.         h11P->blue_mask = bs_long( h11P->blue_mask );
  163.         h11P->bits_per_rgb = bs_long( h11P->bits_per_rgb );
  164.         h11P->colormap_entries = bs_long( h11P->colormap_entries );
  165.         h11P->ncolors = bs_long( h11P->ncolors );
  166.         h11P->window_width = bs_long( h11P->window_width );
  167.         h11P->window_height = bs_long( h11P->window_height );
  168.         h11P->window_x = bs_long( h11P->window_x );
  169.         h11P->window_y = bs_long( h11P->window_y );
  170.         h11P->window_bdrwidth = bs_long( h11P->window_bdrwidth );
  171.         }
  172.     if ( fread( junk, 1, h11P->header_size - sizeof(*h11P), file ) != h11P->header_size - sizeof(*h11P) )
  173.         pm_error( "couldn't read rest of X11 XWD file header", 0,0,0,0,0 );
  174.     if ( fread( junk, sizeof(X11XColor), h11P->colormap_entries, file ) !=
  175.          h11P->colormap_entries )
  176.         pm_error( "couldn't read X11 XWD colormap", 0,0,0,0,0 );
  177.  
  178.     /* Check whether we can handle this dump. */
  179.     if ( h11P->pixmap_depth != 1 || h11P->bits_per_rgb != 1 )
  180.         pm_error( "can't handle X11 color dump - try xwdtoppm", 0,0,0,0,0 );
  181.     if ( h11P->pixmap_format != XYBitmap &&
  182.          h11P->pixmap_format != ZPixmap )
  183.         pm_error(
  184.         "can't handle X11 pixmap_format %d", h11P->pixmap_format,
  185.         0,0,0,0 );
  186. #ifdef notdef
  187.     if ( h11P->bitmap_unit != h11P->bitmap_pad )
  188.         pm_error(
  189.         "X11 bitmap_unit (%d) != bitmap_pad (%d) - can't handle",
  190.         h11P->bitmap_unit, h11P->bitmap_pad, 0,0,0 );
  191. #endif notdef
  192.     if ( h11P->bitmap_unit != 8 && h11P->bitmap_unit != 16 &&
  193.          h11P->bitmap_unit != 32 )
  194.         pm_error(
  195.         "X11 bitmap_unit (%d) is unusual - can't handle",
  196.         h11P->bitmap_unit, 0,0,0,0 );
  197.     if ( h11P->bits_per_pixel != 1 && h11P->bits_per_pixel != 8 )
  198.         {
  199.         pm_error(
  200.         "X11 bits_per_pixel (%d) is unusual - can't handle",
  201.         h11P->bits_per_pixel, 0,0,0,0 );
  202.         exit( 1 );
  203.         }
  204.  
  205.     *colP = h11P->pixmap_width;
  206.     *rowP = h11P->pixmap_height;
  207.     *padrightP =
  208.         h11P->bytes_per_line * 8 / h11P->bits_per_pixel -
  209.         h11P->pixmap_width;
  210.     bits_per_item = h11P->bitmap_unit;
  211.     bits_used = bits_per_item;
  212.     bits_per_pixel = h11P->bits_per_pixel;
  213.     bit_order = h11P->bitmap_bit_order;
  214. #ifdef hpux
  215.     bit_invert = 1;
  216. #else
  217.     bit_invert = 0;
  218. #endif
  219.     }
  220.     else
  221.     pm_error( "unknown XWD file version: %d", h11P->file_version, 0,0,0,0 );
  222.  
  223.     byteP = (char *) buf;
  224.     shortP = (short *) buf;
  225.     longP = (long *) buf;
  226.     }
  227.  
  228. bit
  229. getbit( file )
  230. FILE *file;
  231.     {
  232.     bit b;
  233.  
  234.     if ( bits_used == bits_per_item )
  235.     {
  236.     if ( fread( buf, bits_per_item / 8, 1, file ) != 1 )
  237.         pm_error( "couldn't read bits", 0,0,0,0,0 );
  238.     if ( byte_swap )
  239.         switch ( bits_per_item )
  240.         {
  241.         case 8:
  242.         break;
  243.  
  244.         case 16:
  245.         *shortP = bs_short( *shortP );
  246.         break;
  247.  
  248.         case 32:
  249.         *longP = bs_long( *longP );
  250.         break;
  251.  
  252.         default:
  253.         pm_error( "can't happen", 0,0,0,0,0 );
  254.         }
  255.     bits_used = 0;
  256.  
  257.     if ( bit_order == MSBFirst )
  258.         bit_shift = bits_per_item - bits_per_pixel;
  259.     else
  260.         bit_shift = 0;
  261.     }
  262.  
  263.     switch ( bits_per_item )
  264.     {
  265.     case 8:
  266.     b = ( ( *byteP >> bit_shift ) & 1 ) ? PBM_BLACK : PBM_WHITE;
  267.     break;
  268.  
  269.     case 16:
  270.     b = ( ( *shortP >> bit_shift ) & 1 ) ? PBM_BLACK : PBM_WHITE;
  271.     break;
  272.  
  273.     case 32:
  274.     b = ( ( *longP >> bit_shift ) & 1 ) ? PBM_BLACK : PBM_WHITE;
  275.     break;
  276.  
  277.     default:
  278.     pm_error( "can't happen", 0,0,0,0,0 );
  279.     }
  280.  
  281.     if ( bit_invert )
  282.     b = 1 - b;
  283.  
  284.     if ( bit_order == MSBFirst )
  285.     bit_shift -= bits_per_pixel;
  286.     else
  287.     bit_shift += bits_per_pixel;
  288.     bits_used += bits_per_pixel;
  289.  
  290.     return b;
  291.     }
  292.  
  293. short
  294. bs_short( s )
  295. short s;
  296.     {
  297.     short ss;
  298.     unsigned char *bp, t;
  299.  
  300.     ss = s;
  301.     bp = (unsigned char *) &ss;
  302.     t = bp[0];
  303.     bp[0] = bp[1];
  304.     bp[1] = t;
  305.     return ss;
  306.     }
  307.  
  308. int
  309. bs_int( i )
  310. int i;
  311.     {
  312.     int ii;
  313.     unsigned char *bp, t;
  314.  
  315.     ii = i;
  316.     bp = (unsigned char *) ⅈ
  317.     t = bp[0];
  318.     bp[0] = bp[3];
  319.     bp[3] = t;
  320.     t = bp[1];
  321.     bp[1] = bp[2];
  322.     bp[2] = t;
  323.     return ii;
  324.     }
  325.  
  326. long bs_long( l )
  327. long l;
  328.     {
  329.     return bs_int( l );
  330.     }
  331.