/* * Vis5D system for visualizing five dimensional gridded data sets. * Copyright (C) 1990 - 2000 Bill Hibbard, Johan Kellum, Brian Paul, * Dave Santek, and Andre Battaiola. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * As a special exception to the terms of the GNU General Public * License, you are permitted to link Vis5D with (and distribute the * resulting source and executables) the LUI library (copyright by * Stellar Computer Inc. and licensed for distribution with Vis5D), * the McIDAS library, and/or the NetCDF library, where those * libraries are governed by the terms of their own licenses. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include "../config.h" /* Dump the image in an X xindow to a .xwd file. * This code was extracted by Brian Paul from the xwd program which is * included with X11. The OMIT preprocessor identifier denotes regions * of code I've had to omit. */ /* from xwd.c: */ /* $XConsortium: xwd.c,v 1.56 91/07/25 18:00:15 rws Exp $ */ /* Copyright 1987 Massachusetts Institute of Technology */ /* * xwd.c MIT Project Athena, X Window system window raster image dumper. * * This program will dump a raster image of the contents of a window into a * file for output on graphics printers or for other uses. * * Author: Tony Della Fera, DEC * 17-Jun-85 * * Modification history: * * 11/14/86 Bill Wyatt, Smithsonian Astrophysical Observatory * - Removed Z format option, changing it to an XY option. Monochrome * windows will always dump in XY format. Color windows will dump * in Z format by default, but can be dumped in XY format with the * -xy option. * * 11/18/86 Bill Wyatt * - VERSION 6 is same as version 5 for monchrome. For colors, the * appropriate number of Color structs are dumped after the header, * which has the number of colors (=0 for monochrome) in place of the * V5 padding at the end. Up to 16-bit displays are supported. I * don't yet know how 24- to 32-bit displays will be handled under * the Version 11 protocol. * * 6/15/87 David Krikorian, MIT Project Athena * - VERSION 7 runs under the X Version 11 servers, while the previous * versions of xwd were are for X Version 10. This version is based * on xwd version 6, and should eventually have the same color * abilities. (Xwd V7 has yet to be tested on a color machine, so * all color-related code is commented out until color support * becomes practical.) */ /* * The following XCOLOR struct is to be used in place of X's XColor * struct because on 32-bit systems, sizeof(XColor)=12 while on 64-bit * systems, sizeof(XColor)=16. We MUST have an XColor struct of size * 12 so a correct file is written. BEP July-21-95 */ typedef struct { unsigned int /*long*/ pixel; unsigned short red, green, blue; char flags; /* do_red, do_green, do_blue */ char pad; } XCOLOR; #include #include #include #include #include #include #include static Bool debug = False; static Bool nobdrs = False; static Bool on_root = False; static Bool use_installed = False; static long add_pixel_value = 0; static int format = ZPixmap; static Display *dpy; static char *program_name = "xdump"; static int screen; typedef unsigned long Pixel; /* * outl: a debugging routine. Flushes stdout then prints a message on stderr * and flushes stderr. Used to print messages when past certain points * in code so we can tell where we are. Outl may be invoked like * printf with up to 7 arguments. */ /* VARARGS1 */ static void outl( char *msg ) { fflush(stdout); fprintf(stderr, "%s\n", msg ); fflush(stderr); } /* * Standard fatal error routine - call like printf but maximum of 7 arguments. * Does not require dpy or screen defined. */ /* VARARGS1 */ static void Fatal_Error( char *msg ) { fflush(stdout); fflush(stderr); fprintf(stderr, "%s: error: %s\n", program_name, msg); exit(1); } /* * Determine the pixmap size. */ static int Image_Size( XImage *image ) { if (image->format != ZPixmap) return(image->bytes_per_line * image->height * image->depth); return(image->bytes_per_line * image->height); } #define lowbit(x) ((x) & (~(x) + 1)) /* * Get the XColors of all pixels in image - returns # of colors */ static int Get_XColors( XWindowAttributes *win_info, XColor **colors ) { int i, ncolors; Colormap cmap = win_info->colormap; if (use_installed) /* assume the visual will be OK ... */ cmap = XListInstalledColormaps(dpy, win_info->root, &i)[0]; if (!cmap) return(0); ncolors = win_info->visual->map_entries; if (!(*colors = (XColor *) malloc (sizeof(XColor) * ncolors))) Fatal_Error("Out of memory!"); if (win_info->visual->class == DirectColor || win_info->visual->class == TrueColor) { Pixel red, green, blue, red1, green1, blue1; red = green = blue = 0; red1 = lowbit(win_info->visual->red_mask); green1 = lowbit(win_info->visual->green_mask); blue1 = lowbit(win_info->visual->blue_mask); for (i=0; i win_info->visual->red_mask) red = 0; green += green1; if (green > win_info->visual->green_mask) green = 0; blue += blue1; if (blue > win_info->visual->blue_mask) blue = 0; } } else { for (i=0; i dwidth) width = dwidth - absx; if (absy + height > dheight) height = dheight - absy; XFetchName(dpy, window, &win_name); if (!win_name || !win_name[0]) { win_name = "xwdump"; got_win_name = False; } else { got_win_name = True; } /* sizeof(char) is included for the null string terminator. */ win_name_size = strlen(win_name) + sizeof(char); /* * Snarf the pixmap with XGetImage. */ x = absx - win_info.x; y = absy - win_info.y; if (on_root) image = XGetImage (dpy, RootWindow(dpy, screen), absx, absy, width, height, AllPlanes, format); else image = XGetImage (dpy, window, x, y, width, height, AllPlanes, format); if (!image) { fprintf (stderr, "%s: unable to get image at %dx%d+%d+%d\n", program_name, width, height, x, y); exit (1); } if (add_pixel_value != 0) XAddPixel (image, add_pixel_value); /* * Determine the pixmap size. */ buffer_size = Image_Size(image); if (debug) outl("xwd: Getting Colors.\n"); ncolors = Get_XColors(&win_info, &colors); /* * Inform the user that the image has been retrieved. */ #ifdef OMIT XBell(dpy, FEEP_VOLUME); XBell(dpy, FEEP_VOLUME); #endif XFlush(dpy); /* * Calculate header size. */ if (debug) outl("xwd: Calculating header size.\n"); header_size = sizeof(header) + win_name_size; /* * Write out header information. */ if (debug) outl("xwd: Constructing and dumping file header.\n"); header.header_size = (CARD32) header_size; header.file_version = (CARD32) XWD_FILE_VERSION; header.pixmap_format = (CARD32) format; header.pixmap_depth = (CARD32) image->depth; header.pixmap_width = (CARD32) image->width; header.pixmap_height = (CARD32) image->height; header.xoffset = (CARD32) image->xoffset; header.byte_order = (CARD32) image->byte_order; header.bitmap_unit = (CARD32) image->bitmap_unit; header.bitmap_bit_order = (CARD32) image->bitmap_bit_order; header.bitmap_pad = (CARD32) image->bitmap_pad; header.bits_per_pixel = (CARD32) image->bits_per_pixel; header.bytes_per_line = (CARD32) image->bytes_per_line; header.visual_class = (CARD32) win_info.visual->class; header.red_mask = (CARD32) win_info.visual->red_mask; header.green_mask = (CARD32) win_info.visual->green_mask; header.blue_mask = (CARD32) win_info.visual->blue_mask; header.bits_per_rgb = (CARD32) win_info.visual->bits_per_rgb; header.colormap_entries = (CARD32) win_info.visual->map_entries; header.ncolors = ncolors; header.window_width = (CARD32) win_info.width; header.window_height = (CARD32) win_info.height; header.window_x = absx; header.window_y = absy; header.window_bdrwidth = (CARD32) win_info.border_width; if (*(char *) &swaptest) { _swaplong((char *) &header, sizeof(header)); for (i = 0; i < ncolors; i++) { _swaplong((char *) &colors[i].pixel, sizeof(long)); _swapshort((char *) &colors[i].red, 3 * sizeof(short)); } } (void) fwrite((char *)&header, sizeof(header), 1, out); (void) fwrite(win_name, win_name_size, 1, out); /* * Write out the color maps, if any */ /*if (debug) outl("xwd: Dumping %d colors.\n", ncolors);*/ for (i=0;idata, (int) buffer_size, 1, out); /* * free the color buffer. */ if(debug && ncolors > 0) outl("xwd: Freeing colors.\n"); if(ncolors > 0) free(colors); /* * Free window name string. */ if (debug) outl("xwd: Freeing window name string.\n"); if (got_win_name) XFree(win_name); /* * Free image */ XDestroyImage(image); }