if (colors) free(colors);
xlib_rgb_try_colormap (int nr, int ng, int nb){  int r, g, b;  int ri, gi, bi;  int r0, g0, b0;  Colormap     cmap;  XVisualInfo *visual;  XColor      *colors;  XColor       color;  unsigned long pixels[256];  unsigned long junk[256];  int i;  int d2;  unsigned int colors_needed;  int idx;  int best[256];  if (nr * ng * nb < xlib_rgb_min_colors)    return FALSE;  if (image_info->cmap_alloced) {    cmap = image_info->cmap;    visual = image_info->x_visual_info;  }  else {    cmap = image_info->default_colormap;    visual = image_info->x_visual_info;  }  colors_needed = nr * ng * nb;  for (i = 0; i < 256; i++)    {      best[i] = 192;      pixels[i] = 256;    }#ifndef GAMMA  if (!xlib_rgb_install_cmap) {    /* go out and get the colors for this colormap. */    colors = malloc(sizeof(XColor) * visual->colormap_size);    for (i=0; i < visual->colormap_size; i++){      colors[i].pixel = i;    }    XQueryColors (image_info->display,		  cmap,		  colors, visual->colormap_size);    /* find color cube colors that are already present */    for (i = 0; i < MIN (256, visual->colormap_size); i++)      {	r = colors[i].red >> 8;	g = colors[i].green >> 8;	b = colors[i].blue >> 8;	ri = (r * (nr - 1) + 128) >> 8;	gi = (g * (ng - 1) + 128) >> 8;	bi = (b * (nb - 1) + 128) >> 8;	r0 = ri * 255 / (nr - 1);	g0 = gi * 255 / (ng - 1);	b0 = bi * 255 / (nb - 1);	idx = ((ri * nr) + gi) * nb + bi;	d2 = (r - r0) * (r - r0) + (g - g0) * (g - g0) + (b - b0) * (b - b0);	if (d2 < best[idx]) {	  if (pixels[idx] < 256)	    XFreeColors(image_info->display,			cmap,			pixels + idx,			1, 0);	  else	    colors_needed--;	  color.pixel = colors[i].pixel;	  color.red = colors[i].red;	  color.green = colors[i].green;	  color.blue = colors[i].blue;	  color.flags = 0;	  if (!XAllocColor(image_info->display, cmap, &color))	    return xlib_rgb_cmap_fail ("error allocating system color\n",				      cmap, pixels);	  pixels[idx] = color.pixel; /* which is almost certainly i */	  best[idx] = d2;	}      }  }#endif  if (colors_needed)    {      if (!XAllocColorCells(image_info->display, cmap, 0, NULL, 0, junk, colors_needed))	{	  char tmp_str[80];	  	  sprintf (tmp_str,		   "%d %d %d colormap failed (in XAllocColorCells)\n",		   nr, ng, nb);	  return xlib_rgb_cmap_fail (tmp_str, cmap, pixels);	}      XFreeColors(image_info->display, cmap, junk, (int)colors_needed, 0);    }  for (r = 0, i = 0; r < nr; r++)    for (g = 0; g < ng; g++)      for (b = 0; b < nb; b++, i++)	{	  if (pixels[i] == 256)	    {	      color.red = r * 65535 / (nr - 1);	      color.green = g * 65535 / (ng - 1);	      color.blue = b * 65535 / (nb - 1);#ifdef GAMMA	      color.red = 65535 * pow (color.red / 65535.0, 0.5);	      color.green = 65535 * pow (color.green / 65535.0, 0.5);	      color.blue = 65535 * pow (color.blue / 65535.0, 0.5);#endif	      /* This should be a raw XAllocColor call */	      if (!XAllocColor(image_info->display, cmap, &color))		{		  char tmp_str[80];		  sprintf (tmp_str, "%d %d %d colormap failed\n",			   nr, ng, nb);		  return xlib_rgb_cmap_fail (tmp_str,					    cmap, pixels);		}	      pixels[i] = color.pixel;	    }#ifdef VERBOSE	  printf ("%d: %lx\n", i, pixels[i]);#endif	}  image_info->nred_shades = nr;  image_info->ngreen_shades = ng;  image_info->nblue_shades = nb;  xlib_rgb_make_colorcube (pixels, nr, ng, nb);  xlib_rgb_make_colorcube_d (pixels, nr, ng, nb);  return TRUE;}