[comp.graphics] Dumping X-Windows to TIFF file

matt@rs20dev.UUCP (Matt Howland) (05/01/91)

I am looking for a program to dump images of X-Windows to a TIFF file.
Is there such a program available?  If so, where can I obtain it?
I do not have ftp access to the net, but if it is on the uunet archive
I can UUCP it from there.  Otherwise maybe someone could mail it to me.
Please respond via. E-Mail before sending source code.

Matt Howland         E-Mail: matt@rs20dev.uunet
                       UUCP: uunet!rs20dev!matt

dbs@kodak.enet.dec.com (dan sears) (05/02/91)

Matt,

Get ahold of xsnap.tar.Z from export.lcs.mit.edu and libtiff from
ucbvax.berkeley.edu.
Then apply these patches to xsnap.

--Dan

diff -c orig/AUTHORS new/AUTHORS
*** orig/AUTHORS	Thu Jan 24 09:57:10 1991
--- new/AUTHORS	Fri Mar 15 11:46:07 1991
***************
*** 21,23 ****
--- 21,27 ----
     BULL Research FRANCE -- Koala Project
     lehors@mirsa.inria.fr
  
+ Code to output in TIFF format was added by:
+    Dan Sears
+    Digital Equipment
+    dbs@wse.dec.com
diff -c orig/Imakefile new/Imakefile
*** orig/Imakefile	Tue Feb 19 12:33:29 1991
--- new/Imakefile	Fri Mar 15 11:59:20 1991
***************
*** 1,10 ****
!    XPM_INCLUDES = ../xpm
!          XPMLIB = ../xpm/libXPM2.a
  LOCAL_LIBRARIES = $(XLIB)
             SRCS = xsnap.c
             OBJS = xsnap.o
!  EXTRA_INCLUDES = -I$(XPM_INCLUDES)
! EXTRA_LIBRARIES = $(XPMLIB)
!         DEFINES = -DATK -DXPM
  
  ComplexProgramTarget(xsnap)
--- 1,15 ----
!    XPM_INCLUDES = ../../xpm
!          XPMLIB = ../../xpm/libXPM2.a
!   TIFF_INCLUDES = /cc8/dbs/xtiff/2.3/libtiff
!         TIFFLIB = /cc8/dbs/xtiff/2.3/libtiff/libtiff.a
  LOCAL_LIBRARIES = $(XLIB)
             SRCS = xsnap.c
             OBJS = xsnap.o
! #EXTRA_INCLUDES = -I$(XPM_INCLUDES) -I$(TIFF_INCLUDES)
! #EXTRA_LIBRARIES = $(XPMLIB) $(TIFFLIB)
! #        DEFINES = -DXWD -DATK -DXPM -DTIF
! EXTRA_INCLUDES = -I$(TIFF_INCLUDES)
! EXTRA_LIBRARIES = $(TIFFLIB)
!         DEFINES = -DTIF
  
  ComplexProgramTarget(xsnap)
diff -c orig/xsnap.c new/xsnap.c
*** orig/xsnap.c	Thu Jan 24 09:37:55 1991
--- new/xsnap.c	Sun Apr  7 17:48:23 1991
***************
*** 13,18 ****
--- 13,20 ----
   *   Modified by Arnaud Le Hors lehors@mirsa.inria.fr  November 14 1990
   *    fix code about region option
   *    add -xpm option
+  *   Modified by Dan Sears dbs@wse.dec.com  March 15 1991
+  *    add -tif option
   *
   */
  
***************
*** 21,26 ****
--- 23,31 ----
  #include <X11/Xos.h>
  #include <X11/Xutil.h>
  #include <X11/cursorfont.h>
+ #ifdef TIF
+ #include "tiffio.h"
+ #endif
  #include "patchlevel.h"
  
  #ifndef TRUE
***************
*** 44,49 ****
--- 49,55 ----
  char *region_geom_string = NULL;     /* location of region to copy */
  char *app_name = "xsnap";            /* name of application for window
manager */
  int  xwd_output = FALSE;	     /* store in xwd format */
+ int  tif_output = FALSE;	     /* store in TIFF format */
  int  atk_output = FALSE;	     /* store in ATK format */
  int  xpm_output = FALSE;	     /* store in XPM format */
  char *output_file_name = NULL;	     /* file to store in */
***************
*** 399,407 ****
--- 405,422 ----
  	printf("%s\n", "[-iconic]                Start up in iconic state");
  	printf("%s\n", "[-name name]             Passed to window manager for
name of window.");
  	printf("%s\n", "[-nograb]                Don't grab server during
specification of region.");
+ #ifdef XWD
  	printf("%s\n", "[-xwd]                   Write to output in `xwd' format.");
+ #endif
+ #ifdef TIF
+ 	printf("%s\n", "[-tif]                   Write to output in `tif' format.");
+ #endif
+ #ifdef ATK
  	printf("%s\n", "[-atk]                   Write to output in `atk' format.");
+ #endif
+ #ifdef XPM
  	printf("%s\n", "[-xpm]                   Write to output in `xpm' format.");
+ #endif
  	printf("%s\n", "[-file filename]         Write output to file `filename'.");
  	printf("%s\n", "[-cutbuffer]             Store in cutbuffer in Andrew
raster format.");
  	printf("%s\n", "[-noshow]                Don't display in window.");
***************
*** 475,495 ****
--- 490,523 ----
  		  display_in_window = FALSE;
  		  continue;
  		}
+ #ifdef XWD
  		if (strncmp(argv[i], "-xwd", 4) == 0)
  		{
  		  xwd_output = TRUE;
  		  continue;
  		}
+ #endif
+ #ifdef TIF
+ 		if (strncmp(argv[i], "-tif", 4) == 0)
+ 		{
+ 		  tif_output = TRUE;
+ 		  continue;
+ 		}
+ #endif
+ #ifdef ATK
  		if (strncmp(argv[i], "-atk", 4) == 0)
  		{
  		  atk_output = TRUE;
  		  continue;
  		}
+ #endif
+ #ifdef XPM
  		if (strncmp(argv[i], "-xpm", 4) == 0)
  		{
  		  xpm_output = TRUE;
  		  continue;
  		}
+ #endif
  		if (strncmp(argv[i], "-file", 5) == 0)
  		{
  		  output_file_name = argv[++i];
***************
*** 537,542 ****
--- 565,571 ----
   * Determine the pixmap size.
   */
  
+ #ifdef XWD
  int Image_Size(image, format)
       XImage *image;
       int format;
***************
*** 582,587 ****
--- 611,841 ----
  	bp += 2;
      }
  }
+ #endif
+ 
+ #ifdef TIF
+ save_as_tif_file(display, screen, win_info, pixmap, width, height, depth)
+     Display *display;
+     int screen;
+     XWindowAttributes *win_info;
+     Pixmap pixmap;
+     u_short width, height, depth;
+ {
+     extern char *ctime();
+     char *date_time;
+     long t, date_time_length;
+     TIFF *tif;
+     XImage *image;
+ 
+     t = time(0);
+     date_time = ctime(&t);
+     date_time_length = strlen(date_time) - 1;
+     date_time[date_time_length] = '\0';
+ 
+     image = XGetImage(display, pixmap, 0, 0, width, height, AllPlanes,
ZPixmap);
+ 
+     if ((tif = TIFFOpen(output_file_name, "w")) == NULL) {
+         (void) fprintf(stderr, "can't open %s as a TIFF file\n",
output_file_name);
+         exit(0);
+     }
+ 
+     switch (depth) {
+         case 32:
+         case 24:
+             TIFFDirectColor(display, win_info, width, height, tif,
image, date_time);
+             break;
+         case 8:
+             TIFFPseudoColor(display, win_info, width, height, tif,
image, date_time);
+             break;
+         case 1:
+             TIFFMono(display, win_info, width, height, tif, image,
date_time);
+             break;
+         default:
+ 	        fprintf(stderr, "xsnap: depth %d not supported\n", depth);
+ 	        exit(1);
+     }
+ 
+     XDestroyImage(image);
+     TIFFClose(tif);
+ }
+ 
+ TIFFDirectColor(display, win_info, width, height, tif, image, date_time)
+     Display *display;
+     XWindowAttributes *win_info;
+     u_short width, height;
+     TIFF *tif;
+     XImage *image;
+     char *date_time;
+ {
+     int i, j, ncolors;
+     u_char *row_p, *scan_line;
+     u_long pixel, r, g, b, red_shift, blue_shift, green_shift,
+ 	    red_mask, blue_mask, green_mask;
+     u_short *rmap, *gmap, *bmap;
+     XColor *colors;
+ 
+     ncolors = win_info->visual->map_entries;
+     rmap = (u_short *) malloc(ncolors * sizeof(u_short));
+     gmap = (u_short *) malloc(ncolors * sizeof(u_short));
+     bmap = (u_short *) malloc(ncolors * sizeof(u_short));
+     colors = (XColor *) malloc(ncolors * sizeof(XColor));
+     red_mask = win_info->visual->red_mask;
+     green_mask = win_info->visual->green_mask;
+     blue_mask = win_info->visual->blue_mask;
+ 
+     if (ImageByteOrder(display) == LSBFirst) { /* DECstation 5000 */
+         red_shift = win_info->visual->red_mask == 0xFF000000 ? 24
+             : (win_info->visual->red_mask == 0xFF0000 ? 16
+             : (win_info->visual->red_mask == 0xFF00 ? 8 : 0));
+         green_shift = win_info->visual->green_mask == 0xFF000000 ? 24
+             : (win_info->visual->green_mask == 0xFF0000 ? 16
+             : (win_info->visual->green_mask == 0xFF00 ? 8 : 0));
+         blue_shift = win_info->visual->blue_mask == 0xFF000000 ? 24
+             : (win_info->visual->blue_mask == 0xFF0000 ? 16
+             : (win_info->visual->blue_mask == 0xFF00 ? 8 : 0));
+     } else { /* Ardent */
+         red_shift = win_info->visual->red_mask == 0xFF000000 ? 0
+             : (win_info->visual->red_mask == 0xFF0000 ? 8
+             : (win_info->visual->red_mask == 0xFF00 ? 16 : 24));
+         green_shift = win_info->visual->green_mask == 0xFF000000 ? 0
+             : (win_info->visual->green_mask == 0xFF0000 ? 8
+             : (win_info->visual->green_mask == 0xFF00 ? 16 : 24));
+         blue_shift = win_info->visual->blue_mask == 0xFF000000 ? 0
+             : (win_info->visual->blue_mask == 0xFF0000 ? 8
+             : (win_info->visual->blue_mask == 0xFF00 ? 16 : 24));
+     }
+ 
+     for (r = g = b = i = 0; i < ncolors; i++) {
+         colors[i].pixel = r | g | b;
+         colors[i].pad = 0;
+ 		colors[i].flags = DoRed | DoGreen | DoBlue;
+         r += 1 << red_shift;
+         g += 1 << green_shift;
+         b += 1 << blue_shift;
+     }
+ 
+     XQueryColors(display, win_info->colormap, colors, ncolors);
+ 
+     for (i = 0; i < ncolors; i++) {
+         rmap[i] = colors[i].red;
+         gmap[i] = colors[i].green;
+         bmap[i] = colors[i].blue;
+     }
+ 
+     TIFFSetField(tif, TIFFTAG_IMAGEWIDTH,           width);
+     TIFFSetField(tif, TIFFTAG_IMAGELENGTH,          height);
+     TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE,        8);
+     TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL,      3);
+     TIFFSetField(tif, TIFFTAG_PLANARCONFIG,         PLANARCONFIG_CONTIG);
+     TIFFSetField(tif, TIFFTAG_PHOTOMETRIC,          PHOTOMETRIC_RGB);
+     TIFFSetField(tif, TIFFTAG_COLORRESPONSECURVE,   rmap, gmap, bmap);
+     TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP,         1);
+     TIFFSetField(tif, TIFFTAG_SOFTWARE,             app_name);
+     TIFFSetField(tif, TIFFTAG_DATETIME,             date_time);
+     TIFFSetField(tif, TIFFTAG_COMPRESSION,          COMPRESSION_NONE);
+     TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT,       RESUNIT_NONE);
+ 
+     scan_line = (u_char *) malloc(width * 3);
+ 
+     for (j = height - 1; j >= 0; j--) {
+         for (row_p = scan_line, i = 0; i < width; i++) {
+             pixel = XGetPixel(image, i, j);
+             *row_p++ = (pixel & red_mask) >> red_shift;
+             *row_p++ = (pixel & green_mask) >> green_shift;
+             *row_p++ = (pixel & blue_mask) >> blue_shift;
+         }
+         TIFFWriteScanline(tif, scan_line, j, 0);
+     }
+ }
+ 
+ TIFFPseudoColor(display, win_info, width, height, tif, image, date_time)
+     Display *display;
+     XWindowAttributes *win_info;
+     u_short width, height;
+     TIFF *tif;
+     XImage *image;
+     char *date_time;
+ {
+     int i, j, ncolors;
+     u_char *row_p, *scan_line;
+     u_short *rmap, *gmap, *bmap;
+     XColor *colors;
+ 
+     ncolors = win_info->visual->map_entries;
+     rmap = (u_short *) malloc(ncolors * sizeof(u_short));
+     gmap = (u_short *) malloc(ncolors * sizeof(u_short));
+     bmap = (u_short *) malloc(ncolors * sizeof(u_short));
+     colors = (XColor *) malloc(ncolors * sizeof(XColor));
+ 
+     for (i = 0; i < ncolors; i++) {
+         colors[i].pixel = i;
+         colors[i].pad = 0;
+     }
+ 
+     XQueryColors(display, win_info->colormap, colors, ncolors);
+ 
+     for (i = 0; i < ncolors; i++) {
+         rmap[i] = colors[i].red;
+         gmap[i] = colors[i].green;
+         bmap[i] = colors[i].blue;
+     }
+ 
+     TIFFSetField(tif, TIFFTAG_IMAGEWIDTH,           width);
+     TIFFSetField(tif, TIFFTAG_IMAGELENGTH,          height);
+     TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE,        8);
+     TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL,      1);
+     TIFFSetField(tif, TIFFTAG_PLANARCONFIG,         PLANARCONFIG_CONTIG);
+     TIFFSetField(tif, TIFFTAG_PHOTOMETRIC,          PHOTOMETRIC_PALETTE);
+     TIFFSetField(tif, TIFFTAG_COLORMAP,             rmap, gmap, bmap);
+     TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP,         1);
+     TIFFSetField(tif, TIFFTAG_SOFTWARE,             app_name);
+     TIFFSetField(tif, TIFFTAG_DATETIME,             date_time);
+     TIFFSetField(tif, TIFFTAG_COMPRESSION,          COMPRESSION_NONE);
+     TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT,       RESUNIT_NONE);
+ 
+     scan_line = (u_char *) malloc(width);
+ 
+     for (j = height - 1; j >= 0; j--) {
+         row_p = scan_line;
+         for (i = 0; i < width; i++)
+             *row_p++ = (u_char) XGetPixel(image, i, j);
+         TIFFWriteScanline(tif, scan_line, j, 0);
+     }
+ }
+ 
+ TIFFMono(display, win_info, width, height, tif, image, date_time)
+     Display *display;
+     XWindowAttributes *win_info;
+     u_short width, height;
+     TIFF *tif;
+     XImage *image;
+     char *date_time;
+ {
+     int i, j;
+     u_char *row_p, *scan_line;
+ 
+     TIFFSetField(tif, TIFFTAG_IMAGEWIDTH,           width);
+     TIFFSetField(tif, TIFFTAG_IMAGELENGTH,          height);
+     TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE,        1);
+     TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL,      1);
+     TIFFSetField(tif, TIFFTAG_PLANARCONFIG,         PLANARCONFIG_CONTIG);
+     TIFFSetField(tif, TIFFTAG_PHOTOMETRIC,          PHOTOMETRIC_MINISBLACK);
+     TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP,         1);
+     TIFFSetField(tif, TIFFTAG_SOFTWARE,             app_name);
+     TIFFSetField(tif, TIFFTAG_DATETIME,             date_time);
+     TIFFSetField(tif, TIFFTAG_COMPRESSION,          COMPRESSION_NONE);
+     TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT,       RESUNIT_NONE);
+ 
+     scan_line = (u_char *) malloc(width / 8);
+ 
+     for (j = height - 1; j >= 0; j--) {
+         row_p = scan_line;
+         for (i = 0; i < width / 8; i++)
+             *row_p++ = (u_char) XGetPixel(image, i, j);
+         TIFFWriteScanline(tif, scan_line, j, 0);
+     }
+ }
+ #endif
  
  #ifdef ATK
  write_atk_bytes (file, curbyte, curcount)
***************
*** 633,639 ****
      }
  }
  
- 
  process_atk_byte (pcurcount, pcurbyte, file, newbyte, eolflag)
  int *pcurcount;
  unsigned char *pcurbyte;
--- 887,892 ----
***************
*** 755,760 ****
--- 1008,1014 ----
  }
  #endif
  
+ #ifdef XWD
  #include "X11/XWDFile.h"
  
  save_as_xwd_file (display, screen, win_info, pixmap, width, height, depth)
***************
*** 874,879 ****
--- 1128,1134 ----
       */
      XDestroyImage(image);
  }
+ #endif
  
  #ifdef XPM
  #include "xpm.h"
***************
*** 1017,1026 ****
  	    else
  	      border_color_pixel = WhitePixel(the_display, the_screen);
  
- 
- 
- 
- 
  	    /*
  	     * get location of our window(from the window_geom_string),
  	     * and set up the size hints structure.
--- 1272,1277 ----
***************
*** 1157,1167 ****
--- 1408,1434 ----
  
  	if (xwd_output)
  	{
+ #ifdef XWD
  	    XGetWindowAttributes (the_display, window_to_snap,
  				  &window_attributes);
  	    save_as_xwd_file (the_display, the_screen, &window_attributes,
snap_pixmap, reg_width, reg_height, reg_depth);
+ #else
+ 	    printf("This version of xsnap has not be compiled with the XWD
feature,\n");
+ 	    printf("recompile with XWD defined.\n");
+ #endif
  	}
  
+ 	if (tif_output)
+ 	  {
+ #ifdef TIF
+ 	    XGetWindowAttributes (the_display, window_to_snap,
+ 				  &window_attributes);
+ 	    save_as_tif_file (the_display, the_screen, &window_attributes,
snap_pixmap, reg_width, reg_height, reg_depth);
+ #else
+ 	    printf("This version of xsnap has not be compiled with the TIFF
feature,\n");
+ 	    printf("recompile with TIF defined.\n");
+ #endif
+ 	  }
  	if (atk_output)
  	  {
  #ifdef ATK
diff -c orig/xsnap.man new/xsnap.man
*** orig/xsnap.man	Thu Nov 15 04:20:53 1990
--- new/xsnap.man	Tue Mar 19 12:50:27 1991
***************
*** 13,18 ****
--- 13,19 ----
  [\|\fB-region\fR geometry\|] 
  [\|\fB-iconic\fR\|] 
  [\|\fB-nograb\fR\|] 
+ [\|\fB-tif\fR\|] 
  [\|\fB-atk\fR\|] 
  [\|\fB-xwd\fR\|] 
  [\|\fB-xpm\fR\|] 
***************
*** 53,58 ****
--- 54,68 ----
  .B \-nograb
  Do not grab the server during specification of region.
  .TP 8
+ .B \-tif
+ Store the pixmap as a TIFF 5.0 file.
+ This option handles 32 and 24-bit DirectColor and TrueColor X servers, 
+ 8-bit PseudoColor and StaticColor X servers,
+ and monochrome X servers.
+ The
+ .B -file
+ option is required.
+ .TP 8
  .B \-atk
  Store the pixmap as an Andrew Toolkit raster object to the output. 
Convert color to monochrome.
  .TP 8
***************
*** 66,72 ****
  Store the output in the file \fIfilename\fp.  Overwrite if it already exists.
  .TP 8
  .B \-noshow
! Do not display the pixmap in a window.  (Useful with -atk or -xwd).
  .TP 8
  .B \-name \fIname\fp
  Name for icon to be passed to window manager.
--- 76,82 ----
  Store the output in the file \fIfilename\fp.  Overwrite if it already exists.
  .TP 8
  .B \-noshow
! Do not display the pixmap in a window.  (Useful with -tif, -atk -xwd).
  .TP 8
  .B \-name \fIname\fp
  Name for icon to be passed to window manager.
***************
*** 82,87 ****
--- 92,99 ----
  Since it creates a pixmap for each snapshot,  it can chew up server
memory very fast.
  .br
  The icongeometry option  doesn't know about icon sizes.
+ .SH SEE ALSO
+ xtiff(1X), tiff2ps(1)
  .SH AUTHORS
  Original version: Clauss Strauch
  .br