From: jan@math.chalmers.se (Jan Stein)
Newsgroups: comp.soft-sys.khoros
Subject: Re: Problems with putimage and images with maps
Date: 6 Apr 92 11:01:16 GMT
Article-I.D.: pprg.37285

> 
> I have a 8 bit display and want to display images of type INTEGER
> without loosing the posibility to get the correct value of the pixels.
> The image has a BYTE map and mapping the data would produce a correct
> BYTE image.
> 
> When I start putimage with the option "colormap used" and putimage tells
> me that it has to convert the image to BYTE. The image displayed by
> putimage after the conversion is all black. The value of the pixels is
> printed correct. 
> 
> Who can help me?

I had the same problem three weeks ago. I had a 16-bit image with and a
colourmap 16 -> 8. I tested editimage with no luck and then looked through
the source code discovering that it only displays byte images. So I made
the following modifications to the xvdisplay and vipl library so that any
diplay program that finds a SHORT or an INTEGER image with a BYTE colourmap
and map_enable = VFF_MAP_OPTIONAL uses that colourmap for displaying.
To apply the patch use Larry Wall's patch program and do:

% cd $KHOROS_HOME
% patch -p < This_letter
Recompile the system!

I've used this scheme for a couple of weeks now and it seems to work. 
This patch expands the lvmapdata routine to handle SHORT data but the
vmapdata and the doc aren't updated accordingly (Sorry, I haven't had the
time to do this).

	Jan Stein
	Radio & Space Science
	Chalmers University of Technology
	E-mail: jan@rss.chalmers.se

----------------------------------------------------------
*** src/xvroutines/Lib/xvdisplay/image.c.orig	Mon Mar 30 16:48:32 1992
--- src/xvroutines/Lib/xvdisplay/image.c	Mon Mar 30 16:56:10 1992
***************
*** 175,180 ****
--- 175,207 ----
  
  
  	/*
+ 	 *  First check if there is a color map we can use for converting
+ 	 *  the image. Maybe we should ask the user before doing this?
+ 	 */
+ 	if (xvdisplay->image->map_storage_type == VFF_MAPTYP_1_BYTE)
+ 	{
+ 	    if (xvdisplay->image->map_enable == VFF_MAP_FORCE)
+ 	        image = xvdisplay->image;
+ 	    else if ((image = copyimage(xvdisplay->image)) != NULL)
+ 		xvdisplay->disp_image = image;
+ 	    else
+ 	    {
+ 		xvf_error_wait("Warning!  Unable to make a copy of the original \
+ image.  The original image has been converted instead, which will be reflected \
+ when examining the image data.", "xvd_convert_image", NULL);
+ 	        image = xvdisplay->image;
+ 	    }
+ 
+ 	    if (!lvmapdata(image))
+ 	    {
+ 		xvf_error_wait("lvmapdata failed!  Unable to map image.",
+ 			       "xvd_convert_image", NULL);
+ 		return FALSE;
+ 	    }
+ 	    return TRUE;
+ 	}
+ 	    
+ 	/*
  	 *  Need to inform the user that the image is not in a displayable
  	 *  format and see if they wish to continue.  We also need to prompt
  	 *  them for the scale and normalization factor.
***************
*** 183,212 ****
  	 */
  	if (first)
  	{
!            (void) sprintf(mesg, "Can only display BYTE images.  Do you wish \
  to convert the image?... the image will be normalized to 255.\n\nnote: if you \
  answer yes then images will be automatically converted from now on");
! 
! 	   if (!xvf_warn_wait(mesg, "xvd_convert_image", "Yes", "No"))
! 	      return(FALSE);
! 	   else
! 	      first = False;
  	}
! 
  	/*
  	 *  Call lvconvert() to convert the image to byte format and
  	 *  normalization factor of 255.
  	 */
  	if ((image = copyimage(xvdisplay->image)) == NULL)
! 	   image = xvdisplay->image;
  	else
! 	   xvdisplay->disp_image = image;
! 
  	if (!lvconvert(image, VFF_TYP_1_BYTE, True, False, 255.0, 1.0, False))
  	{
! 	   xvf_error_wait("lvconvert failed!  Unable to convert image.",
! 			  "xvd_convert_image", NULL);
! 	   return(FALSE);
  	}
  
  	/*
--- 210,239 ----
  	 */
  	if (first)
  	{
! 	    (void) sprintf(mesg, "Can only display BYTE images.  Do you wish \
  to convert the image?... the image will be normalized to 255.\n\nnote: if you \
  answer yes then images will be automatically converted from now on");
! 	    
! 	    if (!xvf_warn_wait(mesg, "xvd_convert_image", "Yes", "No"))
! 		return(FALSE);
! 	    else
! 		first = False;
  	}
! 	
  	/*
  	 *  Call lvconvert() to convert the image to byte format and
  	 *  normalization factor of 255.
  	 */
  	if ((image = copyimage(xvdisplay->image)) == NULL)
! 	    image = xvdisplay->image;
  	else
! 	    xvdisplay->disp_image = image;
! 	
  	if (!lvconvert(image, VFF_TYP_1_BYTE, True, False, 255.0, 1.0, False))
  	{
! 	    xvf_error_wait("lvconvert failed!  Unable to convert image.",
! 			   "xvd_convert_image", NULL);
! 	    return(FALSE);
  	}
  
  	/*
*** src/vipl/Lib/lvmapdata.c.orig	Wed Feb 19 17:49:28 1992
--- src/vipl/Lib/lvmapdata.c	Thu Feb 20 12:36:35 1992
***************
*** 120,134 ****
  {
          int i, j, k, imgsize;
          int map_rows, map_cols,*idataptr;
!         unsigned char *bptr, *newdata_char, *btmpmap, *bdataptr,*bmap;
!         short *sptr, *newdata_short, *stmpmap,*smap;
!         long *lptr, *newdata_long, *ltmpmap,*lmap;
!         float *fptr, *newdata_float, *ftmpmap,*fmap;
          char *program = "lvmapdata";
  
               /* make some checks -- must have a map_scheme, the input image
!               * must be of type BYTE or INT, and the input must contain only 1
!               * image.                                                        */
   
          if (image->map_scheme  == VFF_MS_NONE)
          {
--- 120,134 ----
  {
          int i, j, k, imgsize;
          int map_rows, map_cols,*idataptr;
!         unsigned char *bptr, *newdata_char, *btmpmap, *bdataptr, *bmap;
!         short *sptr, *newdata_short, *stmpmap, *sdataptr, *smap;
!         long *lptr, *newdata_long, *ltmpmap, *lmap;
!         float *fptr, *newdata_float, *ftmpmap, *fmap;
          char *program = "lvmapdata";
  
               /* make some checks -- must have a map_scheme, the input image
!               * must be of type BYTE,SHORT or INT, and the input must contain
!               * only 1 image.                                                */
   
          if (image->map_scheme  == VFF_MS_NONE)
          {
***************
*** 137,145 ****
             return(0);
          }
          if (! (propertype(program,image,VFF_TYP_1_BYTE,FALSE) ||
                 propertype(program,image,VFF_TYP_4_BYTE,FALSE))) {
             (void) fprintf(stderr,"\n\nlvmapdata:   ");
!            (void) fprintf(stderr,"Input image must be of type BYTE or INTEGER\n\n");
             return(0);
          }
          if (! (proper_num_images(program,image,1,FALSE)))
--- 137,146 ----
             return(0);
          }
          if (! (propertype(program,image,VFF_TYP_1_BYTE,FALSE) ||
+                propertype(program,image,VFF_TYP_2_BYTE,FALSE) ||
                 propertype(program,image,VFF_TYP_4_BYTE,FALSE))) {
             (void) fprintf(stderr,"\n\nlvmapdata:   ");
!            (void) fprintf(stderr,"Input image must be of type BYTE, SHORT or INTEGER\n\n");
             return(0);
          }
          if (! (proper_num_images(program,image,1,FALSE)))
***************
*** 175,185 ****
--- 176,190 ----
                        for (j=0; j<map_rows; j++) {
                           bdataptr = (unsigned char *) 
                                  (&image->imagedata[i*imgsize]);
+                          sdataptr = (short *)bdataptr; 
                           idataptr = (int *)bdataptr; 
                           btmpmap = bmap+i*map_cols*map_rows+j*map_cols;
                          if (image->data_storage_type == VFF_TYP_1_BYTE)
                            for (k=0; k<imgsize; k++)
                              *bptr++ = btmpmap[*bdataptr++];
+                         else if (image->data_storage_type == VFF_TYP_2_BYTE)
+                           for (k=0; k<imgsize; k++)
+                             *bptr++ = btmpmap[*sdataptr++];
                          else
                            for (k=0; k<imgsize; k++)
                              *bptr++ = btmpmap[*idataptr++];
***************
*** 194,204 ****
--- 199,213 ----
                       for (j=0; j<map_rows; j++) {
                         bdataptr = (unsigned char *) 
                                    (&image->imagedata[i*imgsize]);
+                        sdataptr = (short *)bdataptr; 
                         idataptr = (int *)bdataptr; 
                         btmpmap = bmap+j*map_cols;
                         if (image->data_storage_type == VFF_TYP_1_BYTE)
                           for (k=0; k<imgsize; k++)
                             *bptr++ = btmpmap[*bdataptr++];
+                        else if (image->data_storage_type == VFF_TYP_2_BYTE)
+                          for (k=0; k<imgsize; k++)
+                            *bptr++ = btmpmap[*sdataptr++];
                         else
                           for (k=0; k<imgsize; k++)
                             *bptr++ = btmpmap[*idataptr++];
***************
*** 232,242 ****
--- 241,255 ----
                        for (j=0; j<map_rows; j++) {
                          bdataptr = (unsigned char *) 
                                     (&image->imagedata[i*imgsize]);
+                         sdataptr = (short *)bdataptr; 
                          idataptr = (int *)bdataptr; 
                          stmpmap = smap+i*map_cols*map_rows+j*map_cols;
                          if (image->data_storage_type == VFF_TYP_1_BYTE)
                            for (k=0; k<imgsize; k++)
                              *sptr++ = stmpmap[*bdataptr++];
+                         else if (image->data_storage_type == VFF_TYP_2_BYTE)
+                           for (k=0; k<imgsize; k++)
+                             *sptr++ = stmpmap[*sdataptr++];
                          else
                            for (k=0; k<imgsize; k++)
                              *sptr++ = stmpmap[*idataptr++];
***************
*** 251,261 ****
--- 264,278 ----
                       for (j=0; j<map_rows; j++) {
                            bdataptr = (unsigned char *) 
                                     (&image->imagedata[i*imgsize]);
+                           sdataptr = (short *)bdataptr; 
                            idataptr = (int *)bdataptr; 
                            stmpmap = smap+j*map_cols;
                         if (image->data_storage_type == VFF_TYP_1_BYTE)
                           for (k=0; k<imgsize; k++)
                             *sptr++ = stmpmap[*bdataptr++];
+                        else if (image->data_storage_type == VFF_TYP_2_BYTE)
+                          for (k=0; k<imgsize; k++)
+                            *sptr++ = stmpmap[*sdataptr++];
                         else
                           for (k=0; k<imgsize; k++)
                             *sptr++ = stmpmap[*idataptr++];
***************
*** 289,299 ****
--- 306,320 ----
                        for (j=0; j<map_rows; j++) {
                           bdataptr = (unsigned char *) 
                                     (&image->imagedata[i*imgsize]);
+                          sdataptr = (short *)bdataptr;
                           idataptr = (int *)bdataptr;
                           ltmpmap = lmap+i*map_cols*map_rows+j*map_cols;
                           if (image->data_storage_type == VFF_TYP_1_BYTE)
                             for (k=0; k<imgsize; k++)
                               *lptr++ = ltmpmap[*bdataptr++];
+                          else  if (image->data_storage_type == VFF_TYP_2_BYTE)
+                            for (k=0; k<imgsize; k++)
+                              *lptr++ = ltmpmap[*sdataptr++];
                           else
                             for (k=0; k<imgsize; k++)
                               *lptr++ = ltmpmap[*idataptr++];
***************
*** 308,318 ****
--- 329,343 ----
                       for (j=0; j<map_rows; j++) {
                            bdataptr = (unsigned char *) 
                                     (&image->imagedata[i*imgsize]);
+                           sdataptr = (short *)bdataptr; 
                            idataptr = (int *)bdataptr; 
                            ltmpmap = lmap+j*map_cols;
                            if (image->data_storage_type == VFF_TYP_1_BYTE)
                              for (k=0; k<imgsize; k++)
                                *lptr++ = ltmpmap[*bdataptr++];
+                           else if (image->data_storage_type == VFF_TYP_2_BYTE)
+                             for (k=0; k<imgsize; k++)
+                               *lptr++ = ltmpmap[*sdataptr++];
                            else
                              for (k=0; k<imgsize; k++)
                                *lptr++ = ltmpmap[*idataptr++];
***************
*** 346,356 ****
--- 371,385 ----
                        for (j=0; j<map_rows; j++) {
                           bdataptr = (unsigned char *) 
                                     (&image->imagedata[i*imgsize]);
+                          sdataptr = (short *)bdataptr; 
                           idataptr = (int *)bdataptr; 
                           ftmpmap = fmap+i*map_cols*map_rows+j*map_cols;
                          if (image->data_storage_type == VFF_TYP_1_BYTE)
                            for (k=0; k<imgsize; k++)
                              *fptr++ = ftmpmap[*bdataptr++];
+                         else if (image->data_storage_type == VFF_TYP_2_BYTE)
+                           for (k=0; k<imgsize; k++)
+                             *fptr++ = ftmpmap[*sdataptr++];
                          else
                            for (k=0; k<imgsize; k++)
                              *fptr++ = ftmpmap[*idataptr++];
***************
*** 365,375 ****
--- 394,408 ----
                       for (j=0; j<map_rows; j++) {
                            bdataptr = (unsigned char *) 
                                     (&image->imagedata[i*imgsize]);
+                           sdataptr = (short *)bdataptr; 
                            idataptr = (int *)bdataptr; 
                            ftmpmap = fmap+j*map_cols;
                         if (image->data_storage_type == VFF_TYP_1_BYTE)
                           for (k=0; k<imgsize; k++)
                             *fptr++ = ftmpmap[*bdataptr];
+                        else if (image->data_storage_type == VFF_TYP_2_BYTE)
+                          for (k=0; k<imgsize; k++)
+                            *fptr++ = ftmpmap[*sdataptr];
                         else
                           for (k=0; k<imgsize; k++)
                             *fptr++ = ftmpmap[*idataptr];