v10i092: xloadimage, Patch2, Part01/01

jimf at saber.com jimf at saber.com
Mon Dec 17 06:24:04 AEST 1990


Submitted-by: jimf at saber.com
Posting-number: Volume 10, Issue 92
Archive-name: xloadimage/patch2
Patch-To: xloadimage: Volume 10, Issue 48-56, 64

This file contains a patch to bring xloadimage version 2.01 up to
version 2.02.

Version 2.02 contains the following bug-fixes and enhancements:

	* low-level byte order conversion routines have been
	  macro-ized for the most common case for dramatic speed
	  improvements.
	* -onroot is now compatible with xsetroot.
	* Dithering and halftoning have been sped up somewhat.
	* RLE files now load on MSBFirst machines.
	* Window.c no longer double-paints in some circumstances.
	* Some XWD files that loaded with the wrong colormap will now
	  load correctly.
	* G3 FAX files now load and are differentiated from MacPaint
	  files.
	* A bug where servers whose depths were not 1 or multiples of
	  8 bits would not load images which used the default colormap
	  was fixed.  If you had color problems under 2.x and not
	  under 1.6, this fixes the problem.
	* The default gamma value was changed to 1.0 as documented.
	* A simple normalization function, -normalize, was added.
	* A grayscale conversion function, -gray, was added.
	* An option to load the root weave, -default, was added.

Enjoy,

jim frost
saber software
jimf at saber.com

-- cut here --
diff -c src.2.01/Makefile src.2.02/Makefile
*** src.2.01/Makefile	Mon Oct  1 14:28:52 1990
--- src.2.02/Makefile	Sat Dec  1 14:38:46 1990
***************
*** 156,161 ****
--- 156,167 ----
  	tar cf xloadimage.tar $(ALL)
  	rm Makefile.std
  
+ # target for building debuggable versions
+ 
+ debug:
+ 	@echo Building a debugging version of xloadimage.
+ 	make xloadimage CC=$(STD_CC) CFLAGS="-g -DSYSPATHFILE=\\\"$(SYSPATHFILE)\\\""
+ 
  # these targets are for those of us who have Saber-C
  
  # load all objects in saber.  useful if you then swap the portions to debug
diff -c src.2.01/README src.2.02/README
*** src.2.01/README	Sun Sep 30 19:08:48 1990
--- src.2.02/README	Sun Dec  2 14:13:04 1990
***************
*** 156,162 ****
  (gwh at inmos.com) for a geometry patch, Glenn P. Davis
  (davis at unidata.ucar.edu) for McIDAS areafile support, Keith S. Pickens
  (maxwell.nde.swri.edu!ksp) for fixing the RLE loader to work with the
! updated zio package, and any others whose names I've missed.
  
  HISTORY
  
--- 156,164 ----
  (gwh at inmos.com) for a geometry patch, Glenn P. Davis
  (davis at unidata.ucar.edu) for McIDAS areafile support, Keith S. Pickens
  (maxwell.nde.swri.edu!ksp) for fixing the RLE loader to work with the
! updated zio package, Mike Douglas (douglas at wilbur.coyote.trw.com) for
! normalization, Rod Johnson (johnson at wrl.epi.com) for speedup
! suggestions, and any others whose names I've missed.
  
  HISTORY
  
***************
*** 224,226 ****
--- 226,245 ----
  The gcc-1-37 make target was fixed to prevent a double-define.  The
  GIF loader was patched to respond better to short GIF files.  The Utah
  RLE image loader was patched to work with the updated ZIO package.
+ 
+ Version 2.02 added the options -default, -gray, -normalize, and
+ -private.  The memToVal routines were macro-ized for substantial speed
+ increases.  The atom used for deleting previously allocated colors for
+ the -onroot option was changed to correspond to that used by xsetroot.
+ Dithering and halftoning were changed to use a lookup table for
+ intensities to speed them up somewhat.  Rle.h was changed to use
+ memToValLSB() instead of its own byte-swapping algorithm for
+ portability.  Window.c was modified to eliminate the initial paint,
+ moving it instead to within ConfigureNotify.  A fix was made to xwd.c
+ to fix its colormap loader for out-of-order colormaps.  The G3 FAX
+ identification function was fixed and the G3 loader moved to prior to
+ the MacPaint loader so that both can be used.  A bug in send.c where
+ color images using the default colormap would not appear correctly if
+ the display depth was not a multiple of 8 was corrected.  The default
+ gamma value used in rle.c was changed from 2 to 1.  There were
+ miscellaneous portability changes.
diff -c src.2.01/bright.c src.2.02/bright.c
*** src.2.01/bright.c	Sun Sep 30 19:04:11 1990
--- src.2.02/bright.c	Sun Dec  2 13:11:59 1990
***************
*** 1,6 ****
  /* bright.c
   *
!  * alter an image's brightness by a given percentage
   *
   * jim frost 10.10.89
   *
--- 1,6 ----
  /* bright.c
   *
!  * miscellaneous colormap altering functions
   *
   * jim frost 10.10.89
   *
***************
*** 11,16 ****
--- 11,19 ----
  #include "copyright.h"
  #include "image.h"
  
+ /* alter an image's brightness by a given percentage
+  */
+ 
  void brighten(image, percent, verbose)
       Image        *image;
       unsigned int  percent;
***************
*** 70,75 ****
--- 73,166 ----
      *(image->rgb.blue + a)= gammamap[(*(image->rgb.blue + a))>>8]<<8;
    }
  
+   if (verbose)
+     printf("done\n");
+ }
+ 
+ /* normalize an image.  this was originally written by Michael H. Douglas
+  * to normalize into greyscale and modified by jim frost for color.
+  */
+ 
+ void normalize(image, verbose)
+      Image        *image;
+      unsigned int  verbose;
+ { int          a;
+   Intensity minintensity, maxintensity;
+   float factor;
+ 
+   if (! RGBP(image)) /* we're AT&T */
+     return;
+ 
+   compress(image, verbose);
+ 
+   if (verbose) {
+     printf("  Normalizing image...");
+     fflush(stdout);
+   }
+ 
+   /* find range of intensities
+    */
+ 
+   maxintensity = 0;
+   minintensity = 65536;
+   for (a= 0; a < image->rgb.used; a++) {
+     if (image->rgb.red[a] > maxintensity)
+       maxintensity = image->rgb.red[a];
+     if (image->rgb.red[a] < minintensity)
+       minintensity= image->rgb.red[a];
+     if (image->rgb.green[a] > maxintensity)
+       maxintensity = image->rgb.green[a];
+     if (image->rgb.green[a] < minintensity)
+       minintensity= image->rgb.green[a];
+     if (image->rgb.blue[a] > maxintensity)
+       maxintensity = image->rgb.blue[a];
+     if (image->rgb.blue[a] < minintensity)
+       minintensity= image->rgb.blue[a];
+   }
+ 
+   printf("remapping from %d:%d to 0:65535...", minintensity, maxintensity);
+   fflush(stdout);
+   factor= 65535.0 / (maxintensity - minintensity);
+   for (a= 0; a < image->rgb.used; a++) {
+     image->rgb.red[a]= (float)(image->rgb.red[a] - minintensity) * factor;
+     image->rgb.green[a]= (float)(image->rgb.green[a] - minintensity) * factor;
+     image->rgb.blue[a]= (float)(image->rgb.blue[a] - minintensity) * factor;
+ #if 0
+     newrgb = *(image->rgb.red + a);
+     newrgb = ( newrgb - minrgb ) * 65535 / range;
+     *(image->rgb.red + a)= newrgb;
+     *(image->rgb.green + a)= newrgb;
+     *(image->rgb.blue + a)= newrgb;
+ #endif
+   }
+ 
+   if (verbose)
+     printf("done\n");
+ }
+ 
+ /* convert to grayscale
+  */
+ 
+ void gray(image, verbose)
+      Image *image;
+ { int a;
+   Intensity intensity;
+ 
+   if (!RGBP(image))
+     return;
+ 
+   if (verbose) {
+     printf("  Converting image to grayscale...");
+     fflush(stdout);
+   }
+   for (a= 0; a < image->rgb.used; a++) {
+     intensity= colorIntensity(image->rgb.red[a],
+ 			      image->rgb.green[a],
+ 			      image->rgb.blue[a]);
+     image->rgb.red[a]= intensity;
+     image->rgb.green[a]= intensity;
+     image->rgb.blue[a]= intensity;
+   }
    if (verbose)
      printf("done\n");
  }
diff -c src.2.01/compress.c src.2.02/compress.c
*** src.2.01/compress.c	Sun Sep 30 19:04:12 1990
--- src.2.02/compress.c	Sun Dec  2 13:50:51 1990
***************
*** 18,28 ****
    unsigned int *used;  
    RGBMap        rgb;
    byte         *pixptr, *pixptr2;
!   unsigned int  a, x, y;
    Pixel         color, newpixlen;
  
    goodImage(image, "compress");
!   if (! RGBP(image)) /* we're AT&T */
      return;
  
    if (verbose) {
--- 18,28 ----
    unsigned int *used;  
    RGBMap        rgb;
    byte         *pixptr, *pixptr2;
!   unsigned int  a, x, y, depth;
    Pixel         color, newpixlen;
  
    goodImage(image, "compress");
!   if (!RGBP(image) || image->rgb.compressed) /* we're AT&T */
      return;
  
    if (verbose) {
***************
*** 68,90 ****
    freeRGBMapData(&(image->rgb));
    image->rgb= rgb;
  
! /* Okay, we've compressed the colors, let's do the image */
!   for (y=0,x=1;rgb.used>x;y++) x=x*2;
!   newpixlen = (y / 8) + (y % 8 ? 1 : 0);
!   if (newpixlen < image->pixlen)
!   {
! 	if (verbose)
! 		printf("  Compressing image...");fflush(stdout);
! 	pixptr = image->data; pixptr2 = image->data;
! 	for (y= 0; y < image->height; y++)
! 	 for (x= 0; x < image->width; x++) {
! 		valToMem(memToVal(pixptr2,image->pixlen), pixptr, newpixlen);
! 		pixptr2 += image->pixlen;
! 		pixptr += newpixlen;
! 	 }
! 	image->pixlen = newpixlen;
! 	if (verbose)
! 		printf("done\n");
!    }
  
  }
--- 68,94 ----
    freeRGBMapData(&(image->rgb));
    image->rgb= rgb;
  
!   /* Okay, we've compressed the colors, let's do the image
!    */
  
+   for (depth=0, x=1; rgb.used > x ; depth++)
+     x= x * 2;
+   newpixlen = (depth / 8) + (depth % 8 ? 1 : 0);
+   if (newpixlen < image->pixlen) {
+     if (verbose)
+       printf("  Compressing image...");fflush(stdout);
+     pixptr = image->data; pixptr2 = image->data;
+     for (y= 0; y < image->height; y++)
+       for (x= 0; x < image->width; x++) {
+ 	valToMem(memToVal(pixptr2,image->pixlen), pixptr, newpixlen);
+ 	pixptr2 += image->pixlen;
+ 	pixptr += newpixlen;
+       }
+     image->pixlen = newpixlen;
+     image->depth= depth;
+     if (verbose)
+       printf("done\n");
+   }
+ 
+   image->rgb.compressed= 1;
  }
diff -c src.2.01/copyright.h src.2.02/copyright.h
*** src.2.01/copyright.h	Sun Sep 30 19:04:28 1990
--- src.2.02/copyright.h	Sat Dec  1 14:26:19 1990
***************
*** 19,24 ****
--- 19,26 ----
   * USE OR PERFORMANCE OF THIS SOFTWARE.
   */
  
+ #ifndef __SABER__
  static char *Copyright= "Copyright 1989, 1990 Jim Frost";
+ #endif
  #define _JIM_COPYRIGHT_
  #endif
diff -c src.2.01/dither.c src.2.02/dither.c
*** src.2.01/dither.c	Sun Sep 30 19:04:12 1990
--- src.2.02/dither.c	Wed Oct  3 12:06:28 1990
***************
*** 22,31 ****
  #include "kljcpyrght.h"
  #include "image.h"
  
- #define RedPercent  0.299
- #define GrnPercent  0.587	/* color -> grey conversion parameters */
- #define BluPercent  0.114
- 
  #define MaxIntensity  65536	/* maximum possible Intensity */
  
  #define MaxGrey       32768	/* limits on the grey levels used */
--- 22,27 ----
***************
*** 90,103 ****
    {
      grey = (unsigned int *)lmalloc(sizeof(unsigned int) * cimage->rgb.used);
      for (i=0; i<cimage->rgb.used; i++)
!     {
!       tmp  = (cimage->rgb.red[i]   * RedPercent);
!       tmp += (cimage->rgb.green[i] * GrnPercent);
!       tmp += (cimage->rgb.blue[i]  * BluPercent);
  
-       grey[i] = (tmp / MaxIntensity) * MaxGrey;
-     }
- 
      for (i=0; i<cimage->rgb.used; i++)
        grey[i] = tone_scale_adjust(grey[i]);
    }
--- 86,96 ----
    {
      grey = (unsigned int *)lmalloc(sizeof(unsigned int) * cimage->rgb.used);
      for (i=0; i<cimage->rgb.used; i++)
!       grey[i]=
! 	(colorIntensity(cimage->rgb.red[i],
! 			cimage->rgb.green[i],
! 			cimage->rgb.blue[i]) >> 1);
  
      for (i=0; i<cimage->rgb.used; i++)
        grey[i] = tone_scale_adjust(grey[i]);
    }
***************
*** 136,152 ****
        src  += spl;
        
        if (grey == NULL)
!       {
! 	tmp  = (cimage->rgb.red[color]   * RedPercent);
! 	tmp += (cimage->rgb.green[color] * GrnPercent);
! 	tmp += (cimage->rgb.blue[color]  * BluPercent);
! 
! 	level = tone_scale_adjust((tmp / MaxIntensity) * MaxGrey);
!       }
        else
-       {
  	level = grey[color];
-       }
  
        curr[j] += level;
      }
--- 129,140 ----
        src  += spl;
        
        if (grey == NULL)
! 	level =
! 	  tone_scale_adjust(colorIntensity(cimage->rgb.red[color],
! 					   cimage->rgb.green[color],
! 					   cimage->rgb.blue[color]) >> 1);
        else
  	level = grey[color];
  
        curr[j] += level;
      }
diff -c src.2.01/g3.c src.2.02/g3.c
*** src.2.01/g3.c	Sun Sep 30 19:04:28 1990
--- src.2.02/g3.c	Sat Dec  1 20:00:01 1990
***************
*** 35,40 ****
--- 35,41 ----
  int g3_eof = 0;
  int g3_eols;
  int g3_rawzeros;
+ int g3_Xrawzeros;
  int	maxlinelen;
  int	rows, cols;
  
***************
*** 236,241 ****
--- 237,243 ----
  		curbit = 0;
  		}
  	if (shdata & bmask[curbit]) {
+ 		g3_Xrawzeros = g3_rawzeros;
  		g3_rawzeros = 0;
  		b = 1;
  		}
***************
*** 280,286 ****
  	int	ret = 0;
  
  	for (g3_rawzeros = 0; !g3_rawgetbit(fd) && !g3_eof;);
! 	if(g3_rawzeros >=11 && g3_rawzeros <= 15)
  		ret = 1;
  
  	return(ret);
--- 282,288 ----
  	int	ret = 0;
  
  	for (g3_rawzeros = 0; !g3_rawgetbit(fd) && !g3_eof;);
! 	if(g3_Xrawzeros >=11 && g3_Xrawzeros <= 15)
  		ret = 1;
  
  	return(ret);
***************
*** 350,356 ****
  	}
  
  	if(verbose)
! 		printf("  %s is a %dx%d G3 FAX image.\n", image->width, image->height);
      return(image);
  }
  
--- 352,358 ----
  	}
  
  	if(verbose)
! 		printf("  %s is a %dx%d G3 FAX image.\n", name, image->width, image->height);
      return(image);
  }
  
diff -c src.2.01/halftone.c src.2.02/halftone.c
*** src.2.01/halftone.c	Sun Sep 30 19:04:12 1990
--- src.2.02/halftone.c	Wed Oct  3 12:01:07 1990
***************
*** 13,23 ****
  #include "copyright.h"
  #include "image.h"
  
  /* 4x4 arrays used for dithering, arranged by nybble
   */
  
  #define GRAYS    17 /* ((4 * 4) + 1) patterns for a good dither */
! #define GRAYSTEP ((unsigned long)(65536 * 3) / GRAYS)
  
  static byte DitherBits[GRAYS][4] = {
    0xf, 0xf, 0xf, 0xf,
--- 13,133 ----
  #include "copyright.h"
  #include "image.h"
  
+ /* RGB intensity tables.  red is (val * 0.30), green is (val * 0.59), blue
+  * is (val * .11), where val is intensity >> 8.  these are used by the
+  * colorIntensity() macro in images.h.
+  */
+ 
+ unsigned short RedIntensity[256]= {
+       0,    76,   153,   230,   307,   384,   460,   537,
+     614,   691,   768,   844,   921,   998,  1075,  1152,
+    1228,  1305,  1382,  1459,  1536,  1612,  1689,  1766,
+    1843,  1920,  1996,  2073,  2150,  2227,  2304,  2380,
+    2457,  2534,  2611,  2688,  2764,  2841,  2918,  2995,
+    3072,  3148,  3225,  3302,  3379,  3456,  3532,  3609,
+    3686,  3763,  3840,  3916,  3993,  4070,  4147,  4224,
+    4300,  4377,  4454,  4531,  4608,  4684,  4761,  4838,
+    4915,  4992,  5068,  5145,  5222,  5299,  5376,  5452,
+    5529,  5606,  5683,  5760,  5836,  5913,  5990,  6067,
+    6144,  6220,  6297,  6374,  6451,  6528,  6604,  6681,
+    6758,  6835,  6912,  6988,  7065,  7142,  7219,  7296,
+    7372,  7449,  7526,  7603,  7680,  7756,  7833,  7910,
+    7987,  8064,  8140,  8217,  8294,  8371,  8448,  8524,
+    8601,  8678,  8755,  8832,  8908,  8985,  9062,  9139,
+    9216,  9292,  9369,  9446,  9523,  9600,  9676,  9753,
+    9830,  9907,  9984, 10060, 10137, 10214, 10291, 10368,
+   10444, 10521, 10598, 10675, 10752, 10828, 10905, 10982,
+   11059, 11136, 11212, 11289, 11366, 11443, 11520, 11596,
+   11673, 11750, 11827, 11904, 11980, 12057, 12134, 12211,
+   12288, 12364, 12441, 12518, 12595, 12672, 12748, 12825,
+   12902, 12979, 13056, 13132, 13209, 13286, 13363, 13440,
+   13516, 13593, 13670, 13747, 13824, 13900, 13977, 14054,
+   14131, 14208, 14284, 14361, 14438, 14515, 14592, 14668,
+   14745, 14822, 14899, 14976, 15052, 15129, 15206, 15283,
+   15360, 15436, 15513, 15590, 15667, 15744, 15820, 15897,
+   15974, 16051, 16128, 16204, 16281, 16358, 16435, 16512,
+   16588, 16665, 16742, 16819, 16896, 16972, 17049, 17126,
+   17203, 17280, 17356, 17433, 17510, 17587, 17664, 17740,
+   17817, 17894, 17971, 18048, 18124, 18201, 18278, 18355,
+   18432, 18508, 18585, 18662, 18739, 18816, 18892, 18969,
+   19046, 19123, 19200, 19276, 19353, 19430, 19507, 19584
+ };
+ 
+ unsigned short GreenIntensity[256]= {
+      0,  151,  302,  453,  604,  755,  906, 1057,
+   1208, 1359, 1510, 1661, 1812, 1963, 2114, 2265,
+   2416, 2567, 2718, 2869, 3020, 3171, 3322, 3473,
+   3624, 3776, 3927, 4078, 4229, 4380, 4531, 4682,
+   4833, 4984, 5135, 5286, 5437, 5588, 5739, 5890,
+   6041, 6192, 6343, 6494, 6645, 6796, 6947, 7098,
+   7249, 7400, 7552, 7703, 7854, 8005, 8156, 8307,
+   8458, 8609, 8760, 8911, 9062, 9213, 9364, 9515,
+   9666, 9817, 9968,10119,10270,10421,10572,10723,
+  10874,11025,11176,11328,11479,11630,11781,11932,
+  12083,12234,12385,12536,12687,12838,12989,13140,
+  13291,13442,13593,13744,13895,14046,14197,14348,
+  14499,14650,14801,14952,15104,15255,15406,15557,
+  15708,15859,16010,16161,16312,16463,16614,16765,
+  16916,17067,17218,17369,17520,17671,17822,17973,
+  18124,18275,18426,18577,18728,18880,19031,19182,
+  19333,19484,19635,19786,19937,20088,20239,20390,
+  20541,20692,20843,20994,21145,21296,21447,21598,
+  21749,21900,22051,22202,22353,22504,22656,22807,
+  22958,23109,23260,23411,23562,23713,23864,24015,
+  24166,24317,24468,24619,24770,24921,25072,25223,
+  25374,25525,25676,25827,25978,26129,26280,26432,
+  26583,26734,26885,27036,27187,27338,27489,27640,
+  27791,27942,28093,28244,28395,28546,28697,28848,
+  28999,29150,29301,29452,29603,29754,29905,30056,
+  30208,30359,30510,30661,30812,30963,31114,31265,
+  31416,31567,31718,31869,32020,32171,32322,32473,
+  32624,32775,32926,33077,33228,33379,33530,33681,
+  33832,33984,34135,34286,34437,34588,34739,34890,
+  35041,35192,35343,35494,35645,35796,35947,36098,
+  36249,36400,36551,36702,36853,37004,37155,37306,
+  37457,37608,37760,37911,38062,38213,38364,38515
+ };
+ 
+ unsigned short BlueIntensity[256]= {
+      0,   28,   56,   84,  112,  140,  168,  197,
+    225,  253,  281,  309,  337,  366,  394,  422,
+    450,  478,  506,  535,  563,  591,  619,  647,
+    675,  704,  732,  760,  788,  816,  844,  872,
+    901,  929,  957,  985, 1013, 1041, 1070, 1098,
+   1126, 1154, 1182, 1210, 1239, 1267, 1295, 1323,
+   1351, 1379, 1408, 1436, 1464, 1492, 1520, 1548,
+   1576, 1605, 1633, 1661, 1689, 1717, 1745, 1774,
+   1802, 1830, 1858, 1886, 1914, 1943, 1971, 1999,
+   2027, 2055, 2083, 2112, 2140, 2168, 2196, 2224,
+   2252, 2280, 2309, 2337, 2365, 2393, 2421, 2449,
+   2478, 2506, 2534, 2562, 2590, 2618, 2647, 2675,
+   2703, 2731, 2759, 2787, 2816, 2844, 2872, 2900,
+   2928, 2956, 2984, 3013, 3041, 3069, 3097, 3125,
+   3153, 3182, 3210, 3238, 3266, 3294, 3322, 3351,
+   3379, 3407, 3435, 3463, 3491, 3520, 3548, 3576,
+   3604, 3632, 3660, 3688, 3717, 3745, 3773, 3801,
+   3829, 3857, 3886, 3914, 3942, 3970, 3998, 4026,
+   4055, 4083, 4111, 4139, 4167, 4195, 4224, 4252,
+   4280, 4308, 4336, 4364, 4392, 4421, 4449, 4477,
+   4505, 4533, 4561, 4590, 4618, 4646, 4674, 4702,
+   4730, 4759, 4787, 4815, 4843, 4871, 4899, 4928,
+   4956, 4984, 5012, 5040, 5068, 5096, 5125, 5153,
+   5181, 5209, 5237, 5265, 5294, 5322, 5350, 5378,
+   5406, 5434, 5463, 5491, 5519, 5547, 5575, 5603,
+   5632, 5660, 5688, 5716, 5744, 5772, 5800, 5829,
+   5857, 5885, 5913, 5941, 5969, 5998, 6026, 6054,
+   6082, 6110, 6138, 6167, 6195, 6223, 6251, 6279,
+   6307, 6336, 6364, 6392, 6420, 6448, 6476, 6504,
+   6533, 6561, 6589, 6617, 6645, 6673, 6702, 6730,
+   6758, 6786, 6814, 6842, 6871, 6899, 6927, 6955,
+   6983, 7011, 7040, 7068, 7096, 7124, 7152, 7180
+ };
+ 
  /* 4x4 arrays used for dithering, arranged by nybble
   */
  
  #define GRAYS    17 /* ((4 * 4) + 1) patterns for a good dither */
! #define GRAYSTEP ((unsigned long)(65536 / GRAYS))
  
  static byte DitherBits[GRAYS][4] = {
    0xf, 0xf, 0xf, 0xf,
***************
*** 85,93 ****
      index= (unsigned int *)lmalloc(sizeof(unsigned int) * cimage->rgb.used);
      for (x= 0; x < cimage->rgb.used; x++) {
        *(index + x)=
! 	((unsigned long)(*(cimage->rgb.red + x)) +
! 	 *(cimage->rgb.green + x) +
! 	 *(cimage->rgb.blue + x)) / GRAYSTEP;
        if (*(index + x) >= GRAYS) /* rounding errors can do this */
  	*(index + x)= GRAYS - 1;
      }
--- 195,203 ----
      index= (unsigned int *)lmalloc(sizeof(unsigned int) * cimage->rgb.used);
      for (x= 0; x < cimage->rgb.used; x++) {
        *(index + x)=
! 	((unsigned long)colorIntensity(*(cimage->rgb.red + x),
! 				       *(cimage->rgb.green + x),
! 				       *(cimage->rgb.blue + x))) / GRAYSTEP;
        if (*(index + x) >= GRAYS) /* rounding errors can do this */
  	*(index + x)= GRAYS - 1;
      }
***************
*** 107,115 ****
        if (index)
  	dindex= *(index + color);
        else {
! 	dindex= ((unsigned long)(*(cimage->rgb.red + color)) +
! 		 *(cimage->rgb.green + color) +
! 		 *(cimage->rgb.blue + color)) / GRAYSTEP;
  	if (dindex >= GRAYS) /* rounding errors can do this */
  	  dindex= GRAYS - 1;
        }
--- 217,226 ----
        if (index)
  	dindex= *(index + color);
        else {
! 	dindex= 
! 	  ((unsigned long)colorIntensity(*(cimage->rgb.red + x),
! 					 *(cimage->rgb.green + x),
! 					 *(cimage->rgb.blue + x))) / GRAYSTEP;
  	if (dindex >= GRAYS) /* rounding errors can do this */
  	  dindex= GRAYS - 1;
        }
diff -c src.2.01/image.h src.2.02/image.h
*** src.2.01/image.h	Sun Sep 30 19:04:29 1990
--- src.2.02/image.h	Sun Dec  2 12:21:16 1990
***************
*** 35,43 ****
  #define ZSTDIN    2 /* file is stdin */
  
  typedef struct rgbmap {
!   unsigned int  size;  /* size of RGB map */
!   unsigned int  used;  /* number of colors used in RGB map */
!   Intensity    *red;   /* color values in X style */
    Intensity    *green;
    Intensity    *blue;
  } RGBMap;
--- 35,44 ----
  #define ZSTDIN    2 /* file is stdin */
  
  typedef struct rgbmap {
!   unsigned int  size;       /* size of RGB map */
!   unsigned int  used;       /* number of colors used in RGB map */
!   unsigned int  compressed; /* image uses colormap fully */
!   Intensity    *red;        /* color values in X style */
    Intensity    *green;
    Intensity    *blue;
  } RGBMap;
***************
*** 62,67 ****
--- 63,82 ----
  #define BITMAPP(IMAGE) ((IMAGE)->type == IBITMAP)
  #define RGBP(IMAGE)    ((IMAGE)->type == IRGB)
  
+ /* special case 1-byte transfers so they're inline
+  */
+ 
+ #define memToVal(PTR,LEN)    ((LEN) == 1 ? (unsigned long)(*(PTR)) : \
+ 			      doMemToVal(PTR,LEN))
+ #define memToValLSB(PTR,LEN) ((LEN) == 1 ? (unsigned long)(*(PTR)) : \
+ 			      doMemToValLSB(PTR,LEN))
+ #define valToMem(VAL,PTR,LEN)    ((LEN) == 1 ? \
+ 				  (unsigned long)(*(PTR) = (byte)(VAL)) : \
+ 				  doValToMem(VAL,PTR,LEN))
+ #define valToMemLSB(VAL,PTR,LEN) ((LEN) == 1 ? \
+ 				  (unsigned long)(*(PTR) = (byte)(VAL)) : \
+ 				  (int)doValToMemLSB(VAL,PTR,LEN))
+ 
  /* function declarations
   */
  
***************
*** 68,73 ****
--- 83,91 ----
  Image *clip(); /* clip.c */
  
  void brighten(); /* bright.c */
+ void equalize();
+ void gray();
+ void normalize();
  
  void compress(); /* compress.c */
  
***************
*** 105,115 ****
  void reduceRGBMap(); /* reduce.c */
  void reduce();
  
! unsigned long memToVal(); /* value.c */
! void          valToMem();
! unsigned long memToValLSB();
! void          valToMemLSB();
  
  Image *zoom(); /* zoom.c */
  Image *rotate(); /* rotate.c */
  Image *smooth(); /* smooth.c */
--- 123,148 ----
  void reduceRGBMap(); /* reduce.c */
  void reduce();
  
! /* doMemToVal and doMemToValLSB used to be void type but some compilers
!  * (particularly the 4.1.1 SunOS compiler) couldn't handle the
!  * (void)(thing= value) conversion used in the macros.
!  */
  
+ unsigned long doMemToVal(); /* value.c */
+ unsigned long doValToMem();
+ unsigned long doMemToValLSB();
+ unsigned long doValToMemLSB();
+ 
  Image *zoom(); /* zoom.c */
  Image *rotate(); /* rotate.c */
  Image *smooth(); /* smooth.c */
+ 
+ /* this returns the (approximate) intensity of an RGB triple
+  */
+ 
+ #define colorIntensity(R,G,B) \
+   (RedIntensity[(R) >> 8] + GreenIntensity[(G) >> 8] + BlueIntensity[(B) >> 8])
+ 
+ extern unsigned short RedIntensity[];
+ extern unsigned short GreenIntensity[];
+ extern unsigned short BlueIntensity[];
diff -c src.2.01/imagetypes.h src.2.02/imagetypes.h
*** src.2.01/imagetypes.h	Sun Sep 30 19:04:29 1990
--- src.2.02/imagetypes.h	Sat Dec  1 20:02:53 1990
***************
*** 52,60 ****
    rleIdent,       rleLoad,       "Utah RLE Image",
    xwdIdent,       xwdLoad,       "X Window Dump",
    mcidasIdent,    mcidasLoad,    "McIDAS areafile",
    macIdent,       macLoad,       "MacPaint Image",
    xpixmapIdent,   xpixmapLoad,   "X Pixmap",
    xbitmapIdent,   xbitmapLoad,   "X Bitmap",
-   g3Ident,        g3Load,        "G3 FAX Image",
    NULL,           NULL,          NULL
  };
--- 52,60 ----
    rleIdent,       rleLoad,       "Utah RLE Image",
    xwdIdent,       xwdLoad,       "X Window Dump",
    mcidasIdent,    mcidasLoad,    "McIDAS areafile",
+   g3Ident,        g3Load,        "G3 FAX Image",
    macIdent,       macLoad,       "MacPaint Image",
    xpixmapIdent,   xpixmapLoad,   "X Pixmap",
    xbitmapIdent,   xbitmapLoad,   "X Bitmap",
    NULL,           NULL,          NULL
  };
diff -c src.2.01/kljcpyrght.h src.2.02/kljcpyrght.h
*** src.2.01/kljcpyrght.h	Sun Sep 30 19:04:13 1990
--- src.2.02/kljcpyrght.h	Sat Dec  1 14:26:38 1990
***************
*** 21,26 ****
--- 21,28 ----
    CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  ****/
  
+ #ifndef __SABER__
  static char *KLJCopyright = "Copyright 1989, 1990 Kirk L. Johnson";
+ #endif
  #define _KLJ_COPYRIGHT_
  #endif
diff -c src.2.01/mac.c src.2.02/mac.c
*** src.2.01/mac.c	Sun Sep 30 19:04:13 1990
--- src.2.02/mac.c	Sat Dec  1 20:05:17 1990
***************
*** 73,85 ****
    if (zread(ins, hp, ADD_HDR_LEN) != ADD_HDR_LEN)
      return MACIN_ERR_EOF;
  
!   /*
!    * if mhsum = 0 this is probably a
!    * a g3 fax file.
!    */
!   for (i = 0; i < 10; i++) mhsum += mhdr[1];
! 
!   if (mhdr[0] != MAC_MAGIC && mhsum != 0)
      return MACIN_ERR_BAD_SD;
  
    /* Get image name  (if available) */
--- 73,79 ----
    if (zread(ins, hp, ADD_HDR_LEN) != ADD_HDR_LEN)
      return MACIN_ERR_EOF;
  
!   if (mhdr[0] != MAC_MAGIC)
      return MACIN_ERR_BAD_SD;
  
    /* Get image name  (if available) */
diff -c src.2.01/mc_tables.c src.2.02/mc_tables.c
*** src.2.01/mc_tables.c	Sun Sep 30 19:04:34 1990
--- src.2.02/mc_tables.c	Sun Dec  2 14:17:20 1990
***************
*** 1,5 ****
- /* $Id: mc_tables.c,v 1.1 89/10/16 16:27:48 davis Exp $ */
- 
  /*
   *  From McIDAS Reference Manual
   *     Introduction - pg 21
--- 1,3 ----
diff -c src.2.01/mcidas.h src.2.02/mcidas.h
*** src.2.01/mcidas.h	Sun Sep 30 19:04:35 1990
--- src.2.02/mcidas.h	Sun Dec  2 14:17:54 1990
***************
*** 1,4 ****
! /*	$Id: mcidas.h,v 1.1 90/09/28 20:26:36 davis Exp $ */
  
  /* Argh, looks like the numbers are in vax byte order */
  
--- 1,5 ----
! /* mcidas.h
!  */
  
  /* Argh, looks like the numbers are in vax byte order */
  
***************
*** 69,73 ****
  	struct area_dir *dir ;
  	struct navigation *nav ;
  	unsigned char *image ;
! 	unsigned char *private ; /* conveninence pointer */
  } ;
--- 70,74 ----
  	struct area_dir *dir ;
  	struct navigation *nav ;
  	unsigned char *image ;
! 	unsigned char *priv ; /* conveninence pointer */
  } ;
diff -c src.2.01/misc.c src.2.02/misc.c
*** src.2.01/misc.c	Sun Sep 30 19:04:13 1990
--- src.2.02/misc.c	Sun Dec  2 14:05:55 1990
***************
*** 19,24 ****
--- 19,25 ----
    printf("Global options:\n");
    printf("  -onroot               - load image onto root window\n");
    printf("  -border colorname     - border image with this color\n");
+   printf("  -default              - set root window to default pattern\n");
    printf("  -display dispname     - destination display\n");
    printf("  -fullscreen           - use entire screen for display\n");
    printf("  -geometry WxH+X+Y     - destination size and location\n");
***************
*** 27,32 ****
--- 28,34 ----
    printf("  -list                 - list images in path\n");
    printf("  -install              - explicitly install colormap\n");
    printf("  -path                 - show image path for loading\n");
+   printf("  -private              - force allocation of private colormap\n");
    printf("  -quiet                - silence is golden\n");
    printf("  -slideshow            - show images in slideshow style\n");
    printf("  -supported            - show supported image types\n");
***************
*** 36,51 ****
    printf("Image_options:\n");
    printf("  -at X,Y               - load image at location\n");
    printf("  -background colorname - background color for bitmap images\n");
-   printf("  -gamma display_gamma  - specify display gamma - default = 1.0\n");
    printf("                        - typical display needs 2.0 - 2.5\n");
    printf("  -brighten percentage  - specify brightness multiplier\n");
    printf("  -center               - center image\n");
-   printf("  -colors number        - specify maximum number of RGB colors\n");
    printf("  -clip X,Y,W,H         - use clipped portion of image\n");
    printf("  -dither               - dither color image to bitmap image\n");
    printf("  -foreground colorname - foreground color for bitmap images\n");
    printf("  -halftone             - halftone a color image to bitmap image\n");
    printf("  -name name            - force next argument to be image name\n");
    printf("  -rotate degrees       - rotate an image by a 90 degree angle\n");
    printf("  -smooth               - smooth a color image\n");
    printf("  -xzoom percentage     - zoom the X axis by a percentage\n");
--- 38,55 ----
    printf("Image_options:\n");
    printf("  -at X,Y               - load image at location\n");
    printf("  -background colorname - background color for bitmap images\n");
    printf("                        - typical display needs 2.0 - 2.5\n");
    printf("  -brighten percentage  - specify brightness multiplier\n");
    printf("  -center               - center image\n");
    printf("  -clip X,Y,W,H         - use clipped portion of image\n");
+   printf("  -colors number        - specify maximum number of RGB colors\n");
    printf("  -dither               - dither color image to bitmap image\n");
    printf("  -foreground colorname - foreground color for bitmap images\n");
+   printf("  -gamma display_gamma  - specify display gamma - default = 1.0\n");
+   printf("  -gray                 - convert to grayscale (also -grey)\n");
    printf("  -halftone             - halftone a color image to bitmap image\n");
    printf("  -name name            - force next argument to be image name\n");
+   printf("  -normalize            - convert image to normalized b & w\n");
    printf("  -rotate degrees       - rotate an image by a 90 degree angle\n");
    printf("  -smooth               - smooth a color image\n");
    printf("  -xzoom percentage     - zoom the X axis by a percentage\n");
***************
*** 122,127 ****
--- 126,137 ----
      freeImage(image);
      image= tmpimage;
    }
+ 
+   if (options->gray) /* convert image to grayscale */
+     gray(image, verbose);
+ 
+   if (options->normalize) /* normalize image */
+     normalize(image, verbose);
  
    if (options->bright) /* alter image brightness */
      brighten(image, options->bright, verbose);
diff -c src.2.01/mit.cpyrght src.2.02/mit.cpyrght
*** src.2.01/mit.cpyrght	Sun Sep 30 19:04:13 1990
--- src.2.02/mit.cpyrght	Sat Dec  1 14:26:50 1990
***************
*** 20,26 ****
--- 20,28 ----
   * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   */
  
+ #ifndef __SABER__
  static char *MitCopyright=
    "Copyright 1989 Massachusetts Institute of Technology";
+ #endif
  #define _MIT_COPYRIGHT_
  #endif
diff -c src.2.01/mrmcpyrght.h src.2.02/mrmcpyrght.h
*** src.2.01/mrmcpyrght.h	Sun Sep 30 19:04:13 1990
--- src.2.02/mrmcpyrght.h	Sat Dec  1 14:27:52 1990
***************
*** 21,26 ****
--- 21,28 ----
    CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  ****/
  
+ #ifndef __SABER__
  static char *MRMCopyright = "Copyright 1990 Mark Majhor";
+ #endif
  #define _MRM_COPYRIGHT_
  #endif
diff -c src.2.01/new.c src.2.02/new.c
*** src.2.01/new.c	Sun Sep 30 19:04:13 1990
--- src.2.02/new.c	Sun Dec  2 12:29:54 1990
***************
*** 28,33 ****
--- 28,34 ----
  {
    rgb->used= 0;
    rgb->size= size;
+   rgb->compressed= 0;
    rgb->red= (Intensity *)lmalloc(sizeof(Intensity) * size);
    rgb->green= (Intensity *)lmalloc(sizeof(Intensity) * size);
    rgb->blue= (Intensity *)lmalloc(sizeof(Intensity) * size);
diff -c src.2.01/patchlevel src.2.02/patchlevel
*** src.2.01/patchlevel	Sun Sep 30 19:04:30 1990
--- src.2.02/patchlevel	Wed Oct  3 11:01:10 1990
***************
*** 2,5 ****
   */
  
  #define VERSION    "2"
! #define PATCHLEVEL "01"
--- 2,5 ----
   */
  
  #define VERSION    "2"
! #define PATCHLEVEL "02"
diff -c src.2.01/reduce.c src.2.02/reduce.c
*** src.2.01/reduce.c	Sun Sep 30 19:04:14 1990
--- src.2.02/reduce.c	Sun Dec  2 12:29:25 1990
***************
*** 175,180 ****
--- 175,182 ----
    lfree((byte *)dists);
    lfree((byte *)same);
  
+   rgb->compressed= 0;
+ 
    if (verbose)
      printf("done\n");
  }
diff -c src.2.01/rle.c src.2.02/rle.c
*** src.2.01/rle.c	Sun Sep 30 19:04:14 1990
--- src.2.02/rle.c	Sat Dec  1 20:10:23 1990
***************
*** 37,43 ****
  static int y_min;		/* copy of picture y_min */
  
  /* option stuff (Not functional) */
! static float disp_gam = 2.0;	/* default display gamma correction factor */
  static int gflag = 0;			/* if user supplies display gamma */
  static int iflag=0;			/* user suplied image gamma */
  static int lflag=0;			/* user supplied levels */
--- 37,43 ----
  static int y_min;		/* copy of picture y_min */
  
  /* option stuff (Not functional) */
! static float disp_gam = 1.0;	/* default display gamma correction factor */
  static int gflag = 0;			/* if user supplies display gamma */
  static int iflag=0;			/* user suplied image gamma */
  static int lflag=0;			/* user supplied levels */
diff -c src.2.01/rle.h src.2.02/rle.h
*** src.2.01/rle.h	Sun Sep 30 19:04:14 1990
--- src.2.02/rle.h	Sun Dec  2 14:14:10 1990
***************
*** 27,57 ****
   * 
   * Added optimised dither square size globals
   * 88/07/13 Graeme W. Gill
-  *
-  * $Header: svfb_global.h,v 2.7 86/11/10 11:25:18 thomas Exp $
-  * $Log:	svfb_global.h,v $
-  * Revision 2.7  86/11/10  11:25:18  thomas
-  * Add rle_get_setup return codes.
-  * Add is_seek flag to make pipe input work.
-  * 
-  * Revision 2.6  86/10/08  13:06:07  thomas
-  * Add sv_comments field.
-  * Add is_eof flag to Runget private data.
-  * 
-  * Revision 2.4  86/02/27  10:05:40  thomas
-  * Change for new sv_globals & sv_putrow interface.
-  * Add comments to data structure.
-  * 
-  * Revision 2.3  85/04/26  15:10:04  thomas
-  * New sv_globals structure.  sv_dispatch no longer global variable
-  * (incorporated into globals struct).
-  * 
-  * Revision 2.2  85/04/04  16:42:09  thomas
-  * Take out verbose flag, mapflag.  Add ncmap/cmaplen and map pointer.
-  * 
-  * Revision 2.1  85/03/05  16:02:03  thomas
-  * *** empty log message ***
-  * 
   */
  
  enum sv_dispatch {
--- 27,32 ----
***************
*** 65,83 ****
   * pdp-11's (not sure if it's pdp11 or PDP11 ??)
   * are considered BIGENDIAN machines.
   */
- #if !defined(BIG_ENDIAN) && !defined(LITTLE_ENDIAN)
- #if !defined(vax) && !defined(pdp11) && !defined(ns32000) && !defined(i386)
- #define BIG_ENDIAN
- #else
- #define LITTLE_ENDIAN
- #endif
- #endif
  
! #ifdef BIG_ENDIAN
! #define SWAB(shrt)  (shrt = ((shrt >> 8) & 0xff) | ((shrt << 8) & 0xff00))
! #else
! #define	SWAB(shrt)
! #endif
  
  /* fix up some bezerklysims */
  #ifndef bzero
--- 40,47 ----
   * pdp-11's (not sure if it's pdp11 or PDP11 ??)
   * are considered BIGENDIAN machines.
   */
  
! #define SWAB(val) (val= memToValLSB(&val, sizeof(val)))
  
  /* fix up some bezerklysims */
  #ifndef bzero
diff -c src.2.01/rlelib.c src.2.02/rlelib.c
*** src.2.01/rlelib.c	Sun Sep 30 19:04:32 1990
--- src.2.02/rlelib.c	Sun Dec  2 14:16:38 1990
***************
*** 46,53 ****
   * 		University of Utah
   * Date:	Mon Aug  9 1982
   * Copyright (c) 1982 Spencer W. Thomas
-  * 
-  * $Header: XtndRunsv.h,v 2.2 85/04/26 15:05:30 thomas Exp $
   */
  
  #ifndef XTNDRUNSV
--- 46,51 ----
***************
*** 118,125 ****
   * 		University of Utah
   * Date:	Mon Aug  9 1982
   * Copyright (c) 1982 Spencer W. Thomas
-  * 
-  * $Header: svfb.h,v 2.4 86/02/27 10:03:26 thomas Exp $
   */
  
  /* ****************************************************************
--- 116,121 ----
***************
*** 197,215 ****
   * 		University of Utah
   * Date:	Thu Apr 25 1985
   * Copyright (c) 1985,1986 Spencer W. Thomas
-  * 
-  * $Header: svfb_global.c,v 2.6 86/02/27 10:05:23 thomas Exp $
-  * $Log:	svfb_global.c,v $
-  * Revision 2.6  86/02/27  10:05:23  thomas
-  * Change for new sv_globals
-  * 
-  * Revision 2.5  86/02/25  17:32:18  thomas
-  * Take out misc.h
-  * 
-  * Revision 2.4  85/04/26  15:09:27  thomas
-  * Add header comment.  Change DTable to sv_DTable.  Changes for new
-  * sv_globals structure.
-  * 
   */
  
  
--- 193,198 ----
***************
*** 296,307 ****
   * 		University of Utah
   * Date:	Mon Aug  9 1982
   * Copyright (c) 1982,1986 Spencer W. Thomas
-  * 
-  * $Header: Runsv.c,v 2.9 86/02/27 10:01:13 thomas Locked $
-  * 
-  * Modified by:	Todd W. Fuqua
-  * 	Date:	Jul 22 1984
-  * convert to new RLE format to make room for larger frame buffers
   */
  
  /* THIS IS WAY OUT OF DATE.  See rle.5.
--- 279,284 ----
***************
*** 813,852 ****
   * 		University of Utah
   * Date:	Wed Apr 10 1985
   * Copyright (c) 1985 Spencer W. Thomas
-  * 
-  * $Header: rle_getrow.c,v 1.12 86/11/10 12:30:34 thomas Exp $
-  * $Log:	rle_getrow.c,v $
-  * Revision 1.12  86/11/10  12:30:34  thomas
-  * NULL comments field if no comment in input file.
-  * 
-  * Revision 1.11  86/11/10  11:27:01  thomas
-  * Remove infile arguments.
-  * 
-  * Revision 1.10  86/11/10  11:19:04  thomas
-  * Fix to work with pipe input.
-  * 
-  * Revision 1.9  86/10/08  13:06:32  thomas
-  * Add header comments.
-  * Add EOF opcode.
-  * 
-  * Revision 1.6  86/02/27  10:05:55  thomas
-  * Change for new sv_globals interface.  Put "static" vars in structure.
-  * 
-  * Revision 1.5  86/02/25  17:32:28  thomas
-  * Add debugging.
-  * 
-  * Revision 1.4  86/02/11  11:38:09  thomas
-  * Oops: Only did clear to background right for ncolors = 3.
-  * Some lint fixes.
-  * 
-  * Revision 1.3  86/02/11  11:27:52  thomas
-  * Handle alpha channel.  Use bfill routine for efficiency.
-  * 
-  * Revision 1.2  85/05/22  15:09:23  thomas
-  * Swap magic number on BIGENDIAN machines.
-  * 
-  * Revision 1.1  85/05/22  12:36:21  thomas
-  * Initial revision
   * 
   */
  /*
--- 790,795 ----
diff -c src.2.01/root.c src.2.02/root.c
*** src.2.01/root.c	Sun Sep 30 19:04:14 1990
--- src.2.02/root.c	Sat Dec  1 16:21:13 1990
***************
*** 14,20 ****
  #include "xloadimage.h"
  #include <X11/Xatom.h>
  
! #define RETAIN_PROP_NAME	"XA_XLOADIMAGE_COLORS_XID"
  
  static void
  updateProperty(dpy, w, name, type, format, data, nelem)
--- 14,20 ----
  #include "xloadimage.h"
  #include <X11/Xatom.h>
  
! #define RETAIN_PROP_NAME	"_XSETROOT_ID"
  
  static void
  updateProperty(dpy, w, name, type, format, data, nelem)
***************
*** 134,140 ****
    freePrevious(disp, RootWindow(disp, scrn));
  
    if (! sendImageToX(disp, scrn, DefaultVisual(disp, scrn), image,
! 		     &pixmap, &xcmap, verbose))
      exit(1);
  
    /* changing the root colormap is A Bad Thing, so deny it.
--- 134,140 ----
    freePrevious(disp, RootWindow(disp, scrn));
  
    if (! sendImageToX(disp, scrn, DefaultVisual(disp, scrn), image,
! 		     &pixmap, &xcmap, 0, verbose))
      exit(1);
  
    /* changing the root colormap is A Bad Thing, so deny it.
diff -c src.2.01/send.c src.2.02/send.c
*** src.2.01/send.c	Sun Sep 30 19:04:14 1990
--- src.2.02/send.c	Sat Dec  1 20:27:02 1990
***************
*** 11,17 ****
  #include "copyright.h"
  #include "xloadimage.h"
  
! unsigned int sendImageToX(disp, scrn, visual, image, pixmap, cmap, verbose)
       Display      *disp;
       int           scrn;
       Visual       *visual;
--- 11,19 ----
  #include "copyright.h"
  #include "xloadimage.h"
  
! unsigned int sendImageToX(disp, scrn, visual, image, pixmap, cmap,
! 			  private_cmap,
! 			  verbose)
       Display      *disp;
       int           scrn;
       Visual       *visual;
***************
*** 18,23 ****
--- 20,26 ----
       Image        *image;
       Pixmap       *pixmap;
       Colormap     *cmap;
+      unsigned int  private_cmap;
       unsigned int  verbose;
  { Pixel        *index;
    unsigned int  a, b, newmap, x, y, linelen, ddepth, dpixlen;
***************
*** 45,54 ****
    index= (Pixel *)lmalloc(sizeof(Pixel) * image->rgb.used);
    xcolor.flags= DoRed | DoGreen | DoBlue;
  
!   /* get the colormap to use
     */
  
!   if (visual == DefaultVisual(disp, scrn)) {
      *cmap= DefaultColormap(disp, scrn);
      newmap= 0;
  
--- 48,64 ----
    index= (Pixel *)lmalloc(sizeof(Pixel) * image->rgb.used);
    xcolor.flags= DoRed | DoGreen | DoBlue;
  
!   /* get the colormap to use.
     */
  
!   if (private_cmap) /* user asked us to use a private cmap */
!     newmap= 1;
! 
!   /* if we're using the default visual, also use the default colormap
!    * so we share colors if possible.
!    */
! 
!   else if (visual == DefaultVisual(disp, scrn)) {
      *cmap= DefaultColormap(disp, scrn);
      newmap= 0;
  
***************
*** 70,79 ****
  	   * we had allocated and create a private colormap
  	   */
  
! 	  for (b= 0; b < a; b++)
! 	    XFreeColors(disp, *cmap, index + b, 1, 0);
! 	  *cmap= XCreateColormap(disp, RootWindow(disp, scrn), visual,
! 				 AllocNone);
  	  newmap= 1;
  	  break;
  	}
--- 80,86 ----
  	   * we had allocated and create a private colormap
  	   */
  
! 	  XFreeColors(disp, *cmap, index, a, 0);
  	  newmap= 1;
  	  break;
  	}
***************
*** 80,95 ****
        *(index + a)= xcolor.pixel;
      }
    }
!   else {
      if ((visual->class == PseudoColor) || (visual->class == GrayScale)) {
        *cmap= XCreateColormap(disp, RootWindow(disp, scrn), visual, AllocNone);
      }
      else
        *cmap= XCreateColormap(disp, RootWindow(disp, scrn), visual, AllocAll);
-     newmap= 1;
-   }
- 
-   if (newmap) {
      for (a= 0; a < image->rgb.used; a++) /* count entries we got */
        if (! XAllocColorCells(disp, *cmap, False, NULL, 0, index + a, 1))
  	break;
--- 87,103 ----
        *(index + a)= xcolor.pixel;
      }
    }
!   else
!     newmap= 1;
! 
!   if (newmap) {
!     if (verbose)
!       printf("  Using private colormap\n");
      if ((visual->class == PseudoColor) || (visual->class == GrayScale)) {
        *cmap= XCreateColormap(disp, RootWindow(disp, scrn), visual, AllocNone);
      }
      else
        *cmap= XCreateColormap(disp, RootWindow(disp, scrn), visual, AllocAll);
      for (a= 0; a < image->rgb.used; a++) /* count entries we got */
        if (! XAllocColorCells(disp, *cmap, False, NULL, 0, index + a, 1))
  	break;
***************
*** 140,149 ****
      }
      pixptr= image->data;
      modimageptr = image->data;
!     dpixlen = ddepth / 8;
!     if(image->pixlen != dpixlen) {  /* Need to convert depth */
! 	modimageptr = (byte *)lmalloc(image->height * image->width * dpixlen);
!     }
      destptr = modimageptr;
  	
      for (y= 0; y < image->height; y++)
--- 148,157 ----
      }
      pixptr= image->data;
      modimageptr = image->data;
!     dpixlen= (ddepth + 7) / 8;
!     if (image->pixlen != dpixlen) /* Need to convert depth */
! 	modimageptr=
! 	  (byte *)lmalloc(image->height * image->width * dpixlen);
      destptr = modimageptr;
  	
      for (y= 0; y < image->height; y++)
***************
*** 180,186 ****
        ximage->byte_order= MSBFirst;
  
        for (plane= 1 << (ddepth - 1); plane; plane >>= 1) {
! 	pixptr= image->data;
  	destline= bitplane;
  	for (y= 0; y < image->height; y++) {
  	  destmask= 0x80;
--- 188,194 ----
        ximage->byte_order= MSBFirst;
  
        for (plane= 1 << (ddepth - 1); plane; plane >>= 1) {
! 	pixptr= modimageptr;
  	destline= bitplane;
  	for (y= 0; y < image->height; y++) {
  	  destmask= 0x80;
diff -c src.2.01/smooth.c src.2.02/smooth.c
*** src.2.01/smooth.c	Sun Sep 30 19:04:32 1990
--- src.2.02/smooth.c	Sun Dec  2 11:58:29 1990
***************
*** 44,50 ****
      carray[a].pixel= a;
      carray[a].sum= rgb->red[a] + rgb->green[a] + rgb->blue[a];
    }
!   qsort(carray, rgb->used, sizeof(struct colorarray), colorPredicate);
    return(carray);
  }
  
--- 44,51 ----
      carray[a].pixel= a;
      carray[a].sum= rgb->red[a] + rgb->green[a] + rgb->blue[a];
    }
!   qsort((char *)carray, rgb->used, sizeof(struct colorarray),
! 	colorPredicate);
    return(carray);
  }
  
diff -c src.2.01/value.c src.2.02/value.c
*** src.2.01/value.c	Sun Sep 30 19:04:15 1990
--- src.2.02/value.c	Sat Dec  1 13:57:20 1990
***************
*** 13,19 ****
  #include "copyright.h"
  #include "image.h"
  
! unsigned long memToVal(p, len)
       byte         *p;
       unsigned int  len;
  { unsigned int  a;
--- 13,19 ----
  #include "copyright.h"
  #include "image.h"
  
! unsigned long doMemToVal(p, len)
       byte         *p;
       unsigned int  len;
  { unsigned int  a;
***************
*** 25,31 ****
    return(i);
  }
  
! void valToMem(val, p, len)
       unsigned long  val;
       byte          *p;
       unsigned int   len;
--- 25,31 ----
    return(i);
  }
  
! unsigned long doValToMem(val, p, len)
       unsigned long  val;
       byte          *p;
       unsigned int   len;
***************
*** 35,43 ****
      *(p + a)= val & 0xff;
      val >>= 8;
    }
  }
  
! unsigned long memToValLSB(p, len)
       byte         *p;
       unsigned int  len;
  { int val, a;
--- 35,44 ----
      *(p + a)= val & 0xff;
      val >>= 8;
    }
+   return(val);
  }
  
! unsigned long doMemToValLSB(p, len)
       byte         *p;
       unsigned int  len;
  { int val, a;
***************
*** 51,57 ****
  /* this is provided for orthagonality
   */
  
! void valToMemLSB(val, p, len)
       byte          *p;
       unsigned long  val;
       unsigned int   len;
--- 52,58 ----
  /* this is provided for orthagonality
   */
  
! unsigned long doValToMemLSB(val, p, len)
       byte          *p;
       unsigned long  val;
       unsigned int   len;
***************
*** 60,65 ****
--- 61,67 ----
      *(p++)= val & 0xff;
      val >>= 8;
    }
+   return(val);
  }
  
  /* this flips all the bits in a byte array at byte intervals
diff -c src.2.01/window.c src.2.02/window.c
*** src.2.01/window.c	Sun Sep 30 19:04:32 1990
--- src.2.02/window.c	Sat Dec  1 20:31:55 1990
***************
*** 13,27 ****
  #include <ctype.h>
  #include <X11/cursorfont.h>
  
- #ifdef SYSV
- #include <string.h>
- #define index strchr
- #define rindex strrchr
- #else
- char *index();
- char *rindex();
- #endif
- 
  static Window ImageWindow= 0;
  
  static void setCursor(disp, window, iw, ih, ww, wh, cursor)
--- 13,18 ----
***************
*** 154,160 ****
  }
  
  char imageInWindow(disp, scrn, image, user_geometry,
! 		   fullscreen, install, slideshow, argc, argv, verbose)
       Display      *disp;
       int           scrn;
       Image        *image;
--- 145,152 ----
  }
  
  char imageInWindow(disp, scrn, image, user_geometry,
! 		   fullscreen, install, private_cmap, slideshow,
! 		   argc, argv, verbose)
       Display      *disp;
       int           scrn;
       Image        *image;
***************
*** 161,166 ****
--- 153,159 ----
       char         *user_geometry;
       unsigned int  fullscreen;
       unsigned int  install;
+      unsigned int  private_cmap;
       unsigned int  slideshow;
       int           argc;
       char         *argv[];
***************
*** 221,227 ****
    }
  
    if (! sendImageToX(disp, scrn, DefaultVisual(disp, scrn),
! 		     image, &pixmap, &xcmap, verbose))
      exit(1);
  
    swa.background_pixel= BlackPixel(disp,scrn);
--- 214,220 ----
    }
  
    if (! sendImageToX(disp, scrn, DefaultVisual(disp, scrn),
! 		     image, &pixmap, &xcmap, private_cmap, verbose))
      exit(1);
  
    swa.background_pixel= BlackPixel(disp,scrn);
***************
*** 241,247 ****
  			       InputOutput, CopyFromParent,
  			       CWBackPixel | CWBackingStore |
  			       CWBitGravity | CWCursor | CWColormap |
! 			       CWEventMask | CWSaveUnder, &swa);
      XSetCommand(disp, ImageWindow, argv, argc);
      classHint.res_class = "Xloadimage";
      classHint.res_name=NULL;
--- 234,241 ----
  			       InputOutput, CopyFromParent,
  			       CWBackPixel | CWBackingStore |
  			       CWBitGravity | CWCursor | CWColormap |
! 			       CWEventMask | CWSaveUnder |
! 			       CWOverrideRedirect, &swa);
      XSetCommand(disp, ImageWindow, argv, argc);
      classHint.res_class = "Xloadimage";
      classHint.res_name=NULL;
***************
*** 294,302 ****
--- 288,302 ----
    XMapWindow(disp, ImageWindow);
    placeImage(image->width, image->height, winwidth, winheight, &pixx, &pixy);
    if (paint) {
+ #if 0
+     /* this will happen on ConfigureNotify; we avoid it here to keep from
+      * doing a double paint.
+      */
+ 
      blitImage(disp, pixmap, ImageWindow, gc,
  	      pixx, pixy, image->width, image->height, winwidth, winheight,
  	      0, 0, winwidth, winheight);
+ #endif
      XResizeWindow(disp, ImageWindow, winwidth, winheight);
      XChangeWindowAttributes(disp, ImageWindow, CWColormap, &swa);
    }
***************
*** 393,404 ****
        setCursor(disp, ImageWindow, image->width, image->height,
  		winwidth, winheight, &(swa.cursor));
  
!       /* repaint 
         */
  
!       blitImage(disp, pixmap, ImageWindow, gc,
! 		pixx, pixy, image->width, image->height, winwidth, winheight,
! 		0, 0, winwidth, winheight);
        break;
  
      case DestroyNotify:
--- 393,405 ----
        setCursor(disp, ImageWindow, image->width, image->height,
  		winwidth, winheight, &(swa.cursor));
  
!       /* repaint if we just changed images
         */
  
!       if (paint)
! 	blitImage(disp, pixmap, ImageWindow, gc,
! 		  pixx, pixy, image->width, image->height, winwidth, winheight,
! 		  0, 0, winwidth, winheight);
        break;
  
      case DestroyNotify:
diff -c src.2.01/xloadimage.c src.2.02/xloadimage.c
*** src.2.01/xloadimage.c	Sun Sep 30 19:04:33 1990
--- src.2.02/xloadimage.c	Sun Dec  2 13:17:06 1990
***************
*** 1,4 ****
! /* loadimage.c:
   *
   * generic image loader for X11
   *
--- 1,4 ----
! /* xloadimage.c:
   *
   * generic image loader for X11
   *
***************
*** 21,26 ****
--- 21,27 ----
  char *Options[] = {
    "onroot", /* global options */
    "border",
+   "default",
    "display",
    "fullscreen",
    "geometry",
***************
*** 29,34 ****
--- 30,36 ----
    "list",
    "install",
    "path",
+   "private",
    "quiet",
    "slideshow",
    "supported",
***************
*** 39,52 ****
    "at", /* image options */
    "background",
    "brighten",
-   "gamma",
    "center",
    "clip",
    "colors",
    "dither",
    "foreground",
    "halftone",
    "name",
    "rotate",
    "smooth",
    "xzoom",
--- 41,57 ----
    "at", /* image options */
    "background",
    "brighten",
    "center",
    "clip",
    "colors",
    "dither",
    "foreground",
+   "gamma",
+   "gray",
+   "grey",
    "halftone",
    "name",
+   "normalize",
    "rotate",
    "smooth",
    "xzoom",
***************
*** 60,73 ****
    /* global options
     */
  
!   ONROOT= 0, BORDER, DISPLAY, FULLSCREEN, GEOMETRY, HELP, IDENTIFY, LIST,
!   INSTALL, PATH, QUIET, SLIDESHOW, SUPPORTED, VERBOSE, VER_NUM, VIEW,
  
    /* local options
     */
  
!   AT, BACKGROUND, BRIGHT, GAMMA, CENTER, CLIP, COLORS, DITHER, FOREGROUND,
!   HALFTONE, NAME, ROTATE, SMOOTH, XZOOM, YZOOM, ZOOM
  };
  
  /* if an image loader needs to have our display and screen, it will get
--- 65,80 ----
    /* global options
     */
  
!   ONROOT= 0, BORDER, DEFAULT, DISPLAY, FULLSCREEN, GEOMETRY, HELP,
!   IDENTIFY, LIST, INSTALL, PATH, PRIVATE, QUIET, SLIDESHOW, SUPPORTED,
!   VERBOSE, VER_NUM, VIEW,
  
    /* local options
     */
  
!   AT, BACKGROUND, BRIGHT, CENTER, CLIP, COLORS, DITHER, FOREGROUND,
!   GAMMA, GRAY, GREY, HALFTONE, NAME, NORMALIZE, ROTATE, SMOOTH,
!   XZOOM, YZOOM, ZOOM
  };
  
  /* if an image loader needs to have our display and screen, it will get
***************
*** 78,83 ****
--- 85,100 ----
  Display *Disp= NULL;
  int      Scrn= 0;
  
+ /* used for the -default option.  this is the root weave bitmap with
+  * the bits in the order that xloadimage likes.
+  */
+ 
+ #define root_weave_width 4
+ #define root_weave_height 4
+ static byte root_weave_bits[] = {
+   0xe0, 0xb0, 0xd0, 0x70
+ };
+ 
  /* the real thing
   */
  
***************
*** 88,95 ****
--- 105,114 ----
    char         *dname;
    unsigned int  identify;
    unsigned int  install;
+   unsigned int  private_cmap;
    unsigned int  slideshow;
    unsigned int  verbose;
+   unsigned int  set_default;
    Image        *dispimage;      /* image that will be sent to the display */
    Image        *newimage;       /* new image we're loading */
    Display      *disp;           /* display we're sending to */
***************
*** 104,109 ****
--- 123,129 ----
    unsigned int  slide_colors= 0; /* images when in -slideshow mode */
    unsigned int  slide_dither= 0;
    float         slide_gamma= 1.0;
+   unsigned int  slide_normalize= 0;
    unsigned int  slide_smooth= 0;
    unsigned int  slide_xzoom= 0;
    unsigned int  slide_yzoom= 0;
***************
*** 131,136 ****
--- 151,158 ----
    fullscreen= 0;
    identify= 0;
    install= 0;
+   private_cmap= 0;
+   set_default= 0;
    slideshow= 0;
    user_geometry = NULL;
    winwidth= winheight= 0;
***************
*** 140,145 ****
--- 162,168 ----
      images[a].name= NULL;
      images[a].atx= images[a].aty= 0;
      images[a].bright= 0;
+     images[a].normalize= 0;
      images[a].gamma= 1.0;
      images[a].center= 0;
      images[a].clipx= images[a].clipy= 0;
***************
*** 165,170 ****
--- 188,194 ----
  	images[imagecount++].name= argv[a];
  	if (slideshow && (imagecount < MAXIMAGES)) {
  	  images[imagecount].bright= slide_bright;
+ 	  images[imagecount].normalize= slide_normalize;
  	  images[imagecount].gamma= slide_gamma;
  	  images[imagecount].dither= slide_dither;
  	  images[imagecount].colors= slide_colors;
***************
*** 192,197 ****
--- 216,225 ----
  	border= argv[a];
        break;
  
+     case DEFAULT:
+       set_default= 1;
+       break;
+ 
      case DISPLAY:
        if (argv[++a])
  	dname= argv[a];
***************
*** 226,231 ****
--- 254,263 ----
        showPath();
        break;
  
+     case PRIVATE:
+       private_cmap= 1;
+       break;
+ 
      case QUIET:
        verbose= 0;
        break;
***************
*** 270,275 ****
--- 302,313 ----
  	images[imagecount].bg= argv[a];
        break;
  
+     case NORMALIZE:
+       images[imagecount].normalize= 1;
+       if (slideshow)
+ 	slide_normalize= images[imagecount].normalize;
+       break;
+ 
      case BRIGHT:
        if (argv[++a]) {
  	images[imagecount].bright= atoi(argv[a]);
***************
*** 286,291 ****
--- 324,334 ----
        }
        break;
  
+     case GRAY:
+     case GREY:
+       images[imagecount].gray= 1;
+       break;
+ 
      case CENTER:
        images[imagecount].center= 1;
        break;
***************
*** 410,416 ****
      }
    }
  
!   if (!imagecount) /* NO-OP from here on */
      exit(0);
  
    if (identify) {                    /* identify the named image(s) */
--- 453,459 ----
      }
    }
  
!   if (!imagecount && !set_default) /* NO-OP from here on */
      exit(0);
  
    if (identify) {                    /* identify the named image(s) */
***************
*** 439,444 ****
--- 482,504 ----
    Scrn= scrn= DefaultScreen(disp);
    XSetIOErrorHandler(ioErrorHandler);
  
+   /* handle -default option.  this resets the colormap and loads the
+    * default root weave.
+    */
+ 
+   if (set_default) {
+     byte *old_data;
+ 
+     dispimage= newBitImage(root_weave_width, root_weave_height);
+     old_data= dispimage->data;
+     dispimage->data= root_weave_bits;
+     imageOnRoot(disp, scrn, dispimage, 0);
+     dispimage->data= old_data;
+     freeImage(dispimage);
+     if (!imagecount) /* all done */
+       exit(0);
+   }
+ 
    dispimage= NULL;
  
    if (onroot && (winwidth || winheight || images[0].center ||
***************
*** 505,512 ****
        dispimage= newimage;
      if (slideshow) {
        switch(imageInWindow(disp, scrn, dispimage, user_geometry,
! 			   fullscreen, install, slideshow, argc, argv,
! 			   verbose)) {
        case '\0': /* window got nuked by someone */
  	XCloseDisplay(disp);
  	exit(1);
--- 565,572 ----
        dispimage= newimage;
      if (slideshow) {
        switch(imageInWindow(disp, scrn, dispimage, user_geometry,
! 			   fullscreen, install, private_cmap, slideshow,
! 			   argc, argv, verbose)) {
        case '\0': /* window got nuked by someone */
  	XCloseDisplay(disp);
  	exit(1);
***************
*** 539,545 ****
    else {
      if (!slideshow)
        imageInWindow(disp, scrn, dispimage, user_geometry,
! 		    fullscreen, install, slideshow, argc, argv, verbose);
      cleanUpWindow(disp);
    }
    XCloseDisplay(disp);
--- 599,606 ----
    else {
      if (!slideshow)
        imageInWindow(disp, scrn, dispimage, user_geometry,
! 		    fullscreen, install, private_cmap, slideshow,
! 		    argc, argv, verbose);
      cleanUpWindow(disp);
    }
    XCloseDisplay(disp);
diff -c src.2.01/xloadimage.h src.2.02/xloadimage.h
*** src.2.01/xloadimage.h	Sun Sep 30 19:04:15 1990
--- src.2.02/xloadimage.h	Sun Dec  2 11:28:39 1990
***************
*** 12,17 ****
--- 12,30 ----
  #include <X11/Xlib.h>
  #include <X11/Xutil.h>
  
+ #ifdef SYSV
+ #include <string.h>
+ #ifndef index /* some SysV's do this for you */
+ #define index strchr
+ #endif
+ #ifndef rindex
+ #define rindex strrchr
+ #endif
+ #else
+ char *index();
+ char *rindex();
+ #endif
+ 
  #include "image.h"
  #include "options.h"
  
***************
*** 27,36 ****
--- 40,53 ----
    unsigned int  clipx, clipy; /* area of image to be used */
    unsigned int  clipw, cliph;
    unsigned int  dither;       /* true if image is to be dithered */
+   unsigned int  equalize;     /* true if image is to be equalized */
+   unsigned int  gray;         /* true if image is to be grayed */
+   unsigned int  normalize;    /* true if image is to be normalized */
    unsigned int  colors;       /* max # of colors to use for this image */
    int           rotate;	      /* # degrees to rotate image */
    unsigned int  smooth;       /* true if image is to be smoothed */
    char         *fg, *bg;      /* foreground/background colors if mono image */
+   unsigned int  force;        /* true if we should force alloc of new cmap */
    unsigned int  xzoom, yzoom; /* zoom percentages */
  } ImageOptions;
  
diff -c src.2.01/xloadimage.man src.2.02/xloadimage.man
*** src.2.01/xloadimage.man	Sun Sep 30 19:04:33 1990
--- src.2.02/xloadimage.man	Sun Dec  2 14:04:56 1990
***************
*** 59,64 ****
--- 59,68 ----
  This sets the background portion of the window which is not covered by
  any images to be \fIcolor\fR.
  .TP
+ -default
+ Set the root background to the default root weave.  This is the same
+ as \fIxsetroot\fR with no arguments.
+ .TP
  -display \fIdisplay_name\fR
  X11 display name to send the image(s) to.
  .TP
***************
*** 91,97 ****
  Load image(s) onto the root window instead of viewing in a window.
  This is the opposite of \fI-view\fR.  \fIXSetbg\fR has this option set
  by default.  Loading with the -onroot option will fail if enough
! sharable colors cannot be allocated from the default colormap.
  .TP
  -path
  Displays the image path and image suffixes which will be used when
--- 95,103 ----
  Load image(s) onto the root window instead of viewing in a window.
  This is the opposite of \fI-view\fR.  \fIXSetbg\fR has this option set
  by default.  Loading with the -onroot option will fail if enough
! sharable colors cannot be allocated from the default colormap.  The
! Hewlett-Packard version 2 server will not work correctly with this
! option if you are loading a color image.  See \fIBUGS\fR below.
  .TP
  -path
  Displays the image path and image suffixes which will be used when
***************
*** 98,103 ****
--- 104,115 ----
  looking for images.  These are loaded from ~/.xloadimagerc and
  optionally from a systemwide file (normally /usr/lib/xloadimagerc).
  .TP
+ -private
+ Force the use of a private colormap.  Normally colors are allocated
+ shared unless there are not enough colors available.  This option is
+ always on for the Hewlett-Packard version 2 server due to a server
+ bug.  This flag is ignored if used in conjuntion with -onroot.
+ .TP
  -quiet
  Forces \fIxloadimage\fR and \fIxview\fR to be quiet.  This is the
  default for \fIxsetbg\fR, but the others like to whistle. 
***************
*** 152,161 ****
  the first image, and the \fI-onroot\fR option is specified, the image
  will be centered on the display background. 
  .TP
- -colors \fIn\fR
- Specify the maximum number of colors to use in the image.  This is a
- way to forcibly reduce the depth of an image.
- .TP
  -clip \fIX\fR,\fIY\fR,\fIW\fR,\fIH\fR
  Clip the image before loading it.  \fIX\fR and \fIY\fR define the
  upper-left corner of the clip area, and \fIW\fR and \fIH\fR define the
--- 164,169 ----
***************
*** 162,167 ****
--- 170,179 ----
  extents of the area.  A zero value for \fIW\fR or \fIH\fR will be
  interpreted as the remainder of the image. 
  .TP
+ -colors \fIn\fR
+ Specify the maximum number of colors to use in the image.  This is a
+ way to forcibly reduce the depth of an image.
+ .TP
  -dither
  Dither a color image to monochrome using a Floyd-Steinberg dithering
  algorithm.  This happens by default when viewing color images on a
***************
*** 178,183 ****
--- 190,200 ----
  Specify the gamma correction for the display.
  The default value is 1.0, a typical display needs 2.0 to 2.5.
  .TP
+ -gray
+ Convert an image to grayscale.  This is very useful when displaying
+ colorful images on servers with limited color capability.  The
+ optional spelling \fI-grey\fR may also be used.
+ .TP
  -halftone
  Force halftone dithering of a color image when displaying on a
  monochrome display.  This option is ignored on monochrome images.
***************
*** 189,194 ****
--- 206,214 ----
  Force the next argument to be treated as an image name.  This is
  useful if the name of the image is \fI-dither\fR, for instance. 
  .TP
+ -normalize
+ Normalize a color image.
+ .TP
  -rotate \fIdegrees\fR
  Rotate the image by \fIdegrees\fR clockwise.  The number must be a
  multiple of 90.
***************
*** 260,270 ****
  change the aspect ratio of an image before display.  If you use these
  options, it is recommended that you increase the size of one of the
  dimensions instead of shrinking the other, since shrinking looses
! detail.  For instance, many GIF images have an X:Y ratio of about 2:1.
! You can correct this for viewing on a 1:1 display with either
! \fI-xzoom 50\fR or \fI-yzoom 200\fR (reduce X axis to 50% of its size
! and expand Y axis to 200% of its size, respectively) but the latter
! should be used so no detail is lost in the conversion.
  .PP
  When zooming color images up you can reduce blockiness with
  \fI-smooth\fR.  For zooms of 300% or more, I recommend two smoothing
--- 280,290 ----
  change the aspect ratio of an image before display.  If you use these
  options, it is recommended that you increase the size of one of the
  dimensions instead of shrinking the other, since shrinking looses
! detail.  For instance, many GIF and G3 FAX images have an X:Y ratio of
! about 2:1.  You can correct this for viewing on a 1:1 display with
! either \fI-xzoom 50\fR or \fI-yzoom 200\fR (reduce X axis to 50% of
! its size and expand Y axis to 200% of its size, respectively) but the
! latter should be used so no detail is lost in the conversion.
  .PP
  When zooming color images up you can reduce blockiness with
  \fI-smooth\fR.  For zooms of 300% or more, I recommend two smoothing
***************
*** 307,312 ****
--- 327,335 ----
  white background (which is standard), use \fI-foreground white
  -background black\fR.  This will work on both color and monochrome
  displays.
+ .PP
+ If you're using a display with a small colormap to display colorful
+ images, try using the \fI-gray\fR option to convert to grayscale.
  .SH PATHS AND EXTENSIONS
  The file ~/.xloadimagerc (and optionally a system-wide file) defines
  the path and default extensions that \fIxloadimage\fR will use when
***************
*** 435,437 ****
--- 458,466 ----
  Wherever possible I tried to order operations in such a way as to look
  the best possible (zooming before dithering, for instance) or to
  increase speed (zooming downward before compressing, for instance).
+ .PP
+ The Hewlett-Packard release 2 server supplied with HP 9000/300
+ machines has a bug in XAllocColor where an allocation will not work
+ correctly for the default colormap.  To work around this,
+ \fIxloadimage\fR forces the -private option on for this server.  This
+ bug also results in the failure of -onroot for any color image.
diff -c src.2.01/xwd.c src.2.02/xwd.c
*** src.2.01/xwd.c	Sun Sep 30 19:04:34 1990
--- src.2.02/xwd.c	Thu Nov 15 17:08:53 1990
***************
*** 176,184 ****
    xunits--; /* we want to use one less than the actual # of units */
    shift= (unit - trailer) * 8;
    if (header.byte_order == MSBFirst)
!     loader= memToVal;
    else
!     loader= memToValLSB;
    line= (byte *)lmalloc(dlinelen);
  
    for (y= 0; y < header.pixmap_height; y++) {
--- 176,184 ----
    xunits--; /* we want to use one less than the actual # of units */
    shift= (unit - trailer) * 8;
    if (header.byte_order == MSBFirst)
!     loader= doMemToVal;
    else
!     loader= doMemToValLSB;
    line= (byte *)lmalloc(dlinelen);
  
    for (y= 0; y < header.pixmap_height; y++) {
***************
*** 253,261 ****
    xunits= (header.pixmap_width / (unit * 8)) +
      (header.pixmap_width % (unit * 8) ? 1 : 0);
    if (header.byte_order == MSBFirst)
!     loader= memToVal;
    else
!     loader= memToValLSB;
    line= (byte *)lmalloc(dlinelen);
  
    /* for each plane, load in the bitmap and or it into the image
--- 253,261 ----
    xunits= (header.pixmap_width / (unit * 8)) +
      (header.pixmap_width % (unit * 8) ? 1 : 0);
    if (header.byte_order == MSBFirst)
!     loader= doMemToVal;
    else
!     loader= doMemToValLSB;
    line= (byte *)lmalloc(dlinelen);
  
    /* for each plane, load in the bitmap and or it into the image
***************
*** 342,350 ****
      dlinelen= depth * header.pixmap_width;
    ilinelen= image->width * image->pixlen;
    if (header.byte_order == MSBFirst)
!     loader= memToVal;
    else
!     loader= memToValLSB;
  
    line= (byte *)lmalloc(dlinelen);
  
--- 342,350 ----
      dlinelen= depth * header.pixmap_width;
    ilinelen= image->width * image->pixlen;
    if (header.byte_order == MSBFirst)
!     loader= doMemToVal;
    else
!     loader= doMemToValLSB;
  
    line= (byte *)lmalloc(dlinelen);
  
***************
*** 488,496 ****
  
    image->rgb.used= header.ncolors;
    for (a= 0; a < header.ncolors; a++) {
!     image->rgb.red[a]= memToVal(cmap[a].red, 2);
!     image->rgb.green[a]= memToVal(cmap[a].green, 2);
!     image->rgb.blue[a]= memToVal(cmap[a].blue, 2);
    }
  
    lfree(cmap);
--- 488,496 ----
  
    image->rgb.used= header.ncolors;
    for (a= 0; a < header.ncolors; a++) {
!     image->rgb.red[memToVal(cmap[a].pixel, 4)]= memToVal(cmap[a].red, 2);
!     image->rgb.green[memToVal(cmap[a].pixel, 4)]= memToVal(cmap[a].green, 2);
!     image->rgb.blue[memToVal(cmap[a].pixel, 4)]= memToVal(cmap[a].blue, 2);
    }
  
    lfree(cmap);

--
dan
----------------------------------------------------
O'Reilly && Associates   argv at sun.com / argv at ora.com
Opinions expressed reflect those of the author only.



More information about the Comp.sources.x mailing list