[comp.windows.x] need help using Xlib to zoom images

chapman@lll-crg.llnl.gov (Carol Chapman) (02/17/90)

I am using X11R3 and Athena widgets on a SUN 3/110 running O/S 4.0.3.
I have hacked Clauss Strauch's xsnap.c code so that a user may select
a portion of the screen with the mouse, and a pixmap of that area is
returned.  I then use XGetImage to store an image of that pixmap, then
I use XGetPixel to copy each pixmap value to 4 separate locations in a
data array, then I use XCreateImage to create a new "zoomed" image
twice the size of the original image.  This is stored in a Core widget
and displayed in a popup window.  Something is going wrong -> the
image is appearing at a 90 degree angle from how it should appear,
plus it's backwards and sometimes extra garbage appears!  A definite
problem!  

For both the original image and the zoomed image, the XImage
structures are set as follows:  xoffset = 0, format = ZPixmap,
byte_order = 1, bitmap_unit = 8, bitmap_bit_order = 1, bitmap_pad = 8,
depth = 8, bits_per_pixel = 8.  These are all the default values,
except for bitmap_unit and bitmap_pad which default to 32 and which I
am resetting to 8.

Can anyone give me any advice as to what I'm doing wrong and/or how to
do this correctly?  Relevant portions of my code are included below
for anyone interested.  

thank you,
carol chapman (chapman@lll-crg.llnl.gov)
----------------------------------------------------------------------

  window_to_zoom = XtWindow(toplevel);
  orig_gc_values.subwindow_mode = IncludeInferiors;
  orig_gc_valuemask = GCSubwindowMode;
  orig_gc = XCreateGC(disp, window_to_zoom, orig_gc_valuemask, 
		      &orig_gc_values);
  XGrabServer(disp);
  XSync(disp, 0);
  orig_pixmap = get_pixmap_region(window_to_zoom, orig_gc, orig_width, 
				  orig_height);
  XUngrabServer(disp);    /* ungrab the server */
  orig_image = XGetImage(disp, orig_pixmap, 0, 0,
			 *orig_width, *orig_height, AllPlanes, ZPixmap);
  orig_image->bitmap_unit = 8;
  orig_image->bitmap_pad = 8;

  .
  .
  .

  /* set zoomed image width, height and total area */
  zoom_width = 2 * orig_width;
  zoom_height = 2 * orig_height;
  zoom_size = zoom_width * zoom_height;
  zoom_ptr = (unsigned char *) calloc(zoom_size, sizeof(unsigned char));
  temp_ptr = zoom_ptr;  /* let temp_ptr point at beginning of zoom_ptr */
  /* fill the area pointed to by zoom_ptr with correct pixel values */
  for (row = 0; row < orig_height; row++)
      /* for every row of orig_image */
      for (col = 0; col < orig_width; col++)  {
	  /* for every column of orig_image */
	  pix_value = XGetPixel(orig_image, row, col);
	  if (pix_value > 255)
	     pix_value = 255;
	  *temp_ptr = (unsigned char) pix_value;
	  *(temp_ptr + 1) = (unsigned char) pix_value;
	  *(temp_ptr + zoom_width) = (unsigned char) pix_value;
	  *(temp_ptr + zoom_width + 1) = (unsigned char) pix_value;
	  temp_ptr += 2;
      }  /* of for */
  XDestroyImage(orig_image);
  num_args = 0;  /* reset */
  XtSetArg(args[num_args], XtNborderWidth, 0); num_args++;
  XtSetArg(args[num_args], XtNheight, zoom_height); num_args++;
  XtSetArg(args[num_args], XtNwidth, zoom_width); num_args++;     
  if (zoom_core != NULL)  /* the widget already exists */  {
     XtSetValues(zoom_core, args, num_args);
     XtManageChild(zoom_core);
  }  /* of if */
  else  /* create the widget */
     zoom_core = XtCreateManagedWidget("zoomCore", widgetClass,
				       zoom_viewport, args, num_args);
  zoom_image = XCreateImage(disp, vis, depth, ZPixmap, 0, zoom_ptr, 
			    zoom_width, zoom_height, BitmapPad(disp),
			    zoom_width);
  zoom_image->bitmap_unit = 8;
  zoom_image->bitmap_pad = 8;
  XtPopup(popup_zoom_shell);
  win = XtWindow(zoom_core);
  zoom_gc = XtGetGC(zoom_core, GCForeground | GCBackground, 
		    &gc_values);
  zoom_pixmap = XCreatePixmap(disp, win, zoom_width, zoom_height, depth);
  XSetWindowBackgroundPixmap(disp, win, zoom_pixmap);
  XPutImage(disp, zoom_pixmap, zoom_gc, zoom_image, 0, 0, 0, 0, 
	    zoom_width, zoom_height);
  XClearWindow(disp, win);
  cfree((unsigned char *) zoom_ptr);

  .
  .
  .

rws@EXPO.LCS.MIT.EDU (Bob Scheifler) (03/01/90)

    Something is going wrong -> the
    image is appearing at a 90 degree angle from how it should appear,

You are doing

	  pix_value = XGetPixel(orig_image, row, col);

but it's really XGetPixel(ximage, x, y); you have the args reversed.

    plus it's backwards and sometimes extra garbage appears!

You are arbitrarily smashing bitmap_unit and bitmap_pad; that's not
a reasonable thing to do for the source image.