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