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