1 /*
   2  * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 /*
  27  *      Image dithering and rendering code for X11.
  28  */
  29 
  30 #include <stdio.h>
  31 #include <stdlib.h>
  32 #include <string.h>
  33 #include <math.h>
  34 #include <sys/time.h>
  35 #include <sys/resource.h>
  36 #ifndef HEADLESS
  37 #include <X11/Xlib.h>
  38 #include <X11/Xatom.h>
  39 #include <X11/Xutil.h>
  40 #endif /* !HEADLESS */
  41 #include "awt_p.h"
  42 #include "java_awt_Color.h"
  43 #include "java_awt_SystemColor.h"
  44 #include "java_awt_color_ColorSpace.h"
  45 #include "java_awt_Transparency.h"
  46 #include "java_awt_image_DataBuffer.h"
  47 #include "img_colors.h"
  48 #include "imageInitIDs.h"
  49 #include "dither.h"
  50 
  51 #include <jni.h>
  52 #include <jni_util.h>
  53 
  54 #ifdef DEBUG
  55 static int debug_colormap = 0;
  56 #endif
  57 
  58 #define MAX_PALETTE8_SIZE (256)
  59 #define MAX_PALETTE12_SIZE (4096)
  60 #define MAX_PALETTE_SIZE MAX_PALETTE12_SIZE
  61 
  62 /* returns the absolute value x */
  63 #define ABS(x) ((x) < 0 ? -(x) : (x))
  64 
  65 #define CLIP(val,min,max)       ((val < min) ? min : ((val > max) ? max : val))
  66 
  67 #define RGBTOGRAY(r, g, b) ((int) (.299 * r + .587 * g + .114 * b + 0.5))
  68 
  69 enum {
  70     FREE_COLOR          = 0,
  71     LIKELY_COLOR        = 1,
  72     UNAVAILABLE_COLOR   = 2,
  73     ALLOCATED_COLOR     = 3
  74 };
  75 
  76 /*
  77  * Constants to control the filling of the colormap.
  78  * By default, try to allocate colors in the default colormap until
  79  * CMAP_ALLOC_DEFAULT colors are being used (by Java and/or other
  80  * applications).
  81  * For cases where the default colormap may already have a large
  82  * number of colors in it, make sure that we ourselves try to add
  83  * at least CMAP_ALLOC_MIN new colors, even if we need to allocate
  84  * more than the DEFAULT to do that.
  85  * Under no circumstances will the colormap be filled to more than
  86  * CMAP_ALLOC_MAX colors.
  87  */
  88 #define CMAP_ALLOC_MIN          100     /* minimum number of colors to "add" */
  89 #define CMAP_ALLOC_DEFAULT      200     /* default number of colors in cmap */
  90 #define CMAP_ALLOC_MAX          245     /* maximum number of colors in cmap */
  91 
  92 #ifdef __solaris__
  93 #include <sys/utsname.h>
  94 
  95 struct {
  96     char *machine;
  97     int  cubesize;
  98 } machinemap[] = {
  99     { "i86pc", LOOKUPSIZE / 4 }, /* BugTraq ID 4102599 */
 100     { "sun4c", LOOKUPSIZE / 4 },
 101     { "sun4m", LOOKUPSIZE / 2 },
 102     { "sun4d", LOOKUPSIZE / 2 },
 103     { "sun4u", LOOKUPSIZE / 1 },
 104 };
 105 
 106 #define MACHMAPSIZE     (sizeof(machinemap) / sizeof(machinemap[0]))
 107 
 108 int getVirtCubeSize() {
 109     struct utsname name;
 110     int i, ret;
 111 
 112     ret = uname(&name);
 113     if (ret < 0) {
 114 #ifdef DEBUG
 115 #include <errno.h>
 116         jio_fprintf(stderr, "uname errno = %d, using default cubesize %d\n",
 117                     errno, LOOKUPSIZE);
 118 #endif
 119         return LOOKUPSIZE;
 120     }
 121 
 122     for (i = 0; i < MACHMAPSIZE; i++) {
 123         if (strcmp(name.machine, machinemap[i].machine) == 0) {
 124 #ifdef DEBUG
 125             if (debug_colormap) {
 126                 jio_fprintf(stderr, "'%s'.cubesize = '%d'\n",
 127                             machinemap[i].machine, machinemap[i].cubesize);
 128             }
 129 #endif
 130             return machinemap[i].cubesize;
 131         }
 132     }
 133 
 134 #ifdef DEBUG
 135     if (debug_colormap) {
 136         jio_fprintf(stderr, "unknown machine '%s' using cubesize %d\n",
 137                     name.machine, LOOKUPSIZE);
 138     }
 139 #endif
 140     return LOOKUPSIZE;
 141 }
 142 #else /* __solaris__ */
 143 #define getVirtCubeSize()       (LOOKUPSIZE)
 144 #endif /* __solaris__ */
 145 
 146 unsigned char img_bwgamma[256];
 147 uns_ordered_dither_array img_oda_alpha;
 148 
 149 #ifdef NEED_IMAGE_CONVERT
 150 ImgConvertFcn DirectImageConvert;
 151 ImgConvertFcn Dir16IcmOpqUnsImageConvert;
 152 ImgConvertFcn Dir16IcmTrnUnsImageConvert;
 153 ImgConvertFcn Dir16IcmOpqSclImageConvert;
 154 ImgConvertFcn Dir16DcmOpqUnsImageConvert;
 155 ImgConvertFcn Dir16DcmTrnUnsImageConvert;
 156 ImgConvertFcn Dir16DcmOpqSclImageConvert;
 157 ImgConvertFcn Dir32IcmOpqUnsImageConvert;
 158 ImgConvertFcn Dir32IcmTrnUnsImageConvert;
 159 ImgConvertFcn Dir32IcmOpqSclImageConvert;
 160 ImgConvertFcn Dir32DcmOpqUnsImageConvert;
 161 ImgConvertFcn Dir32DcmTrnUnsImageConvert;
 162 ImgConvertFcn Dir32DcmOpqSclImageConvert;
 163 
 164 ImgConvertFcn PseudoImageConvert;
 165 ImgConvertFcn PseudoFSImageConvert;
 166 ImgConvertFcn FSColorIcmOpqUnsImageConvert;
 167 ImgConvertFcn FSColorDcmOpqUnsImageConvert;
 168 ImgConvertFcn OrdColorIcmOpqUnsImageConvert;
 169 ImgConvertFcn OrdColorDcmOpqUnsImageConvert;
 170 
 171 #endif /* NEED_IMAGE_CONVERT */
 172 
 173 #ifndef HEADLESS
 174 /*
 175  * Find the best color.
 176  */
 177 int
 178 awt_color_matchTC(int r, int g, int b, AwtGraphicsConfigDataPtr awt_data)
 179 {
 180     r = CLIP(r, 0, 255);
 181     g = CLIP(g, 0, 255);
 182     b = CLIP(b, 0, 255);
 183     return (((r >> awt_data->awtImage->clrdata.rScale)
 184                 << awt_data->awtImage->clrdata.rOff) |
 185             ((g >> awt_data->awtImage->clrdata.gScale)
 186                 << awt_data->awtImage->clrdata.gOff) |
 187             ((b >> awt_data->awtImage->clrdata.bScale)
 188                 << awt_data->awtImage->clrdata.bOff));
 189 }
 190 
 191 int
 192 awt_color_matchGS(int r, int g, int b, AwtGraphicsConfigDataPtr awt_data)
 193 {
 194     r = CLIP(r, 0, 255);
 195     g = CLIP(g, 0, 255);
 196     b = CLIP(b, 0, 255);
 197     return awt_data->color_data->img_grays[RGBTOGRAY(r, g, b)];
 198 }
 199 
 200 int
 201 awt_color_match(int r, int g, int b, AwtGraphicsConfigDataPtr awt_data)
 202 {
 203     int besti = 0;
 204     int mindist, i, t, d;
 205     ColorEntry *p = awt_data->color_data->awt_Colors;
 206 
 207     r = CLIP(r, 0, 255);
 208     g = CLIP(g, 0, 255);
 209     b = CLIP(b, 0, 255);
 210 
 211     /* look for pure gray match */
 212     if ((r == g) && (g == b)) {
 213       mindist = 256;
 214       for (i = 0 ; i < awt_data->awt_num_colors ; i++, p++)
 215         if (p->flags == ALLOCATED_COLOR) {
 216           if (! ((p->r == p->g) && (p->g == p->b)) )
 217               continue;
 218           d = ABS(p->r - r);
 219           if (d == 0)
 220               return i;
 221           if (d < mindist) {
 222               besti = i;
 223               mindist = d;
 224           }
 225         }
 226       return besti;
 227     }
 228 
 229     /* look for non-pure gray match */
 230     mindist = 256 * 256 * 256;
 231     for (i = 0 ; i < awt_data->awt_num_colors ; i++, p++)
 232         if (p->flags == ALLOCATED_COLOR) {
 233             t = p->r - r;
 234             d = t * t;
 235             if (d >= mindist)
 236                 continue;
 237             t = p->g - g;
 238             d += t * t;
 239             if (d >= mindist)
 240                 continue;
 241             t = p->b - b;
 242             d += t * t;
 243             if (d >= mindist)
 244                 continue;
 245             if (d == 0)
 246                 return i;
 247             if (d < mindist) {
 248                 besti = i;
 249                 mindist = d;
 250             }
 251         }
 252     return besti;
 253 }
 254 
 255 /*
 256  * Allocate a color in the X color map and return the pixel.
 257  * If the "expected pixel" is non-negative then we will only
 258  * accept the allocation if we get exactly that pixel value.
 259  * This prevents us from seeing a bunch of ReadWrite pixels
 260  * allocated by another imaging application and duplicating
 261  * that set of inaccessible pixels in our precious remaining
 262  * ReadOnly colormap cells.
 263  */
 264 static int
 265 alloc_col(Display *dpy, Colormap cm, int r, int g, int b, int pixel,
 266           AwtGraphicsConfigDataPtr awt_data)
 267 {
 268     XColor col;
 269 
 270     r = CLIP(r, 0, 255);
 271     g = CLIP(g, 0, 255);
 272     b = CLIP(b, 0, 255);
 273 
 274     col.flags = DoRed | DoGreen | DoBlue;
 275     col.red   = (r << 8) | r;
 276     col.green = (g << 8) | g;
 277     col.blue  = (b << 8) | b;
 278     if (XAllocColor(dpy, cm, &col)) {
 279 #ifdef DEBUG
 280         if (debug_colormap)
 281             jio_fprintf(stdout, "allocated %d (%d,%d, %d)\n", col.pixel, r, g, b);
 282 #endif
 283         if (pixel >= 0 && col.pixel != (unsigned long)pixel) {
 284             /*
 285              * If we were trying to allocate a shareable "ReadOnly"
 286              * color then we would have gotten back the expected
 287              * pixel.  If the returned pixel was different, then
 288              * the source color that we were attempting to gain
 289              * access to must be some other application's ReadWrite
 290              * private color.  We free the returned pixel so that
 291              * we won't waste precious colormap entries by duplicating
 292              * that color in the as yet unallocated entries.  We
 293              * return -1 here to indicate the failure to get the
 294              * expected pixel.
 295              */
 296 #ifdef DEBUG
 297             if (debug_colormap)
 298                 jio_fprintf(stdout, "   used by other app, freeing\n");
 299 #endif
 300             awt_data->color_data->awt_Colors[pixel].flags = UNAVAILABLE_COLOR;
 301             XFreeColors(dpy, cm, &col.pixel, 1, 0);
 302             return -1;
 303         }
 304         /*
 305          * Our current implementation doesn't support pixels which
 306          * don't fit in 8 bit (even for 12-bit visuals)
 307          */
 308         if (col.pixel > 255) {
 309 #ifdef DEBUG
 310             if (debug_colormap)
 311                 jio_fprintf(stdout, "pixel %d for (%d,%d, %d) is > 8 bit, releasing.\n",
 312                             col.pixel, r, g, b);
 313 #endif
 314             XFreeColors(dpy, cm, &col.pixel, 1, 0);
 315             return awt_color_match(r, g, b, awt_data);
 316         }
 317 
 318         awt_data->color_data->awt_Colors[col.pixel].flags = ALLOCATED_COLOR;
 319         awt_data->color_data->awt_Colors[col.pixel].r = col.red   >> 8;
 320         awt_data->color_data->awt_Colors[col.pixel].g = col.green >> 8;
 321         awt_data->color_data->awt_Colors[col.pixel].b = col.blue  >> 8;
 322         if (awt_data->color_data->awt_icmLUT != 0) {
 323             awt_data->color_data->awt_icmLUT2Colors[col.pixel] = col.pixel;
 324             awt_data->color_data->awt_icmLUT[col.pixel] =
 325                 0xff000000 |
 326                 (awt_data->color_data->awt_Colors[col.pixel].r<<16) |
 327                 (awt_data->color_data->awt_Colors[col.pixel].g<<8) |
 328                 (awt_data->color_data->awt_Colors[col.pixel].b);
 329         }
 330         return col.pixel;
 331 #ifdef DEBUG
 332     } else if (debug_colormap) {
 333         jio_fprintf(stdout, "can't allocate (%d,%d, %d)\n", r, g, b);
 334 #endif
 335     }
 336 
 337     return awt_color_match(r, g, b, awt_data);
 338 }
 339 
 340 void
 341 awt_allocate_systemcolors(XColor *colorsPtr, int num_pixels, AwtGraphicsConfigDataPtr awtData) {
 342     int i;
 343     int r, g, b, pixel;
 344 
 345     for (i=0; i < num_pixels; i++) {
 346         r = colorsPtr[i].red   >> 8;
 347         g = colorsPtr[i].green >> 8;
 348         b = colorsPtr[i].blue  >> 8;
 349         pixel = alloc_col(awt_display, awtData->awt_cmap, r, g, b, -1, awtData);
 350     }
 351 }
 352 #endif /* !HEADLESS */
 353 
 354 void
 355 awt_fill_imgcv(ImgConvertFcn **array, int mask, int value, ImgConvertFcn fcn)
 356 {
 357     int i;
 358 
 359     for (i = 0; i < NUM_IMGCV; i++) {
 360         if ((i & mask) == value) {
 361             array[i] = fcn;
 362         }
 363     }
 364 }
 365 
 366 #ifndef HEADLESS
 367 /*
 368  * called from X11Server_create() in xlib.c
 369  */
 370 int
 371 awt_allocate_colors(AwtGraphicsConfigDataPtr awt_data)
 372 {
 373     Display *dpy;
 374     unsigned long freecolors[MAX_PALETTE_SIZE], plane_masks[1];
 375     int paletteSize;
 376     XColor cols[MAX_PALETTE_SIZE];
 377     unsigned char reds[256], greens[256], blues[256];
 378     int indices[256];
 379     Colormap cm;
 380     int i, j, k, cmapsize, nfree, depth, bpp;
 381     int allocatedColorsNum, unavailableColorsNum;
 382     XPixmapFormatValues *pPFV;
 383     int numpfv;
 384     XVisualInfo *pVI;
 385     char *forcemono;
 386     char *forcegray;
 387 
 388     make_uns_ordered_dither_array(img_oda_alpha, 256);
 389 
 390 
 391     forcemono = getenv("FORCEMONO");
 392     forcegray = getenv("FORCEGRAY");
 393     if (forcemono && !forcegray)
 394         forcegray = forcemono;
 395 
 396     /*
 397      * Get the colormap and make sure we have the right visual
 398      */
 399     dpy = awt_display;
 400     cm = awt_data->awt_cmap;
 401     depth = awt_data->awt_depth;
 402     pVI = &awt_data->awt_visInfo;
 403     awt_data->awt_num_colors = awt_data->awt_visInfo.colormap_size;
 404     awt_data->awtImage = (awtImageData *) calloc (1, sizeof (awtImageData));
 405 
 406     pPFV = XListPixmapFormats(dpy, &numpfv);
 407     if (pPFV) {
 408         for (i = 0; i < numpfv; i++) {
 409             if (pPFV[i].depth == depth) {
 410                 awt_data->awtImage->wsImageFormat = pPFV[i];
 411                 break;
 412             }
 413         }
 414         XFree(pPFV);
 415     }
 416     bpp = awt_data->awtImage->wsImageFormat.bits_per_pixel;
 417     if (bpp == 24) {
 418         bpp = 32;
 419     }
 420     awt_data->awtImage->clrdata.bitsperpixel = bpp;
 421     awt_data->awtImage->Depth = depth;
 422 
 423     if ((bpp == 32 || bpp == 16) && pVI->class == TrueColor && depth >= 15) {
 424         awt_data->AwtColorMatch = awt_color_matchTC;
 425         awt_data->awtImage->clrdata.rOff = 0;
 426         for (i = pVI->red_mask; (i & 1) == 0; i >>= 1) {
 427             awt_data->awtImage->clrdata.rOff++;
 428         }
 429         awt_data->awtImage->clrdata.rScale = 0;
 430         while (i < 0x80) {
 431             awt_data->awtImage->clrdata.rScale++;
 432             i <<= 1;
 433         }
 434         awt_data->awtImage->clrdata.gOff = 0;
 435         for (i = pVI->green_mask; (i & 1) == 0; i >>= 1) {
 436             awt_data->awtImage->clrdata.gOff++;
 437         }
 438         awt_data->awtImage->clrdata.gScale = 0;
 439         while (i < 0x80) {
 440             awt_data->awtImage->clrdata.gScale++;
 441             i <<= 1;
 442         }
 443         awt_data->awtImage->clrdata.bOff = 0;
 444         for (i = pVI->blue_mask; (i & 1) == 0; i >>= 1) {
 445             awt_data->awtImage->clrdata.bOff++;
 446         }
 447         awt_data->awtImage->clrdata.bScale = 0;
 448         while (i < 0x80) {
 449             awt_data->awtImage->clrdata.bScale++;
 450             i <<= 1;
 451         }
 452 #ifdef NEED_IMAGE_CONVERT
 453         awt_fill_imgcv(awt_data->awtImage->convert, 0, 0, DirectImageConvert);
 454         awt_fill_imgcv(awt_data->awtImage->convert,
 455                        (IMGCV_SCALEBITS | IMGCV_INSIZEBITS
 456                         | IMGCV_ALPHABITS | IMGCV_CMBITS),
 457                        (IMGCV_UNSCALED | IMGCV_BYTEIN
 458                         | IMGCV_OPAQUE | IMGCV_ICM),
 459                        (bpp == 32
 460                         ? Dir32IcmOpqUnsImageConvert
 461                         : Dir16IcmOpqUnsImageConvert));
 462         awt_fill_imgcv(awt_data->awtImage->convert,
 463                        (IMGCV_SCALEBITS | IMGCV_INSIZEBITS
 464                         | IMGCV_ALPHABITS | IMGCV_CMBITS),
 465                        (IMGCV_UNSCALED | IMGCV_BYTEIN
 466                         | IMGCV_ALPHA | IMGCV_ICM),
 467                        (bpp == 32
 468                         ? Dir32IcmTrnUnsImageConvert
 469                         : Dir16IcmTrnUnsImageConvert));
 470         awt_fill_imgcv(awt_data->awtImage->convert,
 471                        (IMGCV_SCALEBITS | IMGCV_INSIZEBITS
 472                         | IMGCV_ALPHABITS | IMGCV_CMBITS),
 473                        (IMGCV_SCALED | IMGCV_BYTEIN
 474                         | IMGCV_OPAQUE | IMGCV_ICM),
 475                        (bpp == 32
 476                         ? Dir32IcmOpqSclImageConvert
 477                         : Dir16IcmOpqSclImageConvert));
 478         awt_fill_imgcv(awt_data->awtImage->convert,
 479                        (IMGCV_SCALEBITS | IMGCV_INSIZEBITS
 480                         | IMGCV_ALPHABITS | IMGCV_CMBITS),
 481                        (IMGCV_UNSCALED | IMGCV_INTIN
 482                         | IMGCV_OPAQUE | IMGCV_DCM8),
 483                        (bpp == 32
 484                         ? Dir32DcmOpqUnsImageConvert
 485                         : Dir16DcmOpqUnsImageConvert));
 486         awt_fill_imgcv(awt_data->awtImage->convert,
 487                        (IMGCV_SCALEBITS | IMGCV_INSIZEBITS
 488                         | IMGCV_ALPHABITS | IMGCV_CMBITS),
 489                        (IMGCV_UNSCALED | IMGCV_INTIN
 490                         | IMGCV_ALPHA | IMGCV_DCM8),
 491                        (bpp == 32
 492                         ? Dir32DcmTrnUnsImageConvert
 493                         : Dir16DcmTrnUnsImageConvert));
 494         awt_fill_imgcv(awt_data->awtImage->convert,
 495                        (IMGCV_SCALEBITS | IMGCV_INSIZEBITS
 496                         | IMGCV_ALPHABITS | IMGCV_CMBITS),
 497                        (IMGCV_SCALED | IMGCV_INTIN
 498                         | IMGCV_OPAQUE | IMGCV_DCM8),
 499                        (bpp == 32
 500                         ? Dir32DcmOpqSclImageConvert
 501                         : Dir16DcmOpqSclImageConvert));
 502 #endif /* NEED_IMAGE_CONVERT */
 503     } else if (bpp <= 16 && (pVI->class == StaticGray
 504                             || pVI->class == GrayScale
 505                             || (pVI->class == PseudoColor && forcegray))) {
 506         awt_data->AwtColorMatch = awt_color_matchGS;
 507         awt_data->awtImage->clrdata.grayscale = 1;
 508         awt_data->awtImage->clrdata.bitsperpixel = MAX(bpp, 8);
 509 #ifdef NEED_IMAGE_CONVERT
 510         awt_fill_imgcv(awt_data->awtImage->convert, 0, 0, PseudoImageConvert);
 511         if (getenv("NOFSDITHER") == NULL) {
 512             awt_fill_imgcv(awt_data->awtImage->convert,
 513                            IMGCV_ORDERBITS, IMGCV_TDLRORDER,
 514                            PseudoFSImageConvert);
 515         }
 516 #endif /* NEED_IMAGE_CONVERT */
 517     } else if (depth <= 12 && (pVI->class == PseudoColor
 518                              || pVI->class == TrueColor
 519                              || pVI->class == StaticColor)) {
 520         if (pVI->class == TrueColor)
 521            awt_data->awt_num_colors = (1 << pVI->depth);
 522         awt_data->AwtColorMatch = awt_color_match;
 523         awt_data->awtImage->clrdata.bitsperpixel = MAX(bpp, 8);
 524 #ifdef NEED_IMAGE_CONVERT
 525         awt_fill_imgcv(awt_data->awtImage->convert, 0, 0, PseudoImageConvert);
 526         if (getenv("NOFSDITHER") == NULL) {
 527             awt_fill_imgcv(awt_data->awtImage->convert, IMGCV_ORDERBITS,
 528                            IMGCV_TDLRORDER, PseudoFSImageConvert);
 529             awt_fill_imgcv(awt_data->awtImage->convert,
 530                            (IMGCV_SCALEBITS | IMGCV_INSIZEBITS
 531                             | IMGCV_ALPHABITS | IMGCV_ORDERBITS
 532                             | IMGCV_CMBITS),
 533                            (IMGCV_UNSCALED | IMGCV_BYTEIN
 534                             | IMGCV_OPAQUE | IMGCV_TDLRORDER
 535                             | IMGCV_ICM),
 536                            FSColorIcmOpqUnsImageConvert);
 537             awt_fill_imgcv(awt_data->awtImage->convert,
 538                            (IMGCV_SCALEBITS | IMGCV_INSIZEBITS
 539                             | IMGCV_ALPHABITS | IMGCV_ORDERBITS
 540                             | IMGCV_CMBITS),
 541                            (IMGCV_UNSCALED | IMGCV_INTIN
 542                             | IMGCV_OPAQUE | IMGCV_TDLRORDER
 543                             | IMGCV_DCM8),
 544                            FSColorDcmOpqUnsImageConvert);
 545         }
 546         awt_fill_imgcv(awt_data->awtImage->convert,
 547                        (IMGCV_SCALEBITS | IMGCV_INSIZEBITS | IMGCV_ALPHABITS
 548                         | IMGCV_ORDERBITS | IMGCV_CMBITS),
 549                        (IMGCV_UNSCALED | IMGCV_BYTEIN | IMGCV_OPAQUE
 550                         | IMGCV_RANDORDER | IMGCV_ICM),
 551                        OrdColorIcmOpqUnsImageConvert);
 552         awt_fill_imgcv(awt_data->awtImage->convert,
 553                        (IMGCV_SCALEBITS | IMGCV_INSIZEBITS | IMGCV_ALPHABITS
 554                         | IMGCV_ORDERBITS | IMGCV_CMBITS),
 555                        (IMGCV_UNSCALED | IMGCV_INTIN | IMGCV_OPAQUE
 556                         | IMGCV_RANDORDER | IMGCV_DCM8),
 557                        OrdColorDcmOpqUnsImageConvert);
 558 #endif /* NEED_IMAGE_CONVERT */
 559     } else {
 560         free (awt_data->awtImage);
 561         return 0;
 562     }
 563 
 564     if (depth > 12) {
 565         return 1;
 566     }
 567 
 568     if (depth == 12) {
 569         paletteSize = MAX_PALETTE12_SIZE;
 570     } else {
 571         paletteSize = MAX_PALETTE8_SIZE;
 572     }
 573 
 574     if (awt_data->awt_num_colors > paletteSize) {
 575         free (awt_data->awtImage);
 576         return 0;
 577     }
 578 
 579     /* Allocate ColorData structure */
 580     awt_data->color_data = ZALLOC (_ColorData);
 581     awt_data->color_data->screendata = 1; /* This ColorData struct corresponds
 582                                              to some AWT screen/visual, so when
 583                                              any IndexColorModel using this
 584                                              struct is finalized, don't free
 585                                              the struct in freeICMColorData.
 586                                            */
 587 
 588     /*
 589      * Initialize colors array
 590      */
 591     for (i = 0; i < awt_data->awt_num_colors; i++) {
 592         cols[i].pixel = i;
 593     }
 594 
 595     awt_data->color_data->awt_Colors =
 596         (ColorEntry *)calloc(paletteSize, sizeof (ColorEntry));
 597 
 598     XQueryColors(dpy, cm, cols, awt_data->awt_num_colors);
 599     for (i = 0; i < awt_data->awt_num_colors; i++) {
 600         awt_data->color_data->awt_Colors[i].r = cols[i].red >> 8;
 601         awt_data->color_data->awt_Colors[i].g = cols[i].green >> 8;
 602         awt_data->color_data->awt_Colors[i].b = cols[i].blue >> 8;
 603         awt_data->color_data->awt_Colors[i].flags = LIKELY_COLOR;
 604     }
 605 
 606     /*
 607      * Determine which colors in the colormap can be allocated and mark
 608      * them in the colors array
 609      */
 610     nfree = 0;
 611     for (i = (paletteSize / 2); i > 0; i >>= 1) {
 612         if (XAllocColorCells(dpy, cm, False, plane_masks, 0,
 613                              freecolors + nfree, i)) {
 614             nfree += i;
 615         }
 616     }
 617 
 618     for (i = 0; i < nfree; i++) {
 619         awt_data->color_data->awt_Colors[freecolors[i]].flags = FREE_COLOR;
 620     }
 621 
 622 #ifdef DEBUG
 623     if (debug_colormap) {
 624         jio_fprintf(stdout, "%d free.\n", nfree);
 625     }
 626 #endif
 627 
 628     XFreeColors(dpy, cm, freecolors, nfree, 0);
 629 
 630     /*
 631      * Allocate the colors that are already allocated by other
 632      * applications
 633      */
 634     for (i = 0; i < awt_data->awt_num_colors; i++) {
 635         if (awt_data->color_data->awt_Colors[i].flags == LIKELY_COLOR) {
 636             awt_data->color_data->awt_Colors[i].flags = FREE_COLOR;
 637             alloc_col(dpy, cm,
 638                       awt_data->color_data->awt_Colors[i].r,
 639                       awt_data->color_data->awt_Colors[i].g,
 640                       awt_data->color_data->awt_Colors[i].b, i, awt_data);
 641         }
 642     }
 643 #ifdef DEBUG
 644     if (debug_colormap) {
 645         jio_fprintf(stdout, "got the already allocated ones\n");
 646     }
 647 #endif
 648 
 649     /*
 650      * Allocate more colors, filling the color space evenly.
 651      */
 652 
 653     alloc_col(dpy, cm, 255, 255, 255, -1, awt_data);
 654     alloc_col(dpy, cm, 0, 0, 0, -1, awt_data);
 655 
 656     if (awt_data->awtImage->clrdata.grayscale) {
 657         int g;
 658         ColorEntry *p;
 659 
 660         if (!forcemono) {
 661             for (i = 128; i > 0; i >>= 1) {
 662                 for (g = i; g < 256; g += (i * 2)) {
 663                     alloc_col(dpy, cm, g, g, g, -1, awt_data);
 664                 }
 665             }
 666         }
 667 
 668         awt_data->color_data->img_grays =
 669             (unsigned char *)calloc(256, sizeof(unsigned char));
 670         for (g = 0; g < 256; g++) {
 671             int mindist, besti;
 672             int d;
 673 
 674             p = awt_data->color_data->awt_Colors;
 675             mindist = 256;
 676             besti = 0;
 677             for (i = 0 ; i < awt_data->awt_num_colors ; i++, p++) {
 678                 if (forcegray && (p->r != p->g || p->g != p->b))
 679                     continue;
 680                 if (forcemono && p->g != 0 && p->g != 255)
 681                     continue;
 682                 if (p->flags == ALLOCATED_COLOR) {
 683                     d = p->g - g;
 684                     if (d < 0) d = -d;
 685                     if (d < mindist) {
 686                         besti = i;
 687                         if (d == 0) {
 688                             break;
 689                         }
 690                         mindist = d;
 691                     }
 692                 }
 693             }
 694 
 695             awt_data->color_data->img_grays[g] = besti;
 696         }
 697 
 698 
 699         if (forcemono || (depth == 1)) {
 700             char *gammastr = getenv("HJGAMMA");
 701             double gamma = atof(gammastr ? gammastr : "1.6");
 702             if (gamma < 0.01) gamma = 1.0;
 703 #ifdef DEBUG
 704             if (debug_colormap) {
 705                 jio_fprintf(stderr, "gamma = %f\n", gamma);
 706             }
 707 #endif
 708             for (i = 0; i < 256; i++) {
 709                 img_bwgamma[i] = (int) (pow(i/255.0, gamma) * 255);
 710 #ifdef DEBUG
 711                 if (debug_colormap) {
 712                     jio_fprintf(stderr, "%3d ", img_bwgamma[i]);
 713                     if ((i & 7) == 7)
 714                         jio_fprintf(stderr, "\n");
 715                 }
 716 #endif
 717             }
 718         } else {
 719             for (i = 0; i < 256; i++) {
 720                 img_bwgamma[i] = i;
 721             }
 722         }
 723 
 724 #ifdef DEBUG
 725         if (debug_colormap) {
 726             jio_fprintf(stderr, "GrayScale initialized\n");
 727             jio_fprintf(stderr, "color table:\n");
 728             for (i = 0; i < awt_data->awt_num_colors; i++) {
 729                 jio_fprintf(stderr, "%3d: %3d %3d %3d\n",
 730                         i, awt_data->color_data->awt_Colors[i].r,
 731                         awt_data->color_data->awt_Colors[i].g,
 732                         awt_data->color_data->awt_Colors[i].b);
 733             }
 734             jio_fprintf(stderr, "gray table:\n");
 735             for (i = 0; i < 256; i++) {
 736                 jio_fprintf(stderr, "%3d ", awt_data->color_data->img_grays[i]);
 737                 if ((i & 7) == 7)
 738                     jio_fprintf(stderr, "\n");
 739             }
 740         }
 741 #endif
 742 
 743     } else {
 744 
 745         alloc_col(dpy, cm, 255, 0, 0, -1, awt_data);
 746         alloc_col(dpy, cm, 0, 255, 0, -1,awt_data);
 747         alloc_col(dpy, cm, 0, 0, 255, -1,awt_data);
 748         alloc_col(dpy, cm, 255, 255, 0, -1,awt_data);
 749         alloc_col(dpy, cm, 255, 0, 255, -1,awt_data);
 750         alloc_col(dpy, cm, 0, 255, 255, -1,awt_data);
 751         alloc_col(dpy, cm, 192, 192, 192, -1,awt_data);
 752         alloc_col(dpy, cm, 255, 128, 128, -1,awt_data);
 753         alloc_col(dpy, cm, 128, 255, 128, -1,awt_data);
 754         alloc_col(dpy, cm, 128, 128, 255, -1,awt_data);
 755         alloc_col(dpy, cm, 255, 255, 128, -1,awt_data);
 756         alloc_col(dpy, cm, 255, 128, 255, -1,awt_data);
 757         alloc_col(dpy, cm, 128, 255, 255, -1,awt_data);
 758     }
 759 
 760     allocatedColorsNum = 0;
 761     unavailableColorsNum = 0;
 762     /* we do not support more than 256 entries in the colormap
 763        even for 12-bit PseudoColor visuals */
 764     for (i = 0; i < MAX_PALETTE8_SIZE; i++) {
 765         if (awt_data->color_data->awt_Colors[i].flags == ALLOCATED_COLOR)
 766         {
 767             reds[allocatedColorsNum] = awt_data->color_data->awt_Colors[i].r;
 768             greens[allocatedColorsNum] = awt_data->color_data->awt_Colors[i].g;
 769             blues[allocatedColorsNum] = awt_data->color_data->awt_Colors[i].b;
 770             allocatedColorsNum++;
 771         } else if (awt_data->color_data->awt_Colors[i].flags ==
 772                                                         UNAVAILABLE_COLOR) {
 773             unavailableColorsNum++;
 774         }
 775     }
 776 
 777     if (depth > 8) {
 778         cmapsize = MAX_PALETTE8_SIZE - unavailableColorsNum;
 779     } else {
 780         cmapsize = 0;
 781         if (getenv("CMAPSIZE") != 0) {
 782             cmapsize = atoi(getenv("CMAPSIZE"));
 783         }
 784 
 785         if (cmapsize <= 0) {
 786             cmapsize = CMAP_ALLOC_DEFAULT;
 787         }
 788 
 789         if (cmapsize < allocatedColorsNum + unavailableColorsNum + CMAP_ALLOC_MIN) {
 790             cmapsize = allocatedColorsNum + unavailableColorsNum + CMAP_ALLOC_MIN;
 791         }
 792 
 793         if (cmapsize > CMAP_ALLOC_MAX) {
 794             cmapsize = CMAP_ALLOC_MAX;
 795         }
 796 
 797         if (cmapsize < allocatedColorsNum) {
 798             cmapsize = allocatedColorsNum;
 799         }
 800         cmapsize -= unavailableColorsNum;
 801     }
 802 
 803     k = 0;
 804     if (getenv("VIRTCUBESIZE") != 0) {
 805         k = atoi(getenv("VIRTCUBESIZE"));
 806     }
 807     if (k == 0 || (k & (k - 1)) != 0 || k > 32) {
 808         k = getVirtCubeSize();
 809     }
 810     awt_data->color_data->img_clr_tbl =
 811         (unsigned char *)calloc(LOOKUPSIZE * LOOKUPSIZE * LOOKUPSIZE,
 812                                 sizeof(unsigned char));
 813     img_makePalette(cmapsize, k, LOOKUPSIZE, 50, 250,
 814                     allocatedColorsNum, TRUE, reds, greens, blues,
 815                     awt_data->color_data->img_clr_tbl);
 816                     /*img_clr_tbl);*/
 817 
 818     for (i = 0; i < cmapsize; i++) {
 819         indices[i] = alloc_col(dpy, cm, reds[i], greens[i], blues[i], -1,
 820                                awt_data);
 821     }
 822     for (i = 0; i < LOOKUPSIZE * LOOKUPSIZE * LOOKUPSIZE  ; i++) {
 823         awt_data->color_data->img_clr_tbl[i] =
 824             indices[awt_data->color_data->img_clr_tbl[i]];
 825     }
 826 
 827     awt_data->color_data->img_oda_red   = &(std_img_oda_red[0][0]);
 828     awt_data->color_data->img_oda_green = &(std_img_oda_green[0][0]);
 829     awt_data->color_data->img_oda_blue  = &(std_img_oda_blue[0][0]);
 830     make_dither_arrays(cmapsize, awt_data->color_data);
 831     std_odas_computed = 1;
 832 
 833 #ifdef DEBUG
 834     if (debug_colormap) {
 835         int alloc_count = 0;
 836         int reuse_count = 0;
 837         int free_count = 0;
 838         for (i = 0; i < awt_data->awt_num_colors; i++) {
 839             switch (awt_data->color_data->awt_Colors[i].flags) {
 840               case ALLOCATED_COLOR:
 841                 alloc_count++;
 842                 break;
 843               case LIKELY_COLOR:
 844                 reuse_count++;
 845                 break;
 846               case FREE_COLOR:
 847                 free_count++;
 848                 break;
 849             }
 850         }
 851         jio_fprintf(stdout, "%d total, %d allocated, %d reused, %d still free.\n",
 852                     awt_data->awt_num_colors, alloc_count, reuse_count, free_count);
 853     }
 854 #endif
 855 
 856     /* Fill in the ICM lut and lut2cmap mapping */
 857     awt_data->color_data->awt_numICMcolors = 0;
 858     awt_data->color_data->awt_icmLUT2Colors =
 859         (unsigned char *)calloc(paletteSize, sizeof (unsigned char));
 860     awt_data->color_data->awt_icmLUT = (int *)calloc(paletteSize, sizeof(int));
 861     for (i=0; i < paletteSize; i++) {
 862         /* Keep the mapping between this lut and the actual cmap */
 863         awt_data->color_data->awt_icmLUT2Colors
 864             [awt_data->color_data->awt_numICMcolors] = i;
 865 
 866         if (awt_data->color_data->awt_Colors[i].flags == ALLOCATED_COLOR) {
 867             /* Screen IndexColorModel LUTS are always xRGB */
 868             awt_data->color_data->awt_icmLUT
 869                     [awt_data->color_data->awt_numICMcolors++] = 0xff000000 |
 870                 (awt_data->color_data->awt_Colors[i].r<<16) |
 871                 (awt_data->color_data->awt_Colors[i].g<<8) |
 872                 (awt_data->color_data->awt_Colors[i].b);
 873         } else {
 874             /* Screen IndexColorModel LUTS are always xRGB */
 875             awt_data->color_data->awt_icmLUT
 876                         [awt_data->color_data->awt_numICMcolors++] = 0;
 877         }
 878     }
 879     return 1;
 880 }
 881 #endif /* !HEADLESS */
 882 
 883 #define red(v)          (((v) >> 16) & 0xFF)
 884 #define green(v)        (((v) >>  8) & 0xFF)
 885 #define blue(v)         (((v) >>  0) & 0xFF)
 886 
 887 #ifndef HEADLESS
 888 
 889 jobject getColorSpace(JNIEnv* env, jint csID) {
 890     jclass clazz;
 891     jobject cspaceL;
 892     jmethodID mid;
 893 
 894     clazz = (*env)->FindClass(env,"java/awt/color/ColorSpace");
 895     CHECK_NULL_RETURN(clazz, NULL);
 896     mid = (*env)->GetStaticMethodID(env, clazz, "getInstance",
 897                                     "(I)Ljava/awt/color/ColorSpace;");
 898     CHECK_NULL_RETURN(mid, NULL);
 899 
 900     /* SECURITY: This is safe, because static methods cannot
 901      *           be overridden, and this method does not invoke
 902      *           client code
 903      */
 904 
 905     return (*env)->CallStaticObjectMethod(env, clazz, mid, csID);
 906 }
 907 
 908 jobject awtJNI_GetColorModel(JNIEnv *env, AwtGraphicsConfigDataPtr aData)
 909 {
 910     jobject awt_colormodel = NULL;
 911     jclass clazz;
 912     jmethodID mid;
 913 
 914     if ((*env)->PushLocalFrame(env, 16) < 0)
 915         return NULL;
 916 
 917     if ((aData->awt_visInfo.class == TrueColor) &&
 918         (aData->awt_depth >= 15))
 919     {
 920         clazz = (*env)->FindClass(env,"java/awt/image/DirectColorModel");
 921         if (clazz == NULL) {
 922             (*env)->PopLocalFrame(env, 0);
 923             return NULL;
 924         }
 925 
 926         if (!aData->isTranslucencySupported) {
 927 
 928             mid = (*env)->GetMethodID(env,clazz,"<init>","(IIIII)V");
 929 
 930             if (mid == NULL) {
 931                 (*env)->PopLocalFrame(env, 0);
 932                 return NULL;
 933             }
 934             awt_colormodel = (*env)->NewObject(env,clazz, mid,
 935                     aData->awt_visInfo.depth,
 936                     aData->awt_visInfo.red_mask,
 937                     aData->awt_visInfo.green_mask,
 938                     aData->awt_visInfo.blue_mask,
 939                     0);
 940         } else {
 941             clazz = (*env)->FindClass(env,"sun/awt/X11GraphicsConfig");
 942             if (clazz == NULL) {
 943                 (*env)->PopLocalFrame(env, 0);
 944                 return NULL;
 945             }
 946 
 947             if (aData->renderPictFormat.direct.red == 16) {
 948                 mid = (*env)->GetStaticMethodID( env,clazz,"createDCM32",
 949                         "(IIIIZ)Ljava/awt/image/DirectColorModel;");
 950 
 951                 if (mid == NULL) {
 952                     (*env)->PopLocalFrame(env, 0);
 953                     return NULL;
 954                 }
 955 
 956                 awt_colormodel = (*env)->CallStaticObjectMethod(
 957                         env,clazz, mid,
 958                         aData->renderPictFormat.direct.redMask
 959                             << aData->renderPictFormat.direct.red,
 960                         aData->renderPictFormat.direct.greenMask
 961                             << aData->renderPictFormat.direct.green,
 962                         aData->renderPictFormat.direct.blueMask
 963                             << aData->renderPictFormat.direct.blue,
 964                         aData->renderPictFormat.direct.alphaMask
 965                             << aData->renderPictFormat.direct.alpha,
 966                         JNI_TRUE);
 967             } else {
 968                 mid = (*env)->GetStaticMethodID( env,clazz,"createABGRCCM",
 969                         "()Ljava/awt/image/ComponentColorModel;");
 970 
 971                 if (mid == NULL) {
 972                     (*env)->PopLocalFrame(env, 0);
 973                     return NULL;
 974                 }
 975 
 976                 awt_colormodel = (*env)->CallStaticObjectMethod(
 977                         env,clazz, mid);
 978             }
 979         }
 980 
 981         if(awt_colormodel == NULL)
 982         {
 983             (*env)->PopLocalFrame(env, 0);
 984             return NULL;
 985         }
 986 
 987     }
 988     else if (aData->awt_visInfo.class == StaticGray &&
 989              aData->awt_num_colors == 256) {
 990         jobject cspace = NULL;
 991         jint bits[1];
 992         jintArray bitsArray;
 993         jboolean falseboolean = JNI_FALSE;
 994 
 995         cspace = getColorSpace(env, java_awt_color_ColorSpace_CS_GRAY);
 996 
 997         if (cspace == NULL) {
 998             (*env)->PopLocalFrame(env, 0);
 999             return NULL;
1000         }
1001 
1002         bits[0] = 8;
1003         bitsArray = (*env)->NewIntArray(env, 1);
1004         if (bitsArray == NULL) {
1005             (*env)->PopLocalFrame(env, 0);
1006             return NULL;
1007         } else {
1008             (*env)->SetIntArrayRegion(env, bitsArray, 0, 1, bits);
1009         }
1010 
1011         clazz = (*env)->FindClass(env,"java/awt/image/ComponentColorModel");
1012         if (clazz == NULL) {
1013             (*env)->PopLocalFrame(env, 0);
1014             return NULL;
1015         }
1016 
1017         mid = (*env)->GetMethodID(env,clazz,"<init>",
1018             "(Ljava/awt/color/ColorSpace;[IZZII)V");
1019 
1020         if (mid == NULL) {
1021             (*env)->PopLocalFrame(env, 0);
1022             return NULL;
1023         }
1024 
1025         awt_colormodel = (*env)->NewObject(env,clazz, mid,
1026                                            cspace,
1027                                            bitsArray,
1028                                            falseboolean,
1029                                            falseboolean,
1030                                            java_awt_Transparency_OPAQUE,
1031                                            java_awt_image_DataBuffer_TYPE_BYTE);
1032 
1033         if(awt_colormodel == NULL)
1034         {
1035             (*env)->PopLocalFrame(env, 0);
1036             return NULL;
1037         }
1038 
1039     } else {
1040         jint rgb[MAX_PALETTE_SIZE];
1041         jbyte valid[MAX_PALETTE_SIZE / 8], *pValid;
1042         jintArray hArray;
1043         jobject validBits = NULL;
1044         ColorEntry *c;
1045         int i, allocAllGray, b, allvalid, paletteSize;
1046         jlong pData;
1047 
1048         if (aData->awt_visInfo.depth == 12) {
1049             paletteSize = MAX_PALETTE12_SIZE;
1050         } else {
1051             paletteSize = MAX_PALETTE8_SIZE;
1052         }
1053 
1054         c = aData->color_data->awt_Colors;
1055         pValid = &valid[sizeof(valid)];
1056         allocAllGray = 1;
1057         b = 0;
1058         allvalid = 1;
1059 
1060         for (i = 0; i < paletteSize; i++, c++) {
1061             if (c->flags == ALLOCATED_COLOR) {
1062                 rgb[i] = (0xff000000 |
1063                           (c->r << 16) |
1064                           (c->g <<  8) |
1065                           (c->b <<  0));
1066                 if (c->r != c->g || c->g != c->b) {
1067                     allocAllGray = 0;
1068                 }
1069                 b |= (1 << (i % 8));
1070             } else {
1071                 rgb[i] = 0;
1072                 b &= ~(1 << (i % 8));
1073                 allvalid = 0;
1074             }
1075             if ((i % 8) == 7) {
1076                 *--pValid = b;
1077                 /* b = 0; not needed as each bit is explicitly set */
1078             }
1079         }
1080 
1081         if (allocAllGray && (aData->awtImage->clrdata.grayscale == 0)) {
1082             /*
1083               Fix for 4351638 - Gray scale HW mode on Dome frame buffer
1084                                 crashes VM on Solaris.
1085               It is possible for an X11 frame buffer to advertise a
1086               PseudoColor visual, but to force all allocated colormap
1087               entries to be gray colors.  The Dome card does this when the
1088               HW is jumpered for a grayscale monitor, but the default
1089               visual is set to PseudoColor.  In that case awtJNI_GetColorModel
1090               will be called with aData->awtImage->clrdata.grayscale == 0,
1091               but the IndexColorModel created below will detect that only
1092               gray colors exist and expect the inverse gray LUT to exist.
1093               So above when filling the hR, hG, and hB arrays we detect
1094               whether all allocated colors are gray.  If so, but
1095               aData->awtImage->clrdata.grayscale == 0, we fall into this
1096               code to set aData->awtImage->clrdata.grayscale = 1 and do
1097               other things needed for the grayscale case.
1098              */
1099 
1100             int i;
1101             int g;
1102             ColorEntry *p;
1103 
1104             aData->awtImage->clrdata.grayscale = 1;
1105 
1106             aData->color_data->img_grays =
1107                 (unsigned char *)calloc(256, sizeof(unsigned char));
1108 
1109             if (aData->color_data->img_grays == NULL) {
1110                 (*env)->PopLocalFrame(env, 0);
1111                 return NULL;
1112             }
1113 
1114             for (g = 0; g < 256; g++) {
1115                 int mindist, besti;
1116                 int d;
1117 
1118                 p = aData->color_data->awt_Colors;
1119                 mindist = 256;
1120                 besti = 0;
1121                 for (i = 0 ; i < paletteSize; i++, p++) {
1122                     if (p->flags == ALLOCATED_COLOR) {
1123                         d = p->g - g;
1124                         if (d < 0) d = -d;
1125                         if (d < mindist) {
1126                             besti = i;
1127                             if (d == 0) {
1128                                 break;
1129                             }
1130                             mindist = d;
1131                         }
1132                     }
1133                 }
1134 
1135                 aData->color_data->img_grays[g] = besti;
1136             }
1137 
1138             for (i = 0; i < 256; i++) {
1139                 img_bwgamma[i] = i;    /* REMIND: what is img_bwgamma?
1140                                         *         is it still used anywhere?
1141                                         */
1142             }
1143         }
1144 
1145         if (aData->awtImage->clrdata.grayscale) {
1146             int i;
1147             ColorEntry *p;
1148 
1149             /* For purposes of creating an IndexColorModel, use
1150                transparent black for non-allocated or non-gray colors.
1151              */
1152             p = aData->color_data->awt_Colors;
1153             b = 0;
1154             pValid = &valid[sizeof(valid)];
1155             for (i = 0; i < paletteSize; i++, p++) {
1156                 if ((p->flags != ALLOCATED_COLOR) ||
1157                     (p->r != p->g || p->g != p->b))
1158                 {
1159                     rgb[i] = 0;
1160                     b &= ~(1 << (i % 8));
1161                     allvalid = 0;
1162                 } else {
1163                     b |= (1 << (i % 8));
1164                 }
1165                 if ((i % 8) == 7) {
1166                     *--pValid = b;
1167                     /* b = 0; not needed as each bit is explicitly set */
1168                 }
1169             }
1170 
1171             if (aData->color_data->pGrayInverseLutData == NULL) {
1172                 /* Compute the inverse gray LUT for this aData->color_data
1173                    struct, if not already computed.
1174                  */
1175                 initInverseGrayLut(rgb, aData->awt_num_colors,
1176                                    aData->color_data);
1177             }
1178         }
1179 
1180         if (!allvalid) {
1181             jobject bArray = (*env)->NewByteArray(env, sizeof(valid));
1182             if (bArray == NULL)
1183             {
1184                 (*env)->PopLocalFrame(env, 0);
1185                 return NULL;
1186             }
1187             else
1188             {
1189                 (*env)->SetByteArrayRegion(env, bArray, 0, sizeof(valid),
1190                                            valid);
1191             }
1192             validBits = JNU_NewObjectByName(env,
1193                                             "java/math/BigInteger",
1194                                             "([B)V", bArray);
1195             if (validBits == NULL)
1196             {
1197                 (*env)->PopLocalFrame(env, 0);
1198                 return NULL;
1199             }
1200         }
1201 
1202         hArray = (*env)->NewIntArray(env, paletteSize);
1203         if (hArray == NULL)
1204         {
1205             (*env)->PopLocalFrame(env, 0);
1206             return NULL;
1207         }
1208         else
1209         {
1210             (*env)->SetIntArrayRegion(env, hArray, 0, paletteSize, rgb);
1211         }
1212 
1213         if (aData->awt_visInfo.depth == 8) {
1214             awt_colormodel =
1215                 JNU_NewObjectByName(env,
1216                                     "java/awt/image/IndexColorModel",
1217                                     "(II[IIILjava/math/BigInteger;)V",
1218                                     8, 256, hArray, 0,
1219                                     java_awt_image_DataBuffer_TYPE_BYTE,
1220                                     validBits);
1221         } else {
1222             awt_colormodel =
1223                 JNU_NewObjectByName(env,
1224                                     "java/awt/image/IndexColorModel",
1225                                     "(II[IIILjava/math/BigInteger;)V",
1226                                     12, 4096, hArray, 0,
1227                                     java_awt_image_DataBuffer_TYPE_USHORT,
1228                                     validBits);
1229         }
1230 
1231         if (awt_colormodel == NULL)
1232         {
1233             (*env)->PopLocalFrame(env, 0);
1234             return NULL;
1235         }
1236 
1237         /* Set pData field of ColorModel to point to ColorData */
1238         JNU_SetLongFieldFromPtr(env, awt_colormodel, g_CMpDataID,
1239                                 aData->color_data);
1240 
1241     }
1242 
1243     return (*env)->PopLocalFrame(env, awt_colormodel);
1244 }
1245 #endif /* !HEADLESS */
1246 
1247 extern jfieldID colorValueID;
1248 
1249 #ifndef HEADLESS
1250 int awtJNI_GetColor(JNIEnv *env,jobject this)
1251 {
1252     /* REMIND: should not be defaultConfig. */
1253     return awtJNI_GetColorForVis (env, this, getDefaultConfig(DefaultScreen(awt_display)));
1254 }
1255 
1256 int awtJNI_GetColorForVis (JNIEnv *env,jobject this, AwtGraphicsConfigDataPtr awt_data)
1257 {
1258     int col;
1259     jclass SYSCLR_class;
1260 
1261     if (!JNU_IsNull(env,this))
1262     {
1263         SYSCLR_class = (*env)->FindClass(env, "java/awt/SystemColor");
1264         CHECK_NULL_RETURN(SYSCLR_class, 0);
1265 
1266         if ((*env)->IsInstanceOf(env, this, SYSCLR_class)) {
1267                 /* SECURITY: This is safe, because there is no way
1268                  *           for client code to insert an object
1269                  *           that is a subclass of SystemColor
1270                  */
1271                 col = (int) JNU_CallMethodByName(env
1272                                           ,NULL
1273                                           ,this
1274                                           ,"getRGB"
1275                                           ,"()I").i;
1276                 JNU_CHECK_EXCEPTION_RETURN(env, 0);
1277         } else {
1278                 col = (int)(*env)->GetIntField(env,this,colorValueID);
1279         }
1280 
1281         if (awt_data->awt_cmap == (Colormap) NULL) {
1282             awtJNI_CreateColorData (env, awt_data, 1);
1283         }
1284 
1285         col = awt_data->AwtColorMatch(red(col), green(col), blue(col),
1286                                       awt_data);
1287         return col;
1288     }
1289 
1290     return 0;
1291 }
1292 
1293 void
1294 awt_allocate_systemrgbcolors (jint *rgbColors, int num_colors,
1295                               AwtGraphicsConfigDataPtr awtData) {
1296     int i, pixel;
1297     for (i = 0; i < num_colors; i++)
1298         pixel = alloc_col (awt_display, awtData->awt_cmap, red (rgbColors [i]),
1299                            green (rgbColors [i]), blue (rgbColors [i]), -1,
1300                            awtData);
1301 }
1302 
1303 int
1304 awtCreateX11Colormap(AwtGraphicsConfigDataPtr adata) {
1305     int screen = adata->awt_visInfo.screen;
1306     Colormap cmap = (Colormap)NULL;
1307 
1308     if (adata->awt_visInfo.visual == DefaultVisual(awt_display, screen)) {
1309         cmap = DefaultColormap(awt_display, screen);
1310     } else {
1311         Window root = RootWindow(awt_display, screen);
1312 
1313         if (adata->awt_visInfo.visual->class % 2) {
1314             Atom actual_type;
1315             int actual_format;
1316             unsigned long nitems, bytes_after;
1317             XStandardColormap *scm;
1318 
1319             XGetWindowProperty (awt_display, root, XA_RGB_DEFAULT_MAP,
1320                                 0L, 1L, False, AnyPropertyType, &actual_type,
1321                                 &actual_format, &nitems, &bytes_after,
1322                                 (unsigned char **) &scm);
1323 
1324             XGetWindowProperty (awt_display, root, XA_RGB_DEFAULT_MAP, 0L,
1325                                 bytes_after/4 + 1, False, AnyPropertyType,
1326                                 &actual_type, &actual_format, &nitems,
1327                                 &bytes_after, (unsigned char **) &scm);
1328 
1329             nitems /= (sizeof (XStandardColormap)/4);
1330             for (; nitems > 0; ++scm, --nitems)
1331                 if (scm->visualid == adata->awt_visInfo.visualid) {
1332                     cmap = scm->colormap;
1333                     break;
1334                 }
1335         }
1336         if (!cmap) {
1337             cmap = XCreateColormap (awt_display, root,
1338                                     adata->awt_visInfo.visual,
1339                                     AllocNone);
1340         }
1341     }
1342 
1343     adata->awt_cmap = cmap;
1344     if (!awt_allocate_colors(adata)) {
1345         XFreeColormap(awt_display, adata->awt_cmap);
1346         adata->awt_cmap = (Colormap)NULL;
1347         return 0;
1348     }
1349     return 1;
1350 }
1351 
1352 void
1353 awtJNI_CreateColorData(JNIEnv *env, AwtGraphicsConfigDataPtr adata,
1354                        int lock) {
1355 
1356     /* Create Colormap */
1357     if (lock) {
1358         AWT_LOCK ();
1359     }
1360 
1361     awtCreateX11Colormap(adata);
1362 
1363     /* If depth is 8, allocate system colors also...  Here
1364      * we just get the array of System Colors and allocate
1365      * it which may be a bit wasteful (if only some were
1366      * changed). But we don't know which ones were changed
1367      * and alloc-ing a pixel that is already allocated won't
1368      * hurt. */
1369 
1370     if (adata->awt_depth == 8 ||
1371         (adata->awt_depth == 12 && adata->awt_visInfo.class == PseudoColor))
1372     {
1373         jint colorVals [java_awt_SystemColor_NUM_COLORS];
1374         jclass sysColors;
1375         jfieldID colorID;
1376         jintArray colors;
1377 
1378         /* Unlock now to initialize the SystemColor class */
1379         if (lock) {
1380             AWT_UNLOCK_CHECK_EXCEPTION(env);
1381         }
1382         sysColors = (*env)->FindClass (env, "java/awt/SystemColor");
1383         CHECK_NULL(sysColors);
1384 
1385         if (lock) {
1386             AWT_LOCK ();
1387         }
1388         colorID = (*env)->GetStaticFieldID (env, sysColors,
1389                                                    "systemColors",
1390                                                    "[I");
1391 
1392         if (colorID == NULL) {
1393             if (lock) {
1394                 AWT_UNLOCK();
1395             }
1396             return;
1397         }
1398 
1399         colors = (jintArray) (*env)->GetStaticObjectField
1400                                                 (env, sysColors, colorID);
1401 
1402         (*env)->GetIntArrayRegion (env, colors, 0,
1403                                      java_awt_SystemColor_NUM_COLORS,
1404                                      (jint *) colorVals);
1405 
1406         awt_allocate_systemrgbcolors (colorVals,
1407                         (java_awt_SystemColor_NUM_COLORS - 1), adata);
1408 
1409     }
1410 
1411     if (lock) {
1412         AWT_UNLOCK ();
1413     }
1414 }
1415 
1416 #endif /* !HEADLESS */