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     if (awt_data->awtImage == NULL) {
 406         return 0;
 407     }
 408 
 409     pPFV = XListPixmapFormats(dpy, &numpfv);
 410     if (pPFV) {
 411         for (i = 0; i < numpfv; i++) {
 412             if (pPFV[i].depth == depth) {
 413                 awt_data->awtImage->wsImageFormat = pPFV[i];
 414                 break;
 415             }
 416         }
 417         XFree(pPFV);
 418     }
 419     bpp = awt_data->awtImage->wsImageFormat.bits_per_pixel;
 420     if (bpp == 24) {
 421         bpp = 32;
 422     }
 423     awt_data->awtImage->clrdata.bitsperpixel = bpp;
 424     awt_data->awtImage->Depth = depth;
 425 
 426     if ((bpp == 32 || bpp == 16) && pVI->class == TrueColor && depth >= 15) {
 427         awt_data->AwtColorMatch = awt_color_matchTC;
 428         awt_data->awtImage->clrdata.rOff = 0;
 429         for (i = pVI->red_mask; (i & 1) == 0; i >>= 1) {
 430             awt_data->awtImage->clrdata.rOff++;
 431         }
 432         awt_data->awtImage->clrdata.rScale = 0;
 433         while (i < 0x80) {
 434             awt_data->awtImage->clrdata.rScale++;
 435             i <<= 1;
 436         }
 437         awt_data->awtImage->clrdata.gOff = 0;
 438         for (i = pVI->green_mask; (i & 1) == 0; i >>= 1) {
 439             awt_data->awtImage->clrdata.gOff++;
 440         }
 441         awt_data->awtImage->clrdata.gScale = 0;
 442         while (i < 0x80) {
 443             awt_data->awtImage->clrdata.gScale++;
 444             i <<= 1;
 445         }
 446         awt_data->awtImage->clrdata.bOff = 0;
 447         for (i = pVI->blue_mask; (i & 1) == 0; i >>= 1) {
 448             awt_data->awtImage->clrdata.bOff++;
 449         }
 450         awt_data->awtImage->clrdata.bScale = 0;
 451         while (i < 0x80) {
 452             awt_data->awtImage->clrdata.bScale++;
 453             i <<= 1;
 454         }
 455 #ifdef NEED_IMAGE_CONVERT
 456         awt_fill_imgcv(awt_data->awtImage->convert, 0, 0, DirectImageConvert);
 457         awt_fill_imgcv(awt_data->awtImage->convert,
 458                        (IMGCV_SCALEBITS | IMGCV_INSIZEBITS
 459                         | IMGCV_ALPHABITS | IMGCV_CMBITS),
 460                        (IMGCV_UNSCALED | IMGCV_BYTEIN
 461                         | IMGCV_OPAQUE | IMGCV_ICM),
 462                        (bpp == 32
 463                         ? Dir32IcmOpqUnsImageConvert
 464                         : Dir16IcmOpqUnsImageConvert));
 465         awt_fill_imgcv(awt_data->awtImage->convert,
 466                        (IMGCV_SCALEBITS | IMGCV_INSIZEBITS
 467                         | IMGCV_ALPHABITS | IMGCV_CMBITS),
 468                        (IMGCV_UNSCALED | IMGCV_BYTEIN
 469                         | IMGCV_ALPHA | IMGCV_ICM),
 470                        (bpp == 32
 471                         ? Dir32IcmTrnUnsImageConvert
 472                         : Dir16IcmTrnUnsImageConvert));
 473         awt_fill_imgcv(awt_data->awtImage->convert,
 474                        (IMGCV_SCALEBITS | IMGCV_INSIZEBITS
 475                         | IMGCV_ALPHABITS | IMGCV_CMBITS),
 476                        (IMGCV_SCALED | IMGCV_BYTEIN
 477                         | IMGCV_OPAQUE | IMGCV_ICM),
 478                        (bpp == 32
 479                         ? Dir32IcmOpqSclImageConvert
 480                         : Dir16IcmOpqSclImageConvert));
 481         awt_fill_imgcv(awt_data->awtImage->convert,
 482                        (IMGCV_SCALEBITS | IMGCV_INSIZEBITS
 483                         | IMGCV_ALPHABITS | IMGCV_CMBITS),
 484                        (IMGCV_UNSCALED | IMGCV_INTIN
 485                         | IMGCV_OPAQUE | IMGCV_DCM8),
 486                        (bpp == 32
 487                         ? Dir32DcmOpqUnsImageConvert
 488                         : Dir16DcmOpqUnsImageConvert));
 489         awt_fill_imgcv(awt_data->awtImage->convert,
 490                        (IMGCV_SCALEBITS | IMGCV_INSIZEBITS
 491                         | IMGCV_ALPHABITS | IMGCV_CMBITS),
 492                        (IMGCV_UNSCALED | IMGCV_INTIN
 493                         | IMGCV_ALPHA | IMGCV_DCM8),
 494                        (bpp == 32
 495                         ? Dir32DcmTrnUnsImageConvert
 496                         : Dir16DcmTrnUnsImageConvert));
 497         awt_fill_imgcv(awt_data->awtImage->convert,
 498                        (IMGCV_SCALEBITS | IMGCV_INSIZEBITS
 499                         | IMGCV_ALPHABITS | IMGCV_CMBITS),
 500                        (IMGCV_SCALED | IMGCV_INTIN
 501                         | IMGCV_OPAQUE | IMGCV_DCM8),
 502                        (bpp == 32
 503                         ? Dir32DcmOpqSclImageConvert
 504                         : Dir16DcmOpqSclImageConvert));
 505 #endif /* NEED_IMAGE_CONVERT */
 506     } else if (bpp <= 16 && (pVI->class == StaticGray
 507                             || pVI->class == GrayScale
 508                             || (pVI->class == PseudoColor && forcegray))) {
 509         awt_data->AwtColorMatch = awt_color_matchGS;
 510         awt_data->awtImage->clrdata.grayscale = 1;
 511         awt_data->awtImage->clrdata.bitsperpixel = MAX(bpp, 8);
 512 #ifdef NEED_IMAGE_CONVERT
 513         awt_fill_imgcv(awt_data->awtImage->convert, 0, 0, PseudoImageConvert);
 514         if (getenv("NOFSDITHER") == NULL) {
 515             awt_fill_imgcv(awt_data->awtImage->convert,
 516                            IMGCV_ORDERBITS, IMGCV_TDLRORDER,
 517                            PseudoFSImageConvert);
 518         }
 519 #endif /* NEED_IMAGE_CONVERT */
 520     } else if (depth <= 12 && (pVI->class == PseudoColor
 521                              || pVI->class == TrueColor
 522                              || pVI->class == StaticColor)) {
 523         if (pVI->class == TrueColor)
 524            awt_data->awt_num_colors = (1 << pVI->depth);
 525         awt_data->AwtColorMatch = awt_color_match;
 526         awt_data->awtImage->clrdata.bitsperpixel = MAX(bpp, 8);
 527 #ifdef NEED_IMAGE_CONVERT
 528         awt_fill_imgcv(awt_data->awtImage->convert, 0, 0, PseudoImageConvert);
 529         if (getenv("NOFSDITHER") == NULL) {
 530             awt_fill_imgcv(awt_data->awtImage->convert, IMGCV_ORDERBITS,
 531                            IMGCV_TDLRORDER, PseudoFSImageConvert);
 532             awt_fill_imgcv(awt_data->awtImage->convert,
 533                            (IMGCV_SCALEBITS | IMGCV_INSIZEBITS
 534                             | IMGCV_ALPHABITS | IMGCV_ORDERBITS
 535                             | IMGCV_CMBITS),
 536                            (IMGCV_UNSCALED | IMGCV_BYTEIN
 537                             | IMGCV_OPAQUE | IMGCV_TDLRORDER
 538                             | IMGCV_ICM),
 539                            FSColorIcmOpqUnsImageConvert);
 540             awt_fill_imgcv(awt_data->awtImage->convert,
 541                            (IMGCV_SCALEBITS | IMGCV_INSIZEBITS
 542                             | IMGCV_ALPHABITS | IMGCV_ORDERBITS
 543                             | IMGCV_CMBITS),
 544                            (IMGCV_UNSCALED | IMGCV_INTIN
 545                             | IMGCV_OPAQUE | IMGCV_TDLRORDER
 546                             | IMGCV_DCM8),
 547                            FSColorDcmOpqUnsImageConvert);
 548         }
 549         awt_fill_imgcv(awt_data->awtImage->convert,
 550                        (IMGCV_SCALEBITS | IMGCV_INSIZEBITS | IMGCV_ALPHABITS
 551                         | IMGCV_ORDERBITS | IMGCV_CMBITS),
 552                        (IMGCV_UNSCALED | IMGCV_BYTEIN | IMGCV_OPAQUE
 553                         | IMGCV_RANDORDER | IMGCV_ICM),
 554                        OrdColorIcmOpqUnsImageConvert);
 555         awt_fill_imgcv(awt_data->awtImage->convert,
 556                        (IMGCV_SCALEBITS | IMGCV_INSIZEBITS | IMGCV_ALPHABITS
 557                         | IMGCV_ORDERBITS | IMGCV_CMBITS),
 558                        (IMGCV_UNSCALED | IMGCV_INTIN | IMGCV_OPAQUE
 559                         | IMGCV_RANDORDER | IMGCV_DCM8),
 560                        OrdColorDcmOpqUnsImageConvert);
 561 #endif /* NEED_IMAGE_CONVERT */
 562     } else {
 563         free (awt_data->awtImage);
 564         return 0;
 565     }
 566 
 567     if (depth > 12) {
 568         free (awt_data->awtImage);
 569         return 1;
 570     }
 571 
 572     if (depth == 12) {
 573         paletteSize = MAX_PALETTE12_SIZE;
 574     } else {
 575         paletteSize = MAX_PALETTE8_SIZE;
 576     }
 577 
 578     if (awt_data->awt_num_colors > paletteSize) {
 579         free (awt_data->awtImage);
 580         return 0;
 581     }
 582 
 583     /* Allocate ColorData structure */
 584     awt_data->color_data = ZALLOC (_ColorData);
 585     awt_data->color_data->screendata = 1; /* This ColorData struct corresponds
 586                                              to some AWT screen/visual, so when
 587                                              any IndexColorModel using this
 588                                              struct is finalized, don't free
 589                                              the struct in freeICMColorData.
 590                                            */
 591 
 592     /*
 593      * Initialize colors array
 594      */
 595     for (i = 0; i < awt_data->awt_num_colors; i++) {
 596         cols[i].pixel = i;
 597     }
 598 
 599     awt_data->color_data->awt_Colors =
 600         (ColorEntry *)calloc(paletteSize, sizeof (ColorEntry));
 601     if (awt_data->color_data->awt_Colors == NULL) {
 602         free (awt_data->awtImage);
 603         return 0;
 604     }
 605 
 606     XQueryColors(dpy, cm, cols, awt_data->awt_num_colors);
 607     for (i = 0; i < awt_data->awt_num_colors; i++) {
 608         awt_data->color_data->awt_Colors[i].r = cols[i].red >> 8;
 609         awt_data->color_data->awt_Colors[i].g = cols[i].green >> 8;
 610         awt_data->color_data->awt_Colors[i].b = cols[i].blue >> 8;
 611         awt_data->color_data->awt_Colors[i].flags = LIKELY_COLOR;
 612     }
 613 
 614     /*
 615      * Determine which colors in the colormap can be allocated and mark
 616      * them in the colors array
 617      */
 618     nfree = 0;
 619     for (i = (paletteSize / 2); i > 0; i >>= 1) {
 620         if (XAllocColorCells(dpy, cm, False, plane_masks, 0,
 621                              freecolors + nfree, i)) {
 622             nfree += i;
 623         }
 624     }
 625 
 626     for (i = 0; i < nfree; i++) {
 627         awt_data->color_data->awt_Colors[freecolors[i]].flags = FREE_COLOR;
 628     }
 629 
 630 #ifdef DEBUG
 631     if (debug_colormap) {
 632         jio_fprintf(stdout, "%d free.\n", nfree);
 633     }
 634 #endif
 635 
 636     XFreeColors(dpy, cm, freecolors, nfree, 0);
 637 
 638     /*
 639      * Allocate the colors that are already allocated by other
 640      * applications
 641      */
 642     for (i = 0; i < awt_data->awt_num_colors; i++) {
 643         if (awt_data->color_data->awt_Colors[i].flags == LIKELY_COLOR) {
 644             awt_data->color_data->awt_Colors[i].flags = FREE_COLOR;
 645             alloc_col(dpy, cm,
 646                       awt_data->color_data->awt_Colors[i].r,
 647                       awt_data->color_data->awt_Colors[i].g,
 648                       awt_data->color_data->awt_Colors[i].b, i, awt_data);
 649         }
 650     }
 651 #ifdef DEBUG
 652     if (debug_colormap) {
 653         jio_fprintf(stdout, "got the already allocated ones\n");
 654     }
 655 #endif
 656 
 657     /*
 658      * Allocate more colors, filling the color space evenly.
 659      */
 660 
 661     alloc_col(dpy, cm, 255, 255, 255, -1, awt_data);
 662     alloc_col(dpy, cm, 0, 0, 0, -1, awt_data);
 663 
 664     if (awt_data->awtImage->clrdata.grayscale) {
 665         int g;
 666         ColorEntry *p;
 667 
 668         if (!forcemono) {
 669             for (i = 128; i > 0; i >>= 1) {
 670                 for (g = i; g < 256; g += (i * 2)) {
 671                     alloc_col(dpy, cm, g, g, g, -1, awt_data);
 672                 }
 673             }
 674         }
 675 
 676         awt_data->color_data->img_grays =
 677             (unsigned char *)calloc(256, sizeof(unsigned char));
 678         if ( awt_data->color_data->img_grays == NULL) {
 679             return 0;
 680         }
 681         for (g = 0; g < 256; g++) {
 682             int mindist, besti;
 683             int d;
 684 
 685             p = awt_data->color_data->awt_Colors;
 686             mindist = 256;
 687             besti = 0;
 688             for (i = 0 ; i < awt_data->awt_num_colors ; i++, p++) {
 689                 if (forcegray && (p->r != p->g || p->g != p->b))
 690                     continue;
 691                 if (forcemono && p->g != 0 && p->g != 255)
 692                     continue;
 693                 if (p->flags == ALLOCATED_COLOR) {
 694                     d = p->g - g;
 695                     if (d < 0) d = -d;
 696                     if (d < mindist) {
 697                         besti = i;
 698                         if (d == 0) {
 699                             break;
 700                         }
 701                         mindist = d;
 702                     }
 703                 }
 704             }
 705 
 706             awt_data->color_data->img_grays[g] = besti;
 707         }
 708 
 709 
 710         if (forcemono || (depth == 1)) {
 711             char *gammastr = getenv("HJGAMMA");
 712             double gamma = atof(gammastr ? gammastr : "1.6");
 713             if (gamma < 0.01) gamma = 1.0;
 714 #ifdef DEBUG
 715             if (debug_colormap) {
 716                 jio_fprintf(stderr, "gamma = %f\n", gamma);
 717             }
 718 #endif
 719             for (i = 0; i < 256; i++) {
 720                 img_bwgamma[i] = (int) (pow(i/255.0, gamma) * 255);
 721 #ifdef DEBUG
 722                 if (debug_colormap) {
 723                     jio_fprintf(stderr, "%3d ", img_bwgamma[i]);
 724                     if ((i & 7) == 7)
 725                         jio_fprintf(stderr, "\n");
 726                 }
 727 #endif
 728             }
 729         } else {
 730             for (i = 0; i < 256; i++) {
 731                 img_bwgamma[i] = i;
 732             }
 733         }
 734 
 735 #ifdef DEBUG
 736         if (debug_colormap) {
 737             jio_fprintf(stderr, "GrayScale initialized\n");
 738             jio_fprintf(stderr, "color table:\n");
 739             for (i = 0; i < awt_data->awt_num_colors; i++) {
 740                 jio_fprintf(stderr, "%3d: %3d %3d %3d\n",
 741                         i, awt_data->color_data->awt_Colors[i].r,
 742                         awt_data->color_data->awt_Colors[i].g,
 743                         awt_data->color_data->awt_Colors[i].b);
 744             }
 745             jio_fprintf(stderr, "gray table:\n");
 746             for (i = 0; i < 256; i++) {
 747                 jio_fprintf(stderr, "%3d ", awt_data->color_data->img_grays[i]);
 748                 if ((i & 7) == 7)
 749                     jio_fprintf(stderr, "\n");
 750             }
 751         }
 752 #endif
 753 
 754     } else {
 755 
 756         alloc_col(dpy, cm, 255, 0, 0, -1, awt_data);
 757         alloc_col(dpy, cm, 0, 255, 0, -1,awt_data);
 758         alloc_col(dpy, cm, 0, 0, 255, -1,awt_data);
 759         alloc_col(dpy, cm, 255, 255, 0, -1,awt_data);
 760         alloc_col(dpy, cm, 255, 0, 255, -1,awt_data);
 761         alloc_col(dpy, cm, 0, 255, 255, -1,awt_data);
 762         alloc_col(dpy, cm, 192, 192, 192, -1,awt_data);
 763         alloc_col(dpy, cm, 255, 128, 128, -1,awt_data);
 764         alloc_col(dpy, cm, 128, 255, 128, -1,awt_data);
 765         alloc_col(dpy, cm, 128, 128, 255, -1,awt_data);
 766         alloc_col(dpy, cm, 255, 255, 128, -1,awt_data);
 767         alloc_col(dpy, cm, 255, 128, 255, -1,awt_data);
 768         alloc_col(dpy, cm, 128, 255, 255, -1,awt_data);
 769     }
 770 
 771     allocatedColorsNum = 0;
 772     unavailableColorsNum = 0;
 773     /* we do not support more than 256 entries in the colormap
 774        even for 12-bit PseudoColor visuals */
 775     for (i = 0; i < MAX_PALETTE8_SIZE; i++) {
 776         if (awt_data->color_data->awt_Colors[i].flags == ALLOCATED_COLOR)
 777         {
 778             reds[allocatedColorsNum] = awt_data->color_data->awt_Colors[i].r;
 779             greens[allocatedColorsNum] = awt_data->color_data->awt_Colors[i].g;
 780             blues[allocatedColorsNum] = awt_data->color_data->awt_Colors[i].b;
 781             allocatedColorsNum++;
 782         } else if (awt_data->color_data->awt_Colors[i].flags ==
 783                                                         UNAVAILABLE_COLOR) {
 784             unavailableColorsNum++;
 785         }
 786     }
 787 
 788     if (depth > 8) {
 789         cmapsize = MAX_PALETTE8_SIZE - unavailableColorsNum;
 790     } else {
 791         cmapsize = 0;
 792         if (getenv("CMAPSIZE") != 0) {
 793             cmapsize = atoi(getenv("CMAPSIZE"));
 794         }
 795 
 796         if (cmapsize <= 0) {
 797             cmapsize = CMAP_ALLOC_DEFAULT;
 798         }
 799 
 800         if (cmapsize < allocatedColorsNum + unavailableColorsNum + CMAP_ALLOC_MIN) {
 801             cmapsize = allocatedColorsNum + unavailableColorsNum + CMAP_ALLOC_MIN;
 802         }
 803 
 804         if (cmapsize > CMAP_ALLOC_MAX) {
 805             cmapsize = CMAP_ALLOC_MAX;
 806         }
 807 
 808         if (cmapsize < allocatedColorsNum) {
 809             cmapsize = allocatedColorsNum;
 810         }
 811         cmapsize -= unavailableColorsNum;
 812     }
 813 
 814     k = 0;
 815     if (getenv("VIRTCUBESIZE") != 0) {
 816         k = atoi(getenv("VIRTCUBESIZE"));
 817     }
 818     if (k == 0 || (k & (k - 1)) != 0 || k > 32) {
 819         k = getVirtCubeSize();
 820     }
 821     awt_data->color_data->img_clr_tbl =
 822         (unsigned char *)calloc(LOOKUPSIZE * LOOKUPSIZE * LOOKUPSIZE,
 823                                 sizeof(unsigned char));
 824     if (awt_data->color_data->img_clr_tbl == NULL) {
 825         return 0;
 826     }
 827     img_makePalette(cmapsize, k, LOOKUPSIZE, 50, 250,
 828                     allocatedColorsNum, TRUE, reds, greens, blues,
 829                     awt_data->color_data->img_clr_tbl);
 830                     /*img_clr_tbl);*/
 831 
 832     for (i = 0; i < cmapsize; i++) {
 833         indices[i] = alloc_col(dpy, cm, reds[i], greens[i], blues[i], -1,
 834                                awt_data);
 835     }
 836     for (i = 0; i < LOOKUPSIZE * LOOKUPSIZE * LOOKUPSIZE  ; i++) {
 837         awt_data->color_data->img_clr_tbl[i] =
 838             indices[awt_data->color_data->img_clr_tbl[i]];
 839     }
 840 
 841     awt_data->color_data->img_oda_red   = &(std_img_oda_red[0][0]);
 842     awt_data->color_data->img_oda_green = &(std_img_oda_green[0][0]);
 843     awt_data->color_data->img_oda_blue  = &(std_img_oda_blue[0][0]);
 844     make_dither_arrays(cmapsize, awt_data->color_data);
 845     std_odas_computed = 1;
 846 
 847 #ifdef DEBUG
 848     if (debug_colormap) {
 849         int alloc_count = 0;
 850         int reuse_count = 0;
 851         int free_count = 0;
 852         for (i = 0; i < awt_data->awt_num_colors; i++) {
 853             switch (awt_data->color_data->awt_Colors[i].flags) {
 854               case ALLOCATED_COLOR:
 855                 alloc_count++;
 856                 break;
 857               case LIKELY_COLOR:
 858                 reuse_count++;
 859                 break;
 860               case FREE_COLOR:
 861                 free_count++;
 862                 break;
 863             }
 864         }
 865         jio_fprintf(stdout, "%d total, %d allocated, %d reused, %d still free.\n",
 866                     awt_data->awt_num_colors, alloc_count, reuse_count, free_count);
 867     }
 868 #endif
 869 
 870     /* Fill in the ICM lut and lut2cmap mapping */
 871     awt_data->color_data->awt_numICMcolors = 0;
 872     awt_data->color_data->awt_icmLUT2Colors =
 873         (unsigned char *)calloc(paletteSize, sizeof (unsigned char));
 874     awt_data->color_data->awt_icmLUT = (int *)calloc(paletteSize, sizeof(int));
 875     if (awt_data->color_data->awt_icmLUT2Colors == NULL || awt_data->color_data->awt_icmLUT == NULL) {
 876         return 0;
 877     }
 878 
 879     for (i=0; i < paletteSize; i++) {
 880         /* Keep the mapping between this lut and the actual cmap */
 881         awt_data->color_data->awt_icmLUT2Colors
 882             [awt_data->color_data->awt_numICMcolors] = i;
 883 
 884         if (awt_data->color_data->awt_Colors[i].flags == ALLOCATED_COLOR) {
 885             /* Screen IndexColorModel LUTS are always xRGB */
 886             awt_data->color_data->awt_icmLUT
 887                     [awt_data->color_data->awt_numICMcolors++] = 0xff000000 |
 888                 (awt_data->color_data->awt_Colors[i].r<<16) |
 889                 (awt_data->color_data->awt_Colors[i].g<<8) |
 890                 (awt_data->color_data->awt_Colors[i].b);
 891         } else {
 892             /* Screen IndexColorModel LUTS are always xRGB */
 893             awt_data->color_data->awt_icmLUT
 894                         [awt_data->color_data->awt_numICMcolors++] = 0;
 895         }
 896     }
 897     return 1;
 898 }
 899 #endif /* !HEADLESS */
 900 
 901 #define red(v)          (((v) >> 16) & 0xFF)
 902 #define green(v)        (((v) >>  8) & 0xFF)
 903 #define blue(v)         (((v) >>  0) & 0xFF)
 904 
 905 #ifndef HEADLESS
 906 
 907 jobject getColorSpace(JNIEnv* env, jint csID) {
 908     jclass clazz;
 909     jobject cspaceL;
 910     jmethodID mid;
 911 
 912     clazz = (*env)->FindClass(env,"java/awt/color/ColorSpace");
 913     CHECK_NULL_RETURN(clazz, NULL);
 914     mid = (*env)->GetStaticMethodID(env, clazz, "getInstance",
 915                                     "(I)Ljava/awt/color/ColorSpace;");
 916     CHECK_NULL_RETURN(mid, NULL);
 917 
 918     /* SECURITY: This is safe, because static methods cannot
 919      *           be overridden, and this method does not invoke
 920      *           client code
 921      */
 922 
 923     return (*env)->CallStaticObjectMethod(env, clazz, mid, csID);
 924 }
 925 
 926 jobject awtJNI_GetColorModel(JNIEnv *env, AwtGraphicsConfigDataPtr aData)
 927 {
 928     jobject awt_colormodel = NULL;
 929     jclass clazz;
 930     jmethodID mid;
 931 
 932     if ((*env)->PushLocalFrame(env, 16) < 0)
 933         return NULL;
 934 
 935     if ((aData->awt_visInfo.class == TrueColor) &&
 936         (aData->awt_depth >= 15))
 937     {
 938         clazz = (*env)->FindClass(env,"java/awt/image/DirectColorModel");
 939         if (clazz == NULL) {
 940             (*env)->PopLocalFrame(env, 0);
 941             return NULL;
 942         }
 943 
 944         if (!aData->isTranslucencySupported) {
 945 
 946             mid = (*env)->GetMethodID(env,clazz,"<init>","(IIIII)V");
 947 
 948             if (mid == NULL) {
 949                 (*env)->PopLocalFrame(env, 0);
 950                 return NULL;
 951             }
 952             awt_colormodel = (*env)->NewObject(env,clazz, mid,
 953                     aData->awt_visInfo.depth,
 954                     aData->awt_visInfo.red_mask,
 955                     aData->awt_visInfo.green_mask,
 956                     aData->awt_visInfo.blue_mask,
 957                     0);
 958         } else {
 959             clazz = (*env)->FindClass(env,"sun/awt/X11GraphicsConfig");
 960             if (clazz == NULL) {
 961                 (*env)->PopLocalFrame(env, 0);
 962                 return NULL;
 963             }
 964 
 965             if (aData->renderPictFormat.direct.red == 16) {
 966                 mid = (*env)->GetStaticMethodID( env,clazz,"createDCM32",
 967                         "(IIIIZ)Ljava/awt/image/DirectColorModel;");
 968 
 969                 if (mid == NULL) {
 970                     (*env)->PopLocalFrame(env, 0);
 971                     return NULL;
 972                 }
 973 
 974                 awt_colormodel = (*env)->CallStaticObjectMethod(
 975                         env,clazz, mid,
 976                         aData->renderPictFormat.direct.redMask
 977                             << aData->renderPictFormat.direct.red,
 978                         aData->renderPictFormat.direct.greenMask
 979                             << aData->renderPictFormat.direct.green,
 980                         aData->renderPictFormat.direct.blueMask
 981                             << aData->renderPictFormat.direct.blue,
 982                         aData->renderPictFormat.direct.alphaMask
 983                             << aData->renderPictFormat.direct.alpha,
 984                         JNI_TRUE);
 985             } else {
 986                 mid = (*env)->GetStaticMethodID( env,clazz,"createABGRCCM",
 987                         "()Ljava/awt/image/ComponentColorModel;");
 988 
 989                 if (mid == NULL) {
 990                     (*env)->PopLocalFrame(env, 0);
 991                     return NULL;
 992                 }
 993 
 994                 awt_colormodel = (*env)->CallStaticObjectMethod(
 995                         env,clazz, mid);
 996             }
 997         }
 998 
 999         if(awt_colormodel == NULL)
1000         {
1001             (*env)->PopLocalFrame(env, 0);
1002             return NULL;
1003         }
1004 
1005     }
1006     else if (aData->awt_visInfo.class == StaticGray &&
1007              aData->awt_num_colors == 256) {
1008         jobject cspace = NULL;
1009         jint bits[1];
1010         jintArray bitsArray;
1011         jboolean falseboolean = JNI_FALSE;
1012 
1013         cspace = getColorSpace(env, java_awt_color_ColorSpace_CS_GRAY);
1014 
1015         if (cspace == NULL) {
1016             (*env)->PopLocalFrame(env, 0);
1017             return NULL;
1018         }
1019 
1020         bits[0] = 8;
1021         bitsArray = (*env)->NewIntArray(env, 1);
1022         if (bitsArray == NULL) {
1023             (*env)->PopLocalFrame(env, 0);
1024             return NULL;
1025         } else {
1026             (*env)->SetIntArrayRegion(env, bitsArray, 0, 1, bits);
1027         }
1028 
1029         clazz = (*env)->FindClass(env,"java/awt/image/ComponentColorModel");
1030         if (clazz == NULL) {
1031             (*env)->PopLocalFrame(env, 0);
1032             return NULL;
1033         }
1034 
1035         mid = (*env)->GetMethodID(env,clazz,"<init>",
1036             "(Ljava/awt/color/ColorSpace;[IZZII)V");
1037 
1038         if (mid == NULL) {
1039             (*env)->PopLocalFrame(env, 0);
1040             return NULL;
1041         }
1042 
1043         awt_colormodel = (*env)->NewObject(env,clazz, mid,
1044                                            cspace,
1045                                            bitsArray,
1046                                            falseboolean,
1047                                            falseboolean,
1048                                            java_awt_Transparency_OPAQUE,
1049                                            java_awt_image_DataBuffer_TYPE_BYTE);
1050 
1051         if(awt_colormodel == NULL)
1052         {
1053             (*env)->PopLocalFrame(env, 0);
1054             return NULL;
1055         }
1056 
1057     } else {
1058         jint rgb[MAX_PALETTE_SIZE];
1059         jbyte valid[MAX_PALETTE_SIZE / 8], *pValid;
1060         jintArray hArray;
1061         jobject validBits = NULL;
1062         ColorEntry *c;
1063         int i, allocAllGray, b, allvalid, paletteSize;
1064         jlong pData;
1065 
1066         if (aData->awt_visInfo.depth == 12) {
1067             paletteSize = MAX_PALETTE12_SIZE;
1068         } else {
1069             paletteSize = MAX_PALETTE8_SIZE;
1070         }
1071 
1072         c = aData->color_data->awt_Colors;
1073         pValid = &valid[sizeof(valid)];
1074         allocAllGray = 1;
1075         b = 0;
1076         allvalid = 1;
1077 
1078         for (i = 0; i < paletteSize; i++, c++) {
1079             if (c->flags == ALLOCATED_COLOR) {
1080                 rgb[i] = (0xff000000 |
1081                           (c->r << 16) |
1082                           (c->g <<  8) |
1083                           (c->b <<  0));
1084                 if (c->r != c->g || c->g != c->b) {
1085                     allocAllGray = 0;
1086                 }
1087                 b |= (1 << (i % 8));
1088             } else {
1089                 rgb[i] = 0;
1090                 b &= ~(1 << (i % 8));
1091                 allvalid = 0;
1092             }
1093             if ((i % 8) == 7) {
1094                 *--pValid = b;
1095                 /* b = 0; not needed as each bit is explicitly set */
1096             }
1097         }
1098 
1099         if (allocAllGray && (aData->awtImage->clrdata.grayscale == 0)) {
1100             /*
1101               Fix for 4351638 - Gray scale HW mode on Dome frame buffer
1102                                 crashes VM on Solaris.
1103               It is possible for an X11 frame buffer to advertise a
1104               PseudoColor visual, but to force all allocated colormap
1105               entries to be gray colors.  The Dome card does this when the
1106               HW is jumpered for a grayscale monitor, but the default
1107               visual is set to PseudoColor.  In that case awtJNI_GetColorModel
1108               will be called with aData->awtImage->clrdata.grayscale == 0,
1109               but the IndexColorModel created below will detect that only
1110               gray colors exist and expect the inverse gray LUT to exist.
1111               So above when filling the hR, hG, and hB arrays we detect
1112               whether all allocated colors are gray.  If so, but
1113               aData->awtImage->clrdata.grayscale == 0, we fall into this
1114               code to set aData->awtImage->clrdata.grayscale = 1 and do
1115               other things needed for the grayscale case.
1116              */
1117 
1118             int i;
1119             int g;
1120             ColorEntry *p;
1121 
1122             aData->awtImage->clrdata.grayscale = 1;
1123 
1124             aData->color_data->img_grays =
1125                 (unsigned char *)calloc(256, sizeof(unsigned char));
1126 
1127             if (aData->color_data->img_grays == NULL) {
1128                 (*env)->PopLocalFrame(env, 0);
1129                 return NULL;
1130             }
1131 
1132             for (g = 0; g < 256; g++) {
1133                 int mindist, besti;
1134                 int d;
1135 
1136                 p = aData->color_data->awt_Colors;
1137                 mindist = 256;
1138                 besti = 0;
1139                 for (i = 0 ; i < paletteSize; i++, p++) {
1140                     if (p->flags == ALLOCATED_COLOR) {
1141                         d = p->g - g;
1142                         if (d < 0) d = -d;
1143                         if (d < mindist) {
1144                             besti = i;
1145                             if (d == 0) {
1146                                 break;
1147                             }
1148                             mindist = d;
1149                         }
1150                     }
1151                 }
1152 
1153                 aData->color_data->img_grays[g] = besti;
1154             }
1155 
1156             for (i = 0; i < 256; i++) {
1157                 img_bwgamma[i] = i;    /* REMIND: what is img_bwgamma?
1158                                         *         is it still used anywhere?
1159                                         */
1160             }
1161         }
1162 
1163         if (aData->awtImage->clrdata.grayscale) {
1164             int i;
1165             ColorEntry *p;
1166 
1167             /* For purposes of creating an IndexColorModel, use
1168                transparent black for non-allocated or non-gray colors.
1169              */
1170             p = aData->color_data->awt_Colors;
1171             b = 0;
1172             pValid = &valid[sizeof(valid)];
1173             for (i = 0; i < paletteSize; i++, p++) {
1174                 if ((p->flags != ALLOCATED_COLOR) ||
1175                     (p->r != p->g || p->g != p->b))
1176                 {
1177                     rgb[i] = 0;
1178                     b &= ~(1 << (i % 8));
1179                     allvalid = 0;
1180                 } else {
1181                     b |= (1 << (i % 8));
1182                 }
1183                 if ((i % 8) == 7) {
1184                     *--pValid = b;
1185                     /* b = 0; not needed as each bit is explicitly set */
1186                 }
1187             }
1188 
1189             if (aData->color_data->pGrayInverseLutData == NULL) {
1190                 /* Compute the inverse gray LUT for this aData->color_data
1191                    struct, if not already computed.
1192                  */
1193                 initInverseGrayLut(rgb, aData->awt_num_colors,
1194                                    aData->color_data);
1195             }
1196         }
1197 
1198         if (!allvalid) {
1199             jobject bArray = (*env)->NewByteArray(env, sizeof(valid));
1200             if (bArray == NULL)
1201             {
1202                 (*env)->PopLocalFrame(env, 0);
1203                 return NULL;
1204             }
1205             else
1206             {
1207                 (*env)->SetByteArrayRegion(env, bArray, 0, sizeof(valid),
1208                                            valid);
1209             }
1210             validBits = JNU_NewObjectByName(env,
1211                                             "java/math/BigInteger",
1212                                             "([B)V", bArray);
1213             if (validBits == NULL)
1214             {
1215                 (*env)->PopLocalFrame(env, 0);
1216                 return NULL;
1217             }
1218         }
1219 
1220         hArray = (*env)->NewIntArray(env, paletteSize);
1221         if (hArray == NULL)
1222         {
1223             (*env)->PopLocalFrame(env, 0);
1224             return NULL;
1225         }
1226         else
1227         {
1228             (*env)->SetIntArrayRegion(env, hArray, 0, paletteSize, rgb);
1229         }
1230 
1231         if (aData->awt_visInfo.depth == 8) {
1232             awt_colormodel =
1233                 JNU_NewObjectByName(env,
1234                                     "java/awt/image/IndexColorModel",
1235                                     "(II[IIILjava/math/BigInteger;)V",
1236                                     8, 256, hArray, 0,
1237                                     java_awt_image_DataBuffer_TYPE_BYTE,
1238                                     validBits);
1239         } else {
1240             awt_colormodel =
1241                 JNU_NewObjectByName(env,
1242                                     "java/awt/image/IndexColorModel",
1243                                     "(II[IIILjava/math/BigInteger;)V",
1244                                     12, 4096, hArray, 0,
1245                                     java_awt_image_DataBuffer_TYPE_USHORT,
1246                                     validBits);
1247         }
1248 
1249         if (awt_colormodel == NULL)
1250         {
1251             (*env)->PopLocalFrame(env, 0);
1252             return NULL;
1253         }
1254 
1255         /* Set pData field of ColorModel to point to ColorData */
1256         JNU_SetLongFieldFromPtr(env, awt_colormodel, g_CMpDataID,
1257                                 aData->color_data);
1258 
1259     }
1260 
1261     return (*env)->PopLocalFrame(env, awt_colormodel);
1262 }
1263 #endif /* !HEADLESS */
1264 
1265 extern jfieldID colorValueID;
1266 
1267 #ifndef HEADLESS
1268 int awtJNI_GetColor(JNIEnv *env,jobject this)
1269 {
1270     /* REMIND: should not be defaultConfig. */
1271     return awtJNI_GetColorForVis (env, this, getDefaultConfig(DefaultScreen(awt_display)));
1272 }
1273 
1274 int awtJNI_GetColorForVis (JNIEnv *env,jobject this, AwtGraphicsConfigDataPtr awt_data)
1275 {
1276     int col;
1277     jclass SYSCLR_class;
1278 
1279     if (!JNU_IsNull(env,this))
1280     {
1281         SYSCLR_class = (*env)->FindClass(env, "java/awt/SystemColor");
1282         CHECK_NULL_RETURN(SYSCLR_class, 0);
1283 
1284         if ((*env)->IsInstanceOf(env, this, SYSCLR_class)) {
1285                 /* SECURITY: This is safe, because there is no way
1286                  *           for client code to insert an object
1287                  *           that is a subclass of SystemColor
1288                  */
1289                 col = (int) JNU_CallMethodByName(env
1290                                           ,NULL
1291                                           ,this
1292                                           ,"getRGB"
1293                                           ,"()I").i;
1294                 JNU_CHECK_EXCEPTION_RETURN(env, 0);
1295         } else {
1296                 col = (int)(*env)->GetIntField(env,this,colorValueID);
1297         }
1298 
1299         if (awt_data->awt_cmap == (Colormap) NULL) {
1300             awtJNI_CreateColorData (env, awt_data, 1);
1301         }
1302 
1303         col = awt_data->AwtColorMatch(red(col), green(col), blue(col),
1304                                       awt_data);
1305         return col;
1306     }
1307 
1308     return 0;
1309 }
1310 
1311 void
1312 awt_allocate_systemrgbcolors (jint *rgbColors, int num_colors,
1313                               AwtGraphicsConfigDataPtr awtData) {
1314     int i, pixel;
1315     for (i = 0; i < num_colors; i++)
1316         pixel = alloc_col (awt_display, awtData->awt_cmap, red (rgbColors [i]),
1317                            green (rgbColors [i]), blue (rgbColors [i]), -1,
1318                            awtData);
1319 }
1320 
1321 int
1322 awtCreateX11Colormap(AwtGraphicsConfigDataPtr adata) {
1323     int screen = adata->awt_visInfo.screen;
1324     Colormap cmap = (Colormap)NULL;
1325 
1326     if (adata->awt_visInfo.visual == DefaultVisual(awt_display, screen)) {
1327         cmap = DefaultColormap(awt_display, screen);
1328     } else {
1329         Window root = RootWindow(awt_display, screen);
1330 
1331         if (adata->awt_visInfo.visual->class % 2) {
1332             Atom actual_type;
1333             int actual_format;
1334             unsigned long nitems, bytes_after;
1335             XStandardColormap *scm;
1336 
1337             XGetWindowProperty (awt_display, root, XA_RGB_DEFAULT_MAP,
1338                                 0L, 1L, False, AnyPropertyType, &actual_type,
1339                                 &actual_format, &nitems, &bytes_after,
1340                                 (unsigned char **) &scm);
1341 
1342             XGetWindowProperty (awt_display, root, XA_RGB_DEFAULT_MAP, 0L,
1343                                 bytes_after/4 + 1, False, AnyPropertyType,
1344                                 &actual_type, &actual_format, &nitems,
1345                                 &bytes_after, (unsigned char **) &scm);
1346 
1347             nitems /= (sizeof (XStandardColormap)/4);
1348             for (; nitems > 0; ++scm, --nitems)
1349                 if (scm->visualid == adata->awt_visInfo.visualid) {
1350                     cmap = scm->colormap;
1351                     break;
1352                 }
1353         }
1354         if (!cmap) {
1355             cmap = XCreateColormap (awt_display, root,
1356                                     adata->awt_visInfo.visual,
1357                                     AllocNone);
1358         }
1359     }
1360 
1361     adata->awt_cmap = cmap;
1362     if (!awt_allocate_colors(adata)) {
1363         XFreeColormap(awt_display, adata->awt_cmap);
1364         adata->awt_cmap = (Colormap)NULL;
1365         return 0;
1366     }
1367     return 1;
1368 }
1369 
1370 void
1371 awtJNI_CreateColorData(JNIEnv *env, AwtGraphicsConfigDataPtr adata,
1372                        int lock) {
1373 
1374     /* Create Colormap */
1375     if (lock) {
1376         AWT_LOCK ();
1377     }
1378 
1379     awtCreateX11Colormap(adata);
1380 
1381     /* If depth is 8, allocate system colors also...  Here
1382      * we just get the array of System Colors and allocate
1383      * it which may be a bit wasteful (if only some were
1384      * changed). But we don't know which ones were changed
1385      * and alloc-ing a pixel that is already allocated won't
1386      * hurt. */
1387 
1388     if (adata->awt_depth == 8 ||
1389         (adata->awt_depth == 12 && adata->awt_visInfo.class == PseudoColor))
1390     {
1391         jint colorVals [java_awt_SystemColor_NUM_COLORS];
1392         jclass sysColors;
1393         jfieldID colorID;
1394         jintArray colors;
1395 
1396         /* Unlock now to initialize the SystemColor class */
1397         if (lock) {
1398             AWT_UNLOCK_CHECK_EXCEPTION(env);
1399         }
1400         sysColors = (*env)->FindClass (env, "java/awt/SystemColor");
1401         CHECK_NULL(sysColors);
1402 
1403         if (lock) {
1404             AWT_LOCK ();
1405         }
1406         colorID = (*env)->GetStaticFieldID (env, sysColors,
1407                                                    "systemColors",
1408                                                    "[I");
1409 
1410         if (colorID == NULL) {
1411             if (lock) {
1412                 AWT_UNLOCK();
1413             }
1414             return;
1415         }
1416 
1417         colors = (jintArray) (*env)->GetStaticObjectField
1418                                                 (env, sysColors, colorID);
1419 
1420         (*env)->GetIntArrayRegion (env, colors, 0,
1421                                      java_awt_SystemColor_NUM_COLORS,
1422                                      (jint *) colorVals);
1423 
1424         awt_allocate_systemrgbcolors (colorVals,
1425                         (java_awt_SystemColor_NUM_COLORS - 1), adata);
1426 
1427     }
1428 
1429     if (lock) {
1430         AWT_UNLOCK ();
1431     }
1432 }
1433 
1434 #endif /* !HEADLESS */