From: daniel.albrecht@jrc.it (Daniel Albrecht)
Newsgroups: comp.soft-sys.khoros
Subject: Graphics with Khoros message #3
Date: 16 Dec 92 13:58:14 GMT
Article-I.D.: pprg.42187


Hello,

        As a still new Khoros user, I wrote some Vroutines which are working
fine.
I am interested in writing HYBRID GRAPHICS(NON interactive) routines.
This to be able to superimpose on B/W (8 bits/pixels)images, overlay
graphics.
Khoros documentation ENCOURAGES users to do so !!!!!!!!!!!!!!!!!!!!!!!!!!!!!

I use a Sun4 standard machine (O.S. (4.1.2)) + Khoros(1.0) + Fortran(1.5)
I know very well 'C' language but I am NOT that used to Xwindows
programming.

<<<<<<< THIS MY 3rd MESSAGE ABOUT GRAPHICS WITH KHOROS >>>>>>>>

!!! Attention !!!
Sun4 openwindows allocates 20 colors for its own business.
I use ONLY 128 gray levels to display my (512*512) B/W images.
I have with the Sun4 ONLY 256 colors(gray-levels) within my
UNIQUE hardware colormap.

Hardware colormap:
      --------------------------------------------
      |  20 colors for openwindows               |
      --------------------------------------------
      |  128 colors(gray levels) for my image(s) |
      --------------------------------------------
      | 108 colors free for further needs        |
      --------------------------------------------

Total : 256 levels

I would like to :
        1) to display simulatenously in my program 2 images.
               - 1 source image.
               - 1 destination image.
        2) to be able to add some graphics on the source image.
        3) to be able to add some graphics and modify the pixels
           on the destination image.

Problems:
        1) I use (2 times of course for both (src,dst) images
           the <<< xvd_create_xvdisplay() >>> function with
                private_cmap = True
                read_only = True
           if read_only is False, Khoros allocates another 128 colors
           packet saturating the 108 remaining available colors.
           Then read_only MUST be True.

     a) Having a look to the short following program,
        I can modify pixels but if I use <<< xvd_update_... >>>
        pixels are of course updated BUT :
                It is impossible to draw colored lines within the
                updated region afterwards ?!?!?!?!?!?!?????????????????
     b) Having a look to the short following program,
        If I do NOT modify pixels it is possible to draw colored lines.
        Therefore I can NOT modify simulaneously pixels & graphics ?????

Here is the short program :

-authors
Albrecht Daniel
-authors_end

-short_prog_descrip9tion
-short_prog_description_end

-short_lib_description
-short_lib_description_end

-man1_long_description
-man1_long_description_end

-man1_examples
-man1_examples_end

-man1_restrictions
-man1_restrictions_end

-man1_see_also
-man1_see_also_end

-man3_long_description
-man3_long_description_end

-man3_restrictions
-man3_restrictions_end

-man3_see_also
-man3_see_also_end

-usage_additions
-usage_additions_end

-include_includes
#include "xvdisplay.h"
#include "xvforms.h"
#include "xvgraphics.h"
#include "xvutils.h"
-include_includes_end

-include_additions
int      PUTIMAGE_DONE;
DisplayStructure        *xvdisplay;
Display                 *display;
XColor  da_col[30];
XColor  yellow, re9d;
int     s_id, d_id;
Coord   line_start, line_end, point_s;
struct  xvimage  *n_im, *src_im;
DisplayStructure *xvresult;
struct  xvimage  *result;
int    status, screen;
Window window;
-include_additions_end

-include_macros
#define READINPUT(image) \
image = readimage(vtst1->i_file);  \
if (image == NULL) {  \
   (void) fprintf(stderr, "vtst1: Can not read input image \n");  \
   exit(1);  /* Quit if bad image */ \
}
#define CHECKINPUT(program, image) \
    proper_num_images(program,image,1,TRUE);  \
    proper_map_enable(program,image,VFF_MAP_OPTIONAL,TRUE); \
    \
    (void) proper_loc_type(program,image,VFF_LOC_IMPLICIT,TRUE)
-include_macros_end

-main_variable_list
struct xvimage *image, *readimage();
-main_variable_list_end

-main_before_lib_call
        if (check_args()) exit(1);

        READINPUT(image) ;
        CHECKINPUT(program, image) ;
-main_before_lib_call_end

-main_library_call
        if(! lvtst1(image))
        {
                (void) fprintf(stderr, "vtst1: lvtst1 Failed\n");
                exit(1);
        }
-main_library_call_end
                 9
-main_after_lib_call
-main_after_lib_call_end

-library_includes
#include        "vtst1.h"
-library_includes_end

-library_input
-library_input_end

-library_output
-library_output_end

-library_def
int lvtst1(img)
struct xvimage *img;

-library_def_end

-library_code
{
unsigned long mask;
void    vtst1_exit();
int     n, c, count;
struct xvimage  *create_pixmap_image(), *create_bitmap_image();


        display = xvf_initialize(ac,av,program);
        if (display == NULL)
        {
             fprintf(stderr, "Could not open connection to server");
             exit(0);
        }

        xvd_initialize(display);
        remove_colormap(img);

        /* Input (source) image is in memory --> display it */
        xvdisplay = xvd_create_xvdisplay(display, img, NULL, NULL, NULL,
                                True, True, "source", 1, 1, True);
        if (xvdisplay == NULL) return(FALSE);
                9
        /* create (destination) image in memory */
        result = createimage( img->row_size,
                          img->col_size,
                          VFF_TYP_1_BYTE,
                          1,
                          img->num_data_bands,
                          "created by vtst1",
                          0,
                          0,
                          VFF_MS_NONE,
                          VFF_MAPTYP_NONE,
                          VFF_LOC_IMPLICIT,
                          0);

        if (result == NULL)
          {
          (void) fprintf(stderr,"lvtst1: Unable to allocate enough memory
for output image!\n");
          return(0);
          }

        result->pixsizx = img->pixsizx;
        result->pixsizy = img->pixsizy;

        transfer_colormap( img, result );

        /* copy (source) image data in destination image data */
        status = copyimagedata(img, &result, False);
        if (status == NULL)
          {
          (void) fprintf(stderr,"lvtst1: Unable to copy data to destination 
                           image!\n");
          return(0);
          }

        /*  (destination) image is in memory --> display it */
        xvresult = xvd_create_xvdisplay(display, result, NULL, NULL, NULL,
                                True, True, "destination", 550, 300, True);
        if (xvresult == NULL) return(FALSE);

        src_im = img;

        /* Graphics Application */

        s_id = 1;
        d_id = 2;

        line_start.x = 0.0;
        line_start.y = 0.0;

        /* in our case(512*512 pixel images), always of type ex.:
200.0/512.0 */
        line_end.x = 1.0;
        line_end.y = 1.0;

        /* prepare graphic ID for both source & destination images */
        X3D_init_graphics(s_id, X2D);
        X3D_set_X11(s_id, display, NULL, xvdisplay->raster);
        X3D_init_graphics(d_id, X2D);
        X3D_set_X11(d_id, display, NULL, xvresult->raster);

        /* Allocate YELLOW & RED colors for application */
        count = X3D_allocate_named_color(display, "yellow", &yellow, True,
X3D_WHITE);
        if(count)
          fprintf(stderr,"\nOK --> %d colour <YELLOW> is allocated\n",
count);
        else
          fputs("ERROR --> colour <YELLOW> is NOT allocated\n",stderr);

        count = X3D_allocate_named_color(display, "red", &red, True,
X3D_WHITE);
        if(count)
          fprintf(stderr,"OK --> %d colour <RED> is allocated\n", count);
        else
          fputs("ERROR --> colour <RED> is NOT allocated\n",stderr);

        /* End of Graphics Application */

        /*
         *  add event handler that will call putimage_exit() when the
         *  user clicks on the image
         */
        mask = ButtonPressMask | ButtonReleaseMask | KeyPressMask;
        XtInsertEventHandler(xvdisplay->raster, mask, False, vtst1_exit,
                        NULL, XtListTail);

        PUTIMAGE_DONE = False;
        while (!PUTIMAGE_DONE)
           xvf_process_event();      /* this does
XtNextEvent/DispatchEvent*/

        /*
         *  The user exits by clicking the mouse on the image widget
         */

        X3D_close_graphics(d_id);
        X3D_close_graphics(s_id);
        xvd_delete_xvdisplay(xvdisplay);
        XSync(display, 0); XCloseDisplay(display);

   return(TRUE);
}

void  vtst1_exit(widget, clientData, event, dispatch)
Widget  widget;                /* unused */
caddr_t clientData;            /* unused */
XEvent  *event;
Boolean *dispatch;
{
Coord   text_center;
Vector  text_dir;
static  int  occurence = 0;
char   character;
struct xvimage  *create_pixmap_image(), *create_bitmap_image();

        screen = XDefaultScreen(display);
        window = XtWindow(widget);

        if(occurence == 0 )
          {
          int sl, col_i;
          int x,y,i;
          unsigned char *ss, *dd;

          fputs("<<< START of fringes_extrema draw function >>>\n",stderr);

          /* Trace a red dashed line troughout source image */
          point_s.x = 0.0/512.0;
          point_s.y = 256.0/512.0;
          for( sl = 0 ; sl < 100 ; sl++ )
            {
            X2D_draw_line( s_id, point_s, point_s, &red );
            point_s.x += 5.0/512.0;
            }

        /* Modify some pixels at will and update to make them visible */
          dd = (unsigned char *) (result->imagedata);
          for( y = 256 ; y < 276 ; y++ )
            for( x = 0 ; x < 512 ; x++ )
              *(dd+x+y*512) = (unsigned char)0;
          xvd_update_region( xvresult, 0, 256, 512, 20 );

          /* Trace a yellow line troughout destination image */
          X2D_draw_line( d_id, line_start, line_end, &yellow );
          /* Trace a yellow dashed line troughout destination image */
          point_s.x = 511.0/512.0;
          point_s.y = 50.0/512.0;
          for( sl = 0 ; sl < 100 ; sl++ )
            {
            X2D_draw_line( d_id, point_s, point_s, &yellow );
            point_s.x -= 5.0/512.0;
            }

          fputs("<<< END of fringes_extrema draw function >>>\n",stderr);

          occurence += 1;
          return;
          }

/*      if(occurence == 1 )
          {
          int x,y,i;
          unsigned char *dd;

          fputs("<<< START of create PIXMAP function and Save
>>>\n",stderr);

          n_im = create_pixmap_image(display,screen,window,0,0,0,0,0);
          if( n_im == NULL )
            fputs("create PIXMAP function FAILED !!!\n",stderr);

          dd = (unsigned char *) (n_im->imagedata);
          for( i = 0 , y = 0 ; y < 512 ; y++ )
            for( x = 0 ; x < 512 ; x++, i++ )
              {
              unsigned char gr = *(dd+i);
              if( gr != 0x96 )
                *(dd+i) = (unsigned char)BlackPixel(display,screen);
              }

          xvd_update_image( xvdisplay, n_im );
          writeimage("gr0.tmp", n_im);

          fputs("<<< END create PIXMAP function and Save  >>>\n",stderr);
          occurence += 1;
          return;
          }
 */

        /*
         *  Add detect code to update when the image updates.
         */
        if (event->type == ButtonRelease)
        {
           PUTIMAGE_DONE = True;
        }
        else if (event->type == KeyPress)
        {
           if (XLookupString(&(event->xkey), &character, 1, NULL, NULL)  ==
0)
              return;

           switch (character)
           {
                case   3:
                case 'q':
                case 'Q':
                        PUTIMAGE_DONE = True;
                        break;
           }
        }
}


remove_colormap(image)
struct xvimage *image;
{
        if (image->maps != NULL) free(image->maps);
        image->maps              = NULL;
        image->map_storage_type  = VFF_MAPTYP_NONE;
        image->map_scheme        = VFF_MS_NONE;
        image->map_enable        = VFF_MAP_OPTIONAL;
        image->color_space_model = VFF_CM_NONE;
        image->map_row_size    =
        image->map_col_size    =
        image->map_subrow_size = 0;
}

transfer_colormap(cmap, image)
struct xvimage *cmap, *image;
{
        if (image->maps != NULL && image->map_row_size > 0)
            free(image->maps);

        image->map_scheme        = cmap->map_scheme;
        image->map_storage_type  = cmap->map_storage_type;
        image->map_row_size      = cmap->map_row_size;
        image->map_col_size      = cmap->map_col_size;
        image->map_subrow_size   = cmap->map_subrow_size;
        image->map_enable        = cmap->map_enable;
        image->maps_per_cycle    = cmap->maps_per_cycle;
        image->color_space_model = cmap->color_space_model;
        copymapdata(cmap, &image, TRUE);
}


-library_code_end

-library_mods
-library_mods_end


                     -------------------------
                     |       Questions       |
                     -------------------------

1) Is it a good way to use Khoros function ???
2) If yes, how can I modify pixels & graphics within the same
   image(simultaneoulsy) ???
3) Is it easily possible to UNdraw any graphic function ???

A rather quick answer will be much appreciated. Thanks.

Regards

-----------------------------------------------------------------
Albrecht daniel       Image Processing laboratory
daniel.albrecht@cen.jrc.it              ( E.E.C. - Europe )
-----------------------------------------------------------------